gpt4 book ai didi

c# - 将 createprocessasuser 的 stdout 重定向到管道在读取时挂起

转载 作者:行者123 更新时间:2023-12-03 17:48:27 26 4
gpt4 key购买 nike

我正在使用 CreateProcessAsUser 从服务运行进程,并将标准输出重定向到命名管道。但是当我尝试从命名管道中读取时,它会卡在读取上并且永远不会返回。
我在一个单独的任务中尝试了这个(目前在下面实现)并且只是在主进程中读取它。我还尝试使用 C# AnonymousPipeServerStream 类(请参阅下面注释掉的代码),但同样挂起。

任何想法我缺少什么?谢谢!

            Native.SECURITY_ATTRIBUTES sa = new Native.SECURITY_ATTRIBUTES();
processAttributes.nLength = Marshal.SizeOf(sa);
processAttributes.lpSecurityDescriptor = IntPtr.Zero;
processAttributes.bInheritHandle = 0;

//AnonymousPipeServerStream pipeServer = new AnonymousPipeServerStream(PipeDirection.In, HandleInheritability.Inheritable);
IntPtr readPipe = IntPtr.Zero;
IntPtr subProcessPipe = IntPtr.Zero;
if(!Native.CreatePipe(out readPipe, out subProcessPipe,ref sa, 0x0001))
{
throw new Exception("createpipe gave error: " + Marshal.GetLastWin32Error());
}

log.InfoFormat("pipe created");

Task readPipeTask = Task.Factory.StartNew(() =>
{
log.InfoFormat("startingtask");
var readBuff = new byte[BufferSize];
uint bytesRead = 0;
bool retval;
while (true)
{
retval = Native.ReadFile(readPipe, readBuff, BufferSize, out bytesRead, IntPtr.Zero);
if (!retval || bytesRead == 0)
{
log.InfoFormat("finalread {0} {1}", retval, bytesRead);
break;
}
log.InfoFormat("after read {0} {1}", retval, bytesRead);
}
log.InfoFormat("endingtask");
});

var processInfo = new Native.ProcessInformation();
var startInfo = new Native.StartupInfo();
startInfo.Size = Marshal.SizeOf(startInfo);
//startInfo.StdOutput = pipeServer.SafePipeHandle.DangerousGetHandle();
startInfo.StdOutput = subProcessPipe;
log.InfoFormat("calling createprocess");
if (!Native.CreateProcessAsUser(
UserTokenHandle,
null,
command,
IntPtr.Zero,
IntPtr.Zero,
false,
0x00000020 | 0x00000010 | 0x00000400,

IntPtr.Zero,
null,
ref startInfo,
out processInfo))
{
throw new Exception("Create process didn't work : " + Marshal.GetLastWin32Error());
}

log.InfoFormat("process id = {0}", processInfo.ProcessId);
int processId = processInfo.ProcessId;


using (var process = Process.GetProcessById(processId))
{
var pid = process.Id;
log.Info("process started : " + pid);

process.WaitForExit(ProcessTimeoutIteration);
log.Info("process Completed");
readPipeTask.Wait();
log.Info("process Completedafter wait");
}
////log.Info("reading pipe canread = " + pipeServer.CanRead);
////log.Info("reading pipe isconnected = " + pipeServer.IsConnected);

var standardOutput = new StringBuilder(InitialBufferSize);

//////var readBuff = new byte[BufferSize];

//var ac = new AsyncCallback(CallBackMethod);
////var bytesRead = pipeServer.Read(readBuff, 0, BufferSize);

log.Info("before first read");
////while (bytesRead > 0)
////{
//// //fileStream.Write(readBuff, 0, bytesRead);
//// standardOutput.Append(Encoding.Unicode.GetString(readBuff));
//// bytesRead = pipeServer.Read(readBuff, 0, BufferSize);
////}

最佳答案

原因很明显:

if (!Native.CreateProcessAsUser(
UserTokenHandle,
null,
command,
IntPtr.Zero,
IntPtr.Zero,
false,
0x00000020 | 0x00000010 | 0x00000400,

您不会通过设置 bInheritHandles 来继承句柄为假。

关于c# - 将 createprocessasuser 的 stdout 重定向到管道在读取时挂起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27642419/

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