使用Windows服务中的凭据启动进程
我有一个以mydomain \
userA身份运行的Windows服务。我希望能够从该服务运行任意.exe。通常,我使用Process.Start()并且它可以正常工作,但是在某些情况下,我想以其他用户(mydomain
\ userB)的身份运行可执行文件。
如果更改了用于启动过程以包括凭据的ProcessStartInfo,则会开始出现错误-
一个错误对话框,提示“应用程序无法正确初始化(0xc0000142)。单击OK终止应用程序。”或“访问被拒绝”
Win32Exception。如果我从命令行运行流程启动代码而不是在服务中运行它,则该流程将开始使用正确的凭据(我已通过将ProcessStartInfo设置为运行whoami.exe并捕获命令行输出来验证了这一点。
)。
我还尝试使用WindowsIdentity.Impersonate()模拟,但这没有用-
据我了解,模拟仅会影响当前线程,而启动新进程将继承该进程的安全描述符,而不继承当前线程。
我在一个隔离的测试域中运行它,因此userA和userB都是域管理员,并且都具有域范围内的“登录即服务”权限。
回答:
使用ProcessStartInfo启动新进程时,该进程在与启动进程相同的窗口站和桌面中启动。如果您使用不同的凭据,则用户通常将没有足够的权限在该桌面上运行。初始化错误失败是由于user32.dll尝试在新进程中进行初始化而无法进行的。
要解决此问题,您必须首先检索与Window Station和桌面相关联的安全描述符,并为用户添加适当的权限到DACL,然后在新的凭据下启动进程。
编辑:关于如何执行此操作和示例代码的详细说明在这里有点长了,所以我整理了一篇代码文章。
//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))
{
}
以上是 使用Windows服务中的凭据启动进程 的全部内容, 来源链接: utcz.com/qa/409713.html