我们正在使用写得很糟糕的Windows服务,当我们尝试从代码中阻止它时,它会挂起。因此,我们需要找到与该服务相关的进程并将其终止。 有什么建议吗?
答案 0 :(得分:12)
您可以使用System.Management.MangementObjectSearcher
获取服务的进程ID,并使用System.Diagnostics.Process
获取相应的Process
实例并将其删除。
以下程序中的KillService()
方法显示了如何执行此操作:
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Management;
namespace KillProcessApp {
class Program {
static void Main(string[] args) {
KillService("YourServiceName");
}
static void KillService(string serviceName) {
string query = string.Format(
"SELECT ProcessId FROM Win32_Service WHERE Name='{0}'",
serviceName);
ManagementObjectSearcher searcher =
new ManagementObjectSearcher(query);
foreach (ManagementObject obj in searcher.Get()) {
uint processId = (uint) obj["ProcessId"];
Process process = null;
try
{
process = Process.GetProcessById((int)processId);
}
catch (ArgumentException)
{
// Thrown if the process specified by processId
// is no longer running.
}
try
{
if (process != null)
{
process.Kill();
}
}
catch (Win32Exception)
{
// Thrown if process is already terminating,
// the process is a Win16 exe or the process
// could not be terminated.
}
catch (InvalidOperationException)
{
// Thrown if the process has already terminated.
}
}
}
}
}
答案 1 :(得分:5)
WMI具有以下信息:Win32_Service类。
像
这样的WQL查询SELECT ProcessId FROM Win32_Service WHERE Name='MyServiceName'
使用System.Management应该可以解决问题。
快速查看:taskllist.exe /svc
以及命令行中的其他工具。
答案 2 :(得分:4)
您可以使用
tasklist /svc /fi "SERVICES eq YourServiceName"
查找进程名称和ID,以及同一进程是否托管其他服务。
答案 3 :(得分:1)
要完全回答我的问题 - 如何查找与某项服务相关的流程:
ManagementObjectSearcher searcher = new ManagementObjectSearcher
("SELECT * FROM Win32_Service WHERE DisplayName = '" + serviceName + "'");
foreach( ManagementObject result in searcher.Get() )
{
if (result["DisplayName"].ToString().ToLower().Equals(serviceName.ToLower()))
{
int iPID = Convert.ToInt32( result["ProcessId"] );
KillProcessByID(iPID, 1000); //some method that will kill Process for given PID and timeout. this should be trivial
}
}
}
答案 4 :(得分:0)
Microsoft / SysInternals有一个名为PsKill的命令行工具,允许您按名称终止进程。此工具还允许您终止其他服务器上的进程。 Windows SysInternals
用法:pskill [-t] [\ computer [-u username [-p password]]]<进程ID |名称>
-t杀死进程及其后代 -u指定登录到远程计算机的可选用户名 -p指定用户名的可选密码。如果省略此项,系统将提示您输入隐藏密码。
答案 5 :(得分:0)
我想这是一个两步过程 - 如果它始终是相同的服务,您可以使用其他答案中建议的方法轻松找到过程名称。
然后,我在.NET 1.1 Web服务器上的类中有以下代码:
Process[] runningProcs =
Process.GetProcessesByName("ProcessName");
foreach (Process runningProc in runningProcs)
{
// NOTE: Kill only works for local processes
runningProc.Kill();
}
Kill method可以抛出一些你应该考虑捕获的异常 - 尤其是Win32Exception,如果进程无法被杀死则抛出。
请注意,WaitForExit method和HasExited property也存在于1.1世界中,但在杀戮1.1的文档页面中未提及。