Kiq*_*net 2 c# wcf credentials process network-service
我在 IIS 中托管了 Wcf 服务,Windows Server 2008 R2,使用带有 NETWORK SERVICE Identity 的 AppPool .NET 4.0。
我的 Wcf 服务有一个使用 Process.Start 调用命令 EXE 的方法。
我需要使用不同的用户作为执行命令 EXE(域用户帐户)的凭据。
我尝试执行它,但它对我不起作用:它似乎没有执行命令 EXE。
更新:进程退出,但不执行代码
我收到如下错误:
退出代码 -1073741502
和 eventvwr:
Process Information:
Process ID: 0xc50
Process Name: C:\DeployTools\DeployTools.Commands.Ejecutar.exe
Exit Status: 0xc0000142
Run Code Online (Sandbox Code Playgroud)
应用程序无法正确启动 (0xC0000142)。单击确定关闭应用程序
有什么建议?
代码:
StreamReader sr = null;
StreamReader serr = null;
try
{
var psi = new ProcessStartInfo(MY_COMMAND_EXE);
psi.WorkingDirectory = Path.GetDirectoryName(MY_COMMAND_EXE);
psi.Arguments = arguments;
psi.Domain = DOMAIN;
psi.UserName = USER_IN_DOMAIN;
psi.Password = SecureStringHelper.ToSecureString(pwd);
psi.LoadUserProfile = true;
psi.UseShellExecute = false;
psi.ErrorDialog = false;
psi.RedirectStandardOutput = true;
psi.RedirectStandardInput = true;
psi.RedirectStandardError = true;
psi.CreateNoWindow = true;
psi.WindowStyle = ProcessWindowStyle.Minimized;
using (Process pr = Process.Start(psi))
{
sr = pr.StandardOutput;
serr = pr.StandardError;
if (!pr.HasExited)
{
pr.WaitForExit(300000);
}
output = pr.StandardOutput.ReadToEnd();
errors = pr.StandardError.ReadToEnd();
exitCode = pr.ExitCode;
return output;
}
}
catch (Exception exc)
{
return "EXCEPCIÓN: " + exc.Message;
}
finally
{
if (sr != null)
{
sr.Close();
sr.Dispose();
sr = null;
}
if (serr != null)
{
serr.Close();
serr.Dispose();
serr = null;
}
}
Run Code Online (Sandbox Code Playgroud)
我必须添加对AsproLock.dll和相关代码的引用,以允许用户帐户访问正在运行的资源。
//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 = NativeMethods.GetProcessWindowStation();
WindowStationSecurity ws = new WindowStationSecurity(hWinSta,
System.Security.AccessControl.AccessControlSections.Access);
ws.AddAccessRule(new WindowStationAccessRule(userPassDto.Usuario,
WindowStationRights.AllAccess, System.Security.AccessControl.AccessControlType.Allow));
ws.AcceptChanges();
IntPtr hDesk = NativeMethods.GetThreadDesktop(NativeMethods.GetCurrentThreadId());
DesktopSecurity ds = new DesktopSecurity(hDesk,
System.Security.AccessControl.AccessControlSections.Access);
ds.AddAccessRule(new DesktopAccessRule(userPassDto.Usuario,
DesktopRights.AllAccess, System.Security.AccessControl.AccessControlType.Allow));
ds.AcceptChanges();
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr GetProcessWindowStation();
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr GetThreadDesktop(int dwThreadId);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern int GetCurrentThreadId();
Run Code Online (Sandbox Code Playgroud)
Asprosys 在新凭证下启动流程的风险和陷阱
这不是一个常见的需求,但也不是那么罕见,所以我认为我最好发布这个分步指南,以解决在模拟凭据下启动进程的问题。这是基于使用 .Net Process 类的 Start 方法,但它也适用于底层 API 调用:CreateProcessWithLogonW 和 CreateProcessWithTokenW。
访问被拒绝- 第一次尝试和访问被拒绝异常立即发生。这是最常见的初始问题,是由服务在 LOCAL SYSTEM 帐户下运行的事实引起的。奇怪的是,SYSTEM 帐户是计算机上最强大的帐户,但它不能做的少数事情之一是使用 CreateProcessWithLogonW 启动进程,它是调用 Process.Start 的基础 API。因此,将您的服务帐户更改为本地服务,无论如何它可能是更合适的帐户。
再次拒绝访问- 啊,我以为我们解决了这个问题。糟糕,请仔细检查您尝试启动的应用程序的权限。请记住,系统尝试以运行该进程的用户帐户而不是服务帐户的身份访问应用程序文件。
无效的目录错误- 什么?所有路径都是正确的。所有目录拼写正确,没有无效字符。这是一个令人难以置信的令人讨厌的错误并且不是很一致。通常,当我们运行一个进程时,我们不会费心设置 WorkingDirectory 属性,而只接受来自父进程的默认值。当使用新凭据启动进程时,您不能这样做,您必须显式设置 WorkingDirectory 的路径,否则您将得到“目录名称无效”。Win32 异常。
失败:没有错误?- Process.Start 可以很好地为您处理新进程的环境块的创建。因此,仅当您使用底层 API 时,这才是一个问题。当调用 CreateProcess* API 之一时,将 lpEnvironment 参数保留为 NULL 并让系统使用从父进程复制块的默认设置是正常的。但是在新凭据下启动时,您必须手动或使用 CreateEnvironmentBlock 显式创建环境块。更糟糕的是,如果您忽略这一点, CreateProcess* 调用将失败,但 GetLastError 将返回 ERROR_SUCCESS,如果您在创建环境块时出错,则不会出现错误,但该进程可能根本无法运行。
应用程序未能正确初始化- 没有更多的例外,你已经解决了所有的问题,流程已经启动。哎呀,过程在哪里?检查事件日志(或者您可能收到了应用程序错误弹出窗口)。应该有一个 Application Error 条目,表明您的进程是有故障的应用程序,user32.dll 或 kernel32.dll 是有故障的模块,异常为:0xC0000142。这可能有一些细微的变化,但基本上是说您的应用程序无法初始化。这样做的原因是在初始化时,在运行任何应用程序代码之前,所有进程都附加到一个 Window Station,所有线程都附加到一个桌面,但您正在启动的用户没有访问 Window Station 和桌面的权限在其中启动您的进程,因此它无法初始化。必须调整 Window Station 和桌面的安全描述符,以向正在启动进程的用户授予 AllAccess 权限。直接在 .Net 中这样做是很麻烦的,因此您可能会发现这里的安全包装类很有用。
不再有错误- 真的,不再有错误,您的流程现在应该可以顺利运行了。根据用户是谁(例如,管理员在某些情况下已经拥有正确的权限)或您正在启动的会话类型,您需要做的事情可能会有一些变化。但是按照这些步骤应该可以让您的生活顺利和轻松(也许不是你的一生)。
参考:
在备用凭据下创建新进程 (createprocessasuser)
| 归档时间: |
|
| 查看次数: |
3272 次 |
| 最近记录: |