WMI 錯誤: 0x80070005 (Access Denied)

問題

使用 WMI 查詢系統資訊時,若查詢對象是本機電腦,程式可正常執行,但如果是遠端機器,則會出現錯誤:Access denied,錯誤代碼為 0x80070005。

原因

通常是被安全機制擋掉了。

解法

先確定作業環境的設定沒有問題,再來看程式碼的寫法。

作業環境:
  • 確保應用程式所在的機器以及欲存取的遠端機器之間沒有防火牆阻隔。最快的確認方法就是把所有硬體、軟體防火牆都關閉。
  • 確認目標電腦有啟用 DCOM。參考下圖。



確認環境設定無誤之後,再來看程式的寫法。底下是先前一篇有關 WMI 的筆記裡面的程式碼:


    public static class WmiQueryHelper
    {
        public static void Run(string hostName, string userName, string password, IWmiQueryResultReader reader)
        {
            StringBuilder sb = new StringBuilder();

            if (String.IsNullOrEmpty(hostName))
            {
                hostName = "localhost";
            }

            string scopeString = String.Format(@"\\{0}\root\cimv2", hostName);

            ManagementScope scope = new ManagementScope(scopeString);

            if ("127.0.0.1".Equals(hostName) == false && "localhost".Equals(hostName) == false)
            {
                ConnectionOptions co = new ConnectionOptions();
                co.Username = userName;  // 系統管理員帳號
                co.Password = password;  // 系統管理員密碼
                co.Authentication = AuthenticationLevel.Default;
                co.Impersonation = ImpersonationLevel.Impersonate;
                scope.Options = co;
            }

            scope.Connect();

            ObjectQuery query = new ObjectQuery(reader.QueryString);

            using (ManagementObjectSearcher moSearcher = new ManagementObjectSearcher(scope, query))
            {
                ManagementObjectCollection results = moSearcher.Get();
                reader.Read(results);
            }           
        }
    }

注意裡面有兩行設定 ConnectionOptions 物件的 Authentication 和 Impersonation 屬性的程式碼,分別用來指定 DCOM 呼叫的驗證等級和模擬等級。如果是存取本機的 WMI 服務,這兩個屬性可以不設定,但如果是存取遠端機器,可試試將驗證等級設定為 Default,且模擬等級設定為 Impersonate,應該就能解決 0x80070005 的問題。

沒有留言:

技術提供:Blogger.
回頂端⬆️