Beispiel #1
0
        /// <summary>
        /// Executes the <paramref name="executable"/> and waits a maximum time of <paramref name="maxWaitMs"/> for completion. If the process doesn't end in
        /// this time, it gets aborted. This method tries to impersonate the interactive user and run the process under its identity.
        /// </summary>
        /// <param name="executable">Program to execute</param>
        /// <param name="arguments">Program arguments</param>
        /// <param name="token">User token to run process</param>
        /// <param name="redirectInputOutput"><c>true</c> to redirect standard streams.</param>
        /// <param name="result">Returns the contents of standard output.</param>
        /// <param name="priorityClass">Process priority</param>
        /// <param name="maxWaitMs">Maximum time to wait for completion</param>
        /// <returns><c>true</c> if process was executed and finished correctly</returns>
        private static bool TryExecute_Impersonated(string executable, string arguments, IntPtr token, bool redirectInputOutput, out string result, ProcessPriorityClass priorityClass = ProcessPriorityClass.Normal, int maxWaitMs = INFINITE)
        {
            // Note: Althought the code is nearly identical as TryExecute, it cannot be easily refactored, as the ImpersonationProcess implements many methods and properties with "new".
            // If such an instance is assigned to "Process" base class, any access will fail here.
            StringBuilder outputBuilder = new StringBuilder();

            using (ImpersonationProcess process = new ImpersonationProcess())
                using (AutoResetEvent outputWaitHandle = new AutoResetEvent(!redirectInputOutput))
                {
                    PrepareProcess(executable, arguments, redirectInputOutput, process, outputWaitHandle, outputBuilder);
                    process.StartAsUser(token);
                    if (!process.HasExited)
                    {
                        process.PriorityClass = priorityClass;
                    }

                    if (redirectInputOutput)
                    {
                        process.BeginOutputReadLine();
                    }

                    if (process.WaitForExit(maxWaitMs) && outputWaitHandle.WaitOne(maxWaitMs))
                    {
                        if (redirectInputOutput)
                        {
                            process.CancelOutputRead();
                        }
                        result = RemoveEncodingPreamble(outputBuilder.ToString());
                        return(process.ExitCode == 0);
                    }
                    if (!process.HasExited)
                    {
                        if (redirectInputOutput)
                        {
                            process.CancelOutputRead();
                        }
                        process.Kill();
                    }
                }
            result = null;
            return(false);
        }
Beispiel #2
0
    /// <summary>
    /// Executes the <paramref name="executable"/> and waits a maximum time of <paramref name="maxWaitMs"/> for completion. If the process doesn't end in 
    /// this time, it gets aborted. This method tries to impersonate the interactive user and run the process under its identity.
    /// </summary>
    /// <param name="executable">Program to execute</param>
    /// <param name="arguments">Program arguments</param>
    /// <param name="token">User token to run process</param>
    /// <param name="redirectInputOutput"><c>true</c> to redirect standard streams.</param>
    /// <param name="result">Returns the contents of standard output.</param>
    /// <param name="priorityClass">Process priority</param>
    /// <param name="maxWaitMs">Maximum time to wait for completion</param>
    /// <returns><c>true</c> if process was executed and finished correctly</returns>
    private static bool TryExecute_Impersonated(string executable, string arguments, IntPtr token, bool redirectInputOutput, out string result, ProcessPriorityClass priorityClass = ProcessPriorityClass.Normal, int maxWaitMs = INFINITE)
    {
      // TODO: code is 99% redundant to TryExecute, refactor Process/ImpersonationProcess and Start/StartAsUser!
      StringBuilder outputBuilder = new StringBuilder();
      using (ImpersonationProcess process = new ImpersonationProcess { StartInfo = new ProcessStartInfo(executable, arguments) { UseShellExecute = false, CreateNoWindow = true, RedirectStandardOutput = redirectInputOutput } })
      {
        if (redirectInputOutput)
        {
          // Set UTF-8 encoding for standard output.
          process.StartInfo.StandardOutputEncoding = CONSOLE_ENCODING;
          // Enable raising events because Process does not raise events by default.
          process.EnableRaisingEvents = true;
          // Attach the event handler for OutputDataReceived before starting the process.
          process.OutputDataReceived += (sender, e) => outputBuilder.Append(e.Data);
        }
        process.StartAsUser(token);
        process.PriorityClass = priorityClass;

        if (redirectInputOutput)
          process.BeginOutputReadLine();

        if (process.WaitForExit(maxWaitMs))
        {
          result = RemoveEncodingPreamble(outputBuilder.ToString());
          return process.ExitCode == 0;
        }
        if (!process.HasExited)
          process.Kill();
      }
      result = null;
      return false;
    }
Beispiel #3
0
    private static bool TryExecute_Impersonated(string executable, string arguments, IntPtr token, bool redirectInputOutput, out string result, ProcessPriorityClass priorityClass = ProcessPriorityClass.Normal, int maxWaitMs = DEFAULT_TIMEOUT)
    {
      // Note: Althought the code is nearly identical as TryExecute, it cannot be easily refactored, as the ImpersonationProcess implements many methods and properties with "new".
      // If such an instance is assigned to "Process" base class, any access will fail here. 
      StringBuilder outputBuilder = new StringBuilder();
      using (ImpersonationProcess process = new ImpersonationProcess())
      using (AutoResetEvent outputWaitHandle = new AutoResetEvent(!redirectInputOutput))
      {
        PrepareProcess(executable, arguments, redirectInputOutput, process, outputWaitHandle, outputBuilder);
        process.StartAsUser(token);
        if (!process.HasExited)
          process.PriorityClass = priorityClass;

        if (redirectInputOutput)
          process.BeginOutputReadLine();

        if (process.WaitForExit(maxWaitMs) && outputWaitHandle.WaitOne(maxWaitMs))
        {
          if (redirectInputOutput)
            process.CancelOutputRead();
          result = RemoveEncodingPreamble(outputBuilder.ToString());
          return process.ExitCode == 0;
        }
        if (!process.HasExited)
        {
          if (redirectInputOutput)
            process.CancelOutputRead();
          process.Kill();
        }
      }
      result = null;
      return false;
    }