我将CoCreateInstance从非托管代码调用到已注册的托管类(HKEY_CLASSES_ROOT \ CLSID {xxxxx-xxxxxx-xxxxxx-xxxxx-xxxxxx-xxxxx}注册表项存在且文件已从其他程序正确加载。< / p>
代码如下:
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 - 成功(返回文件路径)然后在访问DLL之前检查GAC缓存,然后检查几个目录。
CLIENT.EXE 1092 RegQueryKey HKCR \ CLSID {...}成功查询:名称 CLIENT.EXE 1092 RegOpenKey HKCR \ CLSID {...} \ InprocHandler名称未找到所需访问权限:允许的最大值 CLIENT.EXE 1092 RegCloseKey HKCR \ CLSID {9935FEE6-39FD-4EF0-87DB-8372B0992610}成功 CLIENT.EXE 1092 RegOpenKey HKLM \ Software \ Policies \ Microsoft \ Windows \ App Management NAME NOT FOUND所需访问:查询值 CLIENT.EXE 1092 CreateFile LogFile.txt
我认为它是记录错误的最后一条日志消息。
EDIT2: 使用以下代码注册Dll:
Assembly asm = Assembly.LoadFile(dll_name);
RegistrationServices regAsm = new RegistrationServices();
bool bResult = regAsm.RegisterAssembly(asm, AssemblyRegistrationFlags.SetCodeBase);
EDIT3: 在(我的)DLL输出上运行CorFlags.exe:
Version : v2.0.50727
CLR Header: 2.5
PE : PE32
CorFlags : 11
ILONLY : 1
32BIT : 1
Signed : 1
在EXE上运行相同的DLL调用DLL输出:
Version : v1.1.4322
CLR Header: 2.0
PE : PE32
CorFlags : 9
ILONLY : 1
32BIT : 0
Signed : 1
答案 0 :(得分:4)
在EXE上运行相同...
您的CLR版本不匹配问题。 EXE的目标是.NET 1.1,并将加载CLR的v1.1版本。该版本无法加载DLL,它的目标是CLR的v2版本,在.NET 2.0到3.5中使用的版本
解决方法是编写.config文件,强制使用正确版本的CLR。将它放在与.exe相同的目录中,名称为somefile.exe.config,将“somefile”替换为.exe的名称:
<configuration>
<startup>
<supportedRuntime version="v2.0.50757"/>
</startup>
</configuration>