2016-09-13 102 views
0

我正在使用Delphi 2007創建一個將重新啓動網絡連接的計算機的應用程序。使用WMI捕捉EOleException

我有一個名爲rebootMachine的單元,當嘗試連接不通信的計算機時失敗。出於某種原因,如果用戶嘗試重新啓動可能處於脫機狀態的計算機,則該軟件需要能夠處理此情況。當我運行下面的代碼,它停止在

WMIService := SWbemLocator.ConnectServer(host, 'root\CIMV2', username, password); 

我嘗試使用try/catch塊,但它沒有趕上連接失敗,我不知道爲什麼。我提出的錯誤聲明瞭一個EOleException,消息「RPC服務器不可用」。這是真的,因爲機器不在線。在此之後,我得到一條訪問違規消息,讀取地址爲000000000.要注意,如果計算機在線,相同的代碼工作得很好。

function rebootMachine(host: string; username: string; password: string) 
    : Integer; 
const 
    wbemFlagForwardOnly = $00000020; 

var 
    WMIService : OLEVariant; 
    WbemObjectSet: OLEVariant; 
    WbemObject : OLEVariant; 
    SWbemLocator : OLEVariant; 
    oEnum  : IEnumvariant; 
    iValue  : LongWord; 
    mResult  : Integer; 

begin 
    try 
     CoInitialize(nil); // Initializes the COM library on the current thread 
     mResult := -1; 
     // create our wmi object 
     SWbemLocator := CreateOleObject('WbemScripting.SWbemLocator'); 

     // connect remotely to the machine 
     WMIService := SWbemLocator.ConnectServer(host, 'root\CIMV2', username, password); 
.... 
    except 
     on E: EOleException do 
     begin 
      LogFiles.NewException(E); 
      mResult := E.ErrorCode; 
      result := mResult; 
     end; 
    end; 
end; 

所以問題是,我該如何正確捕捉EOleException?

+0

感嘆。顯示完整的MCVE。 –

+0

只是一個想法,但你只捕捉EOleExceptions。如果在EOleException之後還發現了其他異常,會發生什麼? – GuidoG

+0

爲什麼不使用Windows API函數「InitiateSystemShutdown」重新啓動遠程計算機?如果函數失敗「GetLastError」應該給你的原因,這可能是連接到遠程計算機失敗。 –

回答

0

我認爲你所看到的是第一次機會例外,它被SWbemLocator.ConnectServer所困,這就是你爲什麼不能自己陷入困境的原因。我認爲在這種情況下,退貨價值爲零。如果這是正確的,您的代碼可以簡單地調整像這樣

var 
    WMIService : OLEVariant; 
    WbemObjectSet: OLEVariant; 
    WbemObject : OLEVariant; 
    SWbemLocator : OLEVariant; 
    oEnum  : IEnumvariant; 
    iValue  : LongWord; 
    mResult  : Integer; 

begin 
    try 
     CoInitialize(nil); // Initializes the COM library on the current thread 
     mResult := -1; 
     // create our wmi object 
     SWbemLocator := CreateOleObject('WbemScripting.SWbemLocator'); 

     // connect remotely to the machine 
     WMIService := SWbemLocator.ConnectServer(host, 'root\CIMV2', username, password); 
     if assigned(WMIService) then 
     begin 
      ... 
     end; 
    except 
     // good idea to put this in anyway, but not relevant to action 
    end; 
end; 
+0

嗨@DSM,不幸的是,代碼沒有得到設置WMIService的設置。它在WMIService上失敗:= SWbemLocator.ConnectServer(主機,'root \ CIMV2',用戶名,密碼);.另外,由於OLEvariant類型,我無法檢查它是否被分配。編譯器抱怨這些類型不兼容。 – BinaryAssault

0

問題是由編譯器而不是應用程序引起的。在編譯器外直接運行應用程序可以抑制彈出窗口並按預期內部捕獲它。