I'm implementing a WMI interface in Delphi VCL, I managed to have it working, but I'm now trying to make it a little more robust.
The portion of code I'm working on is this:
var
FWbemServices: ISWbemServices;
WMIObject: ISWbemObjectSet;
WMISQLQuery: String;
FCount: Integer;
...
FWbemServices := FWbemLocator.ConnectServer('', 'root\CIMV2', '', '', '', '', 0, nil);
WMIObject := FWbemServices.ExecQuery(WMISQLQuery, 'WQL', wbemFlagReturnImmediately, nil);
...
FCount := WMIObject.Count;
...
It completely works when WMISQLQuery contains a valid WMI query like:
SELECT * FROM Win32_BaseBoard
But if the query is wrong, for example misspelling the class name, when trying to access WMIObject.Count it suddently gives me an EOleException "Invalid query" which I can't handle by surrounding it with a try .. except block.
I checked this MSDN page which clearly states:
After the completion of the ExecQuery method, the Err object can contain one of the error codes in the following list.
wbemErrAccessDenied - 2147749891 (0x80041003)
Current user does not have the permission to view the result set.
wbemErrFailed - 2147749889 (0x80041001)
Unspecified error.
wbemErrInvalidParameter - 2147749896 (0x80041008)
Invalid parameter was specified.
wbemErrInvalidQuery - 2147749911 (0x80041017)
Query syntax is not valid.
wbemErrInvalidQueryType - 2147749912 (0x80041018)
Requested query language is not supported.
wbemErrOutOfMemory - 2147749894 (0x80041006)
Not enough memory to complete the operation.
The fact is, I'm not able to access the Err object in any way.
I still remember the Err object when I was using it in VB like:
On Error Resume Next
...
DoSomething
If Err.Number <> 0 Then
...
I just would like to be able to use it in Delphi.
The fun fact is that in the imported WMI TLB I do have those constants ready for use.
Maybe I was just to tired (it was 3:25AM January, 1st) and needed some rest to see how the whole thing acted. I'm not saying I solved it, since I did not find the way to access the Err object from Delphi, but in this partitular case I was able to handle the exception. Unfortunately I cannot discern them since the class is always EOleException and the Exception.Message is translated to system language, but at least I don't have an unhandled exception.
I've shared a small project on Dropbox, it does not contain binaries, just the minimum required Delphi files to be compiled, you can also check it on VirusTotal.
This example will test a good and a bad WMI query.
I still would appreciate if someone finds a way to get information from the Err object.
EOLEException has ErrorCode property, so you can use something like this
except
on E: EOLEException do
begin
if E.ErrorCode = HRESULT(wbemErrInvalidQuery) then
begin
// do something
end;
end;
end;
User contributions licensed under CC BY-SA 3.0