2016-09-13 104 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

问题是由编译器而不是应用程序引起的。在编译器外直接运行应用程序可以抑制弹出窗口并按预期内部捕获它。