我正試圖編寫一個方法,如果它無法停止使用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)的部分,該部分的開頭部分是「您的標題中唯一使用標籤的時間是*標題*的對話語氣「(強調我的)。 –