3

Accessアプリケーション(MyAppと呼びます)が使用できるように、VB.NETで開発されたCOMコンポーネント(MyLibと呼びます)があります。そのためには、生成されたMyLib.dllファイルとMyLib.tlbファイルを使用してCOM登録を行う必要があります。両方のファイルをMyAppのフォルダーにインストールすると、すべてが正常に機能し、COM関数が正しく呼び出されます。ただし、dllを共通フォルダーにインストールすると、タイトルにエラーが表示されます。これを行う理由は、同じマシンに異なるバージョンのMyAppをインストールできるようにするためです。したがって、COMコンポーネントが変更されない場合は、もちろん、これらの異なるバージョン間でCOMコンポーネントを共有し、Windowsに参照カウントを実行させたいと考えています。

MyAppのインストールフォルダまたはMyLib.dllと同じ共通フォルダのどちらにMyLib.tlbファイルを配置する必要があるかわかりません。しかし、とにかく、私は両方の場所を試しました、そしてそれらはすべて同じエラーを出しました。MyLib。*をMyAppのフォルダーに入れた場合と、MyLib.dllを共通フォルダーに入れた場合のレジストリファイルを比較してみました。もちろん、HKCR \ Wow6432nodes \ CLSID {MYCLSID} \ InprocServer32で登録しようとしているクラスのCodeBaseを除いて、違いはわかりません。私が理解していないもう1つのことは、どちらの場合もHKCR \ Wow6432nodes \CLSID{MYCLSID}の下にTypeLibという名前のサブキーがないことです。

AccessアプリケーションでCOMリファレンスがどのように機能するか正確にはわかりません。間違っている場合は、訂正してください。誰かが私が間違ったことを教えてもらえますか?共有COMdllを登録する正しい方法は何ですか(dllとtlbの両方を共有フォルダーに入れるかどうかに関係なく)?ありがとう!

アップデート:

COM登録に関しては、WIXを使用してWindowsインストーラーを作成し、heat.exeを使用してdllファイルとtlbファイルから情報を収集しています。生成されたファイルには、Class、ProgID、TypeLib、およびRegistryタグの情報が含まれています。前述したように、WIX構成の観点から見ると、2つのケースの唯一の違いは、MyLib.dllファイルを配置する場所です(MyLib.tlbファイルをMyAppインストールフォルダーに配置するのが正しい方法だと思います。もう一度、修正してください。私が間違っている場合)、dllファイルとtlbファイルの両方をアプリケーションのインストールフォルダーに入れると、機能します。登録後のレジストリ構造は次のとおりです

まず、HKCR \ CLSID \ {MYCLSIDs}があり、それぞれが私のCOMクラスの1つを表しています。「InprocServer32」という名前のサブキーには、Assembly、Class、CodeBase、RuntimeVersion、threadingModelがあります。また、CodeBaseは、共通のファイルフォルダー(機能していない)またはMyAppのインストールフォルダー(機能している)のいずれかです。これは、dllを配置するさまざまな場所です。AccessはTypeLibのみを認識し、TypeLibから実際のdllへのリンクがあるはずなので、{MYCLSIDs}の下に別のサブキーTypeLibがあると思いましたが、どちらの場合もこのサブキーはありませんが、 2番目のケースはまだ機能しています。問題はありますか?

次に、HKLM \ Software \ Classes \ CLSID \ {MYCLSIDs}があります。このキーは、上記と同じ構造です。

第三に、HKCR \ {MYPROGIDs}、これらは私のクラスの単なるProgIDです

第4に、HKCR \ Typelib \ {LibID}には、tlbファイルからの情報が含まれています。このIDは、COMコンポーネントプロジェクトのアセンブリGUIDからのものです。

最後に、HKEY_CLASSES_ROOT \ Interface \ {InterfaceID}には、値{00020424-0000-0000-C000-000000000046}のProxyStubClsid32という名前のサブキーがあり、TypeLibという名前のサブキーと値は私のLibIDです。

唯一の違いは最初の項目のCodeBaseであるようです(私は間違っている可能性がありますが、それが私が見ているものです)。問題が発生した場合はお知らせください。ありがとう!

2回目の更新:

MyLib.dllを共有フォルダーにインストールした後、COM呼び出しが失敗します。しかし、SHARED_FOLDER\MyLib.dllのすべてのCodeBase値をINSTALLDIR\MyLib.dllに置き換え、MyLib.dllをINSTALLDIRにコピーすると、実際に機能します。逆に、MyLib.dllをINSTALLDIRにインストールした後(この場合はCOMが機能しています)、CodeBaseの値をINSTALLDIR\MyLib.dllからSHARED_FOLDER\MyLib.dllに変更し、SHARED_FOLDERにコピーします。今回は失敗します。ですから、それはまさに設置場所の問題であるように思われます。これは、私のCOMの理解とは正反対です。また、SHARED_FOLDERはインストーラーが作成するフォルダーにあるため、アクセス許可の問題はないと思います(間違っている可能性があります)。

4

3 に答える 3

7

AccessアプリケーションでCOMリファレンスがどのように機能するのか正確にはわかりません。

