我正试图编写一个方法,如果它无法停止使用StopService方法,将通过进程ID终止远程系统上的服务。我尝试了两种不同的方法来调用ManagementObject上的“Terminate”方法,并得到两个不同的错误。对我来说,我能够从Terminate方法获取返回码也很重要。无法远程终止使用WMI和C的进程#
如果我直接申报ManagementPath到我要终止的过程中,我得到的错误“System.Management.ManagementException:无效的对象路径”在行:
ManagementBaseObject processParams = processObj.InvokeMethod("Terminate", (ManagementBaseObject)null, null);
如果我得到一个ManagementObjectCollection和循环通过它寻找的进程ID我要终止,我得到错误“无效参数”,在线路:
ManagementBaseObject termParams = currentObj.InvokeMethod("Terminate", (ManagementBaseObject)null, null);
因此,在这两种情况下,我当我尝试调用Terminate方法时出现错误,但错误取决于我如何到达对象(直接路径或循环集合)。
我不是认为这与SeDebugPrivilege有关,因为我相信如果是的话,我会得到“访问被拒绝”或“不足的特权”。
代码,如果我试图直接指定路径的过程:
public int KillServiceWMI(string serviceName, string serverName, string serverUser, string serverDomain, string serverPassword)
{
try
{
ConnectionOptions options = new ConnectionOptions();
options.Impersonation = System.Management.ImpersonationLevel.Impersonate;
options.Username = serverDomain + "\\" + serverUser;
options.Password = serverPassword;
ManagementScope scope = new ManagementScope("\\\\" + serverName + "\\root\\cimv2", options);
Console.WriteLine("Connecting to scope");
scope.Connect();
Console.WriteLine("Getting ManagementPath");
ManagementPath servicePath = new ManagementPath("Win32_Service.Name='" + serviceName + "'");
Console.WriteLine("Getting ManagementObject");
ManagementObject serviceObj = new ManagementObject(scope, servicePath, new ObjectGetOptions());
Console.WriteLine("Name of service is " + serviceObj["DisplayName"].ToString());
Console.WriteLine("Process ID of service is " + serviceObj["ProcessId"].ToString());
ManagementPath processPath = new ManagementPath("Win32_Process.ProcessId='" + serviceObj["ProcessId"] + "'");
ManagementObject processObj = new ManagementObject(scope, processPath, new ObjectGetOptions());
ManagementBaseObject processParams = processObj.InvokeMethod("Terminate", (ManagementBaseObject)null, null);
int returnCode = System.Convert.ToInt32(processParams.Properties["ReturnValue"].Value);
return returnCode;
}
catch (Exception connectEx)
{
Console.WriteLine("Connecting to " + serverName + " caused an exception");
Console.Write(connectEx);
return 99;
}
}
代码,如果通过流程的集合我循环:
public int KillServiceWMI(string serviceName, string serverName, string serverUser, string serverDomain, string serverPassword)
{
try
{
ConnectionOptions options = new ConnectionOptions();
options.Impersonation = System.Management.ImpersonationLevel.Impersonate;
options.Username = serverDomain + "\\" + serverUser;
options.Password = serverPassword;
ManagementScope scope = new ManagementScope("\\\\" + serverName + "\\root\\cimv2", options);
Console.WriteLine("Connecting to scope");
scope.Connect();
Console.WriteLine("Getting ManagementPath");
ManagementPath servicePath = new ManagementPath("Win32_Service.Name='" + serviceName + "'");
Console.WriteLine("Getting ManagementObject");
ManagementObject serviceObj = new ManagementObject(scope, servicePath, new ObjectGetOptions());
Console.WriteLine("Name of service is " + serviceObj["DisplayName"].ToString());
Console.WriteLine("Process ID of service is " + serviceObj["ProcessId"].ToString());
ObjectQuery serviceQuery = new ObjectQuery("SELECT * from Win32_Process WHERE ProcessID = '" + serviceObj["ProcessId"].ToString() + "'");
ManagementObjectSearcher serviceSearcher = new ManagementObjectSearcher(scope, serviceQuery);
ManagementObjectCollection serviceColl = serviceSearcher.Get();
int returnCode = 0;
foreach (ManagementObject currentObj in serviceColl)
{
if (currentObj["ProcessId"].ToString().Equals(serviceObj["ProcessId"].ToString(), StringComparison.OrdinalIgnoreCase))
{
Console.WriteLine("Found process " + currentObj["ProcessId"].ToString() + ". Terminating...");
ManagementBaseObject termParams = currentObj.InvokeMethod("Terminate", (ManagementBaseObject)null, null);
returnCode = System.Convert.ToInt32(termParams.Properties["ReturnValue"].Value);
}
}
return returnCode;
}
catch (Exception connectEx)
{
Console.WriteLine("Connecting to " + vaultName + " caused an exception");
Console.Write(connectEx);
return 99;
}
}
在问一个傻问题的风险 - 它必须是WMI/C#?你知道这可以从sysinternals的PSEXEC完成吗? – Leptonator
是的,我知道我可以使用psexec并以这种方式达到目的。在这种情况下,这是用于控制一堆服务器的Web应用程序的一种方法。他们中的一些人,微妙地说,是“pokey”,所以他们的服务在WMI指挥下不会停下来。所以Operations要求我为应用程序添加一个“kill”函数,以便在试图(和失败)干净地停止两次服务之后,尝试终止该进程。 – Formica
@paqogomez,我有一种感觉,你已经阅读[这个元问题](http://meta.stackexchange.com/questions/19190/should-questions-include-tags-in-their-titles),这就是什么激励了你最近的建议编辑。请阅读[评分最高的答案](http://meta.stackexchange.com/a/130208)的部分,该部分的开头部分是“您的标题中唯一使用标签的时间是*标题*的对话语气“(强调我的)。 –