【问题标题】:Stopping a windows service via program通过程序停止 Windows 服务
【发布时间】:2012-09-14 04:17:11
【问题描述】:

在 c# 中以编程方式停止 Windows 服务会生成下面列出的System.InvalidOperationException

{访问被拒绝}

如果我通过 Windows 界面启动/停止,那么一切正常! 我是管理员用户并在 Windows 7 下运行该服务

【问题讨论】:

  • 请在您的问题中插入您用来停止服务的代码。
  • 停止服务运行的程序是什么帐户?
  • 服务登录是什么账号? (显示在Services.msc的右键单击->属性菜单上)
  • if (service.Status == ServiceControllerStatus.Running) { service.Stop(); service.WaitForStatus(ServiceControllerStatus.Stopped); } 服务安装为在本地服务帐户下运行

标签: c# windows-services system


【解决方案1】:

我不确定你是如何阻止它的,但我现在在我的系统上尝试了这个,这种方法至少可以正常工作:

var p = Process.Start(new ProcessStartInfo
        {
          FileName = "net",
          Arguments = "stop NameOfService",
          CreateNoWindow = true,
          WindowStyle = ProcessWindowStyle.Hidden
        });
p.WaitForExit(); //add this line if you want to make sure that the service is stopped before your program execution continues

【讨论】:

  • 您的 Visual Studio 是否在管理员模式下运行?因为我的net start/net stop 确实需要 UAC 批准。
  • 一旦部署了服务,它运行良好,但是当 servicecontroller .stop 命令执行时,我得到异常 System.InvalidOperationException 服务需要在预定义的时间每天执行,所以这就是我想要的原因在必要的过程完成后停止它
  • @Lucero - 是的,我的 VS 正在管理员模式下运行。
  • @ØyvindKnobloch-Bråthen 当您直接从 Windows 资源管理器而不是在 VS 中运行它时它是否仍然有效?
  • 如果我手动启动/停止一切正常!唯一的问题是当我尝试使用 if (service.Status == ServiceControllerStatus.Running) { service.Stop(); 以编程方式停止服务时service.WaitForStatus(ServiceControllerStatus.Stopped); }
【解决方案2】:

这听起来像是 UAC 问题 - 尝试以管理员身份运行应控制服务的应用程序(右键单击“以管理员身份运行”)。

请注意,除非您在管理员模式下明确运行应用程序,否则即使管理员帐户也没有完全权限 - 这是为了保护用户免受 Windows Vista 中恶意软件的侵害而引入的,并且从那时起就一直存在。

【讨论】:

  • 嗨,我已经通过创建清单文件尝试了 UAC 方法,也知道在 Win 7 中,即使管理员用户也被视为标准用户,除非有人说运行为,但这种方法是用户干预以开始停止服务我希望以编程方式停止服务
  • @prashant,嗯,UAC 的全部意义在于防止软件做关键的事情(停止服务就是其中之一——停止某些防病毒服务的防火墙服务会降低机器的安全性)。因此,除非您的用户批准运行您的软件,否则它不会被允许控制服务。也就是说,您可以让服务自行停止,然后向您的服务发送一条“消息”,告诉它自行关闭。
  • 我没有明白你在上一句中所说的安全方面的内容,目前还可以,因为它将在独立服务器上执行。 “您可以让服务自行停止,然后向您的服务发送一条“消息”,告诉它自行关闭”
  • @prashant,该服务通常有足够的权限自行关闭。因此,如果您以某种方式“告诉”服务(例如通过发送到邮槽的消息)自行关闭,您的应用程序可以通过这种方式控制服务的关闭。
  • @prashant - 要查看这是否是问题所在,只需暂时关闭 UAC 并查看您的程序在 UAC 关闭的情况下是否按预期运行。
【解决方案3】:

如果身份验证是问题...

您可以使用

以编程方式控制您正在使用的用户
WindowsIdentity

[DllImport("advapi32.dll", SetLastError = true)]
private static extern bool LogonUser(...)

我不知道这是否可行,但值得一试。

IntPtr token IntPtr.Zero;
LogonUser(username, password ..., ref token) //and some other parameters
var identity = WindowsIdentity(token);

using(identity.Impersonate())
{ 
    //do stuff here using another identity
    //find service and stop it
}

edit:这可用于远程服务器上的身份验证。

【讨论】:

  • 我可能不会选择模拟,我正在使用外部 .bat 文件来停止和启动服务,而不是以编程方式解决它,这解决了我的目的!谢谢!
  • 是的,我在发帖之前就看到了,但仍然想将这种方法分享给其他人。
猜你喜欢
  • 1970-01-01
  • 2012-05-06
  • 1970-01-01
  • 2011-06-18
  • 1970-01-01
  • 2012-05-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多