private static void EnsureUserSession(int pid, string[] argv) { if (WindowsIdentity.GetCurrent().IsSystem) { uint targetSessionID = uint.MaxValue; IntPtr userToken = IntPtr.Zero; // Retrieves the target process Session ID try { using (Process srcPr = Process.GetProcessById(pid)) { targetSessionID = (uint)srcPr.SessionId; } } catch (ArgumentException) { LogHelper.Warning("Unable to retrieve the target process SessionID. Process may have already exited."); targetSessionID = uint.MaxValue; } // If the target Session ID is still unknown or if it belongs to SYSTEM, or the session doesn't work, the currently active session is retrieved. if (targetSessionID == uint.MaxValue || targetSessionID == 0 || (!CommonHelper.WTSQueryUserToken(targetSessionID, ref userToken))) { targetSessionID = CommonHelper.WTSGetActiveConsoleSessionId(); if (targetSessionID == 0xFFFFFFFF) { throw new Exception("No active session found. Aborting."); } // If the active Session ID is still a SYSTEM one, cannot continue. if (targetSessionID == 0) { throw new Exception("WFN can not start in the SYSTEM session."); } // Because the target Session ID is found, impersonation can take place. if (!CommonHelper.WTSQueryUserToken(targetSessionID, ref userToken)) { throw new Win32Exception(Marshal.GetLastWin32Error(), "Unable to retrieve the current user token."); } } try { string argstr = String.Join(" ", argv.Select(a => a.Contains(" ") ? "\"" + a + "\"" : a).ToArray()) + " -impersonated 1"; LogHelper.Debug("Impersonating. Parameters: " + argstr); Impersonation.LaunchProcessAsUser(Process.GetCurrentProcess().MainModule.FileName, argstr, userToken); } finally { CloseHandle(userToken); } Environment.Exit(0); } }