C# 当UseShellExecute为true时,如何读取控制台输出?

C# 当UseShellExecute为true时,如何读取控制台输出?,c#,C#,如果Process.StartInfo.UseShellExecute=false,则获取标准输出。然而,在我的例子中,UseShellExecute必须保持为true。原因是我正在启动一个.exe,它恰好位于路径中,但不在当前工作目录中 以下是我无法使用UseShellExecute=false的原因: var psi = new ProcessStartInfo("cleancss", "--help") { WorkingDirectory = @"C:\SomeRandomDir

如果
Process.StartInfo.UseShellExecute=false,则获取标准输出。然而,在我的例子中,UseShellExecute必须保持为true。原因是我正在启动一个.exe,它恰好位于路径中,但不在当前工作目录中

以下是我无法使用
UseShellExecute=false
的原因:

var psi = new ProcessStartInfo("cleancss", "--help")
{
    WorkingDirectory = @"C:\SomeRandomDirectory",
    UseShellExecute = false,
    RedirectStandardOutput = true,
    RedirectStandardInput = true
};

Process cssClean = Process.Start(psi);  //blows up with The system cannot find the file specified
由于
UseShellExecute=false
需要一个绝对路径,因此它会正确启动。我没有绝对的路径

如果我在上面的示例中设置
UseShellExecute=true
,它会告诉我重定向标准输出在这种情况下不起作用


当UseShellExecute为true时,如何获得标准输出

如果不提供绝对路径,Windows将:

  • 在工作目录中查找一个.bat、.exe、然后是.com文件,该文件在点之前有“cleancss”(我不确定这3个文件的确切顺序;现在它可能包括.VBS和其他可执行文件)

  • 然后遍历path变量条目,对每个条目执行相同的检查

  • 它发现的第一件事就是执行

  • 如果它失败了,并且通过了整个路径列表,只有到那时它才会承认失败

  • (注意,Windows/DOS控制台上有一个0:“检查这是否是一个保留关键字,我应该对自己做出反应”。几十年来,程序不断地从关键字转换到专用进程,然后再转换回来)

    理想情况下,您应该在应用程序设置中设置此路径-无论您使用何种方式来持久化应用程序设置。然后,您可以选择为用户提供一个UI来设置该路径。让Windows找出您所指的文件是DOS时代的一大难题。我们没有像注册处这样的选择。或查找文件对话框。它不应该在2020年投入使用

    如果您不得不保持这种状态(或者您需要找到一个默认值),那么实现Windows搜索模式就很简单了。在计划的工作目录中尝试所有3个扩展。检索路径变量并对其进行迭代


    最后,Windows中的每个程序调用都使用一个绝对路径。只是有时候Windows必须为您找出绝对路径,因为您是一个愚蠢的普通用户,在远离系统目录时键入了“EDIT”。

    您可以使用/c参数启动CMD.exe,后面跟着要执行的内容。Cmd不需要路径,但如果启动,它会从调用方继承环境,并且具有完全填充的路径

    var psi = new ProcessStartInfo("cmd", "/c cleancss --help")
    {
        WorkingDirectory = @"C:\SomeRandomDirectory",
        UseShellExecute = false,
        RedirectStandardOutput = true,
        RedirectStandardInput = true
    };
    
    Process cssClean = Process.Start(psi);  
    
    cmd.exe的/c参数描述如下:

    执行字符串指定的命令,然后终止


    在我的测试中,以这种方式启动的任何输出都会将pipe-d传递到父进程

    请注意,有几种方法可以找到路径中的可执行文件的完整路径。看见