1

Delphiで記述されたコンソールアプリケーション(Host.exe)があります。C#アプリケーション(WinForm)でコンソールアプリケーションの出力をリダイレクトしたい。

以下を使用すると、(Host.exe)は問題なく呼び出されますが、(show-window、完全に独立した)として実行されるため、出力を取得できません。

                ProcessStartInfo pp = new ProcessStartInfo();
                pp.WorkingDirectory = Path.GetDirectoryName(Application.ExecutablePath);
                pp.FileName = Path.Combine(pp.WorkingDirectory, "Host.exe");
                pp.CreateNoWindow = false;
                pp.WindowStyle = ProcessWindowStyle.Normal;
                pp.UseShellExecute = true;
                using (Process pProcess = Process.Start(pp))
                {
                    while ((pProcess != null) && (!pProcess.HasExited))
                    {
                        Application.DoEvents();
                        Thread.Sleep(updatefreq);
                    }
                }

ただし、出力(リダイレクト)をキャプチャしようとすると、プロセスはすぐに終了します(HasExited = true、ループが中断し、デバッガーは「ReadProcessMemoryまたはWriteProcessMemory要求の一部のみが完了しました」と表示します。

                ProcessStartInfo pp = new ProcessStartInfo();
                pp.WorkingDirectory = Path.GetDirectoryName(Application.ExecutablePath);
                pp.FileName = Path.Combine(pp.WorkingDirectory, "Host.exe");
                pp.UseShellExecute = false;
                pp.RedirectStandardOutput = true;
                pp.RedirectStandardInput = true;
                pp.RedirectStandardError = true;
                pp.CreateNoWindow = true;
                pp.WindowStyle = ProcessWindowStyle.Hidden;
                StreamReader outputReader = null;
                using (Process pProcess = Process.Start(pp))
                {
                    if (pProcess != null)
                    {
                        //StreamWriter inputWriter = pProcess.StandardInput;
                        //StreamReader errorReader = pProcess.StandardError;
                        outputReader = pProcess.StandardOutput;
                    }
                    while ((pProcess != null) && (!pProcess.HasExited))
                    {
                        string ss = null;
                        if (outputReader != null)
                        {
                            ss = outputReader.ReadLine();
                        }
                        if ((ss != null) && (2 < ss.Length))
                        {
                            string[] s = ss.Split('|');
                            if (3 == s.Length)
                            {
                                float global;
                                //float.TryParse(s[0], out local);
                                float.TryParse(s[1], out global);
                                RadioTracer.SetCurrentMsg(s[2]);
                                RadioTracer.SetCurrentStep((int)global);
                            }
                        }
                        Application.DoEvents();
                        Thread.Sleep(updatefreq);
                    }
                }

私はたくさんグーグルで検索しましたが、解決策がありません。次のページにも同様の問題があり、提案された解決策を試しましたが、何も機能しません。

https://connect.microsoft.com/VisualStudio/feedback/details/609801/unable-to-redirect-only-the-standard-input-of-process-cmd-exe-or-batch-file-from-windows-フォームアプリケーション

http://go4answers.webhost4life.com/Example/redirectstandardinput-a-32-bit-114440.aspx

http://social.msdn.microsoft.com/Forums/en/csharpgeneral/thread/4f946750-6c47-406c-810c-21a2b103b5c4

どうもありがとう...これはすでに私に多くの時間を浪費します..私はここで解決策を得ることができると思います。

編集: ReadLine()またはReadToEnd()メソッドを使用しなくても、問題は依然として存在します。'UseShellExecute'をfalseに設定すると、Host.exeはすぐに終了します。Host.exeは大きな計算を実行することになっています(約2分かかり、コンソールのWriteLineを介して数秒ごとに進行状況を報告します)。

4

1 に答える 1

1

C#で出力をリダイレクトすると、次の行でエラーが発生することがわかりました。DelphiでConsole.pasユニットを使用しており、そのユニットの初期化でInitScreenModeプロシージャが呼び出されます。

  Reset(Input);
  Rewrite(Output);
  StdIn := TTextRec(Input).Handle;
  StdOut := TTextRec(Output).Handle;

C#で「UseShellExecute」をfalseに設定すると、コンソールの「リセット」または「書き換え」が問題を引き起こすと推測しています。

于 2012-12-06T15:02:29.667 に答える