6

我有一个可以从命令提示符立即运行的可执行文件,但在使用 System.Diagnostics.Process 生成时似乎不会返回:

基本上,我正在围绕 Accurev CLI 接口编写一个 .NET 库包装器,因此每个方法调用都会产生 CLI 进程以执行命令。

这适用于除一个命令之外的所有命令:

  accurev.exe show depots

但是,当从控制台运行它时,它运行良好,当我使用 .net 进程调用它时,它挂起......我使用的进程生成代码是:

    public static string ExecuteCommand(string command)
    {

        Process p = createProcess(command);

        p.Start();            
        p.WaitForExit();

        // Accurev writes to the error stream if ExitCode is non zero.
        if (p.ExitCode != 0)
        {
            string error = p.StandardError.ReadToEnd();
            Log.Write(command + " failed..." + error);
            throw new AccurevException(error);                 
        }
        else
        {
            return p.StandardOutput.ReadToEnd();
        }

    }

    /// Creates Accurev Process 
    /// </summary>
    /// <param name="command"></param>
    /// <returns></returns>
    private static Process createProcess(string command)
    {
        Log.Write("Executing Command: " + command);

        ProcessStartInfo startInfo = new ProcessStartInfo();
        Process p = new Process();

        startInfo.CreateNoWindow = false;
        startInfo.RedirectStandardOutput = true;
        startInfo.RedirectStandardInput = true;
        startInfo.RedirectStandardError = true;

        startInfo.UseShellExecute = false;
        startInfo.Arguments = command;
        startInfo.FileName = _accurev;

        p.StartInfo = startInfo;

        return p;
    }

它挂在 p.WaitForExit() 处。

有什么建议吗?

编辑:解决了!

如果输出缓冲区溢出,.NET 进程会挂起,我切换到使用异步读取方法并且一切正常:

    public static string ExecuteCommand(string command)
    {
        StringBuilder outputData = new StringBuilder();

        Process p = createProcess(command);

        p.OutputDataReceived += delegate(object sender, DataReceivedEventArgs e)
        {
            outputData.AppendLine(e.Data);
        };

        p.Start();
        p.BeginOutputReadLine();

        p.WaitForExit();

        // Accurev writes to the error stream if ExitCode is non zero.
        if (p.ExitCode != 0)
        {
            string error = p.StandardError.ReadToEnd();
            Log.Write(command + " failed..." + error);
            throw new AccurevException(error);                 
        }
        else
        {
            return outputData.ToString();
        }

    }   
4

3 回答 3

2

It is seeking for input? In particular, I notice that you are redirecting stdin, but not closing it - so if it is reading from stdin it will hang.

于 2008-12-16T18:58:05.133 回答
1

WaitForExit() 执行时,生成的进程是否仍然存在?你能附加一个调试器吗?

于 2008-12-16T18:44:12.010 回答
-2

try replacing the WaitForExit() with something like this:

while (!p.WaitForExit(100))
    Console.Write(".");

The other thing to try is setting UseShellExecute to true, and watching the console window be spawned. See this page for the intricacies of that parameter: http://blogs.msdn.com/jmstall/archive/2006/09/28/CreateNoWindow.aspx

于 2008-12-16T19:01:32.550 回答