C# 使用WMI COM对象监视远程服务

C# 使用WMI COM对象监视远程服务,c#,service,wmi,C#,Service,Wmi,我正在尝试使用WMI组件访问远程计算机的服务状态(如果有任何替代方案,请建议)。 下面是我的代码: public void MonitorService() { ConnectionOptions con = new ConnectionOptions(); con.Username = "username"; con.Password = "password"; co

我正在尝试使用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)”

我在
连接选项中使用的用户在远程系统上具有管理员权限。

我已允许用户访问远程计算机中的WMI COM对象。我已经经历了许多困难,但没有帮助我。请告诉我缺少什么。

首先,尝试以管理员身份运行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:(在线转换)

有关更多信息,请参阅codeplex上的开放源码。

另一种选择(根据您的要求)是使用PowerShell远程处理。Powershell远程处理的工作方式与WMI远程处理完全不同


是一个示例,附带使用C#中的
Get Service
cmdlet从远程计算机获取服务信息(默认为
localhost

首先,我建议不要更改身份验证属性的默认值,除非您绝对确定需要这样做。表示数据包级身份验证用于Windows XP及以上版本,而连接级身份验证用于Windows 2000及以下版本。默认设置将使用服务器指定的任何身份验证,这比指定服务器可能不接受的特定身份验证级别更有可能起作用。您需要设置Authority属性也是不寻常的,因为默认情况下,它将对当前用户的域使用NTLM身份验证,但这样做可能不会造成任何影响。对于Impersonation属性,我同意Sameh的观点,即应该使用ImpersonationLevel.Impersonate的值(也是默认值)。通常,您不必更改任何ConnectionOptions属性值,除非您需要连接的用户帐户不是程序运行时使用的帐户,然后您只需更改用户名和密码

其次,我不太清楚你所说的“允许管理员访问远程计算机上的WMI COM”是什么意思。根据我的经验,当远程WMI无法连接时,通常是因为Windows防火墙阻碍了连接。如果您还没有,我还建议在您尝试连接的机器上运行下面的命令(请参阅您最初连接到的页面中的链接)

netsh防火墙设置服务RemoteAdmin启用


关于服务的API,.NET framework包括类,该类提供有关本地或远程计算机上命名服务的信息和对该服务的控制。但是,该API似乎不允许在连接时指定用户名和密码,因此如果您不是以连接用户的身份运行该程序,那么这可能不是一个可行的解决方案。如果您正在以需要用于远程连接的帐户运行该程序,并希望尝试此类,请注意,您必须添加对System.ServiceProcess的引用,因为大多数新VS项目的默认框架引用中都不包含该引用。

尝试了所有ImpersonationLevel选项,并尝试以管理员权限运行VS,仍然收到相同的“拒绝访问”消息。在这里,我面临WSManConnectionInfo类的问题,即使在使用powershell v1中所需的dll添加引用之后也是如此。问题是什么?请随意问另一个问题。:)(或者如果是小的/相关的,请留下评论)
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";
}