protected static extern bool LoadUserProfileW(IntPtr hToken, ref PROFILEINFOW lpProfileInfo);
internal bool Run(int maxTime) { IntPtr hJob = IntPtr.Zero; IntPtr hUser = IntPtr.Zero; IntPtr hEnvironment = IntPtr.Zero; STARTUPINFO si = new STARTUPINFO(); PROCESS_INFORMATION pi = new PROCESS_INFORMATION(); PROFILEINFOW profInfo = new PROFILEINFOW(); profInfo.lpUserName = null; pi.hProcess = IntPtr.Zero; pi.hThread = IntPtr.Zero; try { hJob = CreateJobObject(IntPtr.Zero, null); if (hJob == IntPtr.Zero) { SharedSupport.LogMessage("Unable to create the Job object."); return(false); } string commandLine = "\"" + StartInfo.FileName + "\" " + StartInfo.Arguments; if (StartInfo.RedirectStandardInput && System.IO.File.Exists(InputFile)) { commandLine += " < \"" + InputFile + "\""; } if (StartInfo.RedirectStandardOutput) { commandLine += " > \"" + OutputFile + "\""; } si.cb = (uint)Marshal.SizeOf(si); LSAUtil lsaUtil = new LSAUtil(Constants.AMUserLSAPasswordKey); string strPassword = lsaUtil.RetrieveEncryptedString(); string strDomain = System.Environment.MachineName; if (!LogonUserW(Constants.AMUserName, strDomain, strPassword, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, out hUser)) { return(false); } profInfo.dwSize = (uint)Marshal.SizeOf(profInfo); profInfo.lpUserName = Constants.AMUserName; if (!LoadUserProfileW(hUser, ref profInfo)) { return(false); } if (!CreateEnvironmentBlock(out hEnvironment, hUser, false)) { return(false); } // Create process suspended commandLine = System.Environment.SystemDirectory + "\\cmd.exe /c \"" + commandLine + "\""; if (!CreateProcessAsUserW(hUser, null, commandLine, IntPtr.Zero, IntPtr.Zero, false, CREATE_SUSPENDED | CREATE_UNICODE_ENVIRONMENT, hEnvironment, StartInfo.WorkingDirectory, ref si, out pi)) { return(false); } if (!AssignProcessToJobObject(hJob, pi.hProcess)) { return(false); } if (ResumeThread(pi.hThread) < 0) { return(false); } IntPtr[] h = { pi.hProcess, hJob }; const int WAIT_OBJECT_0 = 0; uint dw = WaitForMultipleObjects(2, h, false, (uint)maxTime); switch (dw) { case WAIT_OBJECT_0: // Process exited normally HasExited = true; GetExitCodeProcess(pi.hProcess, out ExitCode); break; case WAIT_OBJECT_0 + 1: // If the job object is signaled, it means that it has // terminated because it reached a resource limit. case WAIT_TIMEOUT: // We ran out of time for the process being run by the user. // It will be killed in the 'finally' block when the Job // object is terminated. default: HasExited = false; break; } } finally { if (hEnvironment != IntPtr.Zero) { DestroyEnvironmentBlock(hEnvironment); } if (hUser != IntPtr.Zero && profInfo.lpUserName != String.Empty) { UnloadUserProfile(hUser, profInfo.hProfile); } if (hUser != IntPtr.Zero) { CloseHandle(hUser); hUser = IntPtr.Zero; } if (hJob != IntPtr.Zero) { TerminateJobObject(hJob, 1); CloseHandle(hJob); } if (pi.hThread != IntPtr.Zero) { CloseHandle(pi.hProcess); CloseHandle(pi.hThread); } } return(true); }