1

C# を使用して、.Net Framework で登録不要の COM オブジェクトを作成する必要があります。

MSDN ウォークスルーに従いました。または、私には十分に明確ではないか、正しくないため、私はそれに取り組む必要がありますが、これは古い投稿であり、Windows 10 で Visual Studio 2015 を使用しているため、何かが変更されている可能性があります。

以下に、それを機能させるために行った手順を示します。

  1. COM C# dll SideBySide.dll(Target Framework 2.0) をコンパイルします。もちろん、regasm で登録していません。

  2. チュートリアルで説明されているアプローチは使用していません。うまくいかないようです。で作成SideBySide.Manifestしますmt.exe。コマンドは次のとおりです。

    mt -outputresource:"<path SidebySide.dll>" -manifest "<SideBySide.manifest>"

  3. 生成されたマニフェストを手動で変更して、役に立たないタグをすべて削除し、必須のタグを追加しました。変更されたマニフェストは次のとおりです。

    <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
        <assemblyIdentity
            name="SideBySide"
            version="1.0.0.0"
            type="win32" />
        <clrClass
            clsid="{4B72FC46-C543-4101-80DB-7777848D1357}"
            progid="SideBySide.SideBySideClass"
            threadingModel="Both"
            name="SideBySide.SideBySideClass"
            runtimeVersion="v2.0.50727">
        </clrClass>
        <file name="SideBySide.dll">
        </file>
    </assembly>
    
  4. SideBySide.dll次のコマンドでマニフェストを追加しました。

    mt -outputresource:"<Path SidebySide.dll>" -manifest "SideBySide.manifest"

  5. SideBySide.dll using tlbexp`から TLB をエクスポートしました。

  6. C++ クライアントの構成でNoを設定しました。Properties -> Manifest tool -> Embed Manifest

  7. をコンパイルclient.exeし、client.exe.manifestファイルに変更を適用しました。変更されたマニフェストは次のとおりです。

    <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
        <assemblyIdentity
            type = "win32"
            name = "client"
            version = "1.0.0.0" />
        <dependency>
            <dependentAssembly>
                <assemblyIdentity
                    type="win32"
                    name="SideBySide"
                    version="1.0.0.0" />
            </dependentAssembly>
        </dependency>
    </assembly>
    

すべてがうまく機能しており、ネイティブ C++ アプリケーションから .Net Framework COM インターフェイスを使用できるようです。

SideBySide.dllただし、 .Net Framework 4.0 以降でコンパイルしようとすると、次の呼び出し時に問題が発生しますCreateInstance

ISideBySideClassPtr ptr;
HRESULT hr = ptr.CreateInstance(__uuidof(SideBySideClass));

このエラーが発生します:

0x8013101b : このアセンブリは、現在読み込まれているランタイムよりも新しいランタイムによってビルドされているため、読み込むことができません。

もちろん、上記のすべての手順を実行しようとしましたが、DLL のマニフェストでランタイム バージョンも指定しようとしましたが、役に立ちませんでした。

この投稿も読みました。問題は同じですが、ネイティブ クライアントから C# COM オブジェクトを呼び出す必要があるため、私の意見では、解決策は私には適していません。

適用する回避策はありますか、それとも問題に対して別のアプローチが必要ですか?

4

2 に答える 2

2

少し遅れて感謝しますが、これに出くわした他の人のために...

私は今日、この問題を抱えていました。私の登録無料のCOMライブラリは.Net 4.5.2で構築されています。私の解決策は、次のように「runtimeVersion」属性を使用することでした

<clrClass 
   clsid="{...}" 
   progid="Library.Name" 
   threadingModel="Both" 
   name="Library.Name.Class"
   runtimeVersion="v4.0.30319">

または、runtimeVersion 属性を省略して (または v2.0.50272 を指定して)、ライブラリを .Net 3.5 用にコンパイルすることもできます。どちらの解決策でも問題は解決するようです。

于 2017-11-04T00:48:56.190 に答える
0

推測ですが、マニフェスト ファイルではランタイム バージョンが 2.0.50727 であるとのことですが、4 でのコンパイルに問題がありますか? マニフェストとツールのバージョンが一致していません。

マニフェスト ツールを使用して、アセンブリに情報を作成して保存します (PostBuild ステップで)。

"$(PathToYourTools)\mt.exe" -managedassemblyname:$(TargetPath) -nodependency -outputresource:$(TargetPath);#2

.NET アセンブリの typelib を生成する必要がないという追加の利点があります。

于 2016-10-11T17:46:05.450 に答える