示例#1
0
        /// <summary>
        /// Creates a new process in a desktop.
        /// </summary>
        /// <param name="path">Path to application.</param>
        /// <returns>The process object for the newly created process.</returns>
        public Process CreateProcess(string path)
        {
            // make sure object isnt disposed.
            CheckDisposed();

            // make sure a desktop is open.
            if (!IsOpen)
            {
                return(null);
            }

            // set startup parameters.
            var si = new StartUpInfo();

            si.cb        = Marshal.SizeOf(si);
            si.lpDesktop = DesktopName;

            var pi = new ProcessInfo();

            // start the process.
            var result = Kernel32.CreateProcess(null, path, IntPtr.Zero, IntPtr.Zero, true, NORMAL_PRIORITY_CLASS, IntPtr.Zero, null, ref si, ref pi);

            // error?
            return(!result ? null : Process.GetProcessById(pi.ProcessId));
        }
示例#2
0
        public Task <Process> Launch(LaunchOptions options)
        {
            _logger.LogInformation($"Launching app: '{options.FilePath}' using credentials for: '{options.Domain}'");

            StartUpInfo startupInfo = new StartUpInfo();

            startupInfo.cb            = Marshal.SizeOf(startupInfo);
            startupInfo.lpTitle       = null;
            startupInfo.dwFlags       = (int)StartUpInfoFlags.UseCountChars;
            startupInfo.dwYCountChars = 50;

            var workingDirectory = !string.IsNullOrWhiteSpace(options.WorkingDirectory)
                ? options.WorkingDirectory
                : Path.GetDirectoryName(options.FilePath);

            var password = _cipherService.Decrypt(options.Password);

            var process = RunAs.StartProcess(
                userName: options.UserName,
                domain: options.Domain,
                password: password,
                logonFlags: RunAs.LogonFlags.NetworkCredentialsOnly,
                applicationName: null,
                commandLine: options.FilePath,
                creationFlags: RunAs.CreationFlags.NewConsole,
                environment: IntPtr.Zero,
                currentDirectory: workingDirectory,
                startupInfo: ref startupInfo,
                processInfo: out _
                );

            return(Task.FromResult(process));
        }
示例#3
0
        /// <summary>
        /// Starts the process interactively.
        /// </summary>
        /// <param name="request">The request.</param>
        /// <param name="procInfo">The proc information.</param>
        /// <param name="logonInfo">The logon information.</param>
        /// <param name="runAsLocalSystem">if set to <c>true</c> [run asynchronous local system].</param>
        /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
        public bool StartProcessInteractively(IAutomationRequest request, out ProcessInformation procInfo, LogOnDetails?logonInfo = null, bool runAsLocalSystem = false)
        {
            var retval = false;

            procInfo = new ProcessInformation();
            var    winlogonPid = GetSessionId(WTSGetActiveConsoleSessionId());
            IntPtr hUserTokenDup = IntPtr.Zero, hPToken = IntPtr.Zero, hProcess = IntPtr.Zero;
            var    sa = new SecurityAttributes();

            sa.Length = Marshal.SizeOf(sa);
            var si = new StartUpInfo()
            {
                lpDesktop = InteractiveWindowStation
            };

            si.cb = Marshal.SizeOf(si);

            if ((hProcess = OpenProcess(MaximumAllowed, false, winlogonPid)) != IntPtr.Zero &&
                OpenProcessToken(hProcess, TokenDuplicate, ref hPToken))
            {
                if (logonInfo == null)
                {
                    if (runAsLocalSystem)
                    {
                        if (DuplicateTokenEx(hPToken, MaximumAllowed, ref sa,
                                             (int)SecurityImpersonationLevel.SecurityIdentification,
                                             (int)TokenType.TokenPrimary, ref hUserTokenDup))
                        {
                            retval = CreateProcessAsUser(hUserTokenDup, null, request.FileName, ref sa, ref sa,
                                                         false, CreationFlags, IntPtr.Zero, null, ref si, out procInfo);
                        }
                    }
                    else
                    {
                        WTSQueryUserToken(WTSGetActiveConsoleSessionId(), ref hUserTokenDup);

                        retval = CreateProcessAsUser(hUserTokenDup, null, request.FileName, ref sa, ref sa,
                                                     false, CreationFlags, IntPtr.Zero, null, ref si, out procInfo);
                    }
                }
                else
                {
                    retval = StartProcessInteractivelyAsDifferentUser(ref hProcess, ref hPToken, ref hUserTokenDup, logonInfo.Value, ref sa,
                                                                      ref si, ref procInfo, request.FileName);
                }
            }

            CloseHandle(hProcess);
            CloseHandle(hPToken);
            CloseHandle(hUserTokenDup);

            return(retval);
        }
示例#4
0
文件: Mapper.cs 项目: hnnaa/AATool
 public static extern bool CreateProcessAsUser(
     IntPtr hToken,
     string lpApplicationName,
     string lpCommandLine,
     ref SecurityAttributes lpProcessAttributes,
     ref SecurityAttributes lpThreadAttributes,
     bool bInheritHandle,
     Int32 dwCreationFlags,
     IntPtr lpEnvrionment,
     string lpCurrentDirectory,
     ref StartUpInfo lpStartupInfo,
     ref Process_Information lpProcessInformation);
示例#5
0
        /// <summary>
        /// Creates a new process and its primary thread. The new process then runs the
        ///  specified executable file in the security context of the specified
        ///  credentials (user, domain, and password). It can optionally load the user
        ///  profile for the specified user.
        /// </summary>
        /// <remarks>
        /// This method is untested.
        /// </remarks>
        /// <param name="userName">
        /// This is the name of the user account to log on to. If you use the UPN format,
        ///  user@domain, the Domain parameter must be NULL. The user account must have
        ///  the Log On Locally permission on the local computer.
        /// </param>
        /// <param name="domain">
        /// Specifies the name of the domain or server whose account database contains the
        ///  user account. If this parameter is NULL, the user name must be specified in
        ///  UPN format.
        /// </param>
        /// <param name="password">
        /// Specifies the clear-text password for the user account.
        /// </param>
        /// <param name="commandLine">
        /// Specifies the command line to execute. The maximum length of this string is
        ///  32,000 characters. The commandline parameter can be NULL. In that case, the
        ///  function uses the string pointed to by appname as the command line. If the
        ///  file name does not contain an extension, .exe is appended. Therefore, if the
        ///  file name extension is .com, this parameter must include the .com extension.
        ///  If the file name ends in a period with no extension, or if the file name
        ///  contains a path, .exe is not appended. If the file name does not contain a
        ///  directory path, the system searches for the executable file.
        /// </param>
        /// <returns>
        /// Returns a System.Diagnostic.Process which will be null if the call failed.
        /// </returns>
        /// <exception cref="System.ComponentModel.Win32Exception">
        /// Throws a System.ComponentModel.Win32Exception containing the last error if the
        ///  call failed.
        /// </exception>
        public static Process StartProcess(string userName,
                                           string domain, string password, string commandLine)
        {
            var startupInfo = new StartUpInfo();

            startupInfo.cb            = Marshal.SizeOf(startupInfo);
            startupInfo.lpTitle       = null;
            startupInfo.dwFlags       = (int)StartUpInfoFlags.UseCountChars;
            startupInfo.dwYCountChars = 50;

            return(StartProcess(userName, domain, password, LogonFlags.WithProfile,
                                null, commandLine, CreationFlags.NewConsole, IntPtr.Zero,
                                null, ref startupInfo, out ProcessInformation processInfo));
        }
