171 lines
5.8 KiB
C#
171 lines
5.8 KiB
C#
using System;
|
|
using System.Diagnostics;
|
|
using System.IO;
|
|
using System.Runtime.InteropServices;
|
|
|
|
namespace ZC;
|
|
|
|
public class ProcessCreator
|
|
{
|
|
[DllImport("kernel32.dll")]
|
|
[return: MarshalAs(UnmanagedType.Bool)]
|
|
static extern bool CreateProcess(
|
|
string lpApplicationName, string lpCommandLine, ref SECURITY_ATTRIBUTES lpProcessAttributes,
|
|
ref SECURITY_ATTRIBUTES lpThreadAttributes, bool bInheritHandles, uint dwCreationFlags,
|
|
IntPtr lpEnvironment, string lpCurrentDirectory, [In] ref STARTUPINFOEX lpStartupInfo,
|
|
out PROCESS_INFORMATION lpProcessInformation);
|
|
|
|
[DllImport("kernel32.dll", SetLastError = true)]
|
|
[return: MarshalAs(UnmanagedType.Bool)]
|
|
private static extern bool UpdateProcThreadAttribute(
|
|
out IntPtr lpAttributeList, uint dwFlags, IntPtr Attribute, IntPtr lpValue,
|
|
IntPtr cbSize, IntPtr lpPreviousValue, IntPtr lpReturnSize);
|
|
|
|
[DllImport("kernel32.dll", SetLastError = true)]
|
|
[return: MarshalAs(UnmanagedType.Bool)]
|
|
private static extern bool InitializeProcThreadAttributeList(
|
|
out IntPtr lpAttributeList, int dwAttributeCount, int dwFlags, ref IntPtr lpSize);
|
|
|
|
public static bool CreateProcess(int parentProcessId,out PROCESS_INFORMATION pInfo)
|
|
{
|
|
const uint EXTENDED_STARTUPINFO_PRESENT = 0x00080000;
|
|
const int PROC_THREAD_ATTRIBUTE_PARENT_PROCESS = 0x00020000;
|
|
|
|
pInfo = new PROCESS_INFORMATION();
|
|
var sInfoEx = new STARTUPINFOEX();
|
|
var securityAttributes = new SECURITY_ATTRIBUTES();
|
|
securityAttributes.nLength = 1;
|
|
sInfoEx.StartupInfo = new STARTUPINFO();
|
|
var input = CreateFile("./inputfile1", DesiredAccess.GENERIC_READ, 0, ref securityAttributes,
|
|
CreationDisposition.OPEN_EXISTING, 0, IntPtr.Zero);
|
|
|
|
var output = CreateFile("./test.log", DesiredAccess.GENERIC_WRITE, 0, ref securityAttributes,
|
|
CreationDisposition.CREATE_NEW, 0, IntPtr.Zero);
|
|
|
|
sInfoEx.StartupInfo.hStdInput = input;
|
|
sInfoEx.StartupInfo.hStdOutput = output;
|
|
sInfoEx.StartupInfo.hStdError = output;
|
|
sInfoEx.StartupInfo.wShowWindow = 0;
|
|
|
|
if (parentProcessId > 0)
|
|
{
|
|
var lpSize = IntPtr.Zero;
|
|
IntPtr dummyPtr;
|
|
var success = InitializeProcThreadAttributeList(out dummyPtr, 1, 0, ref lpSize);
|
|
if (success || lpSize == IntPtr.Zero)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
sInfoEx.lpAttributeList = Marshal.AllocHGlobal(lpSize);
|
|
if (sInfoEx.lpAttributeList == IntPtr.Zero)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
success = InitializeProcThreadAttributeList(out sInfoEx.lpAttributeList, 1, 0, ref lpSize);
|
|
if (!success)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
var parentHandle = Process.GetProcessById(parentProcessId).Handle;
|
|
success = UpdateProcThreadAttribute(
|
|
out sInfoEx.lpAttributeList,
|
|
0,
|
|
(IntPtr)PROC_THREAD_ATTRIBUTE_PARENT_PROCESS,
|
|
parentHandle,
|
|
(IntPtr)IntPtr.Size,
|
|
IntPtr.Zero,
|
|
IntPtr.Zero);
|
|
if (!success)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
sInfoEx.StartupInfo.cb = Marshal.SizeOf(sInfoEx);
|
|
}
|
|
|
|
|
|
var pSec = new SECURITY_ATTRIBUTES();
|
|
var tSec = new SECURITY_ATTRIBUTES();
|
|
pSec.nLength = Marshal.SizeOf(pSec);
|
|
tSec.nLength = Marshal.SizeOf(tSec);
|
|
var lpApplicationName = Path.Combine(Environment.SystemDirectory, "notepad.exe");
|
|
return CreateProcess(lpApplicationName,
|
|
null,
|
|
ref pSec,
|
|
ref tSec,
|
|
false,
|
|
EXTENDED_STARTUPINFO_PRESENT,
|
|
IntPtr.Zero,
|
|
null,
|
|
ref sInfoEx,
|
|
out pInfo);
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
|
|
struct STARTUPINFOEX
|
|
{
|
|
public STARTUPINFO StartupInfo;
|
|
public IntPtr lpAttributeList;
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
|
|
struct STARTUPINFO
|
|
{
|
|
public Int32 cb;
|
|
public string lpReserved;
|
|
public string lpDesktop;
|
|
public string lpTitle;
|
|
public Int32 dwX;
|
|
public Int32 dwY;
|
|
public Int32 dwXSize;
|
|
public Int32 dwYSize;
|
|
public Int32 dwXCountChars;
|
|
public Int32 dwYCountChars;
|
|
public Int32 dwFillAttribute;
|
|
public Int32 dwFlags;
|
|
public Int16 wShowWindow;
|
|
public Int16 cbReserved2;
|
|
public IntPtr lpReserved2;
|
|
public IntPtr hStdInput;
|
|
public IntPtr hStdOutput;
|
|
public IntPtr hStdError;
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
public struct PROCESS_INFORMATION
|
|
{
|
|
public IntPtr hProcess;
|
|
public IntPtr hThread;
|
|
public int dwProcessId;
|
|
public int dwThreadId;
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
public struct SECURITY_ATTRIBUTES
|
|
{
|
|
public int nLength;
|
|
public IntPtr lpSecurityDescriptor;
|
|
public int bInheritHandle;
|
|
}
|
|
[DllImport("kernel32.dll")]
|
|
public static extern bool CloseHandle(IntPtr hObject);
|
|
[DllImport("kernel32.dll", SetLastError = true)]
|
|
public static extern IntPtr CreateFile(string lpFileName, DesiredAccess dwDesiredAccess, uint dwShareMode, ref SECURITY_ATTRIBUTES lpSecurityAttributes, CreationDisposition dwCreationDisposition, uint dwFlagsAndAttributes, IntPtr hTemplateFile);
|
|
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
|
|
}
|
|
} |