1

已解决,如果any1需要它以供参考,已在其他线程中得到答案..

解释:

本地 WMI 工作,但现在我正在尝试远程进行。我已经尝试禁用两个防火墙,检查 WMI 权限(使用管理员帐户登录),这应该没问题。然而,当尝试连接 IP 时,我不断收到:0x800706BA 错误,但使用 PC 名称时,没有显示错误,但 WMI 没有显示任何结果。

Lansweeper 成功了。(http://www.lansweeper.com/kb/3/WMI-Access-is-denied.html

连接错误:managementScope.Connect() 处的 0x800706BA

System.Runtime.InteropServices.COMException (0x800706BA):RPC 服务器不可用。(来自 HRESULT 的异常:0x800706BA)在 System.Management.ManagementScope.Initialize() 的 System.Management.ThreadDispatch.Start() 在 System.Management.ManagementScope.Connect() 在 Admin_Helper.frmRemoteInformation.button1_Click(Object sender, EventArgs e)在 c:\Users\Stef\Documents\Visual Studio 2012\Projects\Admin_Helper\Admin_Helper\frmRemoteInformation.cs:System.Windows.Forms.Control.OnClick(EventArgs e) 处 System.Windows.Forms.Button.OnClick 的第 110 行(EventArgs e) 在 System.Windows.Forms.Button.OnMouseUp(MouseEventArgs 事件) 在 System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks) 在 System.Windows.Forms.Control.WndProc(Message& m) 在 System.Windows.Forms.ButtonBase。

-

问题:

检查连接是否成功/失败或其 wmi 以及如何修复它的最佳方法是什么。

 ManagementScope managementScope;
    ObjectQuery query;
    private void btnConnect_Click(object sender, EventArgs e)
    {
        try
        {
            ConnectionOptions remoteConnectionOptions = new ConnectionOptions();
            remoteConnectionOptions.Impersonation = ImpersonationLevel.Impersonate;
            remoteConnectionOptions.EnablePrivileges = true;
            remoteConnectionOptions.Authentication = AuthenticationLevel.Packet;
            remoteConnectionOptions.Username = txtUsername.Text;
            remoteConnectionOptions.Password = txtPassword.Text;

            managementScope = new ManagementScope(@"\\" + txtServer.Text + @"\root\CIMV2", remoteConnectionOptions);
            managementScope.Connect();
            MessageBox.Show("Connected");
        }
        catch (Exception ex) { MessageBox.Show(ex.Message); }

    }

    private void cmbClassSelection_SelectedIndexChanged(object sender, EventArgs e)
    {
            var dctPropertyList = new Dictionary<string, string>();
            query = new ObjectQuery(cmbClassSelection.SelectedItem.ToString());
            new Thread(() => FindWMI(managementScope, query, dctPropertyList, lstProperties)).Start();
    }
    private void FindWMI(ManagementScope scope, ObjectQuery query, Dictionary<string, string> dct, ListView listView)
    {
        try
        {
            List<ListViewItem> itemsList = new List<ListViewItem>();

            ManagementObjectSearcher moSearcher = new ManagementObjectSearcher(scope, query);
            Invoke(new MethodInvoker(() =>
            {
                listView.Items.Clear();
            }));

            foreach (ManagementObject moObject in moSearcher.Get())
            {
                if (moObject != null)
                {
                    foreach (PropertyData propData in moObject.Properties)
                    {
                        if (propData.Value != null && propData.Value.ToString() != "" && propData.Name != null && propData.Name != "")
                            dct[propData.Name] = propData.Value.ToString();
                    }
                }
            }
            foreach (KeyValuePair<string, string> listItem in dct)
            {
                ListViewItem lstItem = new ListViewItem(listItem.Key);
                lstItem.SubItems.Add(listItem.Value);
                itemsList.Add(lstItem);
            }

            Invoke(new MethodInvoker(() =>
            {
                listView.Items.AddRange(itemsList.ToArray());
            }));
        }
        catch (Exception) { }
    }

更新:

问题似乎与 WMI 有关。

更新2:

. 有史以来最愚蠢的错误。不得不改变两件事:

  1. remoteConnectionOptions.Username = txtUsername.Text; ==> remoteConnectionOptions.Username = txtServer.Text + @"\" + txtUsername.Text; 这将给出:“服务器名称\用户名”

  2. 查询 = 新 ObjectQuery(cmbClassSelection.SelectedItem.ToString()); ==> objectQuery = new ObjectQuery("select * from " + cmbClassSelection.SelectedItem.ToString());

因为我使用组合框,所以忘记了“select * from”。

万一有人需要代码,我会在清理一下之后更新它。

4

1 回答 1

2

我自己想通了:

请务必检查防火墙和 WMI 设置...