示例#6
0
        /// <summary>
        /// Creates a new process and its primary thread. The new process then runs the
        ///  specified executable file in the security context of the specified
        ///  credentials (user, domain, and password). It can optionally load the user
        ///  profile for the specified user.
        /// </summary>
        /// <remarks>
        /// This method is untested.
        /// </remarks>
        /// <param name="userName">
        /// This is the name of the user account to log on to. If you use the UPN format,
        ///  user@domain, the Domain parameter must be NULL. The user account must have
        ///  the Log On Locally permission on the local computer.
        /// </param>
        /// <param name="domain">
        /// Specifies the name of the domain or server whose account database contains the
        ///  user account. If this parameter is NULL, the user name must be specified in
        ///  UPN format.
        /// </param>
        /// <param name="password">
        /// Specifies the clear-text password for the user account.
        /// </param>
        /// <param name="commandLine">
        /// Specifies the command line to execute. The maximum length of this string is
        ///  32,000 characters. The commandline parameter can be NULL. In that case, the
        ///  function uses the string pointed to by appname as the command line. If the
        ///  file name does not contain an extension, .exe is appended. Therefore, if the
        ///  file name extension is .com, this parameter must include the .com extension.
        ///  If the file name ends in a period with no extension, or if the file name
        ///  contains a path, .exe is not appended. If the file name does not contain a
        ///  directory path, the system searches for the executable file.
        /// </param>
        /// <returns>
        /// Returns a System.Diagnostic.Process which will be null if the call failed.
        /// </returns>
        /// <exception cref="System.ComponentModel.Win32Exception">
        /// Throws a System.ComponentModel.Win32Exception containing the last error if the
        ///  call failed.
        /// </exception>
        public static System.Diagnostics.Process StartProcess(string userName,
                                                              string domain, string password, string commandLine)
        {
            ProcessInformation processInfo;
            StartUpInfo        startupInfo = new StartUpInfo();

            startupInfo.cb            = Marshal.SizeOf(startupInfo);
            startupInfo.lpTitle       = null;
            startupInfo.dwFlags       = (int)StartUpInfoFlags.UseCountChars;
            startupInfo.dwYCountChars = 50;

            return(StartProcess(userName, domain, password, LogonFlags.NetworkCredentialsOnly,
                                null, commandLine, CreationFlags.NewConsole, IntPtr.Zero,
                                null, ref startupInfo, out processInfo));
        }
示例#7
0
        /// <summary>
        /// Creates a new process and its primary thread. The new process then runs the
        ///  specified executable file in the security context of the specified
        ///  credentials (user, domain, and password). It can optionally load the user
        ///  profile for the specified user.
        /// </summary>
        /// <remarks>
        /// This method is untested.
        /// </remarks>
        /// <param name="userName">
        /// This is the name of the user account to log on to. If you use the UPN format,
        ///  user@domain, the Domain parameter must be NULL. The user account must have
        ///  the Log On Locally permission on the local computer.
        /// </param>
        /// <param name="domain">
        /// Specifies the name of the domain or server whose account database contains the
        ///  user account. If this parameter is NULL, the user name must be specified in
        ///  UPN format.
        /// </param>
        /// <param name="password">
        /// Specifies the clear-text password for the user account.
        /// </param>
        /// <param name="logonFlags">
        /// Logon option. This parameter can be zero or one value from the LogonFlags enum.
        /// </param>
        /// <param name="applicationName">
        /// Specifies the module to execute. The specified module can be a Windows-based
        ///  application. It can be some other type of module (for example, MS-DOS or OS/2)
        ///  if the appropriate subsystem is available on the local computer. The string
        ///  can specify the full path and file name of the module to execute or it can
        ///  specify a partial name. In the case of a partial name, the function uses the
        ///  current drive and current directory to complete the specification. The function
        ///  will not use the search path. If the file name does not contain an extension,
        ///  .exe is assumed. Therefore, if the file name extension is .com, this parameter
        ///  must include the .com extension. The appname parameter can be NULL. In that
        ///  case, the module name must be the first white space-delimited token in the
        ///  commandline string. If the executable module is a 16-bit application, appname
        ///  should be NULL, and the string pointed to by commandline should specify the
        ///  executable module as well as its arguments.
        /// </param>
        /// <param name="commandLine">
        /// Specifies the command line to execute. The maximum length of this string is
        ///  32,000 characters. The commandline parameter can be NULL. In that case, the
        ///  function uses the string pointed to by appname as the command line. If the
        ///  file name does not contain an extension, .exe is appended. Therefore, if the
        ///  file name extension is .com, this parameter must include the .com extension.
        ///  If the file name ends in a period with no extension, or if the file name
        ///  contains a path, .exe is not appended. If the file name does not contain a
        ///  directory path, the system searches for the executable file.
        /// </param>
        /// <param name="creationFlags">
        /// Use CreationFlags and PriorityFlags enums. Controls how the process is created.
        ///  Also controls the new process's priority class, which is used to determine the
        ///  scheduling priorities of the process's threads.
        /// </param>
        /// <param name="currentDirectory">
        /// Specifies the full path to the current directory for the process. The string
        ///  can also specify a UNC path. If this parameter is NULL, the new process will
        ///  have the same current drive and directory as the calling process.
        /// </param>
        /// <returns>
        /// Returns a System.Diagnostic.Process which will be null if the call failed.
        /// </returns>
        /// <exception cref="System.ComponentModel.Win32Exception">
        /// Throws a System.ComponentModel.Win32Exception containing the last error if the
        ///  call failed.
        /// </exception>
        public static Process StartProcess(string userName,
                                           string domain, string password, LogonFlags logonFlags, string applicationName,
                                           string commandLine, CreationFlags creationFlags, string currentDirectory)
        {
            var startupInfo = new StartUpInfo();

            startupInfo.cb            = Marshal.SizeOf(startupInfo);
            startupInfo.lpTitle       = null;
            startupInfo.dwFlags       = (int)StartUpInfoFlags.UseCountChars;;
            startupInfo.dwYCountChars = 50;

            return(StartProcess(userName, domain, password, logonFlags, applicationName,
                                commandLine, creationFlags, IntPtr.Zero, currentDirectory, ref startupInfo,
                                out ProcessInformation processInfo));
        }
