From e34ebefcb68f9e45f853f6eb9a4f8d0019a38aca Mon Sep 17 00:00:00 2001 From: "gu.martinm@gmail.com" Date: Mon, 9 Jun 2014 01:24:37 +0200 Subject: [PATCH] Process launcher example. --- Allgemeines/ProcessLauncher/ProcessLauncher.sln | 20 ++++ .../ProcessLauncher/LinuxWindowsProcess.cs | 109 +++++++++++++++++++++ .../ProcessLauncher/ProcessLauncher.csproj | 47 +++++++++ .../ProcessLauncher/ProcessLauncher/Program.cs | 19 ++++ .../ProcessLauncher/Properties/AssemblyInfo.cs | 22 +++++ 5 files changed, 217 insertions(+) create mode 100644 Allgemeines/ProcessLauncher/ProcessLauncher.sln create mode 100644 Allgemeines/ProcessLauncher/ProcessLauncher/LinuxWindowsProcess.cs create mode 100644 Allgemeines/ProcessLauncher/ProcessLauncher/ProcessLauncher.csproj create mode 100644 Allgemeines/ProcessLauncher/ProcessLauncher/Program.cs create mode 100644 Allgemeines/ProcessLauncher/ProcessLauncher/Properties/AssemblyInfo.cs diff --git a/Allgemeines/ProcessLauncher/ProcessLauncher.sln b/Allgemeines/ProcessLauncher/ProcessLauncher.sln new file mode 100644 index 0000000..d6dc8a6 --- /dev/null +++ b/Allgemeines/ProcessLauncher/ProcessLauncher.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2012 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProcessLauncher", "ProcessLauncher\ProcessLauncher.csproj", "{8C9CE3D4-590C-49DA-A165-9B82625E4A3E}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x86 = Debug|x86 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {8C9CE3D4-590C-49DA-A165-9B82625E4A3E}.Debug|x86.ActiveCfg = Debug|x86 + {8C9CE3D4-590C-49DA-A165-9B82625E4A3E}.Debug|x86.Build.0 = Debug|x86 + {8C9CE3D4-590C-49DA-A165-9B82625E4A3E}.Release|x86.ActiveCfg = Release|x86 + {8C9CE3D4-590C-49DA-A165-9B82625E4A3E}.Release|x86.Build.0 = Release|x86 + EndGlobalSection + GlobalSection(MonoDevelopProperties) = preSolution + StartupItem = ProcessLauncher\ProcessLauncher.csproj + EndGlobalSection +EndGlobal diff --git a/Allgemeines/ProcessLauncher/ProcessLauncher/LinuxWindowsProcess.cs b/Allgemeines/ProcessLauncher/ProcessLauncher/LinuxWindowsProcess.cs new file mode 100644 index 0000000..947443f --- /dev/null +++ b/Allgemeines/ProcessLauncher/ProcessLauncher/LinuxWindowsProcess.cs @@ -0,0 +1,109 @@ +using System; +using System.Diagnostics; +using System.IO; +using System.Text; + +namespace ProcessLauncher +{ + public class LinuxWindowsProcess + { + public StringBuilder Test(string command, string arguments) + { + ProcessStartInfo startInfo = new ProcessStartInfo(); + + // What is going to do Mono with this value? + startInfo.CreateNoWindow = true; + + // Set UseShellExecute to false for redirection. + // To use StandardOutput, you must set ProcessStartInfo.UseShellExecute to false, and you must set + // ProcessStartInfo.RedirectStandardOutput to true. Otherwise, reading from the StandardOutput stream throws an exception. + // What is going to do Mono with stdout, stdin and stderr depending on this value? + startInfo.UseShellExecute = false; + + // Redirect the standard output of the subprocess command. + // What is going to do Mono with stdout? Some pipe, I guess. + startInfo.RedirectStandardOutput = true; + + // What is going to do Mono with stdin? + startInfo.RedirectStandardInput = false; + + // What is going to do Mono with stderr? + startInfo.RedirectStandardError = false; + + // What is going to do Mono with this value? What if I am running a GTK (GUI application) + startInfo.WindowStyle = ProcessWindowStyle.Minimized; + + startInfo.Arguments = arguments; + startInfo.FileName = command; + + + + + // Define variables shared by class methods. + StringBuilder processOutput = null; + Process process = new Process(); + + process.StartInfo = startInfo; + + // When is Mono going to call my event implementation? Every time the subprocess writes to stdout? + // From here: http://msdn.microsoft.com/en-us/library/vstudio/system.diagnostics.process.outputdatareceived%28v=vs.110%29.aspx + // Thereafter, the OutputDataReceived event signals each time the process writes a line to the + // redirected StandardOutput stream, until the process exits or calls CancelOutputRead. + // That behaviour is weird (IMHO) Check out the Mono implementation!!! + // Set our event handler to asynchronously read the standard output. + process.OutputDataReceived += new DataReceivedEventHandler( + delegate(object sendingProcess, DataReceivedEventArgs outLine) + { + // Collect the command output. + // To asynchronously collect the redirected StandardOutput or StandardError stream output of a process, you must create + // a method that handles the redirected stream output events. The event-handler method is called when the process writes + // to the redirected stream. The event delegate calls your event handler with an instance of DataReceivedEventArgs. + // The Data property contains the text line that the process wrote to the redirected stream. + if (!String.IsNullOrEmpty(outLine.Data)) + { + // Add the text to the collected output. + processOutput.Append(Environment.NewLine + outLine.Data); + } + }); + // Taken from http://stackoverflow.com/questions/285760/how-to-spawn-a-process-and-capture-its-stdout-in-net + // I do not think this is the right way to read the output stream!!!! + // My event handler will be called (see documentation) every time the process writes a line to the output stream but + // with this code I will be reading the output stream until it is closed by the process. So, I guess, we could end + // up having multiple event handlers reading from the same stream (output stream) Each handler was called each time + // the process wrote a line to the output stream. :/ + // process.OutputDataReceived += new DataReceivedEventHandler( + // delegate(object sender, DataReceivedEventArgs e) + // { + // using (StreamReader output = process.StandardOutput) + // { + // string data = output.ReadToEnd(); + // processOutput.Append(data); + // } + // }); + // Don't mix using statements and lambda expressions :( + // http://blogs.msdn.com/b/jaredpar/archive/2008/07/16/don-t-mix-using-statements-and-lambda-expressions.aspx + // process.OutputDataReceived += (sender, e) => + // { + // using (StreamReader output = process.StandardOutput) + // { + // string data = output.ReadToEnd(); + // processOutput.Append(data); + // } + // }; + + // Start the process. + process.Start(); + + // Start the asynchronous read of the output stream. + process.BeginOutputReadLine(); + + // Wait for the process. + process.WaitForExit(); + + process.Close(); + + return processOutput; + } + } +} + diff --git a/Allgemeines/ProcessLauncher/ProcessLauncher/ProcessLauncher.csproj b/Allgemeines/ProcessLauncher/ProcessLauncher/ProcessLauncher.csproj new file mode 100644 index 0000000..bf80cb6 --- /dev/null +++ b/Allgemeines/ProcessLauncher/ProcessLauncher/ProcessLauncher.csproj @@ -0,0 +1,47 @@ + + + + Debug + x86 + 12.0.0 + 2.0 + {8C9CE3D4-590C-49DA-A165-9B82625E4A3E} + Exe + ProcessLauncher + ProcessLauncher + Launching processes from C# + v4.5 + + + true + full + false + bin\Debug + DEBUG; + prompt + 4 + true + x86 + + + full + true + bin\Release + prompt + 4 + true + x86 + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Allgemeines/ProcessLauncher/ProcessLauncher/Program.cs b/Allgemeines/ProcessLauncher/ProcessLauncher/Program.cs new file mode 100644 index 0000000..2d96dea --- /dev/null +++ b/Allgemeines/ProcessLauncher/ProcessLauncher/Program.cs @@ -0,0 +1,19 @@ +using System; + +namespace ProcessLauncher +{ + class MainClass + { + public static void Main(string[] args) + { + LinuxWindowsProcess process = new LinuxWindowsProcess(); + Console.WriteLine("Linux"); + var output = process.Test("ls", "-lah"); + Console.WriteLine("stdout: {0}", output.ToString()); + + // Console.WriteLine("Windows"); + // output = process.Test("dir", "/a"); + // Console.WriteLine("stdout: {0}", output.ToString()); + } + } +} diff --git a/Allgemeines/ProcessLauncher/ProcessLauncher/Properties/AssemblyInfo.cs b/Allgemeines/ProcessLauncher/ProcessLauncher/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..a4bd30d --- /dev/null +++ b/Allgemeines/ProcessLauncher/ProcessLauncher/Properties/AssemblyInfo.cs @@ -0,0 +1,22 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +// Information about this assembly is defined by the following attributes. +// Change them to the values specific to your project. +[assembly: AssemblyTitle("ProcessLauncher")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("gumartinm.name")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("gumartinm.name")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] +// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". +// The form "{Major}.{Minor}.*" will automatically update the build and revision, +// and "{Major}.{Minor}.{Build}.*" will update just the revision. +[assembly: AssemblyVersion("1.0.*")] +// The following attributes are used to specify the signing key for the assembly, +// if desired. See the Mono documentation for more information about signing. +//[assembly: AssemblyDelaySign(false)] +//[assembly: AssemblyKeyFile("")] + -- 2.1.4