gpt4 book ai didi

c# - 无法使用 WMI 和 C# 远程终止进程

转载 作者:太空宇宙 更新时间:2023-11-03 13:34:54 38 4
gpt4 key购买 nike

我正在尝试编写一种方法,如果它无法使用 StopService 方法停止,将通过进程 ID 终止远程系统上的服务。我尝试了两种不同的方法来调用 ManagementObject 上的“Terminate”方法,但我得到了两个不同的错误。能够从 Terminate 方法获取返回代码对我来说也很重要。

如果我直接向要终止的进程声明 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;
}
}

最佳答案

我最终放弃了尝试在 Win32_Process 上使用 Terminate 方法,而是使用 Create 远程调用 TaskKill.exe。因为返回信息现在隐藏在 taskkill.exe 后面,所以我必须再次获取进程列表并查找目标 pid 以确保进程确实已终止。

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());

// use processid to kill process with taskkill
ObjectGetOptions processObjGetOpt = new ObjectGetOptions();
ManagementPath processPath = new ManagementPath("Win32_Process");
ManagementClass processClass = new ManagementClass(scope, processPath, processObjGetOpt);
ManagementBaseObject processInParams = processClass.GetMethodParameters("Create");
processInParams["CommandLine"] = string.Format("cmd /c \"taskkill /f /pid {0}\"", serviceObj["ProcessId"].ToString());
ManagementBaseObject outParams = processClass.InvokeMethod("Create", processInParams, null);
Console.WriteLine("Return code for taskkill: " + outParams["returnValue"]);
int returnCode = System.Convert.ToInt32(outParams["returnValue"]);

关于c# - 无法使用 WMI 和 C# 远程终止进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18993363/

38 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com