rbhkamal Posted June 16, 2010 Share Posted June 16, 2010 (edited) I'm facing this dilemma and have no idea how to workaround this problem. I wrote a script (a long one) a year ago which controls VirtualBox and sold it off to few customers... the problem now is the new version of VirtualBox crashes. To be specific, the script launches vboxmanage.exe which works fine most of the time but , with the new version of VBOX, crashes in certain cases. If the same command is run again, it works. So... how do I tell if vboxmanage.exe finished executing properly or crashed? Below is the function which is used to call vboxmanage.exe, its pretty much a wrapper around the run() method. THANKS expandcollapse popup; #FUNCTION# ==================================================================================================================== ; Name...........: __VboxMng_exec ; Description ...: Executes vboxmanage.exe and waits for the process to quit. It also retrieves stdout and stderr ; Syntax.........: __VboxMng_exec ($p_sParams ; , ByRef $P_stdOut ; , ByRef $p_stdErr ; , [$p_iWindowFlag = @SW_HIDE] ) ; ; Parameters ....: $p_sParams - The parameters to be passed to vboxmanage.exe ; $P_stdOut - [OUT] Will contain a string that has the output of stdOut ; $p_stdErr - [OUT] Will contain a string that has the output of stdErr ; $p_iWindowFlag - Visible window flag [@SW_HIDE , @SW_MINIMIZE , @SW_MAXIMIZE ] ; ; Return values .: Success - 0 ; Failure - < 0 ; ; Author ........: Ribhi Kamal ; Modified.......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: ; =============================================================================================================================== Func __VboxMng_exec($p_sParams, ByRef $P_stdOut, ByRef $p_stdErr, $p_iWindowFlag = @SW_HIDE, $p_bUpdateCache = True) __event_start("__VboxMng_exec") Local $l_iRc = 0, $l_iErrBit = 0; If Not $__bVboxMng_Initilized Then __event_msg( 8 , "VBoxManage not initialized yet!" ) $l_iRc = BitOR( $l_iRc , 2 ^ $l_iErrBit , $__iVboxMng_NEGATIVE_ERROR ) EndIf $l_iErrBit += 1 If $l_iRc == 0 Then If $p_bUpdateCache Then $__sVboxMng_Cache_STDOUT = "" $__sVboxMng_Cache_STDERR = "" $__sVboxMng_Cache_CMD = $__sVboxMng_exe & $__sVboxMng_Params & " " & $p_sParams EndIf EndIf $P_stdOut = "" $p_stdErr = "" Local $l_sPid If $l_iRc == 0 Then __event_msg( 2 , $__sVboxMng_exe & $__sVboxMng_Params & " " & $p_sParams ) $l_sPid = Run($__sVboxMng_exe & $__sVboxMng_Params & " " & $p_sParams, '', $p_iWindowFlag, $STDERR_CHILD + $STDOUT_CHILD) If @error Then __event_msg( 8 , "Failed to run Vboxmanage.exe with error: " & @error ) $l_iRc = BitOR( $l_iRc , 2 ^ $l_iErrBit , $__iVboxMng_NEGATIVE_ERROR ) EndIf EndIf $l_iErrBit += 1 If $l_iRc == 0 Then While 1 Sleep(10) $P_stdOut = $P_stdOut & StdoutRead($l_sPid) If @error Then ExitLoop WEnd While 1 Sleep(10) $p_stdErr = $p_stdErr & StderrRead($l_sPid) If @error Then ExitLoop WEnd StdioClose($l_sPid) ;Just incase, make sure that all IO is closed If $p_bUpdateCache Then $__sVboxMng_Cache_STDOUT = $P_stdOut $__sVboxMng_Cache_STDERR = $p_stdErr EndIf EndIf __event_end($l_iRc) Return $l_iRc EndFunc ;==>__VboxMng_exec Edited June 16, 2010 by rbhkamal "When the power of love overcomes the love of power, the world will know peace"-Jimi Hendrix Link to comment Share on other sites More sharing options...
rbhkamal Posted June 16, 2010 Author Share Posted June 16, 2010 (edited) I don't know but it looks like I found a solution... I need someone to verify this for me please.I simply need to get the return code, if its negative then something wrong happened; Return handle of given PID Func _ProcessGetHandle($iPID) Local Const $PROCESS_QUERY_INFORMATION = 0x0400 Local $avRET = DllCall("kernel32.dll", "ptr", "OpenProcess", "int", $PROCESS_QUERY_INFORMATION, "int", 0, "int", $iPID) If @error Then Return SetError(1, 0, 0) Else Return $avRET[0] EndIf EndFunc ;==>_ProcessGetHandle ; Close process handle Func _ProcessCloseHandle($hProc) Local $avRET = DllCall("kernel32.dll", "int", "CloseHandle", "ptr", $hProc) If @error Then Return SetError(1, 0, 0) Else Return 1 EndIf EndFunc ;==>_ProcessCloseHandle ; Get process exit code from handle Func _ProcessGetExitCode($hProc) Local $t_ExitCode = DllStructCreate("int") Local $avRET = DllCall("kernel32.dll", "int", "GetExitCodeProcess", "ptr", $hProc, "ptr", DllStructGetPtr($t_ExitCode)) If @error Then Return SetError(1, 0, 0) Else Return DllStructGetData($t_ExitCode, 1) EndIf EndFunc ;==>_ProcessGetExitCode[EDIT]: Thanks to PsaltyDS for sharing his code Edited June 16, 2010 by rbhkamal "When the power of love overcomes the love of power, the world will know peace"-Jimi Hendrix Link to comment Share on other sites More sharing options...
jchd Posted June 16, 2010 Share Posted June 16, 2010 With an avatar like yours, you were sure to attract attention of Penguins! This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe hereRegExp tutorial: enough to get startedPCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta. SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt) Link to comment Share on other sites More sharing options...
rbhkamal Posted June 17, 2010 Author Share Posted June 17, 2010 Yes yes.... I wasn't sure why a Penguin exist on this non-Penguiny forum until you mentioned coolness "When the power of love overcomes the love of power, the world will know peace"-Jimi Hendrix Link to comment Share on other sites More sharing options...
Ascend4nt Posted June 17, 2010 Share Posted June 17, 2010 (edited) I don't know but it looks like I found a solution... I need someone to verify this for me please. I simply need to get the return code, if its negative then something wrong happened I'd be very interested whether 'GetExitCodeProcess' actually returns an exit code for a crashed process - my guess is no, and it would return 0 because the exit code variable wasn't written to. More than likely it won't set an exit code for a crashed process, and will return with a failure as the API return value (which isn't checked in PsaltyDS's function). It would be wiser to add a check to see if $avRET[0]=0, which means the API call failed. When that happens, you should check 'GetLastError', which will probably give you a system error code if the process you were trying to get the Exit code from terminated (ERROR_PROCESS_ABORTED could be returned, for example - but there are a few other possibilities). *edit: I tested a few ways of forcefully crashing an application (using 'Advanced Process Termination'), and sometimes I got a 0 return, sometimes I get a weird value like 3221225477, but in neither case did I get a failure on the API call. Interesting. But seeing as how these were forced crashes, I don't know what an actual crash situation would return for the application you're interested in. Edited June 17, 2010 by Ascend4nt My contributions: Performance Counters in Windows - Measure CPU, Disk, Network etc Performance | Network Interface Info, Statistics, and Traffic | CPU Multi-Processor Usage w/o Performance Counters | Disk and Device Read/Write Statistics | Atom Table Functions | Process, Thread, & DLL Functions UDFs | Process CPU Usage Trackers | PE File Overlay Extraction | A3X Script Extract | File + Process Imports/Exports Information | Windows Desktop Dimmer Shade | Spotlight + Focus GUI - Highlight and Dim for Eyestrain Relief | CrossHairs (FullScreen) | Rubber-Band Boxes using GUI's (_GUIBox) | GUI Fun! | IE Embedded Control Versioning (use IE9+ and HTML5 in a GUI) | Magnifier (Vista+) Functions UDF | _DLLStructDisplay (Debug!) | _EnumChildWindows (controls etc) | _FileFindEx | _ClipGetHTML | _ClipPutHTML + ClipPutHyperlink | _FileGetShortcutEx | _FilePropertiesDialog | I/O Port Functions | File(s) Drag & Drop | _RunWithReducedPrivileges | _ShellExecuteWithReducedPrivileges | _WinAPI_GetSystemInfo | dotNETGetVersions | Drive(s) Power Status | _WinGetDesktopHandle | _StringParseParameters | Screensaver, Sleep, Desktop Lock Disable | Full-Screen Crash Recovery Wrappers/Modifications of others' contributions: _DOSWildcardsToPCRegEx (original code: RobSaunder's) | WinGetAltTabWinList (original: Authenticity) UDF's added support/programming to: _ExplorerWinGetSelectedItems | MIDIEx UDF (original code: eynstyne) (All personal code/wrappers centrally located at Ascend4nt's AutoIT Code) Link to comment Share on other sites More sharing options...
rbhkamal Posted June 17, 2010 Author Share Posted June 17, 2010 I see... maybe the best way is to modify the source for VboxManage.exe (OSE) and force it to print on exit "Exiting with <error code>." That way If I don't see that message in the output, the command will have to run again. Thanks for the help "When the power of love overcomes the love of power, the world will know peace"-Jimi Hendrix 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