[DllImport("kernel32.dll", SetLastError=true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool UpdateProcThreadAttribute(
IntPtr lpAttributeList,
uint dwFlags,
IntPtr Attribute,
IntPtr lpValue,
IntPtr cbSize,
IntPtr lpPreviousValue,
IntPtr lpReturnSize);
Declare Function UpdateProcThreadAttribute Lib "kernel32.dll" (TODO) As TODO
(WinBase.h)
...
PROC_THREAD_ATTRIBUTE_PARENT_PROCESS = 0x00020000,
PROC_THREAD_ATTRIBUTE_HANDLE_LIST = 0x00020002
...
and [STARTUPINFOEX]
Do you know one? Please contribute it!
Call InitializeProcThreadAttributeList before adding attributes. Save the result to a STARTUPINFOEX struct.
Please add some!
NOTE : You need to use DeleteProcThreadAttribute and free memory. These samples do neither!
private static void SetNewProcessParent(ref STARTUPINFOEX startupInfoEx, int parentProcessId)
{
const int reserved = 0;
var parentProcess = Process.GetProcessById(parentProcessId);
IntPtr lpValue = Marshal.AllocHGlobal(IntPtr.Size);
Marshal.WriteIntPtr(lpValue, parentProcess.Handle);
bool hasError = UpdateProcThreadAttribute(
startupInfoEx.lpAttributeList,
reserved,
PROC_THREAD_ATTRIBUTE_PARENT_PROCESS,
lpValue,
(IntPtr)IntPtr.Size,
IntPtr.Zero,
IntPtr.Zero);
if (hasError)
{
throw new Exception(string.Format("Error setting [{0}] as the parentPid for the new process", parentProcessId));
}
}
private static void SetInheritableHandles(ref STARTUPINFOEX startupInfoEx, ICollection<IntPtr> inheritableHandles)
{
const int reserved = 0;
var handleArray = inheritableHandles.ToArray();
var pinnedHandleArray = GCHandle.Alloc(handleArray, GCHandleType.Pinned);
IntPtr handles = pinnedHandleArray.AddrOfPinnedObject();
bool success = UpdateProcThreadAttribute(
startupInfoEx.lpAttributeList,
reserved,
PROC_THREAD_ATTRIBUTE_HANDLE_LIST,
handles,
(IntPtr)(inheritableHandles.Count * IntPtr.Size),
IntPtr.Zero,
IntPtr.Zero);
if (!success)
{
throw new Exception("Error adding inheritable handles to process launch");
}
}