public IProcess Run(ProcessRunSpec runSpec) { Guid processKey = Guid.NewGuid(); var defaultEnvironmentBlock = EnvironmentBlock.CreateSystemDefault(); var environment = defaultEnvironmentBlock.Merge(runSpec.Environment).ToDictionary(); CreateProcessParams @params = new CreateProcessParams { key = processKey, executablePath = runSpec.ExecutablePath, arguments = runSpec.Arguments, environment = environment, workingDirectory = runSpec.WorkingDirectory }; var processDataCallback = BuildProcessDataCallback(runSpec.OutputCallback, runSpec.ErrorCallback); hostClient.SubscribeToProcessData(processKey, processDataCallback); var result = hostClient.CreateProcess(@params); var process = new ConstrainedProcess(hostClient, processKey, result.id, environment); return process; }
public Task<CreateProcessResult> ExecuteAsync(CreateProcessParams p) { var runSpec = new ProcessRunSpec { ExecutablePath = p.executablePath, Arguments = p.arguments, Environment = p.environment, WorkingDirectory = p.workingDirectory, OutputCallback = (data) => { processTracker.HandleProcessData(p.key, ProcessDataType.STDOUT, data); }, ErrorCallback = (data) => { processTracker.HandleProcessData(p.key, ProcessDataType.STDERR, data); }, }; var process = processRunner.Run(runSpec); processTracker.TrackProcess(p.key, process); var result = new CreateProcessResult { id = process.Id, }; return Task.FromResult(result); }
public IContainerHostClient StartContainerHost(string containerId, IContainerDirectory directory, JobObject jobObject, NetworkCredential credentials) { CopyHostToContainer(directory); var hostRunSpec = new ProcessRunSpec { ExecutablePath = directory.MapBinPath(dependencyHelper.ContainerHostExe), Arguments = new[] { containerId }, BufferedInputOutput = true, WorkingDirectory = directory.UserPath, Credentials = credentials, }; // Order here is important. // - Start the process // - Add the process to the job object // - Verify that the process is healthy // - Start the RPC message pump // // We need to ensure that the host process cannot create any new processes before // it's added to the job object. var hostProcess = processRunner.Run(hostRunSpec); jobObject.AssignProcessToJob(hostProcess.Handle); WaitForProcessToStart(hostProcess, HostProcessStartTimeout); var messageTransport = MessageTransport.Create(hostProcess.StandardOutput, hostProcess.StandardInput); var messagingClient = MessagingClient.Create(async message => { await messageTransport.PublishRequestAsync(message); }); messageTransport.SubscribeResponse(message => { messagingClient.PublishResponse(message); return Task.FromResult(0); }); messageTransport.SubscribeEvent(@event => { try { messagingClient.PublishEvent(@event); } catch (Exception e) { log.Log(LogLevel.Error, e.ToString(), e); } return Task.FromResult(0); }); var containerHostClient = new ContainerHostClient(hostProcess, messageTransport, messagingClient, jobObject); messageTransport.Start(); return containerHostClient; }
public IProcess Run(ProcessRunSpec runSpec) { var process = new ImpersonationProcess(runSpec); if (runSpec.ExitHandler != null) { process.Exited += runSpec.ExitHandler; } process.Start(); return(process); }
public void TestExited() { var exited = false; var runner = new ImpersonationProcessRunner(); var spec = new ProcessRunSpec() { ExecutablePath = "whoami", BufferedInputOutput = true, Credentials = creds, ExitHandler = (sender, args) => exited = true }; var process = runner.Run(spec); process.WaitForExit(); Assert.True(exited); }
private bool RunNetsh(string arguments) { log.Info("Running netsh.exe for {0}", arguments); bool success; using (ProcessRunner runner = new ProcessRunner()) { var spec = new ProcessRunSpec { ExecutablePath = "netsh.exe", Arguments = arguments.Split(' '), WorkingDirectory = workingDirectory }; var process = runner.Run(spec); process.WaitForExit(); success = process.ExitCode == 0; } return success; }
private bool RunNetsh(string arguments) { log.Info("Running netsh.exe for {0}", arguments); bool success; using (ProcessRunner runner = new ProcessRunner()) { var spec = new ProcessRunSpec { ExecutablePath = "netsh.exe", Arguments = arguments.Split(' '), WorkingDirectory = workingDirectory }; var process = runner.Run(spec); process.WaitForExit(); success = process.ExitCode == 0; } return(success); }
public void TestHandle() { var runner = new ImpersonationProcessRunner(); var spec = new ProcessRunSpec() { ExecutablePath = "powershell", Arguments = new[] { "-Command", "$x = [Console]::In.ReadLine()" }, BufferedInputOutput = true, Credentials = creds }; var proc = runner.Run(spec); Assert.NotNull(proc.Handle); var pid = GetProcessId(proc.Handle); var realProc = Process.GetProcessById(pid); try { Assert.NotNull(realProc); Assert.Equal("powershell", realProc.ProcessName); } finally { realProc.Kill(); } }
public void TestStderr() { var runner = new ImpersonationProcessRunner(); var spec = new ProcessRunSpec() { ExecutablePath = "powershell", Arguments = new[] { "-Command", "[Console]::Error.WriteLine('hi')" }, BufferedInputOutput = true, Credentials = creds }; var proc = runner.Run(spec); Assert.Equal("hi", proc.StandardError.ReadToEnd().Trim()); }
public void TestStdout() { var runner = new ImpersonationProcessRunner(); var spec = new ProcessRunSpec() { ExecutablePath = "whoami", BufferedInputOutput = true, Credentials = creds }; var proc = runner.Run(spec); Assert.Matches(new Regex(username), proc.StandardOutput.ReadToEnd()); }
public ImpersonationProcess(ProcessRunSpec runSpec) { this.runSpec = runSpec; }
public void SendsCreateProcessMessage() { var spec = new ProcessRunSpec { ExecutablePath = "exe", Arguments = new[] { "arg1", "arg2" }, WorkingDirectory = @"\WorkdirDir", Environment = new Dictionary<string, string> { { "env1", "val1" } }, }; Runner.Run(spec); Client.Received(1).CreateProcess( Arg.Is<CreateProcessParams>(actual => actual.executablePath == spec.ExecutablePath && actual.arguments == spec.Arguments && actual.environment.ContainsKey("env1") && actual.workingDirectory == spec.WorkingDirectory && actual.key != Guid.Empty ) ); }
public IContainerProcess Run(ProcessSpec spec, IProcessIO io) { lock (_ioLock) { ThrowIfNotActive(); var runner = spec.Privileged ? processRunner : constrainedProcessRunner; var executablePath = !spec.DisablePathMapping ? directory.MapUserPath(spec.ExecutablePath) : spec.ExecutablePath; var specEnvironment = spec.Environment ?? new Dictionary<string, string>(); var processEnvironment = this.defaultEnvironment.Merge(specEnvironment); Action<string> stdOut = io == null || io.StandardOutput == null ? (Action<string>) null : data => io.StandardOutput.Write(data); Action<string> stdErr = io == null || io.StandardError == null ? (Action<string>) null : data => io.StandardError.Write(data); var runSpec = new ProcessRunSpec { ExecutablePath = executablePath, Arguments = spec.Arguments, Environment = processEnvironment, WorkingDirectory = directory.MapUserPath(spec.WorkingDirectory ?? DefaultWorkingDirectory), OutputCallback = stdOut, ErrorCallback = stdErr, }; var process = runner.Run(runSpec); return new ContainerProcess(process); } }
public IProcess Run(ProcessRunSpec runSpec) { var startInfo = new ProcessStartInfo { FileName = runSpec.ExecutablePath, Arguments = ArgumentEscaper.Escape(runSpec.Arguments ?? EmptyArguments), WorkingDirectory = runSpec.WorkingDirectory, UseShellExecute = false, LoadUserProfile = false, RedirectStandardError = true, RedirectStandardInput = true, RedirectStandardOutput = true, }; if (runSpec.Credentials != null) { startInfo.UserName = runSpec.Credentials.UserName; startInfo.Password = runSpec.Credentials.SecurePassword; } bool runSpecSpecifiesEnvironment = runSpec.Environment != null && runSpec.Environment.Count > 0; var environment = runSpecSpecifiesEnvironment ? runSpec.Environment : CreateDefaultProcessEnvironment(runSpec.Credentials); startInfo.EnvironmentVariables.Clear(); foreach (var variable in environment) { startInfo.EnvironmentVariables[variable.Key] = variable.Value; } Process p = new Process { StartInfo = startInfo, }; if (runSpec.ExitHandler != null) { p.Exited += runSpec.ExitHandler; } p.EnableRaisingEvents = true; var wrapped = ProcessHelper.WrapProcess(p); if (!runSpec.BufferedInputOutput) { if (runSpec.OutputCallback != null) { p.OutputDataReceived += (sender, e) => { runSpec.OutputCallback(e.Data); }; } if (runSpec.ErrorCallback != null) { p.ErrorDataReceived += (sender, e) => { runSpec.ErrorCallback(e.Data); }; } } log.Trace("Starting Process - FileName: {0} Arguments: {1} WorkingDirectory: {2}", p.StartInfo.FileName, p.StartInfo.Arguments, p.StartInfo.WorkingDirectory); bool started = p.Start(); Debug.Assert(started); // TODO: Should we throw an exception here? Fail fast? if (!runSpec.BufferedInputOutput) { p.BeginOutputReadLine(); p.BeginErrorReadLine(); } return(wrapped); }
public Run() { Spec = new ProcessSpec { ExecutablePath = "/.iishost/iishost.exe", Arguments = new[] { "-p", "3000", "-r", @"/www" }, }; var containerUserPath = @"C:\Containers\handle\user\"; ExpectedRunSpec = new ProcessRunSpec { ExecutablePath = @"C:\Containers\handle\user\.iishost\iishost.exe", Arguments = Spec.Arguments, WorkingDirectory = containerUserPath, }; Directory.MapUserPath("/.iishost/iishost.exe").Returns(ExpectedRunSpec.ExecutablePath); Directory.MapUserPath("/").Returns(containerUserPath); }
public void SetsDefaultEnvironmentBlock() { var spec = new ProcessRunSpec { ExecutablePath = "exe", Arguments = new[] { "arg1", "arg2" }, WorkingDirectory = @"\WorkdirDir", Environment = new Dictionary<string, string>(), }; Runner.Run(spec); Client.Received(1).CreateProcess( Arg.Is<CreateProcessParams>(actual => actual.environment.ContainsKey("TEMP") && actual.environment.ContainsKey("PATH") ) ); }
public IProcess Run(ProcessRunSpec runSpec) { var startInfo = new ProcessStartInfo { FileName = runSpec.ExecutablePath, Arguments = ArgumentEscaper.Escape(runSpec.Arguments ?? EmptyArguments), WorkingDirectory = runSpec.WorkingDirectory, UseShellExecute = false, LoadUserProfile = false, RedirectStandardError = true, RedirectStandardInput = true, RedirectStandardOutput = true, }; if (runSpec.Credentials != null) { startInfo.UserName = runSpec.Credentials.UserName; startInfo.Password = runSpec.Credentials.SecurePassword; } bool runSpecSpecifiesEnvironment = runSpec.Environment != null && runSpec.Environment.Count > 0; var environment = runSpecSpecifiesEnvironment ? runSpec.Environment : CreateDefaultProcessEnvironment(runSpec.Credentials); startInfo.EnvironmentVariables.Clear(); foreach (var variable in environment) { startInfo.EnvironmentVariables[variable.Key] = variable.Value; } Process p = new Process { StartInfo = startInfo, }; if (runSpec.ExitHandler != null) p.Exited += runSpec.ExitHandler; p.EnableRaisingEvents = true; var wrapped = ProcessHelper.WrapProcess(p); if (!runSpec.BufferedInputOutput) { if (runSpec.OutputCallback != null) { p.OutputDataReceived += (sender, e) => { runSpec.OutputCallback(e.Data); }; } if (runSpec.ErrorCallback != null) { p.ErrorDataReceived += (sender, e) => { runSpec.ErrorCallback(e.Data); }; } } log.Trace("Starting Process - FileName: {0} Arguments: {1} WorkingDirectory: {2}", p.StartInfo.FileName, p.StartInfo.Arguments, p.StartInfo.WorkingDirectory); bool started = p.Start(); Debug.Assert(started); // TODO: Should we throw an exception here? Fail fast? if (!runSpec.BufferedInputOutput) { p.BeginOutputReadLine(); p.BeginErrorReadLine(); } return wrapped; }
public void ReturnsProcessWithEnvironment() { int expectedId = 123; Client.CreateProcess(Arg.Any<CreateProcessParams>()).Returns( new CreateProcessResult() { id = expectedId } ); var spec = new ProcessRunSpec { Environment = new Dictionary<string, string> { { "FOO", "BAR" } } }; var process = Runner.Run(spec); Assert.NotNull(process.Environment); Assert.True(process.Environment.Count > 0); Assert.Equal("BAR", process.Environment["FOO"]); }
public ImpersonationProcess(ProcessRunSpec runSpec) { this.runSpec = runSpec; this.Handle = IntPtr.Zero; }
public IProcess Run(ProcessRunSpec runSpec) { var process = new ImpersonationProcess(runSpec); if (runSpec.ExitHandler != null) process.Exited += runSpec.ExitHandler; process.Start(); return process; }