comオブジェクトがWindowsでどのように機能するかは、1990年に登場して以来同じです。そこで、22年間存在していた肉とジャガイモの主力またはテクノロジーについて話しました(そして、オブジェクトが.netで作成されるずっと前のことです)。

したがって、comの動作は、Access、Delphi、FoxPro、VB6、またはcomオブジェクトを使用できるシステムに関して同じです。

次に、そのようなcomオブジェクトの場合、コンピューター上のそのようなオブジェクトのレジストリは本質的にグローバルであることを覚えておくことが重要です。

.netにあるのと同じフォルダに配置されたオブジェクトの動的リンクの概念に近いものは何もありません。

したがって、way.netはグローバル登録を必要としません(実際、登録は必要ありません!)。

ただし、in.netでは、必要に応じてグローバルアセンブリにオブジェクトを登録できます(GAC)。したがって、これはあなたが持っている選択ですが、そのような選択は標準のWindows comオブジェクトではなく、.netオブジェクトの選択です。したがって、それらの.netオブジェクトは、22年間使用していた標準のWindowscomオブジェクトとはまったく関係がありません。

したがって、.net内のほとんどのオブジェクトは、実際にはdirに対してローカルですが、これは標準のウィンドウcomオブジェクトの選択肢ではありません。

したがって、.netオブジェクトまたはアセンブリを使用可能で機能するWindows comオブジェクトに正しく変換するには、オブジェクトをコンピューターにGLOBALに登録する必要があります。つまり、zippy32を使用していませんが、実際にはregasmと呼ばれる.net登録ツールを使用します(これは、comオブジェクトブリッジを構築した後、最終的にはzippy32を実行します)。また、ここで正しいビットバージョン用にコンパイルする必要があることにも注意してください。

また、他のコンピューターに展開する場合は、2.0オブジェクトを生成するようにプロジェクトを設定して、ターゲットコンピューターに.netライブラリがインストールされている可能性が高くなります。したがって、展開中にregasmを使用する必要があります。

これ:C:\ Windows \ Microsoft.NET \ Framework \ v2.0.50727 \ RegAsm.exe

最も重要なのは、GAC(グローバルアセンブリキャッシュ)に.netオブジェクトを登録する必要があるため、regasm.exeのコマンドライン使用に/codebaseを追加することを忘れないでください。これを行わないと、windows comオブジェクトをサポートする非.netアプリケーションは、noirがアセンブリを標準のwindowscomオブジェクトとして使用できないことを認識しません。

したがって、.net以外のオブジェクトについて話す場合、ActiveXまたは一般にWindows comオブジェクトと呼ばれるものをフォルダごとにフォルダに登録するという概念はありません。これは、本質的に常にグローバルです。

そのため、.dllをどのディレクトリまたはフォルダに配置するかについては重要なポイントです。その.dllを正しく登録すると、comオブジェクトをサポートするすべてのシステムで使用できるようになります。

これは、.netでの登録プロセス中に、グローバルアセンブリレジストリオプションを使用する必要があることも意味します(そうでない場合は機能しません)。

于 2012-07-27T06:31:54.327 に答える
2

MyLib.dllは、MyAppインストールフォルダーにまだインストールされている他のライブラリを使用していることが判明しました。そのため、MyLib.dllが共有フォルダーにインストールされている場合、同じライブラリ内でそれらのライブラリを検索しようとしますが、もちろん失敗します。これらのライブラリを共有フォルダにもインストールすると、機能します。

ところで、アセンブリの読み込みの問題を追跡するときに、fulogvw.exeが非常に役立つことがわかりました。たとえば、失敗したログの私の場合、SHARED_FOLDERにファイルxxx.dllを読み込めないと表示され、xxx.dllはMyLib.dllが使用しているライブラリであり、MyLib.dllがそれを必要としていることを私が見るまでわかりませんでした。ログ。

于 2012-08-01T12:50:55.670 に答える
0

私はこれと同じ問題を抱えていて、すべての提案を試しましたが、何も機能しませんでした。次に、の/regフラグを使用regasmして手がかりを探すことにしました。これにより、原因を見つけることができました。.netアセンブリのバージョンが増えたため、登録時にレジストリに新しいブランチが作成され、同時。

tlbこれは、レジストリが常に最新のものを使用しようとするため、以前の作業バージョンにロールバックできないことも意味していました。

これを回避する2つの方法は、ブランチからすべての不正なレジストリキーを手動で削除するかCLSID、アセンブリのバージョン番号を以前の番号にリセットし、再構築して再登録することです。

または、私の場合ははるかに簡単な方法です。.netアセンブリ内のすべての相互運用ガイドを更新します。クラスとインターフェイス、およびアセンブリ自体ごとに新しいものを作成するだけです。次に、再構築し、regasmを使用してtlbを再登録すると、dllが新しいレジストリキーを持つ新しいライブラリになります。
明らかに、VB6の参照を削除して読み取り、新しいライブラリとして表示する必要があります。その後、すべてが正常に機能しました。

于 2021-08-30T15:09:25.653 に答える