はじめに
Windowsサービスからあるbatファイルを起動する際に、そのbatファイルの実行ディレクトリをそのbatファイルないで取得するために「%~dp0」でパスを取得した際、本来はbatファイルと同じフォルダパスになって欲しいのですが、下記の結果となりました。
var path = "C:¥Work¥test.bat";
var process = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = Environment.GetEnvironmentVariable("ComSpec"),
CreateNoWindow = true,
UseShellExecute = false,
Arguments = $"/c ¥"{path}¥" ¥"arg1¥""
}
};
process.Start();
process.WaitForExit();
rem C#から実行されたbatファイル
rem C:¥Work¥test.bat "arg1"
echo %1
echo %~dp0
arg1
C:¥Windows¥System32
「C:¥Work」となることを期待していたのですが、cmd.exeの実行パスとなっていました。
対策
ProcessStartInfoにはオプションとして「WorkingDirectory」が用意されていて、この設定をしてあげることで、好きな作業ディレクトリを設定することができます。
たとえば、「C:¥Work」を作業ディレクトリとしたい場合は下記のように設定します。
var path = "C:¥Work¥test.bat";
var process = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = Environment.GetEnvironmentVariable("ComSpec"),
CreateNoWindow = true,
UseShellExecute = false,
Arguments = $"/c ¥"{path}¥" ¥"arg1¥"",
// *****************************************
// 下記を追加
// *****************************************
WorkingDirectory = "C:¥Work"
}
};
process.Start();
process.WaitForExit();
上記を実行してみた結果が下記の通りです。
rem C#から実行されたbatファイル
rem C:¥Work¥test.bat "arg1"
echo %1
echo %~dp0
arg1
C:¥Work
最後に
少しハマりましたが、C#アプリケーションからbatファイルを呼び出す場合には、作業ディレクトリを決めておくと、良いかと思います。
C#アプリケーションと同じパスで処理したい場合は、下記のように設定しておくと良いかと思います。
using system.Reflection;
using system.IO;
〜〜〜
WorkingDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)
〜〜〜