Jump to content

Accessing the Windows Address Book (com error)


Recommended Posts

The following script uses the WABAccess control (http://wabaccess.sourceforge.net/) to access the windows address book.

#include <GUIConstants.au3>

$WAB_Session = ObjCreate ("WABAccess.Session")
If @error = 1 Then
   MsgBox (0, "Create Object", "Unable to open WAB")
   Exit
EndIf

ObjEvent ("AutoIt.Error", "Error_Handler")

$WAB_Session.Open (True)

MsgBox (0, "", $WAB_Session.Identities($WAB_Session.Identities.LastIdentity).Name)

$WAB_Containers = $WAB_Session.Containers
 
MsgBox (0, "", "Collections = " & $WAB_Containers.Count) 
 
For $Container in $WAB_Containers
    MsgBox (0, "", $Container.Name)
    $Contacts = $Container.elements
    For $Contact in $Contacts
        $Fields = $Contact.Properties
        MsgBox (0, "", $Contact.Name & @CRLF & $Fields.Item(0x3003001F).Value)
    Next
Next

$WAB_Session.Close ()

$Main_Window = GUICreate ("My Window", 600, 600, -1, -1)

GUISetState ()

While 1
    $msg = GUIGetMsg()
    If $msg = $GUI_EVENT_CLOSE Then ExitLoop
Wend

GUIDelete ($Main_Window)

Func Error_Handler ()
    
MsgBox (0, "", "Com Error")

EndFunc

The $Fields.Item(0x3003001F).Value) retrieves the contact's email address. However, if there exists a contact for which an e-mail address is not defined, the item reference throws a com error.

I expected to be able to catch it in the "Error_Handler" function, but it does not receive control when the error occurs. I get the message: "the requested action with this object has failed".

Is there a way to catch the error?

Thank you.

Link to comment
Share on other sites

#include <GUIConstants.au3>

$WAB_Session = ObjCreate("WABAccess.Session")
If @error = 1 Then
    MsgBox(0, "Create Object", "Unable to open WAB")
    Exit
EndIf

ObjEvent("AutoIt.Error", "Error_Handler")

$WAB_Session.Open (True)

MsgBox(0, "", $WAB_Session.Identities ($WAB_Session.Identities.LastIdentity).Name)

$WAB_Containers = $WAB_Session.Containers

MsgBox(0, "", "Collections = " & $WAB_Containers.Count)

For $Container In $WAB_Containers
    MsgBox(0, "", $Container.Name)
    $Contacts = $Container.elements
    For $Contact In $Contacts
        $Fields = $Contact.Properties
        $email = $Fields.Item (0x3003001F).Value
        If @error Then $email = 'no email' ; $email = ''
        MsgBox(0, "", $Contact.Name & @CRLF & $email)
    Next
Next

$WAB_Session.Close ()

$Main_Window = GUICreate("My Window", 600, 600, -1, -1)

GUISetState()

While 1
    $msg = GUIGetMsg()
    If $msg = $GUI_EVENT_CLOSE Then ExitLoop
WEnd

GUIDelete($Main_Window)

Func Error_Handler()
;~  MsgBox(0, "", "Com Error")
    ; on COM error only set @error flag and continue
    SetError(1)
EndFunc

Link to comment
Share on other sites

Thanks for your reply Zedna, BUT, the problem is the $Fields.Item (0x3003001F).Value throws a COM error and the ObjEvent ("AutoIt.Error", "Error_Handler") does NOT catch it; I get the AutoIT error message: the requested action with this object has failed. This is true whether running from SciTE or from a compiled exe.

I expected the Error_Handler to catch the COM error, wouldn't you?

I e-mailed WABAccess support and the response was: "it is by design, the application must catch the COM error"

Do you see anything I'm doing wrong? Should AutoIt be catching the COM error?

Thanks again,

Paul

Link to comment
Share on other sites

Try this:

...
For $Container In $WAB_Containers
    MsgBox(0, "", $Container.Name)
    $Contacts = $Container.elements
    For $Contact In $Contacts
        $Fields = $Contact.Properties
        $item = $Fields.Item (0x3003001F)
        If @error Then 
            $email = 'no email' ; $email = ''
        Else
            $email = $item.Value
            If @error Then $email = 'no email' ; $email = ''
        EndIf
        MsgBox(0, "", $Contact.Name & @CRLF & $email)
    Next
Next
...
Link to comment
Share on other sites

