// Following http://blogs.msdn.com/b/winsdk/archive/2009/07/14/launching-an-interactive-process-from-windows-service-in-windows-vista-and-later.aspx . public static uint RunIt(String strCommand, String strDomain, String strName, String strPassword) { IntPtr hToken = IntPtr.Zero; uint pid = uint.MaxValue; try { Boolean result = Win32ProcessCall.LogonUser(strName, strDomain, strPassword, Win32ProcessCall.LogonType.LOGON32_LOGON_INTERACTIVE, Win32ProcessCall.LogonProvider.LOGON32_PROVIDER_DEFAULT, out hToken); if (!result) { throw new Exception("Logon error #" + Marshal.GetLastWin32Error()); } UInt32 dwSessionId = WTSGetActiveConsoleSessionId(); IntPtr newToken = IntPtr.Zero; //http://stackoverflow.com/questions/3128017/possible-to-launch-a-process-in-a-users-session-from-a-service CNU.RunAs.Alejacma.Win32ProcessCall.STARTUPINFO startInfo = new CNU.RunAs.Alejacma.Win32ProcessCall.STARTUPINFO(); startInfo.cb = Marshal.SizeOf(startInfo); IntPtr envBlock = ProcessAsUser.GetEnvironmentBlock(hToken); pid = ProcessAsUser.LaunchProcessAsUserPid(strCommand, hToken, envBlock); if (envBlock != IntPtr.Zero) { ProcessAsUser.DestroyEnvironmentBlock(envBlock); } } finally { Win32ProcessCall.CloseHandle(hToken); } return(pid); }
public static uint Launch(string appCmdLine) { bool fail = false; uint result = uint.MaxValue; //Either specify the processID explicitly //Or try to get it from a process owned by the user. //In this case assuming there is only one explorer.exe Process[] ps = Process.GetProcessesByName("explorer"); int processId = -1;//=processId if (ps.Length > 0) { processId = ps[0].Id; } if (processId > 1) { IntPtr token = ProcessAsUser.GetPrimaryToken(processId); if (token != IntPtr.Zero) { IntPtr envBlock = ProcessAsUser.GetEnvironmentBlock(token); result = LaunchProcessAsUser(appCmdLine, token, envBlock); if (result == uint.MaxValue) { fail = true; } if (envBlock != IntPtr.Zero) { ProcessAsUser.DestroyEnvironmentBlock(envBlock); } ProcessAsUser.CloseHandle(token); } } return(fail ? uint.MaxValue : result); }