CoCreateInstance возвращает «Класс не зарегистрирован» - PullRequest
7 голосов
/ 19 марта 2012

Я занимаюсь этим уже несколько часов, и это начинает расстраивать.: (

У меня есть COM DLL, которую я создал в .NET 4.0, к которой я хочу иметь доступ с помощью унаследованного приложения, созданного на VC ++ 6. Его видно COM, я уже успешно создал TLB иФайлы SNK, перенесли его на компьютер с унаследованным кодом C ++, # импортировали TLB, все отлично скомпилировалось.

Выполнено следующее:

RegAsm ProtracFunctions.dll / codebase

gacutil / i ProtracFunctions.dll

Они оба успешны.

Когда я запускаю свое приложение, как только я нажимаю CoCreateInstance, мне выдается сообщение "Класс не зарегистрирован".

Я заметил в RegEdit, что моя DLL действительно зарегистрирована. Вот когда я провел какое-то исследование, скачал ProcMon и понял, что он смотрит в разных местах. CLSID немного отличается, и если я пытаюсьизмените файл ProtracFunctions.reg (чтобы использовать GUID, который собирает ProcMon), который мне дает RegAsm, и он оказывает влияние на ProcMon (больше сообщений "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 XP32-разрядный, и «машина» с унаследованным приложением на самом деле является виртуальной машиной на компьютере разработчика, также работающей под управлением XP.

Кроме того, когда я запускаю свое приложение и выбираю пункт меню «Тест», который запускаетПриведенный выше код, в первый раз, когда я получаю сообщение об ошибке «Класс не зарегистрирован», и если я нажимаю его снова после этого, я вижу: «Такой интерфейс не поддерживается» ... Очень странно.

Ответы [ 2 ]

3 голосов
/ 01 апреля 2012

Я думаю, вам нужно встроить манифест в вашу сборку.Смотрите этот 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 голос
/ 20 марта 2012

Эта запись в Regasm.exe в MSDN говорит, что вы не должны использовать параметр / codebase, если ваша сборка находится в GAC.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...