我使用this answer中的示例代码。它有效。
但我需要将标准输入/输出重定向到文件中。 流程启动信息结构包含字段:
public IntPtr hStdInput;
public IntPtr hStdOutput;
public IntPtr hStdError;
我试过这样的事情:
StartupInfo startupInfo = new StartupInfo();
startupInfo.cb = Marshal.SizeOf((object)startupInfo);
startupInfo.dwFlags = 128;
FileStream fs = new FileStream(filePath, FileMode.Open);
startupInfo.hStdInput = fs.Handle;
它不起作用。
如何将文件作为标准输入/输出传递?
UPD1
如何调用CreateProccess:
StartupInfo startupInfo = new StartupInfo();
startupInfo.cb = Marshal.SizeOf((object)startupInfo);
startupInfo.dwFlags = 128;
FileStream fs = new FileStream(filePath, FileMode.Open);
startupInfo.hStdInput = fs.Handle;
Pinvoke.SetErrorMode(ErrorModes.SEM_FAILCRITICALERRORS | ErrorModes.SEM_NOALIGNMENTFAULTEXCEPT | ErrorModes.SEM_NOGPFAULTERRORBOX | ErrorModes.SEM_NOOPENFILEERRORBOX);
CreationFlags dwCreationFlags = CreationFlags.CREATE_BREAKAWAY_FROM_JOB | CreationFlags.CREATE_SUSPENDED | CreationFlags.CREATE_SEPARATE_WOW_VDM;
SecurityAttributes securityAttributes = new SecurityAttributes();
securityAttributes.bInheritHandle = 1;
ProcessInformation pi;
if (!Pinvoke.CreateProcess(null, configuration.RunString, ref securityAttributes, ref securityAttributes, boolInheritHandles: true, dwCreationFlags: dwCreationFlags, lpEnvironment: IntPtr.Zero, lpszCurrentDir: configuration.Directory, startupInfo: ref startupInfo, pi: out pi))
throw new Win32Exception(Marshal.GetLastWin32Error());
UPD2 即可。
我添加了SetHandleInformation
来电,但没有帮助:
FileStream fs = new FileStream(@"C:\input.txt", FileMode.Open, FileAccess.Read);
Pinvoke.SetHandleInformation(fs.Handle, 0x00000001, 0x00000001);
startupInfo.hStdInput = fs.Handle;
答案 0 :(得分:0)
基于评论。
startupInfo.dwFlags
设为0x00000100
添加新功能CreateFile
:
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr CreateFile(string lpFileName, DesiredAccess dwDesiredAccess, uint dwShareMode, ref SecurityAttributes lpSecurityAttributes, CreationDisposition dwCreationDisposition, uint dwFlagsAndAttributes, IntPtr hTemplateFile);
创建输入/输出处理程序:
var input = Pinvoke.CreateFile(inputFile, DesiredAccess.GENERIC_READ, 0, ref securityAttributes,
CreationDisposition.OPEN_EXISTING, 0, IntPtr.Zero);
var output = Pinvoke.CreateFile(outputFile, DesiredAccess.GENERIC_WRITE, 0, ref securityAttributes,
CreationDisposition.CREATE_NEW, 0, IntPtr.Zero);
startupInfo.hStdInput = input;
startupInfo.hStdOutput = output;
...
public enum DesiredAccess : uint
{
GENERIC_WRITE = 30,
GENERIC_READ = 31
}
public enum CreationDisposition : uint
{
CREATE_NEW = 1,
CREATE_ALWAYS = 2,
OPEN_EXISTING = 3,
OPEN_ALWAYS = 4,
TRUNCATE_EXISTING = 5
}