之前做的项目需要注册虚拟摄像头,但是有两个不足是:
在使用Regsvr32.exe注册虚拟摄像头dll时,即便选了“不再提醒”和“允许程序所有操作”后,仍然会被360拦截;使用.bat文件调用Regsvr32.exe时,.bat文件经常被杀毒软件移除。
调研后发现自己实现Regsvr32.exe注册dll的功能的话,360只会拦截一次(有效降低,不会完全解决),重要的是这种方式通过调用exe来注册dll取代了.bat方式注册,解决了.bat文件被移除的问题。
一、Regsvr32.exe使用方式@echo off
mode con lines=30 cols=60
%1 mshta vbscript:CreateObject("Shell.Application").ShellExecute("cmd.exe","/c %~s0 ::","","runas",1)(window.close)&&exit
cd /d "%~dp0"
rem ------------------------
regsvr32 /u /s tal_virtualcamera32.dll rem 反注册
regsvr32 /u /s tal_virtualcamera64.dll rem 反注册
regsvr32 /s tal_virtualcamera32.dll rem 注册
regsvr32 /s tal_virtualcamera64.dll rem 注册
二、自实现注册功能
虚拟摄像头dll的实现可参考这篇文章,dll需要有DllRegisterServer, DllUnregisterServer, DllGetClassObject,DllCanUnloadNow四个导出函数,DllMain是 DLL 入口点:C++ | 虚拟摄像头_该用户还没想到好的昵称的博客-CSDN博客_c++虚拟摄像头
自实现注册功能,只需要调用里面的DllRegisterServer方法和DllUnregisterServer方法即可实现对控件的注册与反注册。
#include#include int main(int argc, char *argv[]) { #ifdef X86 LPCSTR path = "tal_virtualcamera32.dll"; #elif X64 LPCSTR path = "tal_virtualcamera64.dll"; #endif HMODULE dll = LoadLibrary(path); std::cout << GetLastError() << std::endl; //HMODULE dll = LoadLibraryExA(path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); if (dll) { WNDPROC temp = (WNDPROC)GetProcAddress(dll, "DllUnregisterServer"); CallWindowProc(temp, 0, 0, 0, 0); temp = (WNDPROC)GetProcAddress(dll, "DllRegisterServer"); CallWindowProc(temp, 0, 0, 0, 0); FreeLibrary(dll); } return 0; }
注意:
1.区分x86和x64,我这里用自定义宏来区分;
2.注册dll时,如果dll内部出现GetLastError()返回5,ERROR_ACCESS_DENIED,表示拒绝访问,没有访问权限,解决办法:修改UAC执行级别,用管理员权限注册dll。
3.注册dll时,如果dll内部出现CoCreateInstance返回0x800401f0,说明在CoCreateInstance之前我们应该先调用CoInitializeEx:
CoInitializeEx(NULL, COINIT_MULTITHREADED); HRESULT hr = CoCreateInstance(CLSID_FilterMapper2, NULL, CLSCTX_INPROC_SERVER, IID_IFilterMapper2, (void**)&pFM);
4.使用LoadLibrary等windows底层方法时注意编码,我这里用的非unicode。
三、资源文件TestRegsvr.zip-WindowsServer文档类资源-CSDN文库



