我試圖創建一個掃描COM DLL並創建必要的註冊表項的reg文件的程序,而無需調用regsvr32並且不必具有管理權限。掃描沒有管理員權限的COM dll註冊表
爲此,我使用RegOverridePredefKey重新映射HKEY_CURRENT_USER子項中的Windows註冊表配置單元。
https://msdn.microsoft.com/pt-br/library/windows/desktop/ms724901(v=vs.85).aspx
重映射工作。我知道,因爲我可以,例如,調用一個Windows API函數來創建一個虛假的註冊表項HKEY_LOCAL_MACHINE下,它實際上出現在我的HKEY_CURRENT_USER子項下。不需要管理員權限。
下面是重映射代碼:
if (reg::remapRegistry(HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, basekey + "hkcr"))
{
if (reg::remapRegistry(HKEY_LOCAL_MACHINE, HKEY_CURRENT_USER, basekey + "hklm"))
{
if (reg::remapRegistry(HKEY_USERS, HKEY_CURRENT_USER, basekey + "hku"))
{
if (reg::remapRegistry(HKEY_CURRENT_USER, HKEY_CURRENT_USER, basekey + "hkcu"))
{
reg::createKey(HKEY_LOCAL_MACHINE, "Software\\Classes");
reg::createKey(HKEY_CURRENT_USER, "Software\\Classes");
ret = scan(args);
reg::cancelRemapedRegistry(HKEY_CURRENT_USER);
}
reg::cancelRemapedRegistry(HKEY_USERS);
}
reg::cancelRemapedRegistry(HKEY_LOCAL_MACHINE);
}
reg::cancelRemapedRegistry(HKEY_CLASSES_ROOT);
}
參數args給我的掃描功能僅僅是一個結構的路徑,我的DLL。 reg ::函數只是windows api的包裝。
這裏是我的掃描功能:
int scan(const Args &args)
{
typedef HRESULT (__stdcall *pDllRegisterServer) (void);
try
{
HMODULE hDLL = LoadLibrary(args.dll.c_str());
if (hDLL == NULL)
{
LOGERROR("Cannot load dll");
return 1;
}
pDllRegisterServer DllRegisterServer = (pDllRegisterServer) GetProcAddress(hDLL, "DllRegisterServer");
if (DllRegisterServer == NULL)
{
LOGERROR("Cannot find function DllRegisterServer in dll");
FreeLibrary(hDLL);
return 2;
}
HRESULT res = DllRegisterServer();
DWORD err = GetLastError();
switch (res)
{
case S_OK:
LOGINFO("successfully called DllRegisterServer");
return 0;
case SELFREG_E_TYPELIB:
LOGERROR("DllRegisterServer error SELFREG_E_TYPELIB");
return 3;
case SELFREG_E_CLASS:
LOGERROR("DllRegisterServer error SELFREG_E_CLASS");
return 4;
case E_OUTOFMEMORY:
LOGERROR("DllRegisterServer error E_OUTOFMEMORY");
return 5;
case E_UNEXPECTED:
LOGERROR("DllRegisterServer error E_UNEXPECTED");
return 6;
default:
LOGERROR("DllRegisterServer really unexpected error");
}
return 7;
}
catch (...)
{
LOGERROR("unknown error loading dll or function");
return -1;
}
}
中的DllRegisterServer將返回S_OK,但正在創建只有一半的註冊表項。我在HKEY_CURRENT_USER \ tempkey \ hkcr下重新映射的HKEY_CLASSES_ROOT包含所有預期的鍵。但HKEY_CURRENT_USER \ tempkey \ hklm(重映射的HKEY_LOCAL_MACHINE)僅包含我自己創建的空鍵「Software \ Classes」。它缺少DllRegisterServer應該創建的「TypeLib」和「Interface」鍵。
這不是重映射或權限問題,因爲我可以在沒有管理員權限的情況下在HKEY_LOCAL_MACHINE下創建空的「Software \ Classes」。
奇怪的是,在另一臺機器DllRegisterServer上測試失敗,出現SELFREG_E_TYPELIB。
我也嘗試調用LoadTypeLib()和RegisterTypeLib(),我得到錯誤代碼「0x8002801c訪問OLE註冊表時出錯」。
如果我然後以管理員身份重新啓動Visual Studio並再次運行該程序,我會得到所有預期的註冊表項,包括HKLM下的註冊表項。
任何想法,爲什麼它失敗,如何讓這個東西工作?
我知道有可能在沒有管理員的情況下獲取所有註冊表項,因爲wix的收穫工具heat.exe可以成功完成此操作。我已經檢查過他們的源代碼,我相信我已經在做他們正在做的一切。我不希望將wix工具集作爲構建環境的必需條件,因爲我需要將它們的文件格式解析爲* .reg文件。
您不需要管理員權限即可訪問HKCR和HKLM。你真的需要複製一切,而不是隻讀現有的條目嗎? –