/// <summary> /// Runs the specified executable and returns a boolean indicating success or failure /// </summary> /// <remarks>The standard and error output will be streamed to the logger. Child processes do not inherit the env variables from the parent automatically</remarks> public bool Execute(ProcessScannerArguments runnerArgs) { if (runnerArgs == null) { throw new ArgumentNullException("runnerArgs"); } Debug.Assert(!string.IsNullOrWhiteSpace(runnerArgs.ExeName), "Process runner exe name should not be null/empty"); Debug.Assert(runnerArgs.Logger != null, "Process runner logger should not be null/empty"); this.outputLogger = runnerArgs.Logger; if (!File.Exists(runnerArgs.ExeName)) { this.outputLogger.LogError(Resources.ERROR_ProcessRunner_ExeNotFound, runnerArgs.ExeName); this.ExitCode = ErrorCode; return(false); } ProcessStartInfo psi = new ProcessStartInfo() { FileName = runnerArgs.ExeName, RedirectStandardError = true, RedirectStandardOutput = true, UseShellExecute = false, // required if we want to capture the error output ErrorDialog = false, CreateNoWindow = true, Arguments = runnerArgs.GetEscapedArguments(), WorkingDirectory = runnerArgs.WorkingDirectory }; SetEnvironmentVariables(psi, runnerArgs.EnvironmentVariables, runnerArgs.Logger); bool succeeded; using (var process = new Process()) { process.StartInfo = psi; process.ErrorDataReceived += OnErrorDataReceived; process.OutputDataReceived += OnOutputDataReceived; process.Start(); process.BeginErrorReadLine(); process.BeginOutputReadLine(); // Warning: do not log the raw command line args as they // may contain sensitive data this.outputLogger.LogDebug(Resources.MSG_ExecutingFile, runnerArgs.ExeName, runnerArgs.AsLogText(), runnerArgs.WorkingDirectory, runnerArgs.TimeoutInMilliseconds, process.Id); succeeded = process.WaitForExit(runnerArgs.TimeoutInMilliseconds); if (succeeded) { process.WaitForExit(); // Give any asynchronous events the chance to complete } // false means we asked the process to stop but it didn't. // true: we might still have timed out, but the process ended when we asked it to if (succeeded) { this.outputLogger.LogDebug(Resources.MSG_ExecutionExitCode, process.ExitCode); this.ExitCode = process.ExitCode; } else { this.ExitCode = ErrorCode; try { process.Kill(); this.outputLogger.LogWarning(Resources.WARN_ExecutionTimedOutKilled, runnerArgs.TimeoutInMilliseconds, runnerArgs.ExeName); } catch { this.outputLogger.LogWarning(Resources.WARN_ExecutionTimedOutNotKilled, runnerArgs.TimeoutInMilliseconds, runnerArgs.ExeName); } } succeeded = succeeded && (this.ExitCode == 0); } return(succeeded); }
/// <summary> /// Returns whether the property contains any sensitive data /// </summary> public bool ContainsSensitiveData() { return(ProcessScannerArguments.ContainsSensitiveData(this.Id) || ProcessScannerArguments.ContainsSensitiveData(this.Value)); }