2012-03-13 7 views
1

このコードはほとんどの場合、私のサーバーのほとんどで動作しますが、特定のサーバーでは次のコードクエリ。このコードはSQL Server Service Firstを照会し、2番目の部分ではSQL Sevrer Agent Serviceを照会します。WMIスロー例外2回目の同じサーバーへの照会時に「無効なクエリ」が発生しました

私は別のスコープとクエリオブジェクトを作成する可能性のあるすべての組み合わせを試しましたが、何とかクエリしようとしているサーバーは、スコープが接続された後最初のクエリが実行され、サーバー上の何かによって!このサーバーのほとんどのサーバーは正常に動作し、結果は返ってきますが、2台または3台のサーバーが2台目で失敗します。

これはサーバー上のWMIの問題です。これらのステータスを達成するための他の方法はありますか? IPCやソケットのような..?助けてください..!

ハッシュ。

try 
{ 
    agentserviceName = "SQLSERVERAGENT"; 
    serviceName = "MSSQLSERVER"; 
    query = new System.Management.SelectQuery(string.Format("select name, startname, State, StartMode from Win32_Service where name = '{0}'", serviceName)); 
    ManagementScope scope = new ManagementScope("\\\\" + srvName + "\\root\\cimv2"); 
    //ManagementScope scope = new ManagementScope("\\\\ST0176V\\root\\cimv2"); 
    scope.Connect(); 
    System.Management.ManagementObjectSearcher searcher = new System.Management.ManagementObjectSearcher(scope, query); 

    // MessageBox.Show((String)dgv_ChangeSvcAccount.Rows[i].Cells[1].Value.ToString()); 
    foreach (ManagementObject service in searcher.Get()) 
    { 
     dgv_ChangeSvcAccount.Rows[i].Cells[4].Value = service["startname"]; 
     dgv_ChangeSvcAccount.Rows[i].Cells[4].Tag = serviceName; 
     dgv_ChangeSvcAccount.Rows[i].Cells[5].Value = "Currently : " + service["State"] + " - Set As : " + service["StartMode"]; 
    } 

    if (searcher.Get().Count == 0) 
    { 
     dgv_ChangeSvcAccount.Rows[i].Cells[4].Value = "NO SQL Service Found"; 
    } 

    searcher.Dispose(); 

    ManagementScope scope2 = new ManagementScope("\\\\" + srvName + "\\root\\cimv2"); 

    // ObjectQuery query2 = new ObjectQuery("SELECT * FROM Win32_Service WHERE NAME LIKE '" + serviceName.ToString().ToUpper() + "'"); 

    System.Management.SelectQuery query2 = new System.Management.SelectQuery(string.Format("select name, startname, State, StartMode from Win32_Service where name like '{0}'", agentserviceName)); 
    System.Management.ManagementObjectSearcher searcher1 = new System.Management.ManagementObjectSearcher(scope2, query2); 
    foreach (ManagementObject service in searcher1.Get()) // <---- this line throws exception for invalid query, and it is always 2 servers which does that, rest of servers returns proper results. the servers which throws this Invlid Query exceptions are Windows 2000 Server with SP4. 
    { 
     dgv_ChangeSvcAccount.Rows[i].Cells[6].Value = service["startname"]; 
     dgv_ChangeSvcAccount.Rows[i].Cells[6].Tag = agentserviceName; 
     dgv_ChangeSvcAccount.Rows[i].Cells[7].Value = "Currently : " + service["State"] + " - Set As : " + service["StartMode"]; 
    } 
    searcher1.Dispose();   
} 
catch (System.Exception ex) 
{ 
    MessageBox.Show(ex.Message.ToString()); 
} 
+0

「例外」をどの行が投げているのか、またどのデータであるのか具体的に教えてください。それは 'foreach'ブロックの' searcher1.Get() 'への呼び出しですか?常に同じサーバが故障していますか? – BACON

+0