示例#8
0
        /// <summary>
        /// Creates a new process and its primary thread. The new process then runs the
        ///  specified executable file in the security context of the specified
        ///  credentials (user, domain, and password). It can optionally load the user
        ///  profile for the specified user.
        /// </summary>
        /// <remarks>
        /// This method is untested.
        /// </remarks>
        /// <param name="userName">
        /// This is the name of the user account to log on to. If you use the UPN format,
        ///  user@domain, the Domain parameter must be NULL. The user account must have
        ///  the Log On Locally permission on the local computer.
        /// </param>
        /// <param name="domain">
        /// Specifies the name of the domain or server whose account database contains the
        ///  user account. If this parameter is NULL, the user name must be specified in
        ///  UPN format.
        /// </param>
        /// <param name="password">
        /// Specifies the clear-text password for the user account.
        /// </param>
        /// <param name="applicationName">
        /// Specifies the module to execute. The specified module can be a Windows-based
        ///  application. It can be some other type of module (for example, MS-DOS or OS/2)
        ///  if the appropriate subsystem is available on the local computer. The string
        ///  can specify the full path and file name of the module to execute or it can
        ///  specify a partial name. In the case of a partial name, the function uses the
        ///  current drive and current directory to complete the specification. The function
        ///  will not use the search path. If the file name does not contain an extension,
        ///  .exe is assumed. Therefore, if the file name extension is .com, this parameter
        ///  must include the .com extension. The appname parameter can be NULL. In that
        ///  case, the module name must be the first white space-delimited token in the
        ///  commandline string. If the executable module is a 16-bit application, appname
        ///  should be NULL, and the string pointed to by commandline should specify the
        ///  executable module as well as its arguments.
        /// </param>
        /// <param name="commandLine">
        /// Specifies the command line to execute. The maximum length of this string is
        ///  32,000 characters. The commandline parameter can be NULL. In that case, the
        ///  function uses the string pointed to by appname as the command line. If the
        ///  file name does not contain an extension, .exe is appended. Therefore, if the
        ///  file name extension is .com, this parameter must include the .com extension.
        ///  If the file name ends in a period with no extension, or if the file name
        ///  contains a path, .exe is not appended. If the file name does not contain a
        ///  directory path, the system searches for the executable file.
        /// </param>
        /// <param name="currentDirectory">
        /// Specifies the full path to the current directory for the process. The string
        ///  can also specify a UNC path. If this parameter is NULL, the new process will
        ///  have the same current drive and directory as the calling process.
        /// </param>
        /// <returns>
        /// Returns a System.Diagnostic.Process which will be null if the call failed.
        /// </returns>
        /// <exception cref="System.ComponentModel.Win32Exception">
        /// Throws a System.ComponentModel.Win32Exception containing the last error if the
        ///  call failed.
        /// </exception>
        public static System.Diagnostics.Process StartProcess(string userName,
                                                              string domain, string password, string applicationName, string commandLine,
                                                              string currentDirectory)
        {
            ProcessInformation processInfo;
            StartUpInfo        startupInfo = new StartUpInfo();

            startupInfo.cb            = Marshal.SizeOf(startupInfo);
            startupInfo.lpTitle       = null;
            startupInfo.dwFlags       = (int)StartUpInfoFlags.UseCountChars;
            startupInfo.dwYCountChars = 50;

            return(StartProcess(userName, domain, password, LogonFlags.WithProfile,
                                applicationName, commandLine, CreationFlags.NewConsole, IntPtr.Zero,
                                currentDirectory, ref startupInfo, out processInfo));
        }
示例#9
0
 /// <summary>
 /// Initializes default values for all parameters.
 /// </summary>
 /// <remarks>
 /// The following default values are assigned:
 /// <list type="table">
 ///  <listheader>
 ///   <term>
 ///    Parameter
 ///   </term>
 ///   <description>
 ///    Default Value
 ///   </description>
 ///  </listheader>
 ///  <item>
 ///   <term>
 ///    UserName
 ///   </term>
 ///   <description>
 ///    System.Environment.UserName
 ///   </description>
 ///  </item>
 ///  <item>
 ///   <term>
 ///    Domain
 ///   </term>
 ///   <description>
 ///    System.Environment.UserDomainName
 ///   </description>
 ///  </item>
 ///  <item>
 ///   <term>
 ///    Password
 ///   </term>
 ///   <description>
 ///    Empty string ("")
 ///   </description>
 ///  </item>
 ///  <item>
 ///   <term>
 ///    ApplicationName
 ///   </term>
 ///   <description>
 ///    CurrentProcess.StartInfo.FileName
 ///   </description>
 ///  </item>
 ///  <item>
 ///   <term>
 ///    LogonFlagsInstance
 ///   </term>
 ///   <description>
 ///    LogonFlags.WithProfile
 ///   </description>
 ///  </item>
 ///  <item>
 ///   <term>
 ///    CommandLine
 ///   </term>
 ///   <description>
 ///    System.Environment.CommandLine
 ///   </description>
 ///  </item>
 ///  <item>
 ///   <term>
 ///    CreationFlagsInstance
 ///   </term>
 ///   <description>
 ///    CreationFlags.NewConsole
 ///   </description>
 ///  </item>
 ///  <item>
 ///   <term>
 ///    CurrentDirectory
 ///   </term>
 ///   <description>
 ///    System.Environment.CurrentDirectory
 ///   </description>
 ///  </item>
 ///  <item>
 ///   <term>
 ///    Environment
 ///   </term>
 ///   <description>
 ///    IntPtr.Zero
 ///   </description>
 ///  </item>
 ///  <item>
 ///   <term>
 ///    StartupInfo
 ///   </term>
 ///   <description>
 ///    New StartUpInfo instance with the following values set:
 ///    -- cb is set to the size of the instance
 ///    -- dwFlags is set to StartUpInfoFlags.UseCountChars
 ///    --dwYCountChars is set to 50
 ///    --lpTitle is set to CurrentProcess.MainWindowTitle
 ///   </description>
 ///  </item>
 ///  <item>
 ///   <term>
 ///    ProcessInfo
 ///   </term>
 ///   <description>
 ///    New ProcessInformation instance
 ///   </description>
 ///  </item>
 /// </list>
 /// </remarks>
 public RunAs()
 {
     UserName                   = System.Environment.UserName;
     Domain                     = System.Environment.UserDomainName;
     Password                   = "";
     LogonFlagsInstance         = LogonFlags.WithProfile;
     CommandLine                = System.Environment.CommandLine;
     CreationFlagsInstance      = CreationFlags.NewConsole;
     CurrentDirectory           = System.Environment.CurrentDirectory;
     _startupInfo               = new StartUpInfo();
     _startupInfo.cb            = Marshal.SizeOf(_startupInfo);
     _startupInfo.dwFlags       = (int)StartUpInfoFlags.UseCountChars;
     _startupInfo.dwYCountChars = 50;
     using (Process cp = Process.GetCurrentProcess())
     {
         ApplicationName      = cp.StartInfo.FileName;
         _startupInfo.lpTitle = cp.MainWindowTitle;
     }
     _processInfo = new ProcessInformation();
     Environment  = IntPtr.Zero;
 }
