如何从进程内的进程读取进程输出消息?

时间:2016-05-26 09:54:48

标签: c# asp.net process console-application

我正在通过命令行运行exe并获得以下输出。

  

C:\ Users \用户系统管理员> C:\ Users \用户系统管理员\桌面\ New_folder \设置\ PatchInstaller.exe   --mode =无声

     

C:\ Users \ sysadmin开始设置UI模式:无提示错误:   运行另一个实例,一次只能运行一个实例。   退出代码:11

我通过System.daignostics.process运行它。

我的问题是 PatchInstaller.exe 调用另一个进程,该嵌套进程的输出是cmd可见的。但是相同的结果和退出代码我无法通过 PatchInstaller.exe 的Process对象。 有没有办法在流程中运行流程输出? 以下是我累了的代码......

            string command = @"C:\Users\sysadmin\Desktop\Setup\PatchInstaller.exe";
            string result = string.Empty;
            System.Diagnostics.ProcessStartInfo procStartInfo = new ProcessStartInfo();
            procStartInfo = new System.Diagnostics.ProcessStartInfo("cmd", "/c " + command + " --mode=silent);
            System.Diagnostics.Process proc = new Process();
            procStartInfo.ErrorDialog = false;
            procStartInfo.UseShellExecute = false;
            procStartInfo.RedirectStandardOutput = true;
            procStartInfo.RedirectStandardError = true;
            procStartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
            // Do not create the black window.
            procStartInfo.CreateNoWindow = true;

            if (!string.IsNullOrEmpty(domain) && !string.IsNullOrEmpty(user) && !string.IsNullOrEmpty(pwd))
            {
                procStartInfo.Domain = domain;
                procStartInfo.UserName = user;

                System.Security.SecureString ss = new System.Security.SecureString();
                foreach (char c in pwd) { ss.AppendChar(c); }
                procStartInfo.Password = ss;
            }

            proc = System.Diagnostics.Process.Start(procStartInfo);

            proc.ErrorDataReceived += delegate(object sender, System.Diagnostics.DataReceivedEventArgs errorLine)
            {
                if (errorLine.Data != null) result += "error:" + errorLine.Data +;

            };
            proc.OutputDataReceived += delegate(object sender, System.Diagnostics.DataReceivedEventArgs outputLine)
            {
                if (outputLine.Data != null) result += outputLine.Data +;

            };
            proc.BeginErrorReadLine();
            proc.BeginOutputReadLine();
            Process[] pname = Process.GetProcessesByName("PatchInstaller");
            Process[] processlist = Process.GetProcesses();
            foreach (Process theprocess in processlist)
            {
                Console.WriteLine("Process: {0} ID: {1}", theprocess.ProcessName, theprocess.Id);
            }

            proc.WaitForExit();

2 个答案:

答案 0 :(得分:0)

我对ProcessStartInfo了解不多,但我之前使用过Process,从标准输出中获取信息的方式如下所示,我假设它应该是类似的方式只需访问StandardOutput

即可
Process cmd = new Process();

cmd.StartInfo.FileName = "cmd.exe";
cmd.StartInfo.RedirectStandardInput = true;
cmd.StartInfo.RedirectStandardOutput = true;
cmd.StartInfo.CreateNoWindow = false;
cmd.StartInfo.UseShellExecute = false;
cmd.Start();

cmd.StandardInput.WriteLine(command);
cmd.StandardInput.Flush();
cmd.StandardInput.Close();

var output = cmd.StandardOutput.ReadToEnd();

cmd.WaitForExit();

答案 1 :(得分:0)

此代码对我有用:

    const int MAX_EXIT_WAIT_TIME = 3000;
    // Fill needed data
    string username = "";
    string password = "";
    string domain = "";
    string appName = "";

    var dir = Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName);
    var appFullPath = Path.Combine(dir, appName);
    ProcessStartInfo psi = new ProcessStartInfo(appFullPath);
    psi.UserName = username;
    var securePass = new System.Security.SecureString();
    foreach (var c in password)
        securePass.AppendChar(c);
    psi.Password = securePass;
    psi.Domain = domain;
    psi.LoadUserProfile = false;
    psi.WorkingDirectory = dir;
    psi.Arguments = "";
    psi.RedirectStandardOutput = true;
    // Create Process object, but not start it!
    var proc = new Process();
    proc.StartInfo = psi;
    StringCollection values = new StringCollection();
    DataReceivedEventHandler outputDataReceived = (o, e) =>
    {
        lock (values)
            values.Add(e.Data);
    };
    try
    {
        proc.OutputDataReceived += outputDataReceived;
        // Only here we start process
        if (!proc.Start())
            throw new InvalidOperationException("Couldn't start app");
        proc.BeginOutputReadLine();
        proc.WaitForExit(MAX_EXIT_WAIT_TIME);
    }
    finally { proc.OutputDataReceived -= outputDataReceived; }
    Console.WriteLine("Read {0} ", values.Count);
    foreach (var item in values)
        Console.WriteLine("  {0}", item);