現在実行しているDLLのパスを取得する。(GetExecutingAssembly )
.Net Frameworkでは、アプリケーションの配置はXCopyによる配置が主流であるためExeとDLLの場所が異なる場合は、あまり多くありません。殆どの場合、Exeの場所を求めれば課題を解決することができるため、DLLのパスを取得する必要性は以前ほどなくなってきています。
アンマネージドDLLの一種であるActiveX DLLはシステム全体で1箇所のみの配置で、「DLLの位置を基準に、サブフォルダの設定ファイルを読み込む」などといった用途でDLLのパスを取得する事が多くありました。そんな時、アンマネージドDLLではDLLのパスを取得する際に GetModuleFileName を使ってパスを取得していました。
使用用途は以前より限られてくるものの .Net Framework の DLLでのパスの取得方法について整理してみました。
まず、DLLのパスの取得に利用できそうなメソッドがAssemblyクラスの次の3メソッドです。
Assembly.GetEntryAssembly メソッド
既定のアプリケーション ドメインで実行できるプロセスを取得します。
他のアプリケーション ドメインでは、AppDomain.ExecuteAssembly で実行された最初の実行可能ファイルです。
Assembly.GetCallingAssembly メソッド
現在実行中のメソッドを呼び出したメソッドの Assembly を返します。
Assembly.GetExecutingAssembly メソッド
現在実行中のコードを格納しているアセンブリを取得します。
MSDNの説明文を読む限り、GetEntryAssembly(Exeのパス)、GetCallingAssembly(呼び出し元のパス)、GetExecutingAssembly(DLLのパス)のように読み取れます。実際にサンプルコードを作成して、どのような値が取得できるのか、また落とし穴はないか検証してみたいと思います。
検証方法としてはExeとDLLをそれぞれ作成し、DLL側で上記3メソッドを呼び出す処理を実装。Exeから呼び出して結果を確認するという事をしてみたいと思います。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;namespace AssembleyPathTest
{
class Program
{
static void Main(string[] args)
{Console.WriteLine(String.Format("GetEntryAssembly:{0}", AssembleyPath.AssembleyPathResolve.GetEntryAssembly().ToString()));
Console.WriteLine(String.Format("GetCallingAssembly:{0}", AssembleyPath.AssembleyPathResolve.GetCallingAssembly().ToString()));
Console.WriteLine(String.Format("GetExecutingAssembly:{0}", AssembleyPath.AssembleyPathResolve.GetExecutingAssembly().ToString()));Console.ReadLine();
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;namespace AssembleyPath
{
public class AssembleyPathResolve
{public static string GetEntryAssembly()
{
return System.Reflection.Assembly.GetEntryAssembly().Location;
}public static string GetCallingAssembly()
{
return System.Reflection.Assembly.GetCallingAssembly().Location;
}public static string GetExecutingAssembly()
{
return System.Reflection.Assembly.GetExecutingAssembly().Location;
}}
}
検証結果は、以下となりました。パスを取得するには予想通りGetExecutingAssemblyが適切なようです。
GetEntryAssembly:C:\AssembleyPathTest.exe
GetCallingAssembly:C:\AssembleyPathTest.exe
GetExecutingAssembly:C:\AssembleyPath.dll
GetEntryAssemblyとGetCallingAssemblyが同じになっていますが上記のExeとDLLの間にもうひとつアセンブリを挟むとGetCallingAssemblyは挟んだDLL名を返すようになります。(検証済み)