0

使用する必要のあるサードパーティのライブラリを使用するという珍しいシナリオがあります。

ライブラリには、製品の最新の3つのバージョンがパッケージ化されています。通常、これは私のソフトウェアがそれらすべてで動作することを意味し、3つのバージョンの最も古いバージョン(コンパイル時)を参照し、3つのバージョンすべてで動作します。ただし、これは当てはまりません。つまり、ライブラリへの適切な「参照」を使用する場合は、バージョンごとに個別にコンパイルする必要があります。

私の最初の選択肢は、すべてのタイプ固有のコードをレイトバウンド形式を使用するように変換することです。

Dim item as new documentItem          ' this is not real code, just pseudo...

Dim item as object = createobject("clsid.documentItem")

私はこのレイトバウンドフォーマットを実行してコンパイル時のチェックを失うことを絶対に嫌います。特にこのライブラリは巨大で非常に複雑なので。

3つの製品すべてをインストールし、すべてのライブラリを個別に参照するという2番目のアプローチは不可能のようです。互換性を持たせるために「試行」されたようで、COMコンポーネントの一意の識別子は同じです。CLSIDと名前が重複している同じDLLに同じライブラリを3回インポートする方法を誰かが説明できない限り。(これは、ターゲットアプリケーションごとに異なるラッパーを使用するための大量のコード変更またはコード変更も意味します)

質問: このシナリオに対処する他の方法を知っている人はいますか?私の目的は、コンパイル時のチェックとオートコンプリートを維持することです。おそらく、クライアント側で相互運用ライブラリを作成するための何らかの方法です。

アップデート: 関数を1つのプロジェクトに統合するために、独自のラッパーDLLを介してこのライブラリへのすべてのアクセスをすでに実行しました。そのため、当面は、作成したラッパーライブラリ全体を新しいDLLにコピーし、正規表現を使用してレイトバウンド形式への一括会話を行いました。同じルート名前空間を使用して、それらを簡単に切り替えることができます。この形式では、StrictCompilerルールを使用している1つのバージョンに対して開発の大部分を行うことができます。そこで変更が行われ、証明されたので、コピーをレイトバウンドライブラリに移動し、特定の参照をすべて削除します。これまでのところ、これはそれに対処するための最良の方法のようです。公開するには、ライブラリをレイトバウンドバージョンに切り替えます。これまでのところ、これは、これまでのところかなり少量の追加作業で、プログラムで可能な限り多くのコンパイル時間をチェックするための良い方法のようです。

4

1 に答える 1

0

私は自分の問題の解決策を見つけました。

私がしたことは、COM コンポーネントの各バージョンを登録し、プロジェクトを再構築することでした。これにより、.NET は COM コンポーネント用の相互運用ライブラリを作成しました。

次に、新しい「interop.component.dll」をサブディレクトリにコピーし、その名前を「Version1.Component.dll」に変更しました

次のような 4 つの相互運用ライブラリがすべて作成されるまで、これらの手順を繰り返します。

  • 「Version1.Component.dll」
  • 「Version2.Component.dll」
  • 「Version3.Component.dll」
  • 「Version4.Component.dll」

それぞれをプライマリ DLL の埋め込みリソースとしてマークします。

リファレンスの COM ライブラリに対して Copy Local = FALSE を設定します。これにより、コンポーネント クラスがコードで要求されたときに、.NET が必要に応じて Interop ライブラリを読み込もうとしたときに、Interop ライブラリが見つからなくなりました。

プライマリ DLL のモジュールに、次のコードを追加します...

Public WithEvents CurDomain As AppDomain = AppDomain.CurrentDomain

Private Function AssemblyResolve(sender As Object, args As System.ResolveEventArgs) As System.Reflection.Assembly Handles CurDomain.AssemblyResolve
Dim resourceName As String = New Reflection.AssemblyName(args.Name).Name & ".dll"
Dim curAsm As Reflection.Assembly = Reflection.Assembly.GetExecutingAssembly
If resourceName.EndsWith("Component.dll") Then
    'supply the correct resource
    resourceName = ver & "." & resourceName  ' ver is set to the currently desired version.
    Using stc As IO.Stream = curAsm.GetManifestResourceStream(resourceName)
        Dim bt(CInt(stc.Length - 1)) As Byte
        stc.Read(bt, 0, CInt(stc.Length))   'get to a new byte array
        Return Reflection.Assembly.Load(bt) 'load actual assembly from decompressed stream data.
    End Using
End If
End Function

上記のコードは、手動で提供できる DLL を .NET が解決できない場合にトリガーされます。

現在、相互運用ライブラリのわずかに異なる 4 つのバージョンはすべて、マシンに登録されている COM コンポーネントのバージョンに関係なく動作します。

于 2013-04-17T17:54:36.460 に答える