我正在从非托管代码调用CoCreateInstance到一个已注册的托管类(HKEY_CLASSES_ROOT\CLSID{xxxxx-xxxxxx-xxxxxx-xxxxx-xxxxxx-xxxxx} 注册表项存在,并且文件从另一个程序正确加载)。
以下是代码:
HRESULT hRC;
CoInitialize(NULL);
char* sUTProgID = "My.Utilities";
CLSID UTClassID;
hRC = CLSIDFromProgID(
_CW(sUTProgID), // Pointer to the ProgID
&UTClassID ); // Pointer to the CLSID
if ( S_OK != hRC )
{
DOTRACE((_T(" CLSIDFromProgID error 0x%X\n", hRC)));
}
IUnknown* pUnknown;
hRC = CoCreateInstance(
UTClassID, // Class identifier (CLSID) of the object
0, // Pointer to whether object is or isn't part of an aggregate
CLSCTX_ALL, // Context for running executable code
IID_IUnknown, // Reference to the identifier of the interface
(void**) &pUnknown); // Address of output variable that receives the interface pointer requested in riid
if ( S_OK != hRC )
{
//code makes it here with an 80040145 class not registered error
}
同样的代码也适用于其他应用程序。该代码是为x86编译的,并在x86机器上运行。
编辑:这是一个Windows XP机器,所以我认为UAC不适用。我已经记录了ClassID,并且确实是正确的。我还检查了ProcMon日志,显示成功访问了注册表键,并且在注册表键中访问了以下路径: InProcServer32-成功 InProcServerx86-找不到名称 LocalServer32-找不到名称 InProcHandler32-找不到名称 AppId-找不到名称 InProcServer32\ThreadingModel-成功 InProcServer32\1.0.0.0-成功 InProcServer32\1.0.0.0\assembly-缓冲区溢出 InProcServer32\1.0.0.0\assembly-成功 InProcServer32\1.0.0.0\class-成功 InProcServer32\1.0.0.0\RuntimeVersion-成功 InProcServer32\CodeBase-成功(返回文件路径)
然后检查GAC缓存,再访问几个目录,然后才能访问DLL。
CLIENT.EXE 1092 RegQueryKey HKCR\CLSID{...} SUCCESS查询:名称 CLIENT.EXE 1092 RegOpenKey HKCR\CLSID{...}\InprocHandler NAME NOT FOUND 所需访问权限:最大允许 CLIENT.EXE 1092 RegCloseKey HKCR\CLSID{9935FEE6-39FD-4EF0-87DB-8372B0992610} SUCCESS CLIENT.EXE 1092 RegOpenKey HKLM\Software\Policies\Microsoft\Windows\App Management NAME NOT FOUND 所需访问权限:查询值 CLIENT.EXE 1092 CreateFile LogFile.txt
我认为最后一个日志消息记录了错误。
编辑2: 使用以下代码注册Dll:
Assembly asm = Assembly.LoadFile(dll_name);
RegistrationServices regAsm = new RegistrationServices();
bool bResult = regAsm.RegisterAssembly(asm, AssemblyRegistrationFlags.SetCodeBase);
编辑3: 运行 CorFlags.exe 在(我的)失败的 DLL 上输出:
Version : v2.0.50727
CLR Header: 2.5
PE : PE32
CorFlags : 11
ILONLY : 1
32BIT : 1
Signed : 1
在调用DLL的EXE上运行相同代码会输出:
Version : v1.1.4322
CLR Header: 2.0
PE : PE32
CorFlags : 9
ILONLY : 1
32BIT : 0
Signed : 1