gpt4 book ai didi

c# - WCF服务Process.Start在网络服务帐户下模拟为其他用户

转载 作者:太空宇宙 更新时间:2023-11-03 21:45:03 25 4
gpt4 key购买 nike

我已将Wcf Service托管在IIS,Windows Server 2008 R2中,并使用带有网络服务标识的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



  该应用程序无法正确启动(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;
}
}

最佳答案

我必须添加对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();


在新凭据下启动进程的风险和陷阱Asprosys

这不是普遍的需求,但也并不罕见,因此,我认为我最好发布此逐步指南,以解决在模拟凭据下启动进程的问题。这基于使用.Net Process类的Start方法,但是它也适用于基础API调用:CreateProcessWithLogonW和CreateProcessWithTokenW。

访问被拒绝-立即尝试并尝试拒绝访问。这是最常见的初始问题,由服务在本地系统帐户下运行这一事实引起。奇怪的是,SYSTEM帐户是计算机上功能最强大的帐户,但它无法执行的少数操作之一是使用CreateProcessWithLogonW启动流程,该流程是对Process.Start进行调用的基础API。因此,将您的服务帐户更改为“本地服务”,无论如何,这可能是更合适的帐户。

再次拒绝访问-Aargh,我以为我们解决了这个问题。糟糕,请仔细检查您要启动的应用程序的权限。请记住,系统尝试以运行该进程的用户帐户(而不是服务帐户)访问该应用程序文件。

无效的目录错误-什么?所有路径均正确。所有目录的拼写正确,没有无效字符。这是一个令人讨厌的错误,并且不一致。通常,当我们运行一个流程时,我们不必费心设置WorkingDirectory属性,而只接受父流程的默认值。使用新凭据启动进程时,您不能这样做,必须显式设置WorkingDirectory的路径,否则会得到“目录名称无效”的信息。 Win32Exception。

失败:没有错误? -Process.Start可以很好地为新流程处理环境块的创建。因此,仅当您使用基础API时,这才是问题。调用其中一个CreateProcess * API时,通常将lpEnvironment参数保留为NULL,并使系统使用从父进程复制块的默认设置。但是,在使用新凭据启动时,必须手动或使用CreateEnvironmentBlock显式创建一个环境块。更糟糕的是,如果不执行此操作,则CreateProcess *调用将失败,但GetLastError将返回ERROR_SUCCESS;如果在创建环境块时出错,则不会有任何错误,但是该过程可能根本不会运行。

应用程序无法正确初始化-没有更多的例外,您已经解决了所有问题,并且该过程已启动。再次糟糕,流程在哪里?检查事件日志(否则您可能会收到“应用程序错误”弹出窗口)。应该有一个Application Error条目,指出您的进程是有故障的应用程序,user32.dll或kernel32.dll是有故障的模块,并且例外是:0xC0000142。可能会有一些细微的变化,但基本上是说您的应用程序无法初始化。这样做的原因是,在初始化时,在运行任何应用程序代码之前,所有进程均已附加到Window Station,所有线程均已附加到Desktop,但是要在其下启动的用户没有访问Window Station和Desktop的权限。在其中启动您的进程的过程中,因此无法初始化。必须调整Window Station和Desktop的安全描述符,以向要在其下启动进程的用户授予AllAccess权限。这是直接在.Net中执行的恶魔,因此您可能会发现此处的安全包装器类有用。

没有更多错误-实际上,没有更多错误,您的进程现在应该可以平稳运行。根据用户的身份(例如,在某些情况下管理员已经具有正确的权限)或您要启动的会话类型,您需要执行的操作可能有所不同。但是按照以下步骤进行操作可以使您的生活变得更美好流畅轻松(可能不是您的一生)。

参考文献:

The Perils and Pitfalls of Launching a Process Under New Credentials

Aspro Lock - Access Control

Code Samples

Creating New Process Under Alternate Credentials (createprocessasuser)

processstart-hangs

关于c# - WCF服务Process.Start在网络服务帐户下模拟为其他用户,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17488220/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com