【问题标题】:How to run a separate process as a domain user with a 'local system' service?如何使用“本地系统”服务以域用户身份运行单独的进程?
【发布时间】:2012-02-26 08:00:43
【问题描述】:

我有以下简单的服务程序:

using System.Diagnostics;
using System.ServiceProcess;

namespace BasicService
{
    public partial class Service1 : ServiceBase
    {
        public Service1()
        {
            InitializeComponent();
        }

        protected override void OnStart(string[] args)
        {
            ProcessStartInfo processStartInfo = new ProcessStartInfo
                                                    {
                                                        Verb = "runas",
                                                        UserName = "jdoe",
                                                        Password = "XXXXXXX".ConvertToSecureString(),
                                                        Domain = "abc.com",
                                                        UseShellExecute =false,
                                                        FileName = "notepad.exe"
                                                    };
            Process.Start(processStartInfo);
        }

        protected override void OnStop()
        {
        }
    }
}

我将它用作我的服务安装程序:

using System.ComponentModel;
using System.Configuration.Install;
using System.ServiceProcess;

namespace BasicService
{
    [RunInstaller(true)]
    public class ProjectInstaller : Installer
    {
        private readonly ServiceProcessInstaller _process;
        private readonly ServiceInstaller _service;

        public ProjectInstaller()
        {
            _process = new ServiceProcessInstaller {Account = ServiceAccount.LocalSystem};
            _service = new ServiceInstaller
                           {
                               ServiceName = "BasicService",
                               Description = "Just a testing service.",
                               StartType = ServiceStartMode.Automatic,
                           };

            Installers.Add(_process);
            Installers.Add(_service);
        }
    }
}

如果我在没有指定动词、用户名、密码、域和 useshellexecute 的情况下运行此服务,那么一切都运行得很好。如上所述,一旦我指定了这些值,我就会得到以下信息:

服务无法启动。 System.ComponentModel.Win32Exception (0x80004005): 访问被拒绝 System.Diagnostics.Process.StartWithCreateProcess(ProcessStartInfo startInfo) 在 System.Diagnostics.Process.Start() 在 System.Diagnostics.Process.Start(ProcessStartInfo startInfo) 在 BasicService.Service1.OnStart(String[] args) 在 C:\BasicService\BasicService\Service1.cs:第 24 行 System.ServiceProcess.ServiceBase.ServiceQueuedMainCallback(对象 州)

有什么想法吗?

【问题讨论】:

    标签: c# process windows-services impersonation localsystem


    【解决方案1】:

    从 Windows Vista 开始,服务不能简单地显示 ui 或与用户交互。
    http://msdn.microsoft.com/en-us/library/ms683502(VS.85).aspx

    因此,要从您的服务运行 GUI 应用程序,您需要使用 CreateProcessAsUser,它在 .NET 中不直接可用。所以你必须依赖 Pinvoke,有点类似于这里描述的

    http://blogs.msdn.com/b/alejacma/archive/2007/12/20/how-to-call-createprocesswithlogonw-createprocessasuser-in-net.aspx

    【讨论】:

    • 你确定吗?服务无法再通过服务帐户与用户交互,但我不知道 Windows 怎么知道 notepad.exe 是交互式的,除非它实际运行它。在这种情况下,必须启动该过程。
    • @ta.speot.is - 是的,我坚信 CreateProcessAsUser 是从服务创建用户可见的 GUI 应用程序的正确方法。究竟是什么原因导致上面的“访问被拒绝”,我不确定,但从调用堆栈中您可以看到 Windows 实际运行它。 Windows 是如何知道的……可能是通过检查 '/SUBSYSTEM' VS 开关设置的入口点符号。
    • AFAIK 这是我能够做到的唯一方法。我必须将 CreateProcessAsUser 和 LogonUser 结合起来才能正常工作。
    • @user1234883,Process.Execute 采用具有 UserName 和 Password 作为属性的 ProcessStartInfo。为什么它不起作用?
    猜你喜欢
    • 2023-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-19
    • 2013-02-04
    • 1970-01-01
    • 1970-01-01
    • 2016-12-08
    相关资源
    最近更新 更多