SxS を使用し、マニフェスト ファイルが使用されている場合、COM を呼び出す .net は他の .net COM オブジェクトを呼び出しますか?
-
25-09-2019 - |
質問
COM コンポーネント (C++) を呼び出す .net アプリケーションがあり、そのコンポーネントが .NET に実装された別の COM オブジェクトを呼び出します。
このアプリケーションは Windows SxS 機能を使用しており、COM コンポーネントを登録しません。C++ で書かれたものでも、.net で書かれたものでもありません。
C++ COM コンポーネントへのこの最初の呼び出しは正常に機能します。しかし、C++ COM コンポーネントが .net コンポーネントを呼び出すと、クラスが登録されていないため失敗します。
.netコンポーネントを呼び出すマニフェストファイルを使用して小さなC++アプリを作成しようとしましたが、それは機能しました。.net -> COM NATIVE -> .NET COM という流れになるようです。その後、SxS が壊れて動作しなくなります。
Fusion ログ (アセンブリ読み込みログ) を見ると、誰も .NET COM アセンブリを解決しようとしていないことがわかります。
この SxS シナリオはうまくいくはずなのでしょうか (うまくいくはずだと思います)?「はい」の場合、何が間違っているのでしょうか?
これらは私が使用しているマニフェストファイルです。
.net アプリケーションのアプリ マニフェスト (リソースとして埋め込まれます):
<?xml version="1.0" encoding="utf-8"?>
<asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<assemblyIdentity version="1.0.0.0" name="MyApplication.app"/>
<file name="DotNetComConsumer.dll" hashalg="SHA1">
<comClass clsid="{44E69FC9-5EAF-4D57-8C09-430F703AD82F}" tlbid="{4F81C9C3-FDDF-48F6-BC25-6F8CD458EBE6}"/>
<typelib tlbid="{4F81C9C3-FDDF-48F6-BC25-6F8CD458EBE6}" resourceid="1" version="2.0" helpdir="" flags="HASDISKIMAGE"/>
</file>
<comInterfaceExternalProxyStub name="_Class1" iid="{5D41351A-440B-4175-9296-72D5EED83AA7}" tlbid="{4F81C9C3-FDDF-48F6-BC25-6F8CD458EBE6}" proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"/>
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="application.sxs" version="1.0.0.0" />
</dependentAssembly>
</dependency>
</asmv1:assembly>
application.sxs.manifest (通常のファイル):
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity type="win32" name="application.sxs" version="1.0.0.0"/>
<dependency>
<dependentAssembly>
<assemblyIdentity name="PerformanceMonitor" version="10.0.0.9999" publicKeyToken="792843134cf0407a" processorArchitecture="msil"/>
</dependentAssembly>
</dependency>
</assembly>
PerformanceMonitor マニフェスト (XP の .net com バグを回避するために、PerformanceMonitor.dll にリソースとして埋め込まれます):
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity name="PerformanceMonitor" version="10.0.0.9999" publicKeyToken="792843134cf0407a" processorArchitecture="msil"></assemblyIdentity>
<clrClass clsid="{AA614438-BC7D-400c-8837-525BFBB7253A}" progid="PerformanceMonitorFactory" threadingModel="Both" name="PerformanceMonitorFactory" runtimeVersion="v2.0.50727"></clrClass>
<file name="PerformanceMonitor.dll" hashalg="SHA1"/>
</assembly>
解決
それは機能しますが、それを壊す可能性のあるものがあります(私が発見したように)。
どうやら、アプリケーションが WinForms アプリケーションであり、 Application.EnableVisualStyles コマンドを使用して OS が提供するビジュアル スタイルを使用し、同時にマニフェスト ファイルを使用してアクティベーション コンテキストを作成すると、窮地に陥ります。
らしいです(によれば) これ) このコマンド自体が、Microsoft.Windows.Common-Controls バージョン 6.0.0.0 を使用するようにプロセスをリダイレクトするアクティブ化コンテキストを作成します。そして、何らかの理由で、マニフェスト ファイルで定義した .net com オブジェクトの使用が中断されます。
Application.EnableVisualStyles をアプリケーションから削除し、マニフェスト ファイル内のこの依存関係に置き換えることでうまくいくようです。
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="X86"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>