예제 #1
0
 public static extern bool CreateProcessAsUserW(
     IntPtr hToken,
     string lpApplicationName,
     string lpCommandLine,
     IntPtr lpProcessAttributes,
     IntPtr lpThreadAttributes,
     bool bInheritHandles,
     Windows_h.CreationFlags dwCreationFlags,
     IntPtr lpEnvironment,
     string lpCurrentDirectory,
     ref Windows_h.STARTUPINFO lpStartupInfo,
     out Windows_h.PROCESS_INFORMATION lpProcessInformation);
예제 #2
0
        public static Process RunAsDesktopUser(string path, string args)
        {
            int lastError;
            IntPtr shellWindow = User32.GetShellWindow();

            if (shellWindow == IntPtr.Zero)
            {
                throw new InvalidOperationException("Unable to get shell window.");
            }

            uint processID = 0;
            User32.GetWindowThreadProcessId(shellWindow, out processID);
            if (processID == 0)
            {
                lastError = System.Runtime.InteropServices.Marshal.GetLastWin32Error();
                throw new Win32Exception(lastError);
            }

            IntPtr processHandle = Kernel32.OpenProcess(Windows_h.ProcessAccessFlags.QueryInformation, true, processID);

            if (processHandle == IntPtr.Zero)
            {
                lastError = System.Runtime.InteropServices.Marshal.GetLastWin32Error();
                throw new Win32Exception(lastError);
            }

            IntPtr shellProcessToken;

            Windows_h.TokenAccessFlags tokenAccess = Windows_h.TokenAccessFlags.TOKEN_QUERY | Windows_h.TokenAccessFlags.TOKEN_ASSIGN_PRIMARY |
                Windows_h.TokenAccessFlags.TOKEN_DUPLICATE | Windows_h.TokenAccessFlags.TOKEN_ADJUST_DEFAULT |
                Windows_h.TokenAccessFlags.TOKEN_ADJUST_SESSIONID;

            if (!Advapi32.OpenProcessToken(processHandle, tokenAccess, out shellProcessToken))
            {
                lastError = System.Runtime.InteropServices.Marshal.GetLastWin32Error();
                throw new Win32Exception(lastError);
            }

            IntPtr newPrimaryToken;

            if (!Advapi32.DuplicateTokenEx(shellProcessToken, tokenAccess, IntPtr.Zero,
                Windows_h.SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation, Windows_h.TOKEN_TYPE.TokenPrimary, out newPrimaryToken))
            {
                lastError = System.Runtime.InteropServices.Marshal.GetLastWin32Error();
                throw new Win32Exception(lastError);
            }

            Windows_h.STARTUPINFO startupInfo = new Windows_h.STARTUPINFO();
            startupInfo.cb = System.Runtime.InteropServices.Marshal.SizeOf(startupInfo);
            startupInfo.lpDesktop = "";

            Windows_h.PROCESS_INFORMATION processInfo = new Windows_h.PROCESS_INFORMATION();

            if (!Advapi32.CreateProcessAsUserW(newPrimaryToken, path, path + " " + args, IntPtr.Zero, IntPtr.Zero, false, 0,
                IntPtr.Zero, null, ref startupInfo, out processInfo))
            {
                lastError = System.Runtime.InteropServices.Marshal.GetLastWin32Error();
                throw new Win32Exception(lastError);
            }

            Kernel32.CloseHandle(processInfo.hProcess);
            Kernel32.CloseHandle(processInfo.hThread);

            return Process.GetProcessById(processInfo.dwProcessId);
        }