Starting a process with credentials from a Windows Service

后端 未结 8 1612
情话喂你
情话喂你 2020-11-27 05:42

I have a Windows service that runs as mydomain\\userA. I want to be able to run arbitrary .exes from the service. Normally, I use Process.Start() and it works fine, but in s

8条回答
  •  误落风尘
    2020-11-27 06:22

    When you launch a new process using ProcessStartInfo the process is started in the same window station and desktop as the launching process. If you are using different credentials then the user will, in general, not have sufficient rights to run in that desktop. The failure to initialize errors are caused when user32.dll attempts to initialize in the new process and can't.

    To get around this you must first retrieve the security descriptors associated with the window station and desktop and add the appropriate permissions to the DACL for your user, then launch your process under the new credentials.

    EDIT: A detailed description on how to do this and sample code was a little long for here so I put together an article with code.

            //The following security adjustments are necessary to give the new 
            //process sufficient permission to run in the service's window station
            //and desktop. This uses classes from the AsproLock library also from 
            //Asprosys.
            IntPtr hWinSta = GetProcessWindowStation();
            WindowStationSecurity ws = new WindowStationSecurity(hWinSta,
              System.Security.AccessControl.AccessControlSections.Access);
            ws.AddAccessRule(new WindowStationAccessRule("LaunchProcessUser",
                WindowStationRights.AllAccess, System.Security.AccessControl.AccessControlType.Allow));
            ws.AcceptChanges();
    
            IntPtr hDesk = GetThreadDesktop(GetCurrentThreadId());
            DesktopSecurity ds = new DesktopSecurity(hDesk,
                System.Security.AccessControl.AccessControlSections.Access);
            ds.AddAccessRule(new DesktopAccessRule("LaunchProcessUser",
                DesktopRights.AllAccess, System.Security.AccessControl.AccessControlType.Allow));
            ds.AcceptChanges();
    
            EventLog.WriteEntry("Launching application.", EventLogEntryType.Information);
    
            using (Process process = Process.Start(psi))
            {
            }
    

提交回复
热议问题