public override void Specify() { it("can run code like Luke's code", delegate { using (SafeHandle hToken = AccessToken.GetCurrentAccessToken()) { IntPtr hDuplicate = AccessToken.DuplicateTokenAsPrimaryToken(hToken).DangerousGetHandle(); string commandLine = ("powershell"); var startupInfo = StartupInfoWithOutputStreams.Create(); AdvApi32PInvoke.PROCESS_INFORMATION processInformation = new AdvApi32PInvoke.PROCESS_INFORMATION(); if (!AdvApi32PInvoke.CreateProcessWithTokenW(hDuplicate, AdvApi32PInvoke.LogonFlags.LOGON_WITH_PROFILE, null, commandLine, 0, Constants.NULL, Constants.NULL, ref startupInfo.STARTUP_INFO, out processInformation)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } Kernel32.CloseHandle(hDuplicate); Kernel32.CloseHandle(processInformation.hThread); Kernel32.TerminateProcess(processInformation.hProcess, 0); Kernel32.CloseHandle(processInformation.hProcess); } }); it("can run Luke's code", delegate { IntPtr hToken; if (!AdvApi32PInvoke.OpenProcessToken(Kernel32.GetCurrentProcess(), AdvApi32PInvoke.TOKEN_DUPLICATE, out hToken)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } IntPtr hDuplicate; if (!AdvApi32PInvoke.DuplicateTokenEx(hToken, AdvApi32PInvoke.TOKEN_ASSIGN_PRIMARY | AdvApi32PInvoke.TOKEN_DUPLICATE | AdvApi32PInvoke.TOKEN_QUERY | AdvApi32PInvoke.TOKEN_ADJUST_DEFAULT | AdvApi32PInvoke.TOKEN_ADJUST_SESSIONID, Constants.NULL, AdvApi32PInvoke.SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation, AdvApi32PInvoke.TOKEN_TYPE.TokenPrimary, out hDuplicate)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } string commandLine = ("powershell"); AdvApi32PInvoke.STARTUPINFO startupInfo = new AdvApi32PInvoke.STARTUPINFO(); startupInfo.cb = Marshal.SizeOf(typeof(AdvApi32PInvoke.STARTUPINFO)); AdvApi32PInvoke.PROCESS_INFORMATION processInformation = new AdvApi32PInvoke.PROCESS_INFORMATION(); if ( !AdvApi32PInvoke.CreateProcessWithTokenW(hDuplicate, AdvApi32PInvoke.LogonFlags.LOGON_WITH_PROFILE, null, commandLine, 0, Constants.NULL, Constants.NULL, ref startupInfo, out processInformation)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } Kernel32.CloseHandle(hToken); Kernel32.CloseHandle(hDuplicate); Kernel32.CloseHandle(processInformation.hThread); Kernel32.TerminateProcess(processInformation.hProcess, 0); Kernel32.CloseHandle(processInformation.hProcess); }); }
public static ConsoleApplicationResultStreams RunNoninteractiveConsoleProcessForStreams(string commandArguments, out string newLine) { using (var threadToken = AccessToken.GetCurrentAccessTokenDuplicatedAsPrimary()) { StreamReader consoleOutput; StreamReader errorOutput; IntPtr processHandle; int dwProcessId; using (var startupInfo = StartupInfoWithOutputStreams.Create()) { AdvApi32PInvoke.PROCESS_INFORMATION lpProcessInformation = new AdvApi32PInvoke.PROCESS_INFORMATION(); AdvApi32PInvoke.LogonFlags logonFlags = AdvApi32PInvoke.LogonFlags.LOGON_WITH_PROFILE; AdvApi32PInvoke.CreationFlags creationFlags = AdvApi32PInvoke.CreationFlags.CREATE_NEW_CONSOLE; if (!AdvApi32PInvoke.CreateProcessWithTokenW(threadToken.DangerousGetHandle(), logonFlags, null, commandArguments, (int)creationFlags, Constants.NULL, Constants.NULL, ref startupInfo.STARTUP_INFO, out lpProcessInformation)) { int lastWin32Error = Marshal.GetLastWin32Error(); if (lastWin32Error == 0xc1) // found in Process.StartWithCreateProcess { throw new Win32Exception("Invalid application"); } throw new Win32Exception(lastWin32Error); } Kernel32.CloseHandle(lpProcessInformation.hThread); processHandle = lpProcessInformation.hProcess; lpProcessInformation.hProcess = Constants.NULL; consoleOutput = startupInfo.ConsoleOutput; errorOutput = startupInfo.ErrorOutput; startupInfo.ConsoleOutput = null; startupInfo.ErrorOutput = null; } consoleOutput.Peek(); var waitResult = Kernel32.WaitForSingleObject(processHandle, Kernel32.INFINITE); if (waitResult == Kernel32.WAIT_FAILED) { throw new Win32Exception(Marshal.GetLastWin32Error()); } if (waitResult == Kernel32.WAIT_TIMEOUT) { throw new TimeoutException("Timed out waiting for process."); } if (waitResult != Kernel32.WAIT_OBJECT_0) { throw new InvalidOperationException("Unexpected wait result."); } int exitCode; if (!Kernel32.GetExitCodeProcess(processHandle, out exitCode)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } MemoryStream consoleStore = ReadStreamToMemoryStream(consoleOutput.BaseStream); MemoryStream errorStore = ReadStreamToMemoryStream(errorOutput.BaseStream); consoleStore.Seek(0, SeekOrigin.Begin); errorStore.Seek(0, SeekOrigin.Begin); newLine = Environment.NewLine; return(new ConsoleApplicationResultStreams(new StreamReader(consoleStore), new StreamReader(errorStore), exitCode)); } }