使用WMI捕获EOleException

时间:2016-09-13 19:25:56

标签: delphi wmi rpc

我正在使用Delphi 2007来创建一个将重启网络连接计算机的应用程序。

我有一个名为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?

2 个答案:

答案 0 :(得分: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; 

答案 1 :(得分:0)

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

相关问题