gpt4 book ai didi

c# - 如何从 CreateProcessWithLogonW 获得标准输出?

转载 作者:太空宇宙 更新时间:2023-11-03 20:42:35 26 4
gpt4 key购买 nike

我正在使用来自 http://www.pinvoke.net/default.aspx/advapi32.createprocesswithlogonw 的代码.如何从标准输出中获取字符串形式的输出?喜欢在命令窗口中以交互方式运行它时显示的内容吗?

最佳答案

使用重定向的标准输入\输出\错误线程调用 CreateProcessWithLogonW 与使用指定了 user\domain\password 字段的 System.Diagnostics.Process 类执行下面的代码相同,并且重定向* 字段设置为真。事实上,通过使用反射器查看 Process 类的 StartWithCreateProcess 私有(private)方法,您会发现如果应用上述条件,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 后,您可以从管道读取标准输出:

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

希望这对你有帮助,问候

关于c# - 如何从 CreateProcessWithLogonW 获得标准输出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1973376/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com