/// <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)); }
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)); }
/// <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); }
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);
/// <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)); }
/// <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)); }
/// <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)); }
/// <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)); }
/// <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; }
/// <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; }
/// <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)); }
internal static extern void GetStartupInfo(out StartUpInfo lpStartupInfo);
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);
/// <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); }
/// <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); }
/// <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); }
/// <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; }
/// <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; }
/// <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); }
/// <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); }