以编程方式更改Windows服务用户

9

我需要通过编程方式更改Windows服务的登录用户。我正在使用以下代码来实现:

string objPath = string.Format("Win32_Service.Name='{0}'", ServiceName);
using (ManagementObject service = new ManagementObject(new ManagementPath(objPath)))
{
    object[] wmiParams = new object[11];

    if (PredefinedAccount)
    {
        wmiParams[6] = "LocalSystem";
            wmiParams[7] = "";
    }
    else
    {
        wmiParams[6] = ServiceUsername; // provided by user
            wmiParams[7] = ServicePassword; // provided by user
    }

    object invokeResult = service.InvokeMethod("Change", wmiParams);

    // handle invokeResult - no error up to this point
}

这段代码在90%的情况下工作正常,但在某些情况下由于登录失败无法启动服务。通常InvokeMetod不会出错,但尝试启动服务时会出现以下错误:
System.InvalidOperationException: 无法在计算机'.'上启动X服务--> System.ComponentModel.Win32Exception: 由于登录失败而无法启动服务。
解决方法很简单,我们只需要通过Windows界面输入相同的凭据即可解决问题。
因此我的问题是,是否有人在使用ManagementObject时遇到类似的问题?因为在某些情况下,它似乎没有将用户名和密码与Windows服务关联起来。

1
我想知道这是否与你的using语句有关。我的意思是,ManagementObject在完成之前就被销毁了吗?我对WMI不是特别熟悉,所以不确定。 - Hans Van Slooten
由于用户名和密码是用户输入的,我也会在那里寻找问题。确保它们是有效的名称。“DOMAIN\username”在任何系统中都很好,但“username@DOMAIN”在Windows 2000及更早版本中不起作用。 - Hans Van Slooten
我们有同样的问题,我很确定该服务是使用C#、.net 1.1安装程序安装的。我从命令行启动服务('net start'),但出现登录失败的情况。奇怪的是,在机器上安装的7个服务中,有2个会出现这种情况(可能使用相同的安装代码)。我还没有开始诊断,但该机器是带有最新服务包的Windows 2003服务器。这些服务是C# .net 2.0代码编写的。手动输入密码可以解决问题,直到重新启动。 - LegendLength
@HVS:是的,我们正在强制要求他们将用户名输入为“DOMAIN\用户名”。 - Anne
奇怪的是,我刚刚通过使用用户名@域名语法解决了我们的问题。这是带有SP2的W2003服务器。 - LegendLength
显示剩余2条评论
2个回答

9

这是因为该账户没有“作为服务登录”的特权。您需要使用 LsaAddAccountRights 将该特权添加到该账户中。


0

你有注意到这些失败之间有任何模式吗?使用相同的机器吗?相同的操作系统?相同的用户?该用户是否具备“作为服务登录”或“交互式登录”权限?就我个人而言,我不熟悉通过此方式指定服务用户的方法。我认为您需要重新启动服务,但如果它90% 的时间都可以正常工作,那么我想我可能是错的。


这取决于操作系统。没有模式。有时如果密码太短(少于7个字符)就会发生这种情况。在所有这些情况下,当用户通过Windows默认界面输入相同的用户名和密码时,问题都得到解决。因此,我们认为这是我们代码或使用的ManagementObject中的问题。 - Anne

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接