【问题标题】:Stopping windows service with taskkill使用 taskkill 停止 windows 服务
【发布时间】:2014-05-25 16:49:43
【问题描述】:

我需要帮助才能使用 C# 终止 Windows 服务,现在要终止服务,请使用以下选项:

来自 cmd:

sc queryex ServiceName

发现服务的PID

taskkill /pid 1234(exemple) /f

【问题讨论】:

  • 你有C#代码吗?您可以启动一个执行命令的新进程...

标签: c# windows service taskkill


【解决方案1】:

为了便于阅读,如果你明白我的意思,我会将服务交互分离到它自己的类中,并使用单独的方法 IsServiceInstalled、IsServiceRunning、StopService ..etc。

此外,通过停止服务,它应该已经终止了该进程,但我也包括了你将如何做类似的事情。如果服务不会停止并且您通过终止进程来停止它,那么如果您无法正确构建服务代码,我会查看它。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ServiceProcess;
using System.Diagnostics;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            ServiceController sc = ServiceController.GetServices().FirstOrDefault(s => s.ServiceName.Equals("MyServiceNameHere"));
            if (sc != null)
            {
                if (sc.Status.Equals(ServiceControllerStatus.Running))
                {
                    sc.Stop();

                    Process[] procs = Process.GetProcessesByName("MyProcessName");
                    if (procs.Length > 0)
                    {
                        foreach (Process proc in procs)
                        {
                            //do other stuff if you need to find out if this is the correct proc instance if you have more than one
                            proc.Kill();
                        }
                    }
                }
            }
        }
    }
}

【讨论】:

  • 别忘了给它向上箭头并标记为答案。很高兴它对你有用。
  • Process.GetProcessesByName("MyProcessName") 在 Windows 7 上找不到我的服务
【解决方案2】:

Process.GetProcessesByName("service name") 在我的情况下不起作用,但下面是。 您将需要对 System.ServiceProcess 和 System.Management 的引用。

    public static void Kill()
    {
        int processId = GetProcessIdByServiceName(ServiceName);

        var process = Process.GetProcessById(processId);
        process.Kill();
    }

    private static int GetProcessIdByServiceName(string serviceName)
    {

        string qry = $"SELECT PROCESSID FROM WIN32_SERVICE WHERE NAME = '{serviceName }'";
        var searcher = new ManagementObjectSearcher(qry);
        var managementObjects = new ManagementObjectSearcher(qry).Get();

        if (managementObjects.Count != 1)
            throw new InvalidOperationException($"In attempt to kill a service '{serviceName}', expected to find one process for service but found {managementObjects.Count}.");

        int processId = 0;

        foreach (ManagementObject mngntObj in managementObjects)
            processId = (int)(uint) mngntObj["PROCESSID"];

        if (processId == 0)
            throw new InvalidOperationException($"In attempt to kill a service '{serviceName}', process ID for service is 0. Possible reason is the service is already stopped.");

        return processId;
    }

【讨论】:

    【解决方案3】:

    这里的代码使用了 4 种方法来停止你的服务,包括 TaskKill,注意你必须有足够的权限才能这样做。

      foreach (ServiceController Svc in ServiceController.GetServices())
        {
            using (Svc)
            {
                //The short name of "Microsoft Exchange Service Host"
                if (Svc.ServiceName.Equals("YourServiceName"))
                {
                    if (Svc.Status != ServiceControllerStatus.Stopped)
                    {
                        if (Svc.CanStop)
                        {
                            try
                            {
                                Svc.Stop();
                                Svc.WaitForStatus(ServiceControllerStatus.Stopped, new TimeSpan(0, 0, 15));
                            }
                            catch
                            {
                                //Try to stop using Process
                                foreach (Process Prc in Process.GetProcessesByName(Svc.ServiceName))
                                {
                                    using (Prc)
                                    {
                                        try
                                        {
                                            //Try to kill the service process
                                            Prc.Kill();
                                        }
                                        catch
                                        {
                                            //Try to terminate the service using taskkill command
                                            Process.Start(new ProcessStartInfo
                                            {
                                                FileName = "cmd.exe",
                                                CreateNoWindow = true,
                                                UseShellExecute = false,
                                                Arguments = string.Format("/c taskkill /pid {0} /f", Prc.Id)
                                            });
    
                                            //Additional:
                                            Process.Start(new ProcessStartInfo
                                            {
                                                FileName = "net.exe",
                                                CreateNoWindow = true,
                                                UseShellExecute = false,
                                                Arguments = string.Format("stop {0}", Prc.ProcessName)
                                            });
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    

    【讨论】:

    • 对我来说,Process.GetProcessesByName(Svc.ServiceName) 中的 Process Prc 行似乎无法使用服务名称找到进程。
    • 在我的情况下无法按名称查找进程。这是在 Windows 7 上。
    【解决方案4】:

    如果您知道进程 ID,请使用 Process.GetProcessById(Id).Kill(); 如果您知道进程名称,请使用 Process.GetProcessesByName(name).Kill();

    【讨论】:

    • 这两个方法都返回一个数组,所以你不能调用它的方法。
    • 为什么不呢?可以用这个名字杀死所有进程。例如,您有 5 个 Chrome 窗口并想要杀死所有 chrome 进程。使用此方法 Process.GetProcessesByName(name).Kill();有可能杀死所有人。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-07
    • 1970-01-01
    • 1970-01-01
    • 2011-04-25
    相关资源
    最近更新 更多