示例#10
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ProcessRunner"/> class.
 /// </summary>
 public ProcessRunner()
 {
     _userName                  = System.Environment.UserName;
     _domain                    = System.Environment.UserDomainName;
     _password                  = "";
     _logonFlags                = LogonFlags.WithProfile;
     _commandLine               = System.Environment.CommandLine;
     _creationFlags             = CreationFlags.NewConsole;
     _currentDirectory          = System.Environment.CurrentDirectory;
     _startupInfo               = new StartUpInfo();
     _startupInfo.cb            = Marshal.SizeOf(_startupInfo);
     _startupInfo.dwFlags       = (int)StartUpInfoFlags.UseCountChars;
     _startupInfo.dwYCountChars = 50;
     using (System.Diagnostics.Process cp = System.Diagnostics.Process.GetCurrentProcess())
     {
         _applicationName     = cp.StartInfo.FileName;
         _startupInfo.lpTitle = cp.MainWindowTitle;
     }
     _processInfo = new ProcessInformation();
     Environment  = IntPtr.Zero;
 }
示例#11
0
        /// <summary>
        /// Creates a new process and its primary thread. The new process then runs the
        ///  specified executable file in the security context of the specified
        ///  credentials (user, domain, and password). It can optionally load the user
        ///  profile for the specified user.
        /// </summary>
        /// <remarks>
        /// This method is untested.
        /// </remarks>
        /// <param name="userName">
        /// This is the name of the user account to log on to. If you use the UPN format,
        ///  user@domain, the Domain parameter must be NULL. The user account must have
        ///  the Log On Locally permission on the local computer.
        /// </param>
        /// <param name="domain">
        /// Specifies the name of the domain or server whose account database contains the
        ///  user account. If this parameter is NULL, the user name must be specified in
        ///  UPN format.
        /// </param>
        /// <param name="password">
        /// Specifies the clear-text password for the user account.
        /// </param>
        /// <param name="logonFlags">
        /// Logon option. This parameter can be zero or one value from the LogonFlags enum.
        /// </param>
        /// <param name="applicationName">
        /// Specifies the module to execute. The specified module can be a Windows-based
        ///  application. It can be some other type of module (for example, MS-DOS or OS/2)
        ///  if the appropriate subsystem is available on the local computer. The string
        ///  can specify the full path and file name of the module to execute or it can
        ///  specify a partial name. In the case of a partial name, the function uses the
        ///  current drive and current directory to complete the specification. The function
        ///  will not use the search path. If the file name does not contain an extension,
        ///  .exe is assumed. Therefore, if the file name extension is .com, this parameter
        ///  must include the .com extension. The appname parameter can be NULL. In that
        ///  case, the module name must be the first white space-delimited token in the
        ///  commandline string. If the executable module is a 16-bit application, appname
        ///  should be NULL, and the string pointed to by commandline should specify the
        ///  executable module as well as its arguments.
        /// </param>
        /// <param name="commandLine">
        /// Specifies the command line to execute. The maximum length of this string is
        ///  32,000 characters. The commandline parameter can be NULL. In that case, the
        ///  function uses the string pointed to by appname as the command line. If the
        ///  file name does not contain an extension, .exe is appended. Therefore, if the
        ///  file name extension is .com, this parameter must include the .com extension.
        ///  If the file name ends in a period with no extension, or if the file name
        ///  contains a path, .exe is not appended. If the file name does not contain a
        ///  directory path, the system searches for the executable file.
        /// </param>
        /// <param name="creationFlags">
        /// Use CreationFlags and PriorityFlags enums. Controls how the process is created.
        ///  Also controls the new process's priority class, which is used to determine the
        ///  scheduling priorities of the process's threads.
        /// </param>
        /// <param name="currentDirectory">
        /// Specifies the full path to the current directory for the process. The string
        ///  can also specify a UNC path. If this parameter is NULL, the new process will
        ///  have the same current drive and directory as the calling process.
        /// </param>
        /// <param name="environment">
        /// Pointer to an environment block for the new process. If this parameter is NULL,
        ///  the new process uses the environment of the specified user instead of the
        ///  environment of the calling process.
        /// </param>
        /// <param name="startupInfo">
        /// Specifies the window station, desktop, standard handles, and appearance of the
        ///  main window for the new process.
        /// </param>
        /// <param name="processInfo">
        /// ProcessInformation structure that receives identification information for the
        ///  new process, including a handle to the process.
        /// </param>
        /// <returns>
        /// Returns a System.Diagnostic.Process which will be null if the call failed.
        /// </returns>
        /// <exception cref="System.ComponentModel.Win32Exception">
        /// Throws a System.ComponentModel.Win32Exception containing the last error if the
        ///  call failed.
        /// </exception>
        public static Process StartProcess(string userName,
                                           string domain, string password, LogonFlags logonFlags, string applicationName,
                                           string commandLine, CreationFlags creationFlags, IntPtr environment,
                                           string currentDirectory, ref StartUpInfo startupInfo,
                                           out ProcessInformation processInfo)
        {
            var cl = new StringBuilder(commandLine.Length);

            cl.Append(commandLine);
            var retval = CreateProcessWithLogonW(userName, domain, password,
                                                 (int)logonFlags, applicationName, cl, (uint)creationFlags, environment,
                                                 currentDirectory, ref startupInfo, out processInfo);

            if (!retval)
            {
                throw new Win32Exception();
            }

            CloseHandle(processInfo.hProcess);
            CloseHandle(processInfo.hThread);
            return(Process.GetProcessById(processInfo.dwProcessId));
        }
