子プロセスを起動する際のコマンドライン引数は、ProcessStartInfoクラスのArgumentsプロパティで指定することができます。 ただし、このプロパティは引数すべてを単一の文字列として指定する必要があり、また空白
を含む文字列とダブルクオーテーション"
のエスケープが必要な場合はエスケープ済みの文字列を指定する必要があります。
.NET Standard 2.1/.NET Core 2.1以降では、ArgumentListプロパティを使用することもできます。 このプロパティは引数を文字列のコレクションとして指定することができ、また空白
を含む文字列とダブルクオーテーション"
のエスケープも自動的に行われます。
コマンドライン引数はArgumentsまたはArgumentListのどちらか一方のみが設定でき、両方設定した状態でProcess.Startメソッドを呼び出すとInvalidOperationExceptionをスローします。 また、Argumentsに設定した値はArgumentListには反映されず、逆もまた同様です。
ProcessStartInfoクラスで子プロセスのコマンドライン引数を指定する
Imports System
Imports System.Diagnostics
Class Sample
Shared Sub Main(ByVal args() As String)
' 子プロセスとして起動された場合は、コマンドライン引数を一行ごとに表示して終了する
If Not String.IsNullOrEmpty(Environment.GetEnvironmentVariable("CHILD")) Then
For Each arg As String In args
Console.WriteLine(arg)
Next
Return
End If
' 自プロセスと同じ実行可能ファイルに、コマンドライン引数を与えて子プロセスとして起動する
Dim psi As New ProcessStartInfo(Process.GetCurrentProcess().MainModule.FileName)
#If True
' Argumentsプロパティでコマンドライン引数を指定する
psi.Arguments = "/esc=\"" /dir1=C:\Program Files\dotnet /dir2=""C:\Program Files\dotnet"" ""/dir3 = C:\Program Files\dotnet"""
#Else
' ArgumentListプロパティでコマンドライン引数を指定する
psi.ArgumentList.Add("/esc=""")
psi.ArgumentList.Add("/dir1=C:\Program Files\dotnet")
psi.ArgumentList.Add("/dir2=""C:\Program Files\dotnet""")
psi.ArgumentList.Add("""/dir3 = C:\Program Files\dotnet""")
#End If
psi.EnvironmentVariables("CHILD") = "1" ' 子プロセスとして起動したことを示す環境変数を設定しておく (再帰的なプロセス生成を抑止する)
psi.UseShellExecute = False ' ⚠.NET Core/.NET 5以降ではデフォルトでFalseとなっているため、明示的に指定しなくても可
' 上記のパラメータで子プロセスを起動する
Using child As Process = Process.Start(psi)
' 子プロセスの終了を待機する
child.WaitForExit()
End Using
End Sub
End Class
実行結果
/esc=" /dir1=C:\Program Files\dotnet /dir2=C:\Program Files\dotnet /dir3 = C:\Program Files\dotnet
実行結果
/esc=" /dir1=C:\Program Files\dotnet /dir2="C:\Program Files\dotnet" "/dir3 = C:\Program Files\dotnet"
上記のコードでは、コマンドライン引数を与えた上で再帰的にプロセスを起動しています。 上記のコードで環境変数CHILD
を指定せずに実行した場合Fork爆弾と同様の動作となるため、コードを改変する場合は注意してください。