我正在尝试编写一个方法,如果它无法停止使用 StopService 方法,它将通过进程 ID 终止远程系统上的服务。我尝试了两种在 ManagementObject 上调用“终止”方法的不同方法,但我得到了两个不同的错误。对我来说,能够从 Terminate 方法获取返回码也很重要。
如果我直接向要终止的进程声明 ManagementPath,则会在以下行收到错误“System.Management.ManagementException: Invalid object path”:
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;
}
}