示例#12
0
 internal static extern void GetStartupInfo(out StartUpInfo lpStartupInfo);
示例#13
0
文件: RunAs.cs 项目: gaknoia/babbot
 private static extern bool CreateProcessWithLogonW(String lpszUsername, String lpszDomain, String lpszPassword,
                                                    int dwLogonFlags, string applicationName,
                                                    StringBuilder commandLine, uint creationFlags,
                                                    IntPtr environment, string currentDirectory,
                                                    ref StartUpInfo sui, out ProcessInformation processInfo);
示例#14
0
文件: RunAs.cs 项目: gaknoia/babbot
        /// <summary>
        /// Creates a new process and its primary thread. The new process then runs the
        ///  specified executable file in the security context of the specified
        ///  credentials (user, domain, and password). It can optionally load the user
        ///  profile for the specified user.
        /// </summary>
        /// <remarks>
        /// This method is untested.
        /// </remarks>
        /// <param name="userName">
        /// This is the name of the user account to log on to. If you use the UPN format,
        ///  user@domain, the Domain parameter must be NULL. The user account must have
        ///  the Log On Locally permission on the local computer.
        /// </param>
        /// <param name="domain">
        /// Specifies the name of the domain or server whose account database contains the
        ///  user account. If this parameter is NULL, the user name must be specified in
        ///  UPN format.
        /// </param>
        /// <param name="password">
        /// Specifies the clear-text password for the user account.
        /// </param>
        /// <param name="logonFlags">
        /// Logon option. This parameter can be zero or one value from the LogonFlags enum.
        /// </param>
        /// <param name="applicationName">
        /// Specifies the module to execute. The specified module can be a Windows-based
        ///  application. It can be some other type of module (for example, MS-DOS or OS/2)
        ///  if the appropriate subsystem is available on the local computer. The string
        ///  can specify the full path and file name of the module to execute or it can
        ///  specify a partial name. In the case of a partial name, the function uses the
        ///  current drive and current directory to complete the specification. The function
        ///  will not use the search path. If the file name does not contain an extension,
        ///  .exe is assumed. Therefore, if the file name extension is .com, this parameter
        ///  must include the .com extension. The appname parameter can be NULL. In that
        ///  case, the module name must be the first white space-delimited token in the
        ///  commandline string. If the executable module is a 16-bit application, appname
        ///  should be NULL, and the string pointed to by commandline should specify the
        ///  executable module as well as its arguments.
        /// </param>
        /// <param name="commandLine">
        /// Specifies the command line to execute. The maximum length of this string is
        ///  32,000 characters. The commandline parameter can be NULL. In that case, the
        ///  function uses the string pointed to by appname as the command line. If the
        ///  file name does not contain an extension, .exe is appended. Therefore, if the
        ///  file name extension is .com, this parameter must include the .com extension.
        ///  If the file name ends in a period with no extension, or if the file name
        ///  contains a path, .exe is not appended. If the file name does not contain a
        ///  directory path, the system searches for the executable file.
        /// </param>
        /// <param name="creationFlags">
        /// Use CreationFlags and PriorityFlags enums. Controls how the process is created.
        ///  Also controls the new process's priority class, which is used to determine the
        ///  scheduling priorities of the process's threads.
        /// </param>
        /// <param name="currentDirectory">
        /// Specifies the full path to the current directory for the process. The string
        ///  can also specify a UNC path. If this parameter is NULL, the new process will
        ///  have the same current drive and directory as the calling process.
        /// </param>
        /// <returns>
        /// Returns a System.Diagnostic.Process which will be null if the call failed.
        /// </returns>
        /// <exception cref="System.ComponentModel.Win32Exception">
        /// Throws a System.ComponentModel.Win32Exception containing the last error if the
        ///  call failed.
        /// </exception>
        public static Process StartProcess(string userName,
                                           string domain, string password, LogonFlags logonFlags, string applicationName,
                                           string commandLine, CreationFlags creationFlags, string currentDirectory)
        {
            ProcessInformation processInfo;
            var startupInfo = new StartUpInfo();
            startupInfo.cb = Marshal.SizeOf(startupInfo);
            startupInfo.lpTitle = null;
            startupInfo.dwFlags = (int) StartUpInfoFlags.UseCountChars;
            startupInfo.dwYCountChars = 50;

            return StartProcess(userName, domain, password, logonFlags, applicationName,
                                commandLine, creationFlags, IntPtr.Zero, currentDirectory, ref startupInfo,
                                out processInfo);
        }
