myids Posted February 8, 2010 Share Posted February 8, 2010 How do I handle gracefully a situation where an AutoIt COM object being closed unexpectedly thru the object's GUI. I am using Excel at the moment. TIA myids Link to comment Share on other sites More sharing options...
Richard Robertson Posted February 8, 2010 Share Posted February 8, 2010 From the help file $oMyError = ObjEvent("AutoIt.Error","MyErrFunc") Func MyErrFunc() Msgbox(0,"AutoItCOM 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 & hex($oMyError.number,8) & @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 _ ) Endfunc Link to comment Share on other sites More sharing options...
myids Posted February 9, 2010 Author Share Posted February 9, 2010 Thanks very much for the reply. This COM/Object stuff baffles me most of the time. I have more questions. This isn't as importmant for me to know, but It looks like the custom error handler is executed in @error? I am having some trouble implementing. Here's some of the code: expandcollapse popup#Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_icon=..\..\..\..\..\..\Program Files (x86)\AutoIt3\Icons\ids_nl.ico #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #include <GUIConstants.au3> #include <GuiListView.au3> #include <Excel.au3> #include <Array.au3> #Include <Constants.au3> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Define vars and capture values of PwrPCB object ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Global $Selected = 0 $powerPCBApp = ObjGet("", "PowerPCB.Application") $powerPCBDoc = $powerPCBApp.ActiveDocument $mcount = $powerPCBDoc.GetObjects(1).Count $netcount = $powerPCBApp.Activedocument.Nets.Count Dim $ListNets[$netcount] Dim $cell_netlength, $cell_net, $mynet Dim $NetProperties[2][$netcount] Global $pcbname = $powerPCBApp.Activedocument.Name Global $pcbpath = $powerPCBApp.Activedocument.Path Global $pcbfullname = $powerPCBApp.Activedocument.FullName Global $pcbssname = StringLeft($pcbname, StringLen($pcbname) - 4) & ".xls" Global $ssisopen = "" Global $ssfile = "" Global $oExcel = "" Global $oExcelIdent = "" Global $g_eventerror = 0 ; to be checked to know if com error occurs. Must be reset after handling. $oMyError = "" $err = "" ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Setup the tray Icon ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Opt("TrayMenuMode",1) ; Default tray menu items (Script Paused/Exit) will not be shown. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Menu For tray Icon ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; $OpenSSItem = TrayCreateItem("Open SpreadSheet") TrayCreateItem("") $RunItem = TrayCreateItem("Run Length Check") TrayCreateItem("") $SaveSSItem = TrayCreateItem("Save SpreadSheet") TrayCreateItem("") $CloseSSItem = TrayCreateItem("Close Spreadsheet") TrayCreateItem("") $aboutitem = TrayCreateItem("About") TrayCreateItem("") $exititem = TrayCreateItem("Exit") TraySetState() ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Menu For tray Icon ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Loop though events/Menu options in tray icon ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; While 1 $msg = TrayGetMsg() $oMyError = ObjEvent("AutoIt.Error","MyErrFunc") ; Initialize a COM error handler If $g_eventerror then $g_eventerror = 0 Msgbox (0,"AutoItCOM test","Test passed: We got an error number: " & @error) Exit Else Msgbox (0,"AutoItCOM test","Test failed!") Select Case $msg = 0 ContinueLoop Case $msg = $RunItem TrayItemSetState($RunItem, $TRAY_CHECKED) GetNetLengths() Case $msg = $CloseSSItem TrayItemSetState($CloseSSItem, $TRAY_CHECKED) CloseSS() Case $msg = $SaveSSItem TrayItemSetState($SaveSSItem, $TRAY_CHECKED) SaveSS() Case $msg = $OpenSSItem TrayItemSetState($OpenSSItem, $TRAY_CHECKED) OpenSS() Case $msg = $aboutitem TrayItemSetState($aboutitem, $TRAY_CHECKED) Msgbox(64, "about:", "Interactive Design Solutions") Case $msg = $exititem ExitLoop EndSelect Endif ; branch of COM error testing WEnd ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Loop though events/Menu options in tray icon ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Func MenuForTrayIcon() ;EndFunc ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Function: GetNetLengths ; retrieves all nets in pcb db in 2d array ; reads spreadsheet net columns and retrieves each nets routed lengths ; writes the routed length to the spreadsheet ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Func GetNetLengths() ;GUICreate($powerPCBApp.Activedocument.Name, 400, 200) ;GUISetIcon(@SystemDir & "\mspaint.exe", 0) ;GUISetState() $Index = 0 For $nextNet In $powerPCBApp.Activedocument.Nets $NetProperties[0][$Index] = $nextNet.Name $NetProperties[1][$Index] = $nextNet.Length $cindex = $Index + 1 ;GuiCtrlCreateListViewItem($nextNet.Name, $listView) ;_GUICtrlListView_AddItem ($ListView, $nextNet.Name) ;_ExcelWriteCell($oExcel, $nextNet.Name, $cindex, 1) ;_ExcelWriteCell($oExcel, RoutedNetLength ($nextNet.Name), $cindex, 2) $Index = $Index + 1 Next ;_ArrayDisplay($NetProperties, "Net Properties", -1, 1) ;If $oExcel.ActiveSheet.Name Then ; $Index = 0 ; For $i = 1 To 200 ;Loop ; $cindex = $Index + 1 ; _ExcelWriteCell($oExcel, "0", $cindex, 2) ; $Index = $Index + 1 ; Next ;EndIf $oMyError = ObjEvent("AutoIt.Error","MyErrFunc") If $g_eventerror then $g_eventerror = 0 Msgbox (0,"AutoItCOM test","Test passed: We got an error number: " & @error) Else Msgbox (0,"AutoItCOM test","Test failed!") Endif If IsObj($oExcel) Then $Index = 0 For $i = 1 To 200 ;Loop $cindex = $Index + 1 $sCellValue = _ExcelReadCell($oExcel, $i, 1) $cell_net = StringStripWS($sCellValue, 3) If $cell_net = "Netname" Then $cell_net = "" EndIf ;ConsoleWrite( $cell_net & @CRLF) ;MsgBox(0, "", "cell_net is: " & @CRLF & $cell_net, 2) If StringLen($cell_net) Then $nlgth = FindNetinArray($cell_net) _ExcelWriteCell($oExcel, $nlgth, $i, 2) EndIf $Index = $Index + 1 Next Else $oExcel = "" MsgBox(0, "SpreadSheet Was Not Open", "SpreadSheet Was Not Open" & @CRLF & "Open Spreadsheet, to Run a Length Check") ;OpenSS() EndIf EndFunc That should be all the relevant code. This version will always result in the "Test Failed" branch. Kind of obvious I guess. But I've tried embedded in getlength() and in the $RunItem CASE. I don't understand enough for the mechanics of this. I could probably try for hours and days and finally get the code working, but I still don't know that I'll understand. I can post the complete script if needed -- It doesn't seem to be relevent. NOTE: chances you can't run the whole script because of the other object being called? hmmmm....does the other object I have open interfere? I don't think so because I can run the example from help file successfully. Thanks very much for any tips on how to code this. myids Link to comment Share on other sites More sharing options...
Richard Robertson Posted February 9, 2010 Share Posted February 9, 2010 You don't put the error event in a loop. You set that up before you start creating objects I think. Link to comment Share on other sites More sharing options...
myids Posted February 10, 2010 Author Share Posted February 10, 2010 That was a big help. Thanks. I am not sure where I need to reset $g_eventerror to 0, if that is the correct thing to do, after a COM error is intercepted. I am using: If NOT $g_eventerror Then to run code if no $g_eventerror. TIA, myids Link to comment Share on other sites More sharing options...
myids Posted February 10, 2010 Author Share Posted February 10, 2010 This is another symptom if the Excel object was closed. C:\Program Files (x86)\AutoIt3\Include\Excel.au3 (694) : ==> Missing right bracket ')' in expression.:Return $oExcel.Activesheet.Cells($sRangeOrRow, $iColumn).ValueReturn ^ ERRORI think this is due to it being a second object, but not sure. Do I possibly need to setup a different flag or two? OrIs there a way to differentiate between objects for error handling?TIAmyids Link to comment Share on other sites More sharing options...
Richard Robertson Posted February 10, 2010 Share Posted February 10, 2010 I'm sorry but I don't know a lot about COM. I was just trying what I knew. I don't know anything about the Excel objects either. Link to comment Share on other sites More sharing options...
myids Posted February 10, 2010 Author Share Posted February 10, 2010 Richard, Thanks very much. You know more than I do. You helped me through to a better scenario and something that is workable. Maybe someone else can chime in with more insight. myids Link to comment Share on other sites More sharing options...
myids Posted February 10, 2010 Author Share Posted February 10, 2010 Well, I have a resolution although not so elegant and I'm not sure I understand it -- but, the code is behaving like I want it to so far. Luckily, this script isn't huge. If NOT $g_eventerror then ;call/use the object/function here since there is no COM/Object error Else ;reset/re-initialize the flag $g_eventerror = 0 EndIf Summary: After getting the error handler working for a non-existent object, where previously the script would crash, multiple calls to multiple objects still crashed the script despite the error handler. My current solution is to use the above If/Else for EVERY single object usage and re-initialize the error handler flag so the next potential object error could be captured and messaged. I probably could have had the program EXIT once the COM error was intercepted, but, that isn't the behavior I was after. So, even though my solution is a bit of a hassle, it's the only thing that makes to me because The documentation advise on the error handler is that a reset is needed after every intercepted error. Thanks for the help I received on this. If anyone has more thoughts and ideas for elegance, I'd love to read it. myids Link to comment Share on other sites More sharing options...
Richard Robertson Posted February 10, 2010 Share Posted February 10, 2010 Error handling is never "clean". What you've got now looks to be the best from what I can see. Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now