kkamegawaの購入記録

漫画、小説、映画や買ったものの記録をつらつらしていきます。昔は一部技術情報もありました…

.NET Frameworkで現在実行中のモジュールの格納パスを取得する方法

 .NET Frameworkで作成されたa.exeファイルと同じディレクトリに何らかのファイル、もしくは別のexeファイル(b.exeとしましょう)があったとします。このa.exeから子プロセスとして、b.exeを起動させたい場合、a.exeのディレクトリにパスが通っていなく、起動ディレクトリをa.exeがあるフォルダ以外に設定していた場合、起動できない可能性があります。  このような現象を回避するためには、a.exeが格納されているフルパスを取得しなくてはなりませんが、ちょっとはまったので記録として残しておきます(Environment.CurrentDirectoryではだめなんですよ。やってみればわかります)。なお、この問題に対処するにあたって、川俣晶さんの.NET Frameworkで現在実行中のアセンブリのフルパス名を得る方法に助けられました(オータムマガジンの技術雑記に書かれていることは覚えていたのですが、私の検索キーワードがまずくて、ぐぐってもヒットしませんでした(^^;)。方法としては以下の二通りが考えられます。
  1. AssemblyクラスのGetExecutingAssembly経由でとる
  2. Windows APIを使用してGetCommandLine()→CommandLineToArgvW()というコンボでとる
 1の場合、C#で書くとこんな感じです。
using System.Reflection;

Assembly  mainAssembly  =  Assembly.GetExecutingAssembly();
Module  mainMod = mainAssembly.GetModules()[0];
string  strInstalledDir = Path.GetDirectoryName(mainMod.FullyQualifiedName);
 managedコードが使えるので、わざわざ危ないunsafeを使わなくてはならない2を使う必要はあまりないでしょう。そして、こんな苦労をするのは、どのプロセスからロードされるかわからないDLLの中から取得したい場合か、コンソールアプリケーションだけだろうと思います。Formを持つアプリケーションの場合、System.Windows.Forms.Application.StartupPathというプロパティが使えるんですよ。なんでWindows.Formsだけ…。