7

2つのCOMサーバーdllを使用するCOMクライアントアプリケーションを作成しました。このアプリケーションをCOM登録なしで実行したい-つまり:winsxs / .manifests

クライアントアプリケーションからCOMオブジェクトのインスタンスを作成しようとすると、(...ほぼ予想される...)「クラスが登録されていません」というメッセージが表示されます。

私は以前にその種の構成を成功させましたが、なぜこれが失敗するのか理解できません。


詳細は次のとおりです。

  • 私が持っているモジュール:
    • 2つのCOMサーバー(dll1.dllおよびdll2.dll)に依存するMFCクライアント
    • dll1.dllCOMサーバーはdll2.dllに依存します
    • dll2.dllにはCOMの依存関係はありません

私が持っているCOMオブジェクト:

  • dll1.dll(.idl言語)

-

[
    object,
    uuid(262D00FB-3B9F-4A76-98FC-3051FDCAF0A6),
    dual,
    nonextensible,
    helpstring("IDialogManager Interface"),
    pointer_default(unique)
]
interface IDialogManager : IDispatch{
};
[
        uuid(58562535-BCA5-4D04-BB92-78F90EDA201E),
        //...
]
dispinterface _IDialogManagerEvents
{
};
[
        uuid(D599D3F0-A4D1-44A7-87A9-16032CC613CA),
        //...
]
coclass DialogManager
{
        [default] interface IDialogManager;
        [default, source] dispinterface _IDialogManagerEvents;
};

-

  • dll2.dllで

-

[
    object,
    uuid(2A183A2E-A620-4E00-B657-C9D2E59201D4),
    nonextensible,
    helpstring("ICadWizardsManager Interface"),
    pointer_default(unique)
]
interface ICadWizardsManager : IDispatch{
};
[
    object,
    uuid(FE97F3FB-8930-43BC-947D-64C90F45A071),
    nonextensible,
    helpstring("ICadWizard Interface"),
    pointer_default(unique)
]
interface ICadWizard : IDispatch{
};
[
    uuid(5365D4E6-ADFB-4429-9DEA-C44CC94AA3EF),
]
dispinterface _ICadWizardEvents
{
};
[
    uuid(CAC2D0BF-AD5B-4CC8-A04D-53AB23A0CDF4),
]
coclass CadWizard
{
    [default] interface ICadWizard;
    [default, source] dispinterface _ICadWizardEvents;
};
[
    uuid(3164FAC4-6F5F-4E4D-9B09-DC4115850D78),
]
dispinterface _ICadWizardsManagerEvents
{
};
[
    uuid(707CB6C8-311E-45EC-9DCB-50477F588BAF),
]
coclass CadWizardsManager
{
    [default] interface ICadWizardsManager;
    [default, source] dispinterface _ICadWizardsManagerEvents;
};

-

  • クライアントの呼び出し

-

IDialogManagerPtr dialogManager;
dialogManager.CreateInstance(CLSID_DialogManager); // <<< returns "Class not registered"

-

  • client.exe.2.manifest

-

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">

<assemblyIdentity name="client" version="1.0.0.0" type="win32" processorArchitecture="x86"/>
<file name="dll2.dll">
 <comClass
     clsid="{707CB6C8-311E-45EC-9DCB-50477F588BAF}"
     threadingModel="apartment">
 </comClass>
 <comClass
     clsid="{CAC2D0BF-AD5B-4CC8-A04D-53AB23A0CDF4}"
     threadingModel="apartment">
 </comClass>
</file>

<file name="dll1.dll">
 <comClass
     clsid="{D599D3F0-A4D1-44A7-87A9-16032CC613CA}"
     threadingModel="apartment">
 </comClass>
</file>

</assembly>

-


sxsアクティベーションコンテキストの生成中にエラーは発生しません:-Windowsログにエラーはありません(マニフェスト構文が正しいことを意味します)-sxstraceによってエラーが検出されませんでした(ログは「INFO:ActivationContextgenerationsucceeded。」メッセージで終了します。エラーまたは疑わしいメッセージ。さらに、マニフェストが正しくロードされていることがわかります)

何か案が?

sxstraceを使用してsxsをより深くデバッグする方法はありますか?たとえば、実際に登録されたcomまたはclrクラスのリストを取得しますか?

よろしくお願いします

4

2 に答える 2

6

簡単な説明は、.manifestファイルが使用されていないということです。このシナリオで発生する可能性が高いのは、.exeにリソースとして埋め込まれたマニフェストがすでに含まれていることです。MFCアプリで視覚的なスタイルを有効にすることは非常に一般的です。また、ランタイムDLLを見つけるためにマニフェストを埋め込むVS2005または2008コンパイラによってコンパイルされたコードの場合。

これを確認するには、[ファイル]+[開く]+[ファイル]を使用して、コンパイルされた.exeファイルを選択します。RT_MANIFESTノードを探します。Windowsがそのような埋め込みマニフェストを見つけた場合、ファイルベースのマニフェストを探し続けることはありません。regfreeCOMエントリを埋め込みエントリにマージする必要があります。良いMSDNライブラリリンクを提供できればいいのですが、マニフェストに関するドキュメントは深刻な問題を抱えています。

于 2011-02-16T18:44:49.057 に答える
2

通常、登録なしのCOMのアクティベーションコンテキストを構築する場合、少なくとも2つのマニフェストが関係します。

COMコンポーネントを含むアセンブリを含む、依存するアセンブリを指定するEXEマニフェストと、アセンブリ内のdll、ウィンドウクラス、およびCOMオブジェクトを記述するアセンブリマニフェストがあります。

このブログには、.2の意味に関する情報が含まれています。基本的に、システムがマニフェストを探すとき、modulename.exe [.resid] .manifestを探します-residが1の場合、それは省略されます。

つまり、MFCを使用しています。これは、DevStudioを意味します。つまり、プロジェクトは、c-runtimeとcommoncontrol6の設定を使用してRT_MANIFESTリソースを自動的に生成するように構成されている必要があります。

Visual Studio 2005は、XMLを直接マージしようとせずに、dependentAssembly要素をアプリケーションマニフェストとマージするためにこの構文をサポートしています。

#pragma comment(linker, \
    "\"/manifestdependency:type='Win32' "\
    "name='client' "\
    "version='1.0.0.0' "\
    "processorArchitecture='*' "\
    "language='*'\"")

したがって、それを.exeのcppまたはヘッダーに追加し、client.exe.2.manifestを「client.manifest」として保存すると、すべてのシステムが正常に動作するはずです。

于 2011-02-17T20:11:11.593 に答える