我试图通过我目前拥有的某个名称(下面notepad.exe
)来杀死所有进程。一般来说,它的顺序如下:
以下代码基于另一个SO答案,并使用WMI按特定名称获取所有流程并列出用户。
下一步:下一步是杀死我拥有的进程;但是,我如何判断我在这里的PID将与我试图杀死的PID相同?
static void Main(string[] args)
{
const string PROCESS_NAME = "notepad.exe";
var queryString = string.Format("Name = '{0}'", PROCESS_NAME);
var propertiesToSelect = new[] { "Handle", "ProcessId" };
var processQuery = new SelectQuery("Win32_Process", queryString, propertiesToSelect);
using (var searcher = new ManagementObjectSearcher(processQuery))
{
using (var processes = searcher.Get())
foreach (var aProcess in processes)
{
var process = (ManagementObject)aProcess;
var outParameters = new object[2];
var result = (uint)process.InvokeMethod("GetOwner", outParameters);
if (result == 0)
{
var user = (string)outParameters[0];
var domain = (string)outParameters[1];
var processId = (uint)process["ProcessId"];
Console.WriteLine("PID: {0} | User: {1}\\{2}", processId, domain, user);
// TODO: Use process data...
}
else
{
// TODO: Handle GetOwner() failure...
}
}
}
Console.ReadLine();
}
答案 0 :(得分:4)
是的,存在杀死错误进程的风险。重复使用PID可能是历史事故,多年来引起了很多悲痛。
这样做:
通过插入此锁定和验证步骤,您可以确定。
答案 1 :(得分:3)
从我获取PID到杀死它的时间有多大可能,另一个应用程序可能会产生使用该PID?
如果另一个应用程序在另一个应用程序处于活动状态时生成,则不会为其分配相同的PID。所以这种情况不会发生在Windows' PID是特定过程的唯一十进制数。
如果我获取ID为123的PID,它有多大可能关闭,而另一个应用程序现在拥有PID 123?
这在技术上是可行的,可以在您获得对该进程的处理与您想要终止该进程之间关闭该进程。但是,这完全取决于代码中进程处理的生命周期。我想总会有一些边缘情况,应用程序可能会被关闭,就像你要挂钩它一样,但是如果你说毫秒/几秒钟,我想它会很少而且很远。至于Windows之后立即分配相同的PID,我不确定,但它们看起来很随机,现在在使用后立即再次分配,但最终会这样做。
在限制我杀掉错误PID的可能性的同时,我可以合理地解决这个问题的最佳方式是什么?
管理事件观察器类似乎允许您监视进程的启动和停止。也许这可以用来捕获事件,只要它们关闭给你的给定进程名称,所以这样你知道它不再存在?
答案 2 :(得分:1)
考虑相反的方法 - 调整服务帐户的权限,使无法杀死其他用户的进程。
我相信这些权限非常接近非管理员帐户的默认值(或者只是默认值) - 因此,除非您以管理员/系统方式运行服务,否则您可以使用无代码解决方案。
答案 3 :(得分:1)
只要进程继续运行,进程ID就保证保持不变。一旦流程退出......就无法保证。
当新进程启动时,Windows将选择一个随机进程ID并将其分配给新进程。它不太可能,但可能选择的id与最近退出的过程有关。
你看过System.Diagnostics.Process
吗?
他们有一个GetProcessesByName
方法,它将返回一个Process对象列表。
Process [] localByName = Process.GetProcessesByName("notepad");
然后你可以简单地遍历进程并杀死它们。由于Process对象具有进程的句柄...尝试终止它将生成一个有用的异常,您可以捕获它。
foreach (Process p in localByName)
{
try
{
p.Kill();
}
catch (Exception e)
{
// process either couldn't be terminated or was no longer running
}
}