public static int Run() { var stream = TryConnect(TimeSpan.FromSeconds(1)); if (stream == null) { Elevate(); stream = TryConnect(TimeSpan.FromSeconds(30)); if (stream == null) { Console.WriteLine("[[ Unable to contact sudo server! ]]"); return -7; } } using (stream) { var writer = new StreamWriter(stream); var reader = new StreamReader(stream); var programName = Environment.GetCommandLineArgs()[0]; var commandLine = Environment.CommandLine; var index = commandLine.IndexOf(programName) + programName.Length; if (commandLine[index] == '"') { index++; } // Slight chance commandLine = commandLine.Substring(index); var request = new ExecuteRequest() { ClientPid = Process.GetCurrentProcess().Id, CommandLine = commandLine, WorkingDirectory = Environment.CurrentDirectory }; foreach(DictionaryEntry kvp in Environment.GetEnvironmentVariables()) { request.Environment.Add((string)kvp.Key, (string)kvp.Value); } request.Write(writer); writer.Flush(); stream.Flush(); var response = Int32.Parse(reader.ReadLine()); var message = reader.ReadLine(); if (message != "OK") { Console.WriteLine("Internal Error: {0}", message); } return response; } }
public static ExecuteRequest Read( TextReader reader ) { StringWriter writer = new StringWriter(); writer.WriteLine( "Reading request..." ); var request = new ExecuteRequest(); var pidString = reader.ReadLine(); if ( pidString == null ) { return null; } int pid; if ( !Int32.TryParse( pidString, out pid ) ) { return null; } request.ClientPid = pid; writer.WriteLine( "PID: {0}", request.ClientPid ); request.WorkingDirectory = reader.ReadLine(); if ( request.WorkingDirectory == null ) { return null; } writer.WriteLine( "Working Directory: {0}", request.WorkingDirectory ); var environmentVariable = reader.ReadLine(); while ( environmentVariable != String.Empty ) { if ( environmentVariable == null ) { return null; } var environmentValue = reader.ReadLine(); if ( environmentValue == null ) { return null; } writer.WriteLine( "Set: {0} = {1}", environmentVariable, environmentValue ); request.Environment.Add( environmentVariable, environmentValue ); environmentVariable = reader.ReadLine(); } request.CommandLine = reader.ReadLine(); if ( request.CommandLine == null ) { return null; } writer.WriteLine( "Command Line: {0}", request.CommandLine ); writer.Flush(); Tracer.WriteLine( writer.ToString() ); return request; }
static int Execute( ExecuteRequest request ) { try { // Spawn off the child process. // Note that the command line here is magic. It *is* possible to screw it up. Please don't. // var startInfo = new ProcessStartInfo() { FileName = String.Format( "\"{0}\"", Assembly.GetEntryAssembly().Location ), Arguments = String.Format( "-Exec {0} {1} {2}", request.ClientPid, Executor.MagicDelimiter, request.CommandLine ), WorkingDirectory = request.WorkingDirectory, UseShellExecute = false, CreateNoWindow = true }; startInfo.EnvironmentVariables.Clear(); foreach ( var kvp in request.Environment ) { startInfo.EnvironmentVariables.Add( kvp.Key, kvp.Value ); } Tracer.WriteLine( "SI FileName: {0} \nArgs: {1}\nWorking: {2}", startInfo.FileName, startInfo.Arguments, startInfo.WorkingDirectory ); var process = Process.Start( startInfo ); process.WaitForExit(); Tracer.WriteLine( "Done: {0}\n\n\n", process.ExitCode ); return process.ExitCode; } finally { // // NOTE: There is a discontinuity here. Because we cannot rely on the finalizer we clear the "active // server" count once this method completes. In order to make the counts sane, this object can be // used only once. // lock ( ServerLock ) { ActiveServers--; if ( ActiveServers == 0 ) { NoActiveServers.Set(); } } } }