Example #1
0
        /// <summary>
        /// Runs a command.
        /// </summary>
        /// <param name="commandFilePath">The command file path.</param>
        /// <param name="commandArguments">The command arguments.</param>
        /// <param name="workingDirectory">The working directory.</param>
        /// <param name="waitForExit">if set to <c>true</c> wait for exit.</param>
        /// <returns>The launched process.</returns>
        /// <exception cref="Exception">Create Process failed.</exception>
        /// <exception cref="Win32Exception">Creation of the process failed.</exception>
        public Process RunCommand(string commandFilePath, string commandArguments, string workingDirectory, bool waitForExit)
        {
            IntPtr token      = new IntPtr(0);
            IntPtr dupedToken = new IntPtr(0);
            bool   ret;

            SECURITY_ATTRIBUTES sa = new SECURITY_ATTRIBUTES();

            sa.bInheritHandle       = false;
            sa.Length               = Marshal.SizeOf(sa);
            sa.lpSecurityDescriptor = (IntPtr)0;

            token = WindowsIdentity.GetCurrent().Token;

            const int SecurityImpersonation = 2;
            const int TokenType             = 1;

            ret = NativeMethods.DuplicateTokenEx(token, (int)TokenAccessRights.AssignPrimary | (int)TokenAccessRights.Duplicate | (int)TokenAccessRights.Query, ref sa, SecurityImpersonation, TokenType, ref dupedToken);

            if (ret == false)
            {
                //NativeMethods.CloseHandle(token);
                NativeMethods.CloseHandle(dupedToken);

                throw new Exception(Marshal.GetLastWin32Error().ToString());
            }

            // Load Profile
            PROFILEINFO pri = new PROFILEINFO();

            pri.dwSize     = Marshal.SizeOf(pri);
            pri.lpUserName = _userName;
            pri.dwFlags    = 1;
            if (!NativeMethods.LoadUserProfile(dupedToken, ref pri) && pri.hProfile == IntPtr.Zero)
            {
                NativeMethods.CloseHandle(dupedToken);
                throw new Exception(Marshal.GetLastWin32Error().ToString());
            }

            // Process Information
            PROCESS_INFORMATION pi = new PROCESS_INFORMATION();

            // Startup Information
            STARTUPINFO si = new STARTUPINFO();

            si.cb = Marshal.SizeOf(si);

            //if this member is NULL, the new process inherits the desktop
            //and window station of its parent process. If this member is
            //an empty string, the process does not inherit the desktop and
            //window station of its parent process; instead, the system
            //determines if a new desktop and window station need to be created.
            //If the impersonated user already has a desktop, the system uses the
            //existing desktop.
            si.lpDesktop = null;
            //si.lpDesktop = "";

            //si.lpDesktop = @"WinSta0\Default"; //Modify as needed
            //si.dwFlags = (uint)STARTF.STARTF_USESHOWWINDOW | (uint)STARTF.STARTF_FORCEONFEEDBACK;
            //si.wShowWindow = (short)ShowWindowCommands.SW_HIDE;

            IntPtr environmentBlock = IntPtr.Zero;

            try
            {
                ret = NativeMethods.CreateEnvironmentBlock(ref environmentBlock, token, false);
                if (ret)
                {
                    ret = NativeMethods.CreateProcessAsUser(dupedToken, commandFilePath, commandArguments, ref sa, ref sa, false, (int)CREATE_PROCESS_FLAGS.CREATE_UNICODE_ENVIRONMENT, environmentBlock, workingDirectory, ref si, out pi);
                }
            }
            finally
            {
                if (environmentBlock != IntPtr.Zero)
                {
                    NativeMethods.DestroyEnvironmentBlock(environmentBlock);
                }
            }

            Process p = null;

            if (!ret)
            {
                throw (new Win32Exception("Creation of the process failed with " + Marshal.GetLastWin32Error()));
            }
            else
            {
                try
                {
                    p = Process.GetProcessById((int)pi.dwProcessId);
                    if (waitForExit)
                    {
                        p.WaitForExit();
                    }
                }
                catch
                {
                }
                NativeMethods.CloseHandle(pi.hProcess);
                NativeMethods.CloseHandle(pi.hThread);
            }

            NativeMethods.UnloadUserProfile(token, pri.hProfile);
            //NativeMethods.CloseHandle(token);
            ret = NativeMethods.CloseHandle(dupedToken);
            if (ret == false)
            {
                throw (new Exception(Marshal.GetLastWin32Error().ToString()));
            }

            return(p);
        }
 // This is called by AppDomain.GetThreadPrincipal() via reflection.
 private static IPrincipal GetDefaultInstance() => new WindowsPrincipal(WindowsIdentity.GetCurrent());