示例#15
0
文件: RunAs.cs 项目: gaknoia/babbot
        /// <summary>
        /// Creates a new process and its primary thread. The new process then runs the
        ///  specified executable file in the security context of the specified
        ///  credentials (user, domain, and password). It can optionally load the user
        ///  profile for the specified user.
        /// </summary>
        /// <remarks>
        /// This method is untested.
        /// </remarks>
        /// <param name="userName">
        /// This is the name of the user account to log on to. If you use the UPN format,
        ///  user@domain, the Domain parameter must be NULL. The user account must have
        ///  the Log On Locally permission on the local computer.
        /// </param>
        /// <param name="domain">
        /// Specifies the name of the domain or server whose account database contains the
        ///  user account. If this parameter is NULL, the user name must be specified in
        ///  UPN format.
        /// </param>
        /// <param name="password">
        /// Specifies the clear-text password for the user account.
        /// </param>
        /// <param name="commandLine">
        /// Specifies the command line to execute. The maximum length of this string is
        ///  32,000 characters. The commandline parameter can be NULL. In that case, the
        ///  function uses the string pointed to by appname as the command line. If the
        ///  file name does not contain an extension, .exe is appended. Therefore, if the
        ///  file name extension is .com, this parameter must include the .com extension.
        ///  If the file name ends in a period with no extension, or if the file name
        ///  contains a path, .exe is not appended. If the file name does not contain a
        ///  directory path, the system searches for the executable file.
        /// </param>
        /// <returns>
        /// Returns a System.Diagnostic.Process which will be null if the call failed.
        /// </returns>
        /// <exception cref="System.ComponentModel.Win32Exception">
        /// Throws a System.ComponentModel.Win32Exception containing the last error if the
        ///  call failed.
        /// </exception>
        public static Process StartProcess(string userName,
                                           string domain, string password, string commandLine)
        {
            ProcessInformation processInfo;
            var startupInfo = new StartUpInfo();
            startupInfo.cb = Marshal.SizeOf(startupInfo);
            startupInfo.lpTitle = null;
            startupInfo.dwFlags = (int)StartUpInfoFlags.UseCountChars;
            startupInfo.dwYCountChars = 50;

            return StartProcess(userName, domain, password, LogonFlags.WithProfile,
                                null, commandLine, CreationFlags.NewConsole | CreationFlags.Suspended, IntPtr.Zero,
                                null, ref startupInfo, out processInfo);
        }
示例#16
0
文件: RunAs.cs 项目: gaknoia/babbot
        /// <summary>
        /// Creates a new process and its primary thread. The new process then runs the
        ///  specified executable file in the security context of the specified
        ///  credentials (user, domain, and password). It can optionally load the user
        ///  profile for the specified user.
        /// </summary>
        /// <remarks>
        /// This method is untested.
        /// </remarks>
        /// <param name="userName">
        /// This is the name of the user account to log on to. If you use the UPN format,
        ///  user@domain, the Domain parameter must be NULL. The user account must have
        ///  the Log On Locally permission on the local computer.
        /// </param>
        /// <param name="domain">
        /// Specifies the name of the domain or server whose account database contains the
        ///  user account. If this parameter is NULL, the user name must be specified in
        ///  UPN format.
        /// </param>
        /// <param name="password">
        /// Specifies the clear-text password for the user account.
        /// </param>
        /// <param name="logonFlags">
        /// Logon option. This parameter can be zero or one value from the LogonFlags enum.
        /// </param>
        /// <param name="applicationName">
        /// Specifies the module to execute. The specified module can be a Windows-based
        ///  application. It can be some other type of module (for example, MS-DOS or OS/2)
        ///  if the appropriate subsystem is available on the local computer. The string
        ///  can specify the full path and file name of the module to execute or it can
        ///  specify a partial name. In the case of a partial name, the function uses the
        ///  current drive and current directory to complete the specification. The function
        ///  will not use the search path. If the file name does not contain an extension,
        ///  .exe is assumed. Therefore, if the file name extension is .com, this parameter
        ///  must include the .com extension. The appname parameter can be NULL. In that
        ///  case, the module name must be the first white space-delimited token in the
        ///  commandline string. If the executable module is a 16-bit application, appname
        ///  should be NULL, and the string pointed to by commandline should specify the
        ///  executable module as well as its arguments.
        /// </param>
        /// <param name="commandLine">
        /// Specifies the command line to execute. The maximum length of this string is
        ///  32,000 characters. The commandline parameter can be NULL. In that case, the
        ///  function uses the string pointed to by appname as the command line. If the
        ///  file name does not contain an extension, .exe is appended. Therefore, if the
        ///  file name extension is .com, this parameter must include the .com extension.
        ///  If the file name ends in a period with no extension, or if the file name
        ///  contains a path, .exe is not appended. If the file name does not contain a
        ///  directory path, the system searches for the executable file.
        /// </param>
        /// <param name="creationFlags">
        /// Use CreationFlags and PriorityFlags enums. Controls how the process is created.
        ///  Also controls the new process's priority class, which is used to determine the
        ///  scheduling priorities of the process's threads.
        /// </param>
        /// <param name="currentDirectory">
        /// Specifies the full path to the current directory for the process. The string
        ///  can also specify a UNC path. If this parameter is NULL, the new process will
        ///  have the same current drive and directory as the calling process.
        /// </param>
        /// <param name="environment">
        /// Pointer to an environment block for the new process. If this parameter is NULL,
        ///  the new process uses the environment of the specified user instead of the
        ///  environment of the calling process.
        /// </param>
        /// <param name="startupInfo">
        /// Specifies the window station, desktop, standard handles, and appearance of the
        ///  main window for the new process.
        /// </param>
        /// <param name="processInfo">
        /// ProcessInformation structure that receives identification information for the
        ///  new process, including a handle to the process.
        /// </param>
        /// <returns>
        /// Returns a System.Diagnostic.Process which will be null if the call failed.
        /// </returns>
        /// <exception cref="System.ComponentModel.Win32Exception">
        /// Throws a System.ComponentModel.Win32Exception containing the last error if the
        ///  call failed.
        /// </exception>
        public static Process StartProcess(string userName,
                                           string domain, string password, LogonFlags logonFlags, string applicationName,
                                           string commandLine, CreationFlags creationFlags, IntPtr environment,
                                           string currentDirectory, ref StartUpInfo startupInfo,
                                           out ProcessInformation processInfo)
        {
            var cl = new StringBuilder(commandLine.Length);
            cl.Append(commandLine);
            bool retval = CreateProcessWithLogonW(userName, domain, password,
                                                  (int) logonFlags, applicationName, cl, (uint) creationFlags,
                                                  environment,
                                                  currentDirectory, ref startupInfo, out processInfo);
            if (!retval)
            {
                throw new Win32Exception();
            }

            CloseHandle(processInfo.hProcess);
            CloseHandle(processInfo.hThread);
            return Process.GetProcessById(processInfo.dwProcessId);
        }
