2009-12-29 138 views

回答

2

你为什么不使用Process.Start Method以下过载?

+0

它没有为我工作。我碰到一个“应用程序未能正确初始化”看到相关的问题:http://stackoverflow.com/questions/1972649/help-with-using-createprocesswithlogonw-in-c/1972860#1972860 – 2009-12-29 17:43:40

2

主叫CreateProcessWithLogonW与重定向STD输入\输出\错误线程是相同于执行以下,使用的System.Diagnostics.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领域。水木清华这样的:

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方法完成

希望这会有所帮助,至于

相关问题