public static void ForEachProcessInfo(ITerminalServerHandle server, ListProcessInfosCallback callback) { IntPtr ppProcessInfo; int count; if (NativeMethods.WTSEnumerateProcesses(server.Handle, 0, 1, out ppProcessInfo, out count) == 0) { throw new Win32Exception(); } try { var processInfos = PtrToStructureList <WTS_PROCESS_INFO>(ppProcessInfo, count); foreach (WTS_PROCESS_INFO processInfo in processInfos) { if (processInfo.ProcessId != 0) { callback(processInfo); } } } finally { if (ppProcessInfo != IntPtr.Zero) { NativeMethods.WTSFreeMemory(ppProcessInfo); ppProcessInfo = IntPtr.Zero; } } }
public static void ForEachProcessInfo(ITerminalServerHandle server, ListProcessInfosCallback callback) { IntPtr ppProcessInfo; int count; if (NativeMethods.WTSEnumerateProcesses(server.Handle, 0, 1, out ppProcessInfo, out count) == 0) { throw new Win32Exception(); } try { // We can't just return a list of WTS_PROCESS_INFOs because those have pointers to // SIDs that have to be copied into managed memory first. So we use a callback instead. IList <WTS_PROCESS_INFO> processInfos = PtrToStructureList <WTS_PROCESS_INFO>(ppProcessInfo, count); foreach (WTS_PROCESS_INFO processInfo in processInfos) { // It seems that WTSEnumerateProcesses likes to return an empty struct in the first // element of the array, so we ignore that here. // TODO: Find out why this happens. if (processInfo.ProcessId != 0) { callback(processInfo); } } } finally { NativeMethods.WTSFreeMemory(ppProcessInfo); } }