如何从CreateProcessWithLogonW获取标准输出?

我使用的是http://www.pinvoke.net/default.aspx/advapi32.createprocesswithlogonw中的代码。 如何将标准输出的输出作为字符串? 就像在命令窗口中以交互方式运行它时出现的东西一样?

使用重定向的std input \ output \ error线程调用CreateProcessWithLogonW与使用System.Diagnostics.Process类执行下面的代码相同,指定了user \ domain \ password字段并且Redirect * fields设置为true。 事实上,通过使用reflection器查看Process类的StartWithCreateProcess私有方法,您会发现如果应用了上述条件, NativeMethods.CreateProcessWithLogonW过程将在那里执行。

Process process1 = new Process(); process1.StartInfo.FileName = @"c:\windows\system32\ping.exe"; process1.StartInfo.Arguments = "127.0.0.1"; // all 3 redirect* fields have to be set process1.StartInfo.RedirectStandardOutput = true; process1.StartInfo.RedirectStandardInput = true; process1.StartInfo.RedirectStandardError = true; process1.StartInfo.UseShellExecute = false; process1.StartInfo.UserName = "admin"; process1.StartInfo.Domain = System.Environment.MachineName; SecureString password = new SecureString(); foreach (char a in "password".ToCharArray()) password.AppendChar(a); process1.StartInfo.Password = password; process1.Start(); string output = process1.StandardOutput.ReadToEnd(); Console.WriteLine(output); process1.WaitForExit(); 

至于原始问题:

您需要将管道句柄设置为StartupInfo的stdOutput,stdError,stdInput字段。 Smth是这样的:

 StartupInfo startupInfo = new StartupInfo(); startupInfo.reserved = null; startupInfo.flags = STARTF_USESTDHANDLES; startupInfo.showWindow = SW_SHOW; ... SafeFileHandle inputHandle = null; SafeFileHandle outputHandle = null; SafeFileHandle errorHandle = null; CreatePipe(out inputHandle, out startupInfo.stdInput, true); CreatePipe(out outputHandle, out startupInfo.stdOutput, false); CreatePipe(out errorHandle, out startupInfo.stdError, false); 

下面是CreatePipe实现:

 public static void CreatePipe(out SafeFileHandle parentHandle, out SafeFileHandle childHandle, bool parentInputs) { SECURITY_ATTRIBUTES lpPipeAttributes = new SECURITY_ATTRIBUTES(); lpPipeAttributes.bInheritHandle = true; SafeFileHandle hWritePipe = null; try { if (parentInputs) CreatePipeWithSecurityAttributes(out childHandle, out hWritePipe, lpPipeAttributes, 0); else CreatePipeWithSecurityAttributes(out hWritePipe, out childHandle, lpPipeAttributes, 0); if (!DuplicateHandle(GetCurrentProcess(), hWritePipe, GetCurrentProcess(), out parentHandle, 0, false, 2)) throw new Exception(); } finally { if ((hWritePipe != null) && !hWritePipe.IsInvalid) { hWritePipe.Close(); } } } [StructLayout(LayoutKind.Sequential)] public class SECURITY_ATTRIBUTES { public int nLength; public IntPtr lpSecurityDescriptor; public bool bInheritHandle; public SECURITY_ATTRIBUTES() { nLength = 12; lpSecurityDescriptor = IntPtr.Zero; } } [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] public static extern bool CreatePipe(out SafeFileHandle hReadPipe, out SafeFileHandle hWritePipe, SECURITY_ATTRIBUTES lpPipeAttributes, int nSize); [DllImport("kernel32.dll", CharSet = CharSet.Ansi, SetLastError = true)] public static extern bool DuplicateHandle(IntPtr hSourceProcessHandle, SafeHandle hSourceHandle, IntPtr hTargetProcess, out SafeFileHandle targetHandle, int dwDesiredAccess, bool bInheritHandle, int dwOptions); [DllImport("kernel32.dll", CharSet = CharSet.Ansi, SetLastError = true)] public static extern IntPtr GetCurrentProcess(); public static void CreatePipeWithSecurityAttributes(out SafeFileHandle hReadPipe, out SafeFileHandle hWritePipe, SECURITY_ATTRIBUTES lpPipeAttributes, int nSize) { hReadPipe = null; if ((!CreatePipe(out hReadPipe, out hWritePipe, lpPipeAttributes, nSize) || hReadPipe.IsInvalid) || hWritePipe.IsInvalid) throw new Exception(); } 

完成创建管道并执行CreateProcessWithLogonW后,您可以从管道读取std输出:

 StreamWriter standardInput = new StreamWriter(new FileStream(inputHandle, FileAccess.Write, 0x1000, false), Console.InputEncoding, 0x1000); standardInput.AutoFlush = true; StreamReader reader = new StreamReader(new FileStream(outputHandle, FileAccess.Read, 0x1000, false), Console.OutputEncoding, true, 0x1000); StreamReader error = new StreamReader(new FileStream(errorHandle, FileAccess.Read, 0x1000, false), Console.OutputEncoding, true, 0x1000); while (!reader.EndOfStream) { string line = reader.ReadLine(); if (line.Length>0) Console.WriteLine(line); } 

上面的代码基本上是在Process类的StartWithCreateProcess方法中完成的

希望这会有所帮助,问候

为什么不使用Process.Start方法的以下重载?

这篇post为我解决了。 不是输出部分,而是我使CreateProcessWithLogonW工作。

http://blogs.msdn.com/alejacma/archive/2007/12/20/how-to-call-createprocesswithlogonw-createprocessasuser-in-net.aspx