起動してるプログラムの名前を取得したい
◆ Environment.GetCommandLineArgs()[0]
◆ フルパスだったりファイル名だったり拡張子なかったり
◆ bat から起動しても大丈夫
◆ デバッグ実行でも動いてる exe (vshost 付き) がとれる
◆ Assembly.GetExecutingAssembly().Location か GetEntryAssembly
◆ あくまでアセンブリなので exe とあってないこともある
◆ executing の方はそのコードがあるアセンブリ dll にあるかもしれない
◆ entry の方は 最初に起動したもの
◆ フルパスだったりファイル名だったり拡張子なかったり
◆ bat から起動しても大丈夫
◆ デバッグ実行でも動いてる exe (vshost 付き) がとれる
◆ Assembly.GetExecutingAssembly().Location か GetEntryAssembly
◆ あくまでアセンブリなので exe とあってないこともある
◆ executing の方はそのコードがあるアセンブリ dll にあるかもしれない
◆ entry の方は 最初に起動したもの
○○.exe というのを知りたいです
前に実行中のフォルダの取得方法を調べたときの方法は
こういうものがありました
ディレクトリを直接取得してるのを除外すると
と
フォルダのときは カレントディレクトリが変更されると正しくフォルダをとれなかったのですが それはフルパスじゃなくて exe ファイルの名前だけで実行された場合にフルパス化するときにカレントディレクトリが使われるからです
ということでファイル名取るのに問題なさそう?
とりあえずこの辺を調べてみました
また フルパスのこともあるので
のようにファイル名だけにしないといけません
あと VisualStudio のデバッグ実行だと app-test.vshost.exe になっています
一応実行されてる exe が vshost 付きなので間違ってはないです
その分 .exe が付くかどうかの心配はいらないです
デバッグ実行でも vshost がつきません
ただ 実際にタスクマネージャにある exe は vshost 付きなので コマンドプロンプト経由でプロセス ID 取得してどうこうするとか そういうときにちゃんと動かなそうです
それと GetExecutingAssembly() は名前通り そのコードを実行したアセンブリの取得です
C# interactive や csi を直接起動したときの REPL で入力するスクリプトではちょっと特殊で アセンブリ自体は取得できますが Location は空文字です
動的に作られたもの?のようです
代わりに Assembly.GetEntryAssembly() を使うとエントリーポイントのアセンブリが取得できます
こっちだと
C# は InteractiveHost.exe
csi 直接は csi.exe
と ちゃんと取得できます
ただこれも最初に起動したアセンブリのようなので 場合によっては目的のものは取れないかもです
もうひとつ GetAssembly があって それは GetCallingAssembly
実行中メソッドを呼び出したメソッドがあるアセンブリを取得するようです
別 dll のライブラリとかで便利なのかもとおもいましたが ドキュメント見てみると 最適化でインライン展開されてると結果が変わるとか書いていて 使わない方がいいやつかな と思えました
アセンブリ使う場合は 実行中よりエントリーポイント見たほうがいいかも
前に実行中のフォルダの取得方法を調べたときの方法は
System.AppDomain.CurrentDomain.BaseDirectory
Directory.GetCurrentDirectory()
Assembly.GetExecutingAssembly().Location
Environment.CurrentDirectory
Environment.GetCommandLineArgs()[0]
Directory.GetCurrentDirectory()
Assembly.GetExecutingAssembly().Location
Environment.CurrentDirectory
Environment.GetCommandLineArgs()[0]
こういうものがありました
ディレクトリを直接取得してるのを除外すると
Assembly.GetExecutingAssembly().Location
と
Environment.GetCommandLineArgs()[0]
フォルダのときは カレントディレクトリが変更されると正しくフォルダをとれなかったのですが それはフルパスじゃなくて exe ファイルの名前だけで実行された場合にフルパス化するときにカレントディレクトリが使われるからです
ということでファイル名取るのに問題なさそう?
とりあえずこの辺を調べてみました
コマンドライン引数の場合
問題ないかなと思ったのですが 起動するときにコマンドプロンプトに最初に書くあれなので app-test.exe だったり app-test だけだったりもしますまた フルパスのこともあるので
Path.GetFileName(@"C:\data\programs\vs\sample\bin\app-test.exe");
// app-test.exe
// app-test.exe
のようにファイル名だけにしないといけません
あと VisualStudio のデバッグ実行だと app-test.vshost.exe になっています
一応実行されてる exe が vshost 付きなので間違ってはないです
Assembly の場合
アセンブリのフルパスなのでこっちは Path.GetFileName は必須ですその分 .exe が付くかどうかの心配はいらないです
デバッグ実行でも vshost がつきません
ただ 実際にタスクマネージャにある exe は vshost 付きなので コマンドプロンプト経由でプロセス ID 取得してどうこうするとか そういうときにちゃんと動かなそうです
それと GetExecutingAssembly() は名前通り そのコードを実行したアセンブリの取得です
C# interactive や csi を直接起動したときの REPL で入力するスクリプトではちょっと特殊で アセンブリ自体は取得できますが Location は空文字です
動的に作られたもの?のようです
代わりに Assembly.GetEntryAssembly() を使うとエントリーポイントのアセンブリが取得できます
こっちだと
C# は InteractiveHost.exe
csi 直接は csi.exe
と ちゃんと取得できます
ただこれも最初に起動したアセンブリのようなので 場合によっては目的のものは取れないかもです
もうひとつ GetAssembly があって それは GetCallingAssembly
実行中メソッドを呼び出したメソッドがあるアセンブリを取得するようです
別 dll のライブラリとかで便利なのかもとおもいましたが ドキュメント見てみると 最適化でインライン展開されてると結果が変わるとか書いていて 使わない方がいいやつかな と思えました
まとめ
実際の動いてる exe 名を知りたいならEnvironment.GetCommandLineArgs()[0]
に .exe ないならつけて Path.GetFileName するのがよさそうアセンブリ使う場合は 実行中よりエントリーポイント見たほうがいいかも