在此脚本中,如果我使用批处理文件,它将工作:
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;
}
但是,如果我将其更改为test.ps1
,则会返回以下错误: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.'
在阅读.Net Core 2.0 Process.Start throws "The specified executable is not a valid application for this OS platform"之后,我接着盲目地尝试添加
proc.StartInfo.UseShellExecute = true;
这会产生另一个错误:System.InvalidOperationException: 'The Process object must have the UseShellExecute property set to false in order to redirect IO streams.'
你知道这是为什么吗?
1条答案
按热度按时间j9per5c41#
首先要做的是:从.NET可执行文件执行PowerShell代码的一种替代、更高效、更灵活的方法是使用PowerShell SDK***,它支持 * 进程内执行 , 具有 * 完整的.NET类型支持**-有关示例,请参见this answer。
批处理文件(
.bat
、.cmd
文件)在Windows上具有 * 特殊状态*:它们是Windows API(作为.NET API的基础)将其视为 * 可直接执行的二进制文件 * 的唯一 * 脚本 * 类型文件,方法是 * 隐式 * 将此类文件传递给cmd.exe /c
执行。所有其他脚本文件,根据定义需要脚本 * 引擎 (shell), 不能 * 以这种方式执行,必须在
System.Diagnostics.ProcessStartInfo
类的.FileName
属性中将其关联的脚本引擎/ shell CLI指定为可执行文件,后跟请求执行脚本文件的相应引擎/shell特定命令行参数,如果需要,还可以包含脚本文件本身的路径。.UseShellExecute = true
,您将失去捕获已启动进程的输出和控制其窗口(创建)样式的能力。.UseShellExecute = true
,您 * 可以 * 直接在.FileName
中指定脚本文件,但不能保证它会 * 执行 *,因为这是随后执行的 * 默认GUI shell操作 *(不会在 * 当前 * 控制台窗口中运行),这对于脚本文件通常意味着 * 打开它们进行编辑 *。要通过
powershell.exe
(Windows PowerShell CLI)执行.ps1
脚本,请使用powershell.exe -file
。因此: