WCF服务Process.Start假装网络服务账号下不同用户我用的是AppPool.NET4.0withNETWORKSERVICE身份Wcf服务托管在IIS、WindowsServer2008R2中。我的Wcf服务有一个使用Process.Start调用命令EXE的方法。我需要使用不同的用户作为凭据来执行命令EXE(域用户帐户)。我尝试执行它但它对我不起作用:它似乎没有执行命令EXE。更新:进程退出但代码未执行我得到的错误如下:退出代码-1073741502和eventvwr:进程信息:进程ID:0xc50进程名称:C:DeployToolsDeployTools.Commands.Ejecutar.exe退出状态:0xc0000142应用程序启动失败(0xC0000142)。单击“确定”关闭应用程序有什么建议?码:StreamReadersr=null;StreamReaderserr=null;尝试{varpsi=newProcessStartInfo(MY_COMMAND_EXE);psi.WorkingDirectory=Path.GetDirectoryName(MY_COMMAND_EXE);psi.Arguments=参数;psi.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;使用(Processpr=Process.Start(psi)){sr=pr.StandardOutput;serr=pr.StandardError;如果(!pr.HasExited){pr.WaitForExit(300000);}output=pr.StandardOutput.ReadToEnd();错误=pr.StandardError.ReadToEnd();exitCode=pr.ExitCode;返回输出;}}catch(Exceptionexc){return"EXCEPCIóN:"+exc.Message;}finally{if(sr!=null){sr.Close();高级处置();sr=空;}if(serr!=null){serr.Close();serr.Dispose();塞尔=空;我必须添加对AsproLock.dll和相关代码的引用,以允许用户帐户访问正在运行的资源//以下安全调整是必要的,以便为新的//进程提供足够的权限以在服务的窗口站//和桌面上运行。这使用来自//Asprosys的AsproLock库中的类。IntPtrhWinSta=NativeMethods.GetProcessWindowStation();WindowStationSecurityws=newWindowStationSecurity(hWinSta,System.Security.AccessControl.AccessControlSections.Access);ws.AddAccessRule(newWindowStationAccessRule(userPassDto.Usuario,WindowStationRights.AllAccess,System.Security.AccessControl.AccessControlType.Allow));ws.AcceptChanges();IntPtrhDesk=NativeMethods.GetThreadDesktop(NativeMethods.GetCurrentThreadId());DesktopSecurityds=newDesktopSecurity(hDesk,System.Security.AccessControl.AccessControlSections.Access);ds.AddAccessRule(newDesktopAccessRule(userPassDto.Usuario,DesktopRights.AllAccess,System.Security.AccessControl.AccessControlType.Allow));ds.AcceptChanges();[DllImport("user32.dll",设置LastError=true)]publicstaticexternIntPtrGetProcessWindowStation();[DllImport("user32.dll",SetLastError=true)]publicstaticexternIntPtrGetThreadDesktop(intdwThreadId);[DllImport("kernel32.dll",SetLastError=true)]publicstaticexternintGetCurrentThreadId();Asprosys在新凭证下启动进程的危险和陷阱这不是常见的需求,但也不是那么罕见,所以我想我最好发布这个逐步指南以排除在模拟中无法在凭证下启动进程这是基于关于使用.NetProcess类的Start方法,但它也适用于底层API调用:CreateProcessWithLogonW和CreateProcessWithTokenW。拒绝访问-首次尝试和拒绝访问异常。这是最常见的初始问题,是由在LOCALSYSTEM帐户下运行的服务引起的。奇怪的是,SYSTEM帐户是计算机上最强大的帐户,但它不能做的一件事是使用CreateProcessWithLogonW启动进程,这是调用Process.Start的API。因此,将您的服务帐户更改为本地服务,无论如何它可能是更合适的帐户。访问再次被拒绝-啊,我以为我们解决了这个问题。糟糕,仔细检查您尝试启动的应用程序的权限。请记住,系统会尝试以进程将在其下运行的用户帐户而不是服务帐户的身份访问应用程序文件。无效目录错误-什么?所有路径都是正确的。所有目录都拼写正确,没有无效字符。这是一个非常烦人的错误,它不是很一致。通常当我们运行一个进程时,我们不会费心去设置WorkingDirectory属性,而只是接受来自父进程的默认值。使用新凭据启动进程时不能执行此操作,必须明确设置WorkingDirectory的路径,否则会出现“目录名称无效”。Win32异常。失败:没有错误?-Process.Start很好地处理了为新进程创建环境块。所以只有在使用底层API时才会出现问题。当调用其中一个CreateProcess*API时,通常将lpEnvironment参数保留为NULL并让系统使用从父进程复制块的默认值。但是,在新凭据下启动时,您必须手动或使用CreateEnvironmentBlock显式创建环境块。更糟糕的是,如果您忽略这一点,CreateProcess*调用将失败,但GetLastError将返回ERROR_SUCCESS,如果您在创建环境块时出错,则不会引发任何错误,但进程可能根本不会运行。应用程序未能正确初始化-没有更多异常,您已修复所有问题并且进程已启动。又糟糕了,过程在哪里?检查事件日志(或者您可能收到“应用程序错误”弹出窗口)。应用程序错误应该有一个条目表明您的进程是有故障的应用程序,user32.dll或kernel32.dll是故障模块,异常是:0xC0000142。这可能有一些细微的变化,但基本上是说您的应用程序无法初始化。原因是在初始化时,在运行任何应用程序代码之前,所有进程都附加到WindowStation,所有线程都附加到桌面,但是您启动的用户无权访问WindowStation和桌面您的进程正在启动,无法初始化。必须调整WindowStation和Desktop的安全描述符,以向启动进程的用户授予AllAccess权限。这是直接在.Net中执行的操作,因此您可能会发现此处的安全包装类很有用。没有更多的错误-真的,没有更多的错误,您的流程现在应该可以顺利运行。根据用户是谁(例如,管理员在某些情况下已经拥有正确的权限)或您要启动的会话类型,您可能需要进行一些更改。但遵循这些步骤应该会让您的生活更顺利、更轻松(也许不是您的整个生活)。参考:DangersandPitfallsofStartingaProcessUnderaNewCredentialsAsproLock-AccessControlCodeExampleCreatingaNewProcessUnderAlternateCredentials(createprocessasuser)processstart-hang以上为C#学习教程:WCF服务进程.StartunderNetworkServiceAccount我假装是不同用户分享的所有内容。如果对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
