Prozess In & Output umleiten

    • C#
    • .NET (FX) 3.0–3.5

      Prozess In & Output umleiten

      Guten Tag,
      ich habe kürzlich in einem anderem Forum Hilfestellung gegeben, um Befehle in den InputStream eines Prozesses zu schreiben. Rausgekommen ist die Klasse ProcessController, vieleicht kann ja jemand damit was anfangen.

      ProcessController

      C#-Quellcode

      1. class ProcessController : IDisposable
      2. {
      3. #region Events
      4. //***************
      5. public event EventHandler<ProcessControllerEventArgs.ProcessStart> OnProcessStart;
      6. protected virtual void EventProcessStart(Process p, DateTime startTime)
      7. {
      8. if (OnProcessStart != null)
      9. OnProcessStart(this, new ProcessControllerEventArgs.ProcessStart(p, startTime));
      10. }
      11. public event EventHandler<ProcessControllerEventArgs.ProcessStop> OnProcessStop;
      12. protected virtual void EventProcessStop(string processName, DateTime shutdownTime)
      13. {
      14. if (OnProcessStop != null)
      15. OnProcessStop(this, new ProcessControllerEventArgs.ProcessStop(processName, shutdownTime));
      16. }
      17. public event EventHandler<ProcessControllerEventArgs.ProcessOutputDataReceived> OnProcessOutputDataReceived;
      18. protected virtual void EventProcessOutputDataReceived(string data)
      19. {
      20. if (OnProcessOutputDataReceived != null)
      21. OnProcessOutputDataReceived(this, new ProcessControllerEventArgs.ProcessOutputDataReceived(data));
      22. }
      23. public event EventHandler<ProcessControllerEventArgs.ProcessErrorDataReceived> OnProcessErrorDataReceived;
      24. protected virtual void EventProcessErrorDataReceived(string data)
      25. {
      26. if (OnProcessErrorDataReceived != null)
      27. OnProcessErrorDataReceived(this, new ProcessControllerEventArgs.ProcessErrorDataReceived(data));
      28. }
      29. //=============
      30. #endregion Events
      31. #region Private Felder
      32. //***********************
      33. private Process process;
      34. private StreamWriter swCmdWriter;
      35. //==================
      36. #endregion Private Felder
      37. #region Konstruktoren
      38. //***********************
      39. /// <summary>
      40. /// ProcessController Konstruktor
      41. /// </summary>
      42. /// <param name="executableName">Name des Processes der gestartet werden soll</param>
      43. /// <param name="arguments">Startargumente die verwerndet werden sollen. Wenn keine Startargumente verwendet werden sollen, muss ein leerer string übergeben werden.</param>
      44. /// <param name="createNoWindow">Wenn False, wird keine Prozessfenster erstellt</param>
      45. public ProcessController(string executableName, string arguments, bool createNoWindow)
      46. {
      47. if (executableName == null || executableName == "")
      48. throw new ArgumentNullException("Executable name can´t be null");
      49. // Prozess Instanzieren
      50. process = new Process();
      51. process.StartInfo = CreateStartInfo(executableName, arguments, createNoWindow);
      52. process.OutputDataReceived += ProcessOutputDataReceived;
      53. process.ErrorDataReceived += ProcessErrorDataReceived;
      54. process.Start();
      55. // Event Feuern
      56. EventProcessStart(process, DateTime.Now);
      57. // Output des Prozesses Asynchron lesen
      58. process.BeginErrorReadLine();
      59. process.BeginOutputReadLine();
      60. // Standartinput des Prozess festlegen
      61. swCmdWriter = process.StandardInput;
      62. }
      63. //
      64. public ProcessController(string executableName, bool createNoWindow) : this(executableName, "", createNoWindow) { }
      65. //
      66. public ProcessController(string executableName, string arguments) : this(executableName, arguments, false) { }
      67. //
      68. public ProcessController(string executableName) : this(executableName, "") { }
      69. //==================
      70. #endregion Konstruktoren
      71. public void Dispose()
      72. {
      73. if (process != null) {
      74. process.OutputDataReceived -= ProcessOutputDataReceived;
      75. process.ErrorDataReceived -= ProcessErrorDataReceived;
      76. StopProcess();
      77. process.Dispose();
      78. process = null;
      79. }
      80. if (swCmdWriter != null)
      81. swCmdWriter.Dispose();
      82. GC.SuppressFinalize(this);
      83. }
      84. /// <summary>
      85. /// Stoppt den Prozess
      86. /// </summary>
      87. public void StopProcess()
      88. {
      89. if (process != null && IsProcessAlive) {
      90. process.Kill();
      91. // Event Feuern
      92. EventProcessStop(process.ProcessName, DateTime.Now);
      93. }
      94. }
      95. /// <summary>
      96. /// Schreibt den anbgegebenen Befehl in den Inputstream des Prozesses
      97. /// </summary>
      98. /// <param name="cmd">Befehl der in den Inputstream geschrieben werden soll</param>
      99. /// <returns>True wenn der befehl geschrieben wurde, andernfalls false</returns>
      100. public bool ExecuteCommand(string cmd)
      101. {
      102. if (process == null || !IsProcessAlive || cmd == "")
      103. return false;
      104. swCmdWriter.WriteLine(cmd);
      105. return true;
      106. }
      107. /// <summary>
      108. /// Erstellt ein ProcessStartInfo -Objekt
      109. /// </summary>
      110. /// <param name="executableName">Name des Processes der gestartet werden soll</param>
      111. /// <param name="arguments">Startargumente die verwerndet werden sollen.</param>
      112. /// <param name="createNoWindow">Wenn False, wird keine Prozessfenster erstellt</param>
      113. /// <returns>ProcessStartInfo</returns>
      114. private ProcessStartInfo CreateStartInfo(string executableName, string arguments, bool createNoWindow)
      115. {
      116. ProcessStartInfo procInfo = new ProcessStartInfo(executableName);
      117. procInfo.CreateNoWindow = createNoWindow;
      118. if (arguments != "")
      119. procInfo.Arguments = arguments;
      120. procInfo.UseShellExecute = false;
      121. procInfo.RedirectStandardInput = true;
      122. procInfo.RedirectStandardOutput = true;
      123. procInfo.RedirectStandardError = true;
      124. return procInfo;
      125. }
      126. /// <summary>
      127. /// Prüft ob eine Prozess Instanz aktiv ist
      128. /// </summary>
      129. private bool IsProcessAlive
      130. {
      131. get
      132. {
      133. if (process != null)
      134. return Process.GetProcessesByName(process.ProcessName).ToList().Find(x => x.Id == process.Id) != null;
      135. else
      136. return false;
      137. }
      138. }
      139. // Abonnierter Process -Events
      140. //********************************
      141. private void ProcessOutputDataReceived(object sender, DataReceivedEventArgs e)
      142. {
      143. EventProcessOutputDataReceived(e.Data);
      144. }
      145. private void ProcessErrorDataReceived(object sender, DataReceivedEventArgs e)
      146. {
      147. EventProcessErrorDataReceived(e.Data);
      148. }
      149. }


      C#-Quellcode

      1. class ProcessControllerEventArgs
      2. {
      3. public class ProcessStart : EventArgs
      4. {
      5. public Process CurrentProcess { get; private set; }
      6. public DateTime StartTime { get; private set; }
      7. public ProcessStart(Process p, DateTime startTime)
      8. {
      9. CurrentProcess = p;
      10. StartTime = startTime;
      11. }
      12. }
      13. public class ProcessStop : EventArgs
      14. {
      15. public string ProcessName { get; private set; }
      16. public DateTime ShutdownTime { get; private set; }
      17. public ProcessStop(string processName, DateTime shutdownTime)
      18. {
      19. ProcessName = processName;
      20. ShutdownTime = shutdownTime;
      21. }
      22. }
      23. public class ProcessOutputDataReceived : EventArgs
      24. {
      25. public string Data { get; private set; }
      26. public ProcessOutputDataReceived(string data)
      27. {
      28. Data = data;
      29. }
      30. }
      31. public class ProcessErrorDataReceived : EventArgs
      32. {
      33. public string Data { get; private set; }
      34. public ProcessErrorDataReceived(string data)
      35. {
      36. Data = data;
      37. }
      38. }
      39. }



      AnwendungsBeispiel

      C#-Quellcode

      1. ProcessController pc;
      2. #region GUI
      3. //************
      4. private void button_startProcess_Click(object sender, EventArgs e)
      5. {
      6. if (textBox_process.Text == "")
      7. return;
      8. if (pc != null) {
      9. pc.Dispose();
      10. pc = null;
      11. }
      12. pc = new ProcessController(textBox_process.Text, true);
      13. pc.OnProcessStart += pc_OnProcessStart;
      14. pc.OnProcessStop+=pc_OnProcessStop;
      15. pc.OnProcessOutputDataReceived +=pc_OnProcessOutputDataReceived;
      16. pc.OnProcessErrorDataReceived+=pc_OnProcessErrorDataReceived;
      17. }
      18. private void button_stopProcess_Click(object sender, EventArgs e)
      19. {
      20. pc.StopProcess();
      21. pc.Dispose();
      22. pc = null;
      23. }
      24. private void button_prozessCmd_Click(object sender, EventArgs e)
      25. {
      26. if (pc == null || textBox_cmd.Text == "")
      27. return;
      28. pc.ExecuteCommand(textBox_cmd.Text);
      29. }
      30. //==========
      31. #endregion GUI
      32. #region Abonnierte Events
      33. //***************************
      34. private void pc_OnProcessStart(object sender, ProcessControllerEventArgs.ProcessStart e)
      35. {
      36. WriteProcessMessage(string.Format("[{0}] Prozess {1} wurde gestartet...",e.StartTime.ToShortTimeString(), e.CurrentProcess.ProcessName));
      37. }
      38. private void pc_OnProcessStop(object sender, ProcessControllerEventArgs.ProcessStop e)
      39. {
      40. WriteProcessMessage(string.Format("[{0}] Prozess {1} wurde beendet...",e.ShutdownTime.ToShortTimeString(), e.ProcessName));
      41. }
      42. private void pc_OnProcessOutputDataReceived(object sender, ProcessControllerEventArgs.ProcessOutputDataReceived e)
      43. {
      44. WriteProcessMessage(e.Data);
      45. }
      46. private void pc_OnProcessErrorDataReceived(object sender, ProcessControllerEventArgs.ProcessErrorDataReceived e)
      47. {
      48. WriteProcessMessage(e.Data);
      49. }
      50. //=====================
      51. #endregion Abonnierte Events
      52. private void WriteProcessMessage(string msg)
      53. {
      54. if (textBox_output.InvokeRequired)
      55. textBox_output.Invoke(new MethodInvoker(delegate()
      56. {
      57. textBox_output.Text += msg + Environment.NewLine;
      58. }));
      59. else
      60. textBox_output.Text += msg + Environment.NewLine;
      61. }