アプリケーションの実行パスを取得する。どの方法が適切か検討してみた。

アプリケーションの実行パスを取得する方法について調べると実にさまざまな方法が見つかります。どの方法でも実行ファイルのパスを取得できるようなのですが、では実際にどの方法を使えばいいのか。一番良い方法はどれなのかを検討してみました。

まずは、Googleの検索結果を見て行きます。

@IT 実行ファイルのパスを取得するには?
http://www.atmarkit.co.jp/fdotnet/dotnettips/016exepath/exepath.html


Assembly myAssembly = Assembly.GetEntryAssembly();
string path = myAssembly.Location;


string path = Application.ExecutablePath;

@IT ClickOnceアプリのディレクトリ・パスを取得するには?[2.0のみ、C#VB
http://www.atmarkit.co.jp/fdotnet/dotnettips/501clickonapppath/clickonapppath.html


Assembly asm = Assembly.GetEntryAssembly();
string fullPath = asm.Location;

WoodenSoldier Software
http://www.woodensoldier.info/computer/csharptips/66.htm


Console.WriteLine(Application.StartupPath + "\\property.xml");

http://capsulecorp.studio-web.net/tora9/cs/GetCwd.html


return System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);

http://d.hatena.ne.jp/tomandjelly/20110211/1297402861


String exeName = Assembly.GetEntryAssembly().ManifestModule.Name;

http://www.be-styles.jp/archives/2468


Environment.GetCommandLineArgs()[0]);

http://hiros-dot.net/VBNET2003/File/File10.htm


strAppPath = System.AppDomain.CurrentDomain.BaseDirectory


どれを使うべきか迷う所ですが、結果が同じなら取得に使うクラスが所属している名前空間アセンブリが標準的なものであるかで判断したいと思います。(参照設定なしに利用できるので)


・Assemblyクラスは、名前空間: System.Reflection アセンブリ: mscorlib (mscorlib.dll 内)

・Applicationクラスは、名前空間: System.Windows.Forms アセンブリ: System.Windows.Forms (system.windows.forms.dll 内)

・Environmentクラスは、名前空間: System アセンブリ: mscorlib (mscorlib.dll 内)

・AppDomainクラスは名前空間: System アセンブリ: mscorlib (mscorlib.dll 内)


System名前空間が最も標準的なので、EnvironmentクラスとAppDomainクラスのいずれかに決めたいと思います。どちらが良いかは判断に迷う所なので、それぞれのマニュアルを参照してアプリケーションの実行パスとしてふさわしいか判断したいと思います。

Environment.GetCommandLineArgs メソッド


配列の先頭の要素には、実行中のプログラムのファイル名が格納されます。ファイル名が取得できない場合、先頭の要素は String.Empty に等しくなります。残りの要素には、コマンド ラインで入力された追加のトークンが格納されます。

プログラム ファイル名にはパス情報を含めることができますが、必須ではありません。

引用符 (QUOTATION MARK, U+0022) 内に空白が存在しない場合、コマンド ライン引数は空白 (SPACE (U+0020) または CHARACTER TABULATION (U+0009)) で区切られます。引用符内の空白は、引用符で囲まれたテキストの一部と見なされます。区切り記号は、コマンド ライン引数には含まれません。

引用符の後に続く円記号 ("\") (REVERSE SOLIDUS (U+005C)) は、特別に解釈されます。引用符の後に 2n 個の円記号 ("\") が続く場合、コマンド ライン引数には n 個の円記号が含まれ、引用符で囲まれたテキストが開始 (前のテキストが引用符で囲まれていない場合) または終了 (前のテキストが引用符で囲まれている場合) します。引用符の後に 2n+1 個の円記号 ("\") が続く場合、コマンド ライン引数には n 個の円記号とリテラルの一重引用符が含まれます。n 個の円記号 ("\") の前に引用符がない場合、コマンド ライン引数には n 個の円記号が含まれます。

コマンド ラインを単一の文字列として取得するには、CommandLine プロパティを使用します。

Windows NT 4.0, Windows 2000 プラットフォームメモ : 実行可能ファイルの名前にパスは含まれません。

Windows 98, Windows Millennium Edition プラットフォームメモ : 実行可能ファイルの名前にパスが含まれます。長いファイル名 (8.3 形式ではないファイル名) は、8.3 形式に短縮される可能性があります。

環境によってパスが含まれなかったり、短い形式のファイル名になる場合があるようです。

AppDomain.BaseDirectory


アセンブリを探すためにアセンブリゾルバーが使用したベース ディレクトリを取得します。

アセンブリゾルバーが使用するベースディレクトリは、アプリケーションの実行パスなので問題ないと思います。新しくアプリケーションドメインを作成して使用する場合は問題がありそうですが、一般的なショートカットから起動するタイプのアプリケーションでは問題にならないでしょう。

結論
System.AppDomain.CurrentDomain.BaseDirectory

次回は、DLLの場所について調べてみたいと思います。