CoCreateInstance返回“未注册的类”

时间:2012-03-19 19:57:20

标签: c# c++ dll managed

我已经在这几个小时了,它开始变得沮丧。 :(

我有一个我在.NET 4.0中创建的COM DLL,我希望能够使用VC ++ 6中的遗留应用程序访问它。它对COM可见,我已经成功创建了TLB和SNK文件,移动了它使用传统的C ++代码到机器上,#imported TLB,一切都编译得很好。

请尝试以下内容:

RegAsm ProtracFunctions.dll / codebase

gacutil / i ProtracFunctions.dll

他们都很成功。

当我启动我的应用程序时,只要我点击CoCreateInstance,我就会收到消息“Class not registered”。

我在RegEdit中注意到我的DLL似乎已经注册了。那是我做了一些研究,下载了ProcMon,并意识到它在不同的位置。 CLSID略有不同,如果我尝试修改ProtracFunctions.reg文件(使用ProcMon提取的GUID)RegAsm给我的,它会对ProcMon产生影响(比“NAME”更多“SUCCESS”消息至少找不到“消息”,但我似乎错过了,大量的注册表位置。如关键的“TreatAs”,“InprocServerX86”等

如果有人能告诉我:

A)我在第一时间做错了什么

B)当您“注册”COM DLL时,确切地添加了哪些注册表值的列表,以便我可以自己进行并手动执行。 (不太理想,我意识到了。)

TIA!

我的代码:

CoInitialize(NULL);
CComQIPtr <ProtracFunctions::IDockingStation> spTestCom;
HRESULT hRes = spTestCom.CoCreateInstance(CLSID_ProtracDCS, 0, CLSCTX_ALL);

if (SUCCEEDED (hRes))
{
    printf("Created the instance");

    unsigned char Ret;
    unsigned char ErrCode;
    SAFEARRAY *pSA;

    spTestCom->DockConnect(3, 19200, &Ret);
    spTestCom->GetTagReads(1, &ErrCode, &pSA); 

    spTestCom->PowerOffReader(1, &Ret);
    spTestCom->DockDisconnect();

    spTestCom.Release ();
}
else
{
   _com_error error(hRes);
   LPCTSTR errorText = error.ErrorMessage();

   AfxMessageBox(errorText);

   //automatic cleanup when error goes out of scope
}

添加了备注:

开发机器运行Win XP 32位,带有旧应用程序的“机器”实际上是开发计算机上的虚拟机,也运行XP。

此外,当我运行我的应用程序,并选择我的测试菜单项来触发上述代码时,我第一次收到错误“Class not registered”,如果我再次点击它,我看到:“没有这样的界面支持“...很奇怪。

2 个答案:

答案 0 :(得分:3)

我认为您需要在程序集中嵌入清单。 请参阅此URL。 http://blogs.msdn.com/b/cheller/archive/2006/08/24/718757.aspx

您也可以使其无需使用此代码注册程序集(Regasm.exe)即可使用。

{
    DWORD cookie;
    ACTCTX actctx = {sizeof(actctx)};
    actctx.lpSource = L"YOUR ASSEMBLY FULL PATH";
    actctx.lpResourceName = MAKEINTRESOURCE(1); //MAYBE 2 FOR DLL
    actctx.dwFlags = ACTCTX_FLAG_RESOURCE_NAME_VALID;   
    HANDLE hActCtx = CreateActCtx(&actctx);
    BOOL fOK = ActivateActCtx(hActCtx, &cookie);
    if (!fOK)
        return E_FAIL;

    CComPtr<CSharpComInterface::ITestCSharpInterface> spCSharpTest;
    HRESULT hr = spCSharpTest.CoCreateInstance(__uuidof(CSharpComInterface::CoClass));

    if (hr != S_OK)
    {
        cout << "Failed to create instance CSharpComInterface::CoClass" <<endl;
    }
    else
    {
        cout << "Load Successfully : CSharpComInterface::CoClass" << endl;
        spCSharpTest->TestMethod();
    }

    DeactivateActCtx(0, cookie);
    ReleaseActCtx(hActCtx);
}

答案 1 :(得分:1)

MSDN中的这个entry on Regasm.exe表示如果您的程序集在GAC中,则不应使用/ codebase选项。