好的,检查连接是否成功的一种方法是:

ManagementScope myscope = new ManagementScope(@"\\Server\Username", ConnectionOptions);

if (myscope.IsConnected) { MessageBox.Show("Connected"); } else { MessageBox.Show("Disconnected"); }

现在您知道您的连接是否有效,然后只需搜索标准查询即可尝试并将其与您自己的代码进行比较...

示例:msdn 上的示例

完成代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;
using System.Management;
using System.Diagnostics;

namespace Admin_Helper
{
public partial class frmRemoteInformation : Form
{
    public frmRemoteInformation()
    {
        InitializeComponent();
    }

    string strServername;
    string strUsername;
    string strPassword;
    string strClassSelection;
    ConnectionOptions rcOptions;
    ManagementObjectCollection moCollection;
    ObjectQuery oQuery;
    ManagementObjectSearcher moSearcher;
    ManagementScope mScope;

    private void frmRemoteInformation_Load(object sender, EventArgs e)
    {
        if (mScope.IsConnected == true) { lblConnectionStateWarning.Text = "Connected"; } else { lblConnectionStateWarning.Text = "Disconnected"; } //I have a label that displays connectionstate, you can leave that out
    }

    private void btnConnect_Click(object sender, EventArgs e)
    {
        try
        {
            strServername = txtServer.Text;
            strUsername = txtUsername.Text;
            strPassword = txtPassword.Text;

            remoteConnection(strServername, strUsername, strPassword);
        }
        catch (Exception ex) { MessageBox.Show(ex.Message); }

    }

    private void cmbClassSelection_SelectedIndexChanged(object sender, EventArgs e)
    {
            var dctPropertyList = new Dictionary<string, string>();
            strClassSelection = cmbClassSelection.SelectedItem.ToString();
            new Thread(() => FindWMI(strServername, strClassSelection, rcOptions, dctPropertyList, lstProperties)).Start();
    }

    private void remoteConnection(string servername, string username, string password)
    {
        try
        {
            rcOptions = new ConnectionOptions();
            rcOptions.Authentication = AuthenticationLevel.Packet;
            rcOptions.Impersonation = ImpersonationLevel.Impersonate;
            rcOptions.EnablePrivileges = true;
            rcOptions.Username = servername + @"\" + username;
            rcOptions.Password = password;

            mScope = new ManagementScope(String.Format(@"\\{0}\root\cimv2", servername), rcOptions);
            mScope.Connect();
            if (mScope.IsConnected == true) { MessageBox.Show("Connection Succeeded", "Alert"); } else { MessageBox.Show("Connection Failed", "Alert"); }
            if (mScope.IsConnected == true) { lblConnectionStateWarning.Text = "Connected"; } else { lblConnectionStateWarning.Text = "Disconnected"; } //I have a label that displays connectionstate, you can leave that out

        }
        catch (Exception ex) { MessageBox.Show(ex.Message); }
    }

    private void FindWMI(string servername, string classSelection, ConnectionOptions rcOptions, Dictionary<string, string> dct, ListView listView)
    {
        try
        {
            List<ListViewItem> itemsList = new List<ListViewItem>();
            oQuery = new ObjectQuery("select * from " + classSelection);
            moSearcher = new ManagementObjectSearcher(mScope, oQuery);
            moCollection = moSearcher.Get();

            Invoke(new MethodInvoker(() =>
            {
                listView.Items.Clear();
            }));

            foreach (ManagementObject mObject in moCollection)
            {
                if (mObject != null)
                {
                    foreach (PropertyData propData in mObject.Properties)
                    {
                        if (propData.Value != null && propData.Value.ToString() != "" && propData.Name != null && propData.Name != "")
                            dct[propData.Name] = propData.Value.ToString();
                    }
                }
            }

            foreach (KeyValuePair<string, string> listItem in dct)
            {
                ListViewItem lstItem = new ListViewItem(listItem.Key);
                lstItem.SubItems.Add(listItem.Value);
                itemsList.Add(lstItem);
            }

            Invoke(new MethodInvoker(() =>
            {
                listView.Items.AddRange(itemsList.ToArray());
            }));
        }
        catch (Exception) { }
    }

    private void frmRemoteInformation_FormClosed(object sender, FormClosedEventArgs e)
    {
        foreach (System.Diagnostics.Process myProc in System.Diagnostics.Process.GetProcesses())
        {
            if (myProc.ProcessName == "WmiPrvSE")
            {
                myProc.Kill();
            }
        }

        if (mScope.IsConnected == true) { mScope.Options.Authentication = AuthenticationLevel.None; }; //Change option so that the connection closes, no disconnect option
    }

}
}
于 2013-01-31T19:22:46.960 回答