我正在尝试使用WMI组件访问远程计算机的服务状态(如果有任何其他方式建议)。
以下是我的代码:
public void MonitorService()
{
ConnectionOptions con = new ConnectionOptions();
con.Username = "username";
con.Password = "password";
con.Authority = "ntlmdomain:somedomain";
con.Authentication = AuthenticationLevel.Connect;
con.EnablePrivileges = true;
con.Impersonation = ImpersonationLevel.Identify;
ManagementScope scope = new ManagementScope(@"\\machinename\root\cimv2", con);
scope.Connect();
ManagementPath path = new ManagementPath("Win32_Service");
ManagementClass services;
services = new ManagementClass(scope, path, null);
foreach (ManagementObject service in services.GetInstances())
{
// some manipulations
}
}
在scope.Connect()
,我从HRESULT获得错误"异常:0x80070005(E_ACCESSDENIED)"
我在ConnectionOption
中使用的用户在远程系统上拥有管理员权限。
我允许用户访问远程计算机中的WMI COM对象。我已经通过link但没有帮助我。请告诉我我缺少的东西。
答案 0 :(得分:1)
首先,尝试以管理员身份运行visual studio,或以管理员身份运行输出exe。
此外,您需要使用Impersonation = ImpersonationLevel.Impersonate而不是Identity,因此请尝试以下代码:
VB.NET:
Dim opt As ObjectGetOptions
opt = New ObjectGetOptions(Nothing, TimeSpan.MaxValue, True)
Using manClass As New ManagementClass("\\YOUR_MACHINE\root\cimv2", "Win32_Service", opt)
manClass.Scope.Options.EnablePrivileges = True
manClass.Scope.Options.Impersonation = ImpersonationLevel.Impersonate
manClass.Scope.Options.Username = "username"
manClass.Scope.Options.Password = "pass"
manClass.Scope.Options.Authority = "ntlmdomain:Domain"
End Using
C#:(在线转换)
ObjectGetOptions opt = default(ObjectGetOptions);
opt = new ObjectGetOptions(null, TimeSpan.MaxValue, true);
using (ManagementClass manClass = new ManagementClass("\\\\YOUR_MACHINE\\root\\cimv2", "Win32_Service", opt)) {
manClass.Scope.Options.EnablePrivileges = true;
manClass.Scope.Options.Impersonation = ImpersonationLevel.Impersonate;
manClass.Scope.Options.Username = "username";
manClass.Scope.Options.Password = "pass";
manClass.Scope.Options.Authority = "ntlmdomain:Domain";
}
有关详细信息,请参阅codeplex上的开源Windows Services Manager (Services+)。
答案 1 :(得分:0)
另一种选择(根据您的要求)将使用PowerShell远程处理。与WMI远程处理相比,Powershell远程处理以一种根本不同的方式工作。
Here是一个示例,偶然使用来自C#的Get-Service
cmdlet从远程计算机获取服务信息(默认为localhost
)
答案 2 :(得分:0)
首先,我建议不要将Authentication属性更改为默认值,除非您完全确定需要这样做。 Documentation for this property表示数据包级别身份验证用于Windows XP及更高版本,而连接级别身份验证用于Windows 2000及更低版本。默认设置将使用服务器指定的任何身份验证,这比指示服务器可能不接受的特定身份验证级别更有可能。你需要设置Authority属性也是不寻常的,因为默认情况下它将对当前用户的域使用NTLM身份验证,但这样做可能不会伤害任何东西。对于Impersonation属性,我同意Sameh应该使用ImpersonationLevel.Impersonate的值(也是默认值)。通常,您不必更改任何ConnectionOptions属性值,除非您需要连接除运行该程序的用户帐户以外的用户帐户,然后您只需要更改用户名和密码。
其次,我不太确定“允许管理员访问远程计算机上的WMI COM”的含义。根据我的经验,当远程WMI无法连接时,通常是因为Windows防火墙阻碍了它。如果您还没有,我还建议您在尝试连接的计算机上运行以下命令(请参阅您最初Connecting Through Windows Firewall所在页面中的链接linked)。
netsh防火墙设置服务RemoteAdmin启用
关于服务的API,.NET框架包括System.ServiceProcess.ServiceController类,它提供有关本地或远程计算机上的命名服务的信息并对其进行控制。但是,看起来这个API不允许在连接时指定用户名和密码,因此如果您没有以连接用户身份运行程序,这可能不是一个可行的解决方案。如果您将程序作为需要用于远程连接的帐户运行并想要尝试此类,请注意您必须添加对System.ServiceProcess的引用,因为它未包含在默认框架中大多数新VS项目的参考资料。