示例#17
0
文件: RunAs.cs 项目: gaknoia/babbot
 /// <summary>
 /// Initializes default values for all parameters.
 /// </summary>
 /// <remarks>
 /// The following default values are assigned:
 /// <list type="table">
 ///  <listheader>
 ///   <term>
 ///    Parameter
 ///   </term>
 ///   <description>
 ///    Default Value
 ///   </description>
 ///  </listheader>
 ///  <item>
 ///   <term>
 ///    UserName
 ///   </term>
 ///   <description>
 ///    System.Environment.UserName
 ///   </description>
 ///  </item>
 ///  <item>
 ///   <term>
 ///    Domain
 ///   </term>
 ///   <description>
 ///    System.Environment.UserDomainName
 ///   </description>
 ///  </item>
 ///  <item>
 ///   <term>
 ///    Password
 ///   </term>
 ///   <description>
 ///    Empty string ("")
 ///   </description>
 ///  </item>
 ///  <item>
 ///   <term>
 ///    ApplicationName
 ///   </term>
 ///   <description>
 ///    CurrentProcess.StartInfo.FileName
 ///   </description>
 ///  </item>
 ///  <item>
 ///   <term>
 ///    LogonFlagsInstance
 ///   </term>
 ///   <description>
 ///    LogonFlags.WithProfile
 ///   </description>
 ///  </item>
 ///  <item>
 ///   <term>
 ///    CommandLine
 ///   </term>
 ///   <description>
 ///    System.Environment.CommandLine
 ///   </description>
 ///  </item>
 ///  <item>
 ///   <term>
 ///    CreationFlagsInstance
 ///   </term>
 ///   <description>
 ///    CreationFlags.NewConsole
 ///   </description>
 ///  </item>
 ///  <item>
 ///   <term>
 ///    CurrentDirectory
 ///   </term>
 ///   <description>
 ///    System.Environment.CurrentDirectory
 ///   </description>
 ///  </item>
 ///  <item>
 ///   <term>
 ///    Environment
 ///   </term>
 ///   <description>
 ///    IntPtr.Zero
 ///   </description>
 ///  </item>
 ///  <item>
 ///   <term>
 ///    StartupInfo
 ///   </term>
 ///   <description>
 ///    New StartUpInfo instance with the following values set:
 ///    -- cb is set to the size of the instance
 ///    -- dwFlags is set to StartUpInfoFlags.UseCountChars
 ///    --dwYCountChars is set to 50
 ///    --lpTitle is set to CurrentProcess.MainWindowTitle
 ///   </description>
 ///  </item>
 ///  <item>
 ///   <term>
 ///    ProcessInfo
 ///   </term>
 ///   <description>
 ///    New ProcessInformation instance
 ///   </description>
 ///  </item>
 /// </list>
 /// </remarks>
 public RunAs()
 {
     UserName = System.Environment.UserName;
     Domain = System.Environment.UserDomainName;
     Password = "";
     LogonFlagsInstance = LogonFlags.WithProfile;
     CommandLine = System.Environment.CommandLine;
     CreationFlagsInstance = CreationFlags.NewConsole;
     CurrentDirectory = System.Environment.CurrentDirectory;
     _startupInfo = new StartUpInfo();
     _startupInfo.cb = Marshal.SizeOf(_startupInfo);
     _startupInfo.dwFlags = (int) StartUpInfoFlags.UseCountChars;
     _startupInfo.dwYCountChars = 50;
     using (Process cp = Process.GetCurrentProcess())
     {
         ApplicationName = cp.StartInfo.FileName;
         _startupInfo.lpTitle = cp.MainWindowTitle;
     }
     _processInfo = new ProcessInformation();
     Environment = IntPtr.Zero;
 }
示例#18
0
 /// <summary>
 /// Initializes default values for all parameters.
 /// </summary>
 /// <remarks>
 /// The following default values are assigned:
 /// <list type="table">
 ///  <listheader>
 ///   <term>
 ///    Parameter
 ///   </term>
 ///   <description>
 ///    Default Value
 ///   </description>
 ///  </listheader>
 ///  <item>
 ///   <term>
 ///    UserName
 ///   </term>
 ///   <description>
 ///    System.Environment.UserName
 ///   </description>
 ///  </item>
 ///  <item>
 ///   <term>
 ///    Domain
 ///   </term>
 ///   <description>
 ///    System.Environment.UserDomainName
 ///   </description>
 ///  </item>
 ///  <item>
 ///   <term>
 ///    Password
 ///   </term>
 ///   <description>
 ///    Empty string ("")
 ///   </description>
 ///  </item>
 ///  <item>
 ///   <term>
 ///    ApplicationName
 ///   </term>
 ///   <description>
 ///    CurrentProcess.StartInfo.FileName
 ///   </description>
 ///  </item>
 ///  <item>
 ///   <term>
 ///    LogonFlagsInstance
 ///   </term>
 ///   <description>
 ///    LogonFlags.WithProfile
 ///   </description>
 ///  </item>
 ///  <item>
 ///   <term>
 ///    CommandLine
 ///   </term>
 ///   <description>
 ///    System.Environment.CommandLine
 ///   </description>
 ///  </item>
 ///  <item>
 ///   <term>
 ///    CreationFlagsInstance
 ///   </term>
 ///   <description>
 ///    CreationFlags.NewConsole
 ///   </description>
 ///  </item>
 ///  <item>
 ///   <term>
 ///    CurrentDirectory
 ///   </term>
 ///   <description>
 ///    System.Environment.CurrentDirectory
 ///   </description>
 ///  </item>
 ///  <item>
 ///   <term>
 ///    Environment
 ///   </term>
 ///   <description>
 ///    IntPtr.Zero
 ///   </description>
 ///  </item>
 ///  <item>
 ///   <term>
 ///    StartupInfo
 ///   </term>
 ///   <description>
 ///    New StartUpInfo instance with the following values set:
 ///    -- cb is set to the size of the instance
 ///    -- dwFlags is set to StartUpInfoFlags.UseCountChars
 ///    --dwYCountChars is set to 50
 ///    --lpTitle is set to CurrentProcess.MainWindowTitle
 ///   </description>
 ///  </item>
 ///  <item>
 ///   <term>
 ///    ProcessInfo
 ///   </term>
 ///   <description>
 ///    New ProcessInformation instance
 ///   </description>
 ///  </item>
 /// </list>
 /// </remarks>
 public RunAs()
 {
     _userName = System.Environment.UserName;
     _domain = System.Environment.UserDomainName;
     _password = "";
     _logonFlags = LogonFlags.WithProfile;
     _commandLine = System.Environment.CommandLine;
     _creationFlags = CreationFlags.NewConsole;
     _currentDirectory = System.Environment.CurrentDirectory;
     _startupInfo = new StartUpInfo();
     _startupInfo.cb = Marshal.SizeOf(_startupInfo);
     _startupInfo.dwFlags = (int)StartUpInfoFlags.UseCountChars;
     _startupInfo.dwYCountChars = 50;
     using (System.Diagnostics.Process cp = System.Diagnostics.Process.GetCurrentProcess())
     {
         _applicationName = cp.StartInfo.FileName;
         _startupInfo.lpTitle = cp.MainWindowTitle;
     }
     _processInfo = new ProcessInformation();
     _environment = IntPtr.Zero;
 }
