2012-03-13 4 views
1

이 코드는 대부분 내 서버에서 작동하지만 거의 모든 시간 동안이 코드가 작동하지만 일부 특정 서버의 경우 두 번째 부분에서 실패합니다. 질문. 이 코드는 SQL Server Service를 먼저 쿼리하고 두 번째 부분에서는 SQL Sevrer Agent Service를 쿼리합니다.WMI throw 예외 두 번째 시도에서 동일한 서버를 쿼리 할 때 "잘못된 쿼리"

다른 범위 및 쿼리 개체를 만들 수있는 가능한 모든 조합을 시도했지만 어떻게 든 쿼리하려고 시도하는 서버가 범위 연결 및 첫 번째 쿼리가 실행 된 후 두 번째 부분이 차단 된 것처럼 보이는 초당 부분을 반환하지 않습니다. 서버에서 뭔가로 ..! 이 중 하나에 대한 도움을 주시면 감사하겠습니다 .. 거의 99 %의 서버가 정상적으로 작동하고 원하는 결과를 반환하지만 두 번째 또는 세 번째 서버는 두 번째 부분에 실패합니다 ..

서버의 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을 throw하는 줄은 foreach (ManagementObject 서비스가 포함 된 것입니다. searcher1.Get())에서이 데이터는 StartName, State 및 StartMode가되어야합니다. – user1265448

+0

다른 서비스 이름을 필터링하는 것만으로 동일한 쿼리를 두 번 실행하는 것처럼 보입니다. 그래서 왜 다른 서비스 이름이 작동하는지 상상할 수는 없지만 다른 서비스 이름은 상상할 수 없습니다. 나는 당신이'scope.Connect()'를 호출하고 있지만'scope2.Connect()'를 호출하지 않는다는 것을 알아 차릴 수있다. 그러나이 메소드는 문서에서'Connect' 메소드에 대해 말하고있다. "이 메소드는 scope가 사용되었을 때 암묵적으로 호출된다. 연결이 필요한 작업. " Windows 2000은 두 개의 동시 스코프 연결을 좋아하지 않을 수도 있습니다. 두 번째'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 .. !!!! 브라보..! 이 훌륭한 작동합니다 ..이 완벽한 솔루션입니다! 아주 잘 생각 ..! 나는 couldnt한다이 길을 이해했다. 다시 한번 너를 Thnak ..! 이 솔루션은 .. 완료됩니다! WMI 대신 Quick Qestion 만 있으면 IPC 또는 소켓을 사용하여 서비스 상태를 쿼리 할 수있는 다른 방법이 있습니까? 모든 예제 사이트 ..?왜 나는 다른 많은 서버에서 WMI가 손상되었거나 RPC 서비스가 고장 났으며 WMI를 사용하지 않고 서버에 연결하는 방법을 모르는 것입니다. 어쨌든.. ! 이 문제에 대해 회신 해 주셔서 감사합니다 ...! – user1265448

+0

P/Inviles [서비스 용 Win32 API] (http://msdn.microsoft.com/library/windows/desktop/ms685974.aspx)로이 작업을 수행 할 수 있습니다. 설명서를 빨리 ​​살펴보면 [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