- 締切済み
VB.NetのWMIを用いたリモート端末への接続
下記の環境で作成したWinアプリからWMIを用いてリモート 端末に接続し、その端末のCPU使用率を取得しようとする と、下記ソースの30行目実行時に不定期間隔でエラーに なったりならなかったりします。どのたか解決策をご存知でし たら、お教え願います。 開発環境:VisualStudio 2005 / .NET FrameWorkバージョン:2.0 開発言語:VB.NET リモート接続端末:Windows Server 2003 R2 リモート接続ポート:135 リモートインストール済み.NET FrameWorkバージョン:1.0、2.0 エラー内容:「オブジェクト参照がオブジェクト インスタンスに設定されていません。」 以下ソース↓ Imports System.Management Public Class Form1 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim Query As New ObjectQuery Dim Options As New ConnectionOptions Dim Scope As New ManagementScope Dim Searcher As New ManagementObjectSearcher Dim PrcCol As ManagementObjectCollection Dim sngCpu使用率 As Single = 0 Dim objPrc As ManagementBaseObject = Nothing Try Query.QueryString = "SELECT * FROM Win32_Processor" Options.Username = "接続端末名" + "\" + "ログインID" Options.Password = "ログインパスワード" Scope.Options = Options Scope.Path.Server = "接続端末名" Searcher.Query = Query Searcher.Scope = Scope Do PrcCol = Searcher.Get For Each objPrc In PrcCol 'CPU使用率取得 sngCpu使用率 = CSng(objPrc("LoadPercentage").ToString) '←ここでエラー Next Loop Catch ex As Exception MsgBox(ex.Message, MsgBoxStyle.Critical) End Try End Sub End Class ここまで ↑
- みんなの回答 (2)
- 専門家の回答
みんなの回答
- vbhanatyan
- ベストアンサー率79% (70/88)
>リモート端末にインストールされているFrameWorkの仕様もしくはバグで >はないかと考えています。 そこまでお調べになったのなら、開発環境の FrameWork のバージョンとサービスパックが 同じかどうかをお調べになり、開発環境と同じFrameWork のバージョンとサービスパックを インストールして見たら動作するのではないですか? 確かに、FrameWork 1.1 の SP1 では、WMI に不具合がありましたが、それ以降は問題ないように 聞いております。 因みに、私の環境では、.NET Framework 2.0 のバージョンは、2.0.50727.4016 です。
- vbhanatyan
- ベストアンサー率79% (70/88)
Do PrcCol = Searcher.Get For Each objPrc In PrcCol 'CPU使用率取得 sngCpu使用率 = CSng(objPrc("LoadPercentage").ToString) '←ここでエラー Next Loop このように永遠と超高速に取得しているからではないですか? ループの部分をタイマーコントロールを使って 500 ミリ秒間隔位で取得してどうなりますか?
お礼
ご回答ありがとうございます。 ご参考にさせて頂きます。
補足
vbhanatyanさん ご回答ありがとうございます。 ご指摘頂いたように、タイマーコントロールを用いて 500ミリ秒間隔で取得するように修正しましたが、 エラーになります。ちなみに10000ミリ秒間隔でも エラーになるため、WMIの実行間隔とエラーの関係 性は低いと考えられます。 エラーになる理由を詳細に説明しますとWMI実行時に リモート端末のリソースコレクションが取得できず、参照型 の変数(objPrc)の参照先がNothingのため、ToStringメッソ ド呼出時にエラーなっしまいます。なので原因はリモート端末 側に有ると考えています。 いろいろと調査しましたが、現在把握している状況は 1.エラーになるリモート端末とならないリモート端末が有る。 2.エラーにならないリモート端末のみ、FrameWork4.0が インストールされている。 3.FrameWorkを用いないWMI接続(VB6.0)ではエラーにな らない。 4.リモート端末、監視端末共にWMIのサービスは起動して いる。 5.リモート端末、監視端末共にCPUパワーやメモリの消費 に余裕がある。 上記の把握状況から、今回のエラー(現象)はリモート端末 にインストールされているFrameWorkの仕様もしくはバグで はないかと考えています。
お礼
ご回答ありがとうございます。 参考にさせて頂きます。
補足
vbhanatyanさん 回答が遅くなり申し訳ないです。 結果、解決しました。 制約上の問題が有り、接続先ホストのFrameworkのバージョンを更新 することはできませんでした。 解決方法としては、CPU使用率を取得するWMIクラスを変更すること で対応できました。以下、修正したソースです。 Private Function Win32_PPOS_Processor() As Boolean Dim Query As New ObjectQuery Dim Options As New ConnectionOptions Dim Scope As New ManagementScope Dim Searcher As New ManagementObjectSearcher Dim PrcCol As ManagementObjectCollection Dim objPrc As ManagementBaseObject = Nothing Dim dblPT1 As Double = 0 Dim dblUT1 As Double = 0 Dim dblTS1 As Double = 0 Dim dblPT2 As Double = 0 Dim dblUT2 As Double = 0 Dim dblTS2 As Double = 0 Dim dblPT差分 As Double = 0 Dim dblUT差分 As Double = 0 Dim dblTS差分 As Double = 0 Dim dblCpu使用率 As Double = 0 Dim intCpu使用率 As Integer = 0 Try 'WQLコマンド設定 Query.QueryString = "SELECT Name" + _ ",PercentPrivilegedTime" + _ ",PercentUserTime" + _ ",Timestamp_Sys100NS " + _ "FROM Win32_PerfRawData_PerfOS_Processor " + _ "WHERE Name = '_Total'" '接続IDとパスワードを設定 Options.Username = Me.txtホスト名.Text + "\" + Me.txtID.Text Options.Password = Me.txtPass.Text '接続情報設定 Scope.Options = Options Scope.Path.Server = Me.txtホスト名.Text 'WQLコマンド実行クラスにWQLコマンド、接続情報を設定 Searcher.Query = Query Searcher.Scope = Scope 'リソースコレクション取得 PrcCol = Searcher.Get For Each objPrc In PrcCol dblPT1 = CDbl(objPrc("PercentPrivilegedTime")) dblUT1 = CDbl(objPrc("PercentUserTime")) dblTS1 = CDbl(objPrc("Timestamp_Sys100NS")) Next '5秒間停止 System.Threading.Thread.Sleep(500) 'リソースコレクション再取得 PrcCol = Searcher.Get For Each objPrc In PrcCol dblPT2 = CDbl(objPrc("PercentPrivilegedTime")) dblUT2 = CDbl(objPrc("PercentUserTime")) dblTS2 = CDbl(objPrc("Timestamp_Sys100NS")) Next '差分算出 dblPT差分 = dblPT2 - dblPT1 dblUT差分 = dblUT2 - dblUT1 dblTS差分 = dblTS2 - dblTS1 If dblTS差分 > 0 Then 'CPU使用率算出 dblCpu使用率 = (dblPT差分 + dblUT差分) / (dblTS差分) * 100 intCpu使用率 = CInt(dblCpu使用率) End If Catch ex As Exception MsgBox(ex.Message, MsgBoxStyle.Critical) End Try End Function