【问题标题】:Change Windows Service user programmatically以编程方式更改 Windows 服务用户
【发布时间】:2009-06-07 11:11:36
【问题描述】:

我需要以编程方式更改 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 服务相关联?

【问题讨论】:

  • 不知道是不是因为你的 using 语句。我的意思是 ManagementObject 在允许完成之前被销毁?我对 WMI 不太熟悉,所以不确定。
  • 由于用户名和密码是用户输入的,我也会在那里寻找问题。确保它们是有效的名称。 "DOMAIN\username" 在任何系统中都很好,但在 Windows 2000 和更早版本中,'username@DOMAIN' 不起作用。
  • 我们有同样的问题,我很确定该服务是使用 C#、.net 1.1 安装程序安装的。我从命令行('net start')启动服务并登录失败。奇怪的是,这发生在机器上安装的 7 个服务中有 2 个(可能使用相同的安装代码)。我还没来得及诊断它,但机器是带有最新服务包的 Windows 2003 服务器。这些服务是 c# .net 2.0 代码。手动输入密码会修复它,直到重新启动。
  • @HVS:是的,我们强制他们输入用户名作为 'DOMAIN\username'。
  • 我认为 HVS 的第一条评论有一些优点。 WMI 对象可能在登录完成之前就被释放了,尤其是当登录咨询在另一台计算机上控制的域或目录时。凭据可能会在用户以交互方式登录后被缓存,这可能解释了为什么它会为您工作。尝试循环测试登录的内容,这应该使 WMI 对象保持足够长的活动时间以进行登录。或者删除 using 语句。

标签: c# .net windows-services


【解决方案1】:

这是因为该帐户没有“作为服务登录”权限。您需要使用 LsaAddAccountRights 将此类权限添加到帐户。

请查看这篇文章:

How To Manage User Privileges Programmatically in Windows NT

【讨论】:

  • 这是一个旧答案,部分仅链接答案请在答案中添加墨水的基本部分。
【解决方案2】:

您注意到这些失败中有什么规律吗?同一台机器?相同的操作系统?同一个用户?用户是否拥有“logon as service”或“交互式登录”权限?就个人而言,我不熟悉这种为服务指定用户的方法。我原以为您必须重新启动服务,但我想如果它在 90% 的时间内都可以正常工作。

【讨论】:

  • 嗯,这取决于各种操作系统。没有模式。如果密码很短(少于 7 个字符),有时会发生这种情况。在所有这些情况下,当用户通过 Windows 默认界面输入相同的用户名和密码时,问题就解决了。所以我们假设它是我们的代码或我们正在使用的 ManagementObject 中的东西。
猜你喜欢
  • 1970-01-01
  • 2011-11-16
  • 1970-01-01
  • 2011-10-03
  • 1970-01-01
  • 2010-11-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多