In this script, if I use a batch file, it works:
private async void cmdRunBatchFile2_Click(object sender, EventArgs e)
{
cmdRunBatchFile2.Enabled = false;
await Task.Run(() => {
var proc = new Process();
proc.StartInfo.FileName = @"test.bat";
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.RedirectStandardError = true;
proc.StartInfo.CreateNoWindow = true;
if (proc.Start())
{
//do something
}
proc.WaitForExit();
});
cmdRunBatchFile2.Enabled = true;
}
However if I change it to test.ps1, it returns this error: System.ComponentModel.Win32Exception: 'An error occurred trying to start process 'test.ps1' with working directory XYZ. The specified executable is not a valid application for this OS platform.'
After reading .Net Core 2.0 Process.Start throws "The specified executable is not a valid application for this OS platform", I then blindly try adding
proc.StartInfo.UseShellExecute = true;
This yields another error: System.InvalidOperationException: 'The Process object must have the UseShellExecute property set to false in order to redirect IO streams.'
Do you know why is that?
First things first: An alternative, more efficient and flexible way to execute PowerShell code from a .NET executable is to use the PowerShell SDK, which enables in-process execution with full .NET type support - see this answer for an example.
Batch files (
.bat,.cmdfiles) have special status on Windows: They are the only script-type files that the Windows API - which underlies the .NET APIs - treats as if they were directly executable, binary files, by implicitly passing such files tocmd.exe /cfor execution.All other script files, which by definition require a scripting engine (shell) to execute, can not be executed this way, and instead you must specify their associated scripting engine / shell CLI as the executable in the
.FileNameproperty of theSystem.Diagnostics.ProcessStartInfoclass, followed by the appropriate engine / shell-specific command-line parameter that requests execution of a script file, if necessary, and the script file's path itself..UseShellExecute = true, you'll lose the ability to capture the launched process' output and to control its window (creation) style..UseShellExecute = true, you can specify a script file directly in.FileName, but there's no guarantee that it will execute, given that is the default GUI shell operation that is then performed (which never runs in the current console window), which for script files often means opening them for editing.In order to execute a
.ps1script viapowershell.exe, the Windows PowerShell CLI, usepowershell.exe -file.Therefore: