我正在使用WMI在远程计算机上安装/启动/停止等服务。这很好用,只有UserControlService
的调用似乎是一个问题。
我知道也可以冒充用户然后使用ServiceController类,但由于我已经有了所有其他方法,我宁愿保留WMI代码并让我的方法发送服务控制请求。
以下代码:
public static string SendServiceControlRequest(string remoteHost, string serviceName, string username,
string password, int request)
{
ConnectionOptions theConnection = new ConnectionOptions();
theConnection.Username = username;
theConnection.Password = password;
ManagementScope theScope = new ManagementScope(string.Format("\\\\{0}\\root\\cimv2", remoteHost), theConnection);
using (ManagementObject theClass = new ManagementObject(theScope, new ManagementPath("Win32_Service"),
new ObjectGetOptions())) // causes an ArgumentOutOfRangeException (Parametername: path)
{
using (ManagementBaseObject inParams = theClass.GetMethodParameters("UserControlService"))
{
inParams["ControlCode"] = (Byte)request;
ManagementBaseObject outParams = theClass.InvokeMethod("UserControlService", inParams, null);
return outParams["ReturnValue"].ToString();
}
}
}
引发System.Management.ManagementException
抱怨无效参数(请求150,这应该有效)。在theClass.InvokeMethod
上抛出异常我不确定为什么会发生这种情况,我从以下方法获得方法的描述:
http://msdn.microsoft.com/en-us/library/aa393952(v=vs.85).aspx
编辑:Hans Passant更正的工作版本:
public static bool SendServiceControlRequest(string remoteHost, string serviceName, string username,
string password, int request)
{
ConnectionOptions theConnection = new ConnectionOptions();
theConnection.Username = username;
theConnection.Password = password;
ManagementScope theScope = new ManagementScope(string.Format("\\\\{0}\\root\\cimv2", remoteHost),
theConnection);
string servicePath = string.Format("Win32_Service.Name='{0}'", serviceName);
ManagementPath path = new ManagementPath(servicePath);
using (ManagementObject theClass = new ManagementObject(theScope, path,
new ObjectGetOptions()))
{
using (ManagementBaseObject inParams = theClass.GetMethodParameters("UserControlService"))
{
inParams["ControlCode"] = (Byte)request;
ManagementBaseObject outParams = theClass.InvokeMethod("UserControlService", inParams, null);
return outParams["ReturnValue"].ToString() == "0";
}
}
}
答案 0 :(得分:1)
而不是
inParams["ControlCode"] = (Byte)request;
尝试
inParams.SetPropertyValue("ControlCode", (Byte)request);
修改强>
未经测试,但这似乎是您可能正在寻找的:
而不是
using (ManagementBaseObject inParams = theClass.GetMethodParameters("UserControlService"))
{
inParams["ControlCode"] = (Byte)request;
ManagementBaseObject outParams = theClass.InvokeMethod("UserControlService", inParams, null);
return outParams["ReturnValue"].ToString();
}
尝试使用ManagementClass实例(来自http://social.msdn.microsoft.com/Forums/vstudio/en-US/1dbe4995-ce73-4f01-8d9a-6cf1650bce8a/wmi-c-managementclassinvokemethod-failure):
foreach (var instance in theClass.GetInstances())
{
using (ManagementBaseObject inParams = instance.GetMethodParameters("UserControlService"))
{
inParams["ControlCode"] = (Byte)request;
ManagementBaseObject outParams = instance.InvokeMethod("UserControlService", inParams, null);
return outParams["ReturnValue"].ToString();
}
}
答案 1 :(得分:1)
是的,您的代码中存在错误。您正确地向方法添加了 serviceName 参数,但是您忘记了实际使用它。这很重要,你真的必须具体说明你将这个控制代码发送到哪个特定服务。
让它看起来像这样:
var path = string.Format("Win32_Service.Name='{0}'", serviceName);
var thePath = new ManagementPath(path);
var theClass = new ManagementObject(theScope, thePath, null);
// etc...