ありがとうございましたBACONさん、詳細を紛失して申し訳ありません。私は、エラーをスローするコードにコメントを追加しました。これらのサーバーはSP4のWindows 2000サーバーであり、excpetionをスローする行はforeach(ManagementObjectサービスsearcher1.Get())、この中のデータは、このサービスのStartName、State、およびStartModeでなければなりません。 – user1265448

+0

別のサービス名でフィルタリングするだけで、まったく同じクエリを2回実行しているように見えます。私はあなたが 'scope.Connect()'を呼んでいるが、 'scope2.Connect()'を呼んでいないことに気づいていますが、 'Connect'メソッドのドキュメントではこのスコープが暗黙的に呼び出されていますそれが接続されることを必要とする操作」。たぶん、Windows 2000は2つの同時スコープ接続が気に入らないでしょうか? 2番目の 'foreach'ブロックの前に' scope2.Connect() 'を挿入して、その行に失敗するかどうか確認してください。 – BACON

答えて

3

我々はコメントで議論されてきたように、我々はそれが複数のアクティブManagementScopeオブジェクトを持つとしなければならないかもしれません考えている、ので、これにあなたのコードの最初の半分を変更してみてくださいは:

string agentserviceName = "SQLSERVERAGENT"; 
string serviceName = "MSSQLSERVER"; 
// Let the SelectQuery class build our WQL query text... 
string className = "Win32_Service"; 
string condition = string.Format("Name = '{0}'", serviceName); 
string[] selectedProperties = new string[] { "Name", "StartName", "State", "StartMode" }; 
SelectQuery query = new SelectQuery(className, condition, selectedProperties); 

using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(query)) 
{ 
    searcher.Scope = new ManagementScope("\\\\" + srvName + "\\root\\cimv2"); 

    foreach (ManagementObject service in searcher.Get()) 
    { 
     dgv_ChangeSvcAccount.Rows[i].Cells[4].Value = service["startname"]; 
     dgv_ChangeSvcAccount.Rows[i].Cells[4].Tag = serviceName; 
     dgv_ChangeSvcAccount.Rows[i].Cells[5].Value = "Currently : " + service["State"] + " - Set As : " + service["StartMode"]; 
    } 

    if (searcher.Get().Count == 0) 
    { 
     dgv_ChangeSvcAccount.Rows[i].Cells[4].Value = "NO SQL Service Found"; 
    } 
} 

// Second query goes here... 

最初のクエリが使用された時点でManagementObjectSearcherを処理し、リモートサーバーのManagementScopeへの唯一の参照を保持するようにします。

+0

Bravo .. !!!!ブラボー..!これは素晴らしい作品です。これは完璧なソリューションです!非常によく考えて..!私はこの方法を理解できませんでした..!もう一度Thnak ..!この解決策は..! WMIの代わりにクイックQestionを使用するだけで、IPCまたはソケットを使用してサービスステータスを照会することができます。任意の例のサイト..?どうして私は多くの他のサーバーでWMIが壊れているのか、RPCサービスが壊れているのか、WMIを使わずにどうやってそれらにアクセスするのか不明な点があります。とにかく..!この件に関してあなたの返事をありがとうございました...! – user1265448

+0

[Win32 API for services](http://msdn.microsoft.com/library/windows/desktop/ms685974.aspx)をP /呼び出して実行できます。ドキュメントをブラウズするだけで、[OpenSCManager](http://msdn.microsoft.com/library/windows/desktop/ms684323.aspx)、[OpenService](http://msdn.microsoft.com/library/ windows/desktop/ms684330.aspx)、および[QueryServiceStatusEx](http://msdn.microsoft.com/library/windows/desktop/ms684941.aspx)関数を使用すると、そこにアクセスする可能性があります。しかし、私はこれまでに(P/InvokeやCを通して)これをやったことはありません。あなたはそのために新しい質問を開くべきです。 – BACON

+0

ありがとうBACON ..!私はあなたの提案で最初に手を汚すようにしようとします。どうもありがとうございました..!楽しんで..! – user1265448

関連する問題