今やってる案件が初の.Net開発ということで四苦八苦しながら.Net勉強してます。そのなかで別のフォルダのDLLをみれないのか?という疑問がわきいろいろ調べてみました。
結論としては「しかるべき手順をとればできる」ということです。ネット上の掲示板等では「exeと同じ階層にDLLを置くのが常識だ」という意見がちらほらありましたが、下記の連載をみるとそうではないそうです。
インサイド .NET Framework [改訂版]第3回 アセンブリのロード (かなり詳しいレベルで書かれてますが、連載すべてはかなりの量です。まだ少ししか読んでません)
これによると.Netで作られた実行ファイル(正確にはCLR)は下記の順序でアセンブリ(DLL等)を探しに行くみたいです。
1. DEVPATH環境変数に列挙されているディレクトリ 2. グローバル・アセンブリ・キャッシュ 3. アセンブリのコードベース 4. 3.が存在しなかった場合はプローブを行う
この4.のプローブというのが1.~3.まで探して見つからなかったときに最終手段として実行ファイルと同じ階層かアセンブリ名のついたサブフォルダを探すことのようです。
ということは、1.~3.の方法で行うのが正しいということですな。
1.はよく調べてないんであれですが、2.はどのアプリからでも使うDLLを登録して置く方法みたいです。この方法だと、昔のCOMみたいに結局レジストリに参照の設定を書かないといけないし、そもそも自身のアプリしか使わないのにグローバルのするのは勧められてません。
ということで推奨されているのは3.の方法です。これは参照するアセンブリをアプリケーション構成ファイル(app.config) に明記してやる方法です。
ということで、3.をするための具体的な方法を書いていきます。(ほとんど上記リンクの簡易解説となりますが。。)
大まかには下記の流れになります。
【1】アセンブリに署名し厳密名を割り当てる。 【2】sn.exeで厳密名を確認。 【3】アプリケーション構成ファイルにて使用するアセンブリの定義を書く。
【1】アセンブリに署名し厳密名を割り当てる。
まず、参照されるアセンブリは厳密名(いわゆる「アセンブリ署名」)というものがないといけません。
アセンブリの名前は下記の種類があるようです。
* 名前(簡易名) * バージョン * カルチャ(どの言語ロケールかというものを指定するみたい。"ja-JP"など) * 公開キー
この公開キーが付いたもの(署名されたもの)が厳密名のついたアセンブリだそうです。
この公開鍵そして秘密鍵を署名に使っているところがなかなか面白いです。(ちょっと余談ですが、、) アセンブリのハッシュを秘密鍵で暗号化。それを公開鍵とともにアセンブリに追加(署名)。 これにより、実行時に公開鍵で暗号化されたハッシュを複合して、アセンブリ自体のハッシュと比較してアセンブリが改ざんされていないかどうかチェックできる仕組みみたいです。電子メールの署名とかの技術をそのままアセンブリにも使ったという感じですが、ウイルス等への対策となることを考えると有効な方法ですね。
まあ、それはさておきとにかく署名をしないといけません。
Visual Studio2005ではIDE上で簡単に署名ができます。
1.プロジェクトのプロパティを開きます。 2.署名タブにて、「アセンブリの署名」にチェック。 3.「新規作成」にて新しいキーが簡単に作れます(しかも1回作っておけば使い回しがききます)
これで署名完了です。
【2】sn.exeで厳密名を確認。
次はアプリケーション構成ファイル(app.config)に読み込むアセンブリを定義します。
が、このとき厳密名を書かないといけません。
この厳密名がVS上でわかればいいのですが、私は見つけられませんでした。。
(署名はできるのに、厳密名がわからんとはどういうこっちゃ。。。)
とういことで、.Net Frameworkに付属している "sn.exe"というツールで確認できます。
(このsnですが、環境によっては入ってない場合もあるようです。VSのインストール時のオプションも関係あるのかな? 自分はProgram Files\Microsoft Visual Studio 8\SDK\v2.0\Binに入ってました)
下記のように使います。
>>sn -Tp test.dll(アセンブリ名) Microsoft(R) .NET Framework Strong Name Utility バージョン 2.0.50727.42 Copyright (c) Microsoft Corporation. All rights reserved. 公開キー 0024000004800........... 公開キー トークン d57fc5c09b533907
この「公開キー トークン」が厳密名になります。
【3】アプリケーション構成ファイルにて使用するアセンブリの定義を書く。
1.アプリケーション構成ファイルを追加(VSならソリューションエクスプローラでプロジェクト右クリック→追加→新しい項目→アプリケーション構成ファイル) すでに存在しているならその中に書いていきます。 2.アプリケーション構成ファイルに次のように使用するアセンブリへの参照を定義します。
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <dependentAssembly> <assemblyIdentity name="test(アセンブリ(簡易)名)" publicKeyToken="d57fc5c09b533907(上述の公開キートークン)" culture="neutral" /> <codeBase version="1.0.0.0" href="..\Common\Bin\test.dll(アセンブリへのパス)"/> </dependentAssembly> </assemblyBinding> </runtime>
結構めんどくさいのがあれですね。
まあでもこれで
* 複数のアプリケーションで共有できる * バージョン管理の対象となる * セキュリティ・チェックができる
という.Net Frameworkの利点が利用できるのはいいことです。
ちなみに、VS2005の署名タブのところで、「遅延署名のみ」というのがあるのですがこれがいまいちよくわかりません。
遅延署名自体の考え方は分かっているのですが、プロジェクトの実行やデバッグができないというのは困りますね。。