Thanks again for the reply Zedna.

That's good thinking...

The $item = $Fields.Item (0x3003001F) still fails though -- The requested action with this object has failed.

Just to be certain, I checked @error after establishing the COM error handler:

ObjEvent ("AutoIt.Error", "Error_Handler")

If @error Then MsgBox (0, "", "Unable to set COM error handler")

The ObjEvent is successful -- AutoIt just doesn't trap this COM error.

I wish a developer could take a look at it. I don't know if AutoIT should trap the error or if the author of the WEBAccess control is not following normal conventions. I know nothing about COM programming...

I sure would like to be able to use this control though...

Sincerely,

Paul

Link to comment
Share on other sites

Does anyone of any ideas on this subject?

I would appreciate being enlightened regarding what kinds of COM errors an ObjEvent ("AutoIt.Error", "Error_Handler") traps?

Particularly, is there a way to trap the "requested action with this object has failed" error.

Without that knowledge, it makes me wonder if the COM error handling in AuotIt is functioning correctly?

Perhaps a developer could comment....

Link to comment
Share on other sites

Add checking code

If @error Then ...

after each COM command in your script to check where exactly occurs first (primary) problem.

For example after: $Fields = $Contact.Properties

Your problem seems to be secondary.

No difference -- no errors occur until the $Fields.Item (0x3003001F).Value statement is executed, which again, according to the author of the control, is by design.

The documentation for ObjEvent ( "AutoIt.Error" [, "function name"] ) simply states that "if any COM error occurs, the given function is called".

It appears this may be a defect in AutoIt's COM error handling, or something unique to my environment.

The WABAccess control is simple to install -- perhaps someone else could try the example script on their machine.

Thanks again,

Paul

Link to comment
Share on other sites

@all

This should give you correct error checking :

#include <GUIConstants.au3>

$WAB_Session = ObjCreate("WABAccess.Session")
If @error = 1 Then
    MsgBox(0, "Create Object", "Unable to open WAB")
    Exit
EndIf

; Initialize error handler 
$oMyError = ObjEvent("AutoIt.Error","MyErrFunc")

$WAB_Session.Open (True)

MsgBox(0, "", $WAB_Session.Identities ($WAB_Session.Identities.LastIdentity).Name)

$WAB_Containers = $WAB_Session.Containers

MsgBox(0, "", "Collections = " & $WAB_Containers.Count)

For $Container In $WAB_Containers
    MsgBox(0, "", $Container.Name)
    $Contacts = $Container.elements
    For $Contact In $Contacts
        $Fields = $Contact.Properties
        $email = $Fields.Item (0x3003001F).Value
        If @error Then $email = 'no email' ; $email = ''
        MsgBox(0, "", $Contact.Name & @CRLF & $email)
    Next
Next

$WAB_Session.Close ()

$Main_Window = GUICreate("My Window", 600, 600, -1, -1)

GUISetState()

While 1
    $msg = GUIGetMsg()
    If $msg = $GUI_EVENT_CLOSE Then ExitLoop
WEnd

GUIDelete($Main_Window)

;------------------------------ This is a COM Error handler --------------------------------
Func MyErrFunc()
  $HexNumber=hex($oMyError.number,8)
  Msgbox(0,"COM Error Test","We intercepted a COM Error !"       & @CRLF  & @CRLF & _
             "err.description is: "    & @TAB & $oMyError.description    & @CRLF & _
             "err.windescription:"     & @TAB & $oMyError.windescription & @CRLF & _
             "err.number is: "         & @TAB & $HexNumber              & @CRLF & _
             "err.lastdllerror is: "   & @TAB & $oMyError.lastdllerror   & @CRLF & _
             "err.scriptline is: "     & @TAB & $oMyError.scriptline     & @CRLF & _
             "err.source is: "         & @TAB & $oMyError.source         & @CRLF & _
             "err.helpfile is: "       & @TAB & $oMyError.helpfile       & @CRLF & _
             "err.helpcontext is: "    & @TAB & $oMyError.helpcontext _
            )
  SetError(1)  ; to check for after this function returns
Endfunc

regards

ptrex

Link to comment
Share on other sites

Thanks Ptrex,

If I hadn't tried setting a variable = ObjEvent, you would have provided the answer, although I may not have understood why!

Do you find if you code just ObjEvent, the COM handler doesn't get control? If so, it may be helpful to others if the documentation noted that requirement.

Paul

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...