获取类未注册的类80041054

时间:2014-02-07 06:42:06

标签: c# c++ com

我将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

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>