示例#19
0
        /// <summary>
        /// Creates a new process and its primary thread. The new process then runs the
        ///  specified executable file in the security context of the specified
        ///  credentials (user, domain, and password). It can optionally load the user
        ///  profile for the specified user.
        /// </summary>
        /// <remarks>
        /// This method is untested.
        /// </remarks>
        /// <param name="userName">
        /// This is the name of the user account to log on to. If you use the UPN format,
        ///  user@domain, the Domain parameter must be NULL. The user account must have
        ///  the Log On Locally permission on the local computer.
        /// </param>
        /// <param name="domain">
        /// Specifies the name of the domain or server whose account database contains the
        ///  user account. If this parameter is NULL, the user name must be specified in
        ///  UPN format.
        /// </param>
        /// <param name="password">
        /// Specifies the clear-text password for the user account.
        /// </param>
        /// <param name="applicationName">
        /// Specifies the module to execute. The specified module can be a Windows-based
        ///  application. It can be some other type of module (for example, MS-DOS or OS/2)
        ///  if the appropriate subsystem is available on the local computer. The string
        ///  can specify the full path and file name of the module to execute or it can
        ///  specify a partial name. In the case of a partial name, the function uses the
        ///  current drive and current directory to complete the specification. The function
        ///  will not use the search path. If the file name does not contain an extension,
        ///  .exe is assumed. Therefore, if the file name extension is .com, this parameter
        ///  must include the .com extension. The appname parameter can be NULL. In that
        ///  case, the module name must be the first white space-delimited token in the
        ///  commandline string. If the executable module is a 16-bit application, appname
        ///  should be NULL, and the string pointed to by commandline should specify the
        ///  executable module as well as its arguments.
        /// </param>
        /// <param name="commandLine">
        /// Specifies the command line to execute. The maximum length of this string is
        ///  32,000 characters. The commandline parameter can be NULL. In that case, the
        ///  function uses the string pointed to by appname as the command line. If the
        ///  file name does not contain an extension, .exe is appended. Therefore, if the
        ///  file name extension is .com, this parameter must include the .com extension.
        ///  If the file name ends in a period with no extension, or if the file name
        ///  contains a path, .exe is not appended. If the file name does not contain a
        ///  directory path, the system searches for the executable file.
        /// </param>
        /// <param name="currentDirectory">
        /// Specifies the full path to the current directory for the process. The string
        ///  can also specify a UNC path. If this parameter is NULL, the new process will
        ///  have the same current drive and directory as the calling process.
        /// </param>
        /// <returns>
        /// Returns a System.Diagnostic.Process which will be null if the call failed.
        /// </returns>
        /// <exception cref="System.ComponentModel.Win32Exception">
        /// Throws a System.ComponentModel.Win32Exception containing the last error if the
        ///  call failed.
        /// </exception>
        public static System.Diagnostics.Process StartProcess(string userName,
			string domain, string password, string applicationName, string commandLine,
			string currentDirectory)
        {
            ProcessInformation processInfo;
            StartUpInfo startupInfo = new StartUpInfo();
            startupInfo.cb = Marshal.SizeOf(startupInfo);
            startupInfo.lpTitle = null;
            startupInfo.dwFlags = (int)StartUpInfoFlags.UseCountChars;
            startupInfo.dwYCountChars = 50;

            return StartProcess(userName, domain, password, LogonFlags.WithProfile,
                applicationName, commandLine, CreationFlags.NewConsole, IntPtr.Zero,
                currentDirectory, ref startupInfo, out processInfo);
        }
示例#20
0
 private static extern bool CreateProcessWithLogonW(String lpszUsername, String lpszDomain, String lpszPassword, int dwLogonFlags, string applicationName, StringBuilder commandLine, uint creationFlags, IntPtr environment, string currentDirectory, ref StartUpInfo sui, out ProcessInformation processInfo);
示例#21
0
        /// <summary>
        /// Starts the process interactively asynchronous different user.
        /// </summary>
        /// <param name="hProcess">The authentication process.</param>
        /// <param name="hPToken">The authentication application token.</param>
        /// <param name="hUserTokenDup">The authentication user token dup.</param>
        /// <param name="logonInfo">The logon information.</param>
        /// <param name="sa">The sa.</param>
        /// <param name="si">The si.</param>
        /// <param name="procInfo">The proc information.</param>
        /// <param name="imageName">Name of the image.</param>
        /// <returns></returns>
        private bool StartProcessInteractivelyAsDifferentUser(ref IntPtr hProcess, ref IntPtr hPToken, ref IntPtr hUserTokenDup,
                                                              LogOnDetails logonInfo, ref SecurityAttributes sa, ref StartUpInfo si, ref ProcessInformation procInfo, string imageName)
        {
            //TODO: This method needs to be revised because WDM is killing the process
            var retval = false;

            if (LogonUser(logonInfo.UserName, logonInfo.Domain, logonInfo.Password, Logon32LogonInteractive, Logon32ProviderDefault, ref hUserTokenDup))
            {
                var luid      = new Luid();
                var sessionId = WTSGetActiveConsoleSessionId();
                if (LookupPrivilegeValue(IntPtr.Zero, SeDebugName, ref luid))
                {
                    if (SetTokenInformation(hUserTokenDup, TokenInformationClass.TokenSessionId, ref sessionId, (UInt32)IntPtr.Size))
                    {
                        var tp = new TokenPrivileges()
                        {
                            PrivilegeCount = 1,
                            Privileges     = new int[] { luid.LowPart, luid.HighPart, SePrivilegeEnabled }
                        };

                        if (AdjustTokenPrivileges(hUserTokenDup, false, ref tp, Marshal.SizeOf(tp), IntPtr.Zero, IntPtr.Zero))
                        {
                            retval = CreateProcessAsUser(hUserTokenDup, null, imageName, ref sa, ref sa,
                                                         false, CreationFlags, IntPtr.Zero, null, ref si, out procInfo);
                        }
                    }
                }
            }

            return(retval);
        }