- PR -

C#で作成したライブラリをVB6.0から使用

1
投稿者投稿内容
のり
会議室デビュー日: 2002/06/04
投稿数: 12
投稿日時: 2002-07-10 20:28
VS.NETで「C#クラスライブラリ」を作成し、そのDLLをVB6.0から使用する方法を調査しています。

.NET Framework付属の RegAsm.exe で DLL をCOMサーバーとして登録することでVB6.0から利用できるところまではわかりました。
つまり、VB6.0で作成したアプリケーションがCOMクライアントとして機能するわけです。

しかし、DLLの探索がうまくいきません。
例えば、VB6.0からデバッグをしようとすると、「COMサーバーが見つからない」というような内容のエラーになってしまいます。
VB6.0で作成したEXEと同じディレクトリにDLLを配置して実行すればそのようなことはありません。
また、VBのインストールディレクトリにDLLを配置すれば、VBでのデバッグでも正常に動作します。
つまり、DLLの探索があくまでもEXEのカレントしか行われていないようなのです。
(Path環境変数に指定されたパスにDLLを配置しても駄目です)


何かの手順が足りないのでしょうか?
どなかた対処方法をご存知の方、その手順を教えていただけないでしょうか。

よろしくお願いします。

NothingBut.NETFX
大ベテラン
会議室デビュー日: 2001/09/13
投稿数: 102
投稿日時: 2002-07-10 20:45
>つまり、DLLの探索があくまでもEXEのカレントしか行われていないようなのです。
>(Path環境変数に指定されたパスにDLLを配置しても駄目です)

おっしゃるとおり、.NET FrameworkではPATH変数は意味を持ちません。

C#で作成されたDLL(アセンブリ)は、共通言語ランタイム(CLR)によって探索が行われます。レジストリを見てみてください。従来ならDLLへのパスが書いてあった場所に、mscoree.dllファイルが指定されているはずです。mscoree.dllは共通言語ランタイム(の一部)です。同じレジストリキーに、探索すべきアセンブリの名前が「簡易名,Version=x.x.x.x,Culture=neutral,PublicKeyToken=null」などと書いてあると思います。これがCLRが探すアセンブリの名前です。

したがって、VB6のアプリケーションが起動してCOMオブジェクトををCreateObject(New)しようとすると、このレジストリが探されて、mscoree.dllがロードされます。mscoree.dllは同じレジストリキーにあるアセンブリの名前を見て、それをファイル名に変換しようと試みます。実はこの手順は、拙著で恐縮ですが、本@ITのInsider .NETフォーラムのインサイド.NET Framework 第4回 アセンブリのロード(前・後編)で解説しています。詳しくはご一読いただければと思います。

簡単に説明すると、C#のDLL(アセンブリ)を探し出すために、CLRはまずGACを参照します。ここで見つからない場合、次にアプリケーションの構成ファイルを探します。このファイルは、アプリケーション名.configという名前で、アプリケーションと同じフォルダに配置されている必要があります。のりさんのVB6のアプリケーションの名前が「App.exe」なら、ファイル名は「App.exe.config」になります。VB6のIDEからデバッグ実行をしている場合は、VB6.exe.configというファイルをVBがインストールされているフォルダに配置します。ファイルの内容は記事をご覧ください。

上記2箇所で見つからなかった場合、CLRはアプリケーションのカレントディレクトリなどを探します。ただしこの手順はお勧めできません。C#のDLL(アセンブリ)は上記2箇所(GACか構成ファイル)のどちらかに適切に配置することをお勧めします。
のり
会議室デビュー日: 2002/06/04
投稿数: 12
投稿日時: 2002-07-11 13:14
NothingBut.NETFXさん:
貴重な情報、ありがとうございました。
ご指摘の通り手順を踏みましたところ、DLLの探索がうまく行われるようになりました。
今回は、GACに登録する方法で確認しました。
つまり、

@アセンブリに厳密名を与える
・sn.exeでキー・ペア作成(CSPコンテナに保管)
・AssemblyKeyNameを指定
[assembly: AssemblyKeyName("CspContainer")]

AGACに登録する(gacutil)

という手順です。
これにより、VB6のIDEからのデバッグ実行でも、VB6で作成したアプリからの実行でも、カレントにDLLがなくとも正常に動作するようになりました。


さて、次にこのアセンブリ(DLL)をこの動作確認を行ったのとは別のマシンに持っていき、そのマシン上でVB6から利用するためにはどうしたらよいのかということも確認してみました。
結果としては何も特別なことはなくて、GACへの登録だけで利用できました。

今回はGACへ登録する「グローバル配置」で確認しました。
このほうがVB6からのデバックとVB6アプリケーションの両方から利用できると思ったからです。
1回だけGACに登録すれば良いと勘違いしていましたが、DLLが更新されるたびにgacutilによる登録が必要なようですね。
コマンドプロンプトを使用して、GAC以下の構成を確認したところ、DLLそのものがコピーされていることがわかりました。
つまり、GAC以下にコピーされたDLLが使用されているということですね。
最初は、コードベースに指定されているパスのDLLが使われるものと思っていました。


記事中でもご指摘のように、アセンブリの配置は構成ファイルを利用する「プライベート配置」のほうが良さそうなので、こちらのほうもこれから試してみたいと思います。


最後に今回の件とは別の話題になりますが、一つ気になったことがあります。
アセンブリに厳密名を与える過程でキー・ペアを作成し、それをCSPコンテナに保管しました。
開発が完了し、運用・保守フェーズに入ったアプリケーションを考えた場合、このキー・ペアの管理というのも考慮していかなければならないのでしょうか?
つまり、本番環境への配布は、配布用モジュール作成用のマシンを用意し、そのマシンでキー・ペアが管理されるというイメージになるでしょうか。
今回のことでアセンブリについていろいろ勉強できたので、引き続きこのあたりのことを確認したいと考えています。


今回はどうもありがとうございました。


NothingBut.NETFX
大ベテラン
会議室デビュー日: 2001/09/13
投稿数: 102
投稿日時: 2002-07-11 16:14
>開発が完了し、運用・保守フェーズに入ったアプリケーションを考えた場合、
>このキー・ペアの管理というのも考慮していかなければならないのでしょうか?
>つまり、本番環境への配布は、配布用モジュール作成用のマシンを用意し、
>そのマシンでキー・ペアが管理されるというイメージになるでしょうか。

まったく手前味噌ですが、インサイド .NET Framework 第2回 アセンブリのアイデンティティ(前編) 遅延署名機能の利用でその辺の話を取りあげています。ご参考まで。

原則的には、会社で1つのCspContainerを作り、それを厳重に(金庫にしまうくらいの勢いで)管理します。開発終了、配布待ちという状態になったら、CspContainer(マシンでもいいし、ICカードでもいい)からキーペアを取り出して署名をするわけです。

このあたりは、ホンモノのコンポーネントベンダーさん(フォーラムスポンサーさんとか)にご登場いただいてぜひ手順の解説がほしいところですね。>@ITさま
1

スキルアップ/キャリアアップ(JOB@IT)