相关疑难解决方法(0)

ProcessStartInfo挂在"WaitForExit"上?为什么?

我有以下代码:

info = new System.Diagnostics.ProcessStartInfo("TheProgram.exe", String.Join(" ", args));
info.CreateNoWindow = true;
info.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
info.RedirectStandardOutput = true;
info.UseShellExecute = false;
System.Diagnostics.Process p = System.Diagnostics.Process.Start(info);
p.WaitForExit();
Console.WriteLine(p.StandardOutput.ReadToEnd()); //need the StandardOutput contents
Run Code Online (Sandbox Code Playgroud)

我知道我开始的进程的输出大约是7MB.在Windows控制台中运行它可以正常工作.不幸的是,这会在WaitForExit上无限期挂起.另请注意,对于较小的输出(例如3KB),此代码不会挂起.

ProcessStartInfo中的内部StandardOutput是否可能无法缓冲7MB?如果是这样,我该怎么做呢?如果没有,我做错了什么?

c# processstartinfo

179
推荐指数
8
解决办法
11万
查看次数

我可以单独捕获stdout/stderr并保持原始顺序吗?

我使用原生win32 API编写了一个Windows应用程序.我的应用程序将启动其他进程并捕获输出并以红色突出显示stderr输出.

为了实现这一点,我为stdout和stderr创建了一个单独的管道,并在调用CreateProcess时在STARTUPINFO结构中使用它们.然后,我为每个stdout/stderr句柄启动一个单独的线程,该句柄从管道读取并将输出记录到窗口.

在大多数情况下,这样做很好.我遇到的问题是,如果子进程快速连续记录到stderr和stdout,我的应用程序有时会以错误的顺序显示输出.我假设这是由于使用两个线程从每个句柄读取.

是否有可能以写入的原始顺序捕获stdout和stderr,同时能够区分这两者?

winapi redirect stdout stderr

8
推荐指数
1
解决办法
1716
查看次数

如何重定向CreateProcess执行的命令的大量输出?

我需要从命令行运行sqlite backup命令.我不想使用"cmd/c".命令是:

sqlite3.exe MYDB.db .dump> MYDB.bak

我在SO上找不到任何显示如何执行此操作的示例.

到目前为止,从各种SO帖子收集的代码是这样的,但是非常不完整:

function StartProcess(const ACommandLine: string; AShowWindow: boolean = True;
  AWaitForFinish: boolean = False): Integer;
var
  CommandLine: string;
  StartupInfo: TStartupInfo;
  ProcessInformation: TProcessInformation;
  StdOutPipeRead, StdOutPipeWrite: THandle;
  Handle: boolean;
begin
   Result := 0;
   FillChar(StartupInfo, SizeOf(TStartupInfo), 0);
   FillChar(ProcessInformation, SizeOf(TProcessInformation), 0);
   StartupInfo.cb := SizeOf(TStartupInfo);

   StartupInfo.hStdInput := GetStdHandle(STD_INPUT_HANDLE);
   StartupInfo.hStdOutput := StdOutPipeWrite;
   StartupInfo.hStdError := StdOutPipeWrite;

   if not(AShowWindow) then
   begin
   StartupInfo.dwFlags := STARTF_USESHOWWINDOW;
   StartupInfo.wShowWindow := SW_SHOWNORMAL;
   end;

   CommandLine := ACommandLine;
   UniqueString(CommandLine);
   Handle := CreateProcess(nil, PChar(CommandLine), nil, nil, False,
   CREATE_NEW_PROCESS_GROUP + NORMAL_PRIORITY_CLASS, …
Run Code Online (Sandbox Code Playgroud)

delphi winapi

5
推荐指数
1
解决办法
2054
查看次数

如何在不重定向的情况下从Process.StandardOutput读取?(F#)

我有这个小功能,可以省去处理可怕的System.Diagnostics.Process API的一些麻烦:

let HiddenExec (command: string, arguments: string) =
    let startInfo = new System.Diagnostics.ProcessStartInfo(command)
    startInfo.Arguments <- arguments
    startInfo.UseShellExecute <- false

    startInfo.RedirectStandardError <- true
    startInfo.RedirectStandardOutput <- true

    use proc = System.Diagnostics.Process.Start(startInfo)
    proc.WaitForExit()
    (proc.ExitCode,proc.StandardOutput.ReadToEnd(),proc.StandardError.ReadToEnd())
Run Code Online (Sandbox Code Playgroud)

这很好用,因为我得到了一个包含exitcode,stdout和stderr结果的三个元素的元组.

现在,假设我不想"隐藏"执行.也就是说,我想写一个假设的,更简单的Exec函数.然后解决方案是不重定向stdout/stderr,我们完成了:

let Exec (command: string, arguments: string) =
    let startInfo = new System.Diagnostics.ProcessStartInfo(command)
    startInfo.Arguments <- arguments
    startInfo.UseShellExecute <- false

    let proc = System.Diagnostics.Process.Start(startInfo)
    proc.WaitForExit()
    proc.ExitCode
Run Code Online (Sandbox Code Playgroud)

但是,如果我可以重构这两个函数将它们聚合成一个函数,并且只是向它传递一个"隐藏的"bool标志,那将是很好的:

let NewExec (command: string, arguments: string, hidden: bool) =
Run Code Online (Sandbox Code Playgroud)

这样,NewExec(_,_,false)也会返回stdout,stderr(不仅像之前一样退出exitCode).问题是,如果我不进行重定向舞蹈(startInfo.RedirectStandardError <- true),那么我以后无法从输出中读取,proc.StandardOutput.ReadToEnd()因为我得到了错误StandardOut has not …

.net f# system.diagnostics processstartinfo redirectstandardoutput

4
推荐指数
1
解决办法
895
查看次数