Jump to content

accessing VirtualBox with COM


Wiedmann
 Share

Recommended Posts

Hello all,

I'm having problems accessing VirtualBox via the COM API. Somethings are working, but the importants not...

Here is a small script in PHP whis is working as expected:

<?php
try {
    $IVirtualBox = new COM("VirtualBox.VirtualBox");
} catch (Exception $e) {
    fwrite(STDERR, "Unable to instantiate VirtualBox".PHP_EOL);
    exit(1);
}

$IMachine = $IVirtualBox->Machines;
foreach ($IMachine as $aMachine) {
    fwrite(STDOUT, $aMachine->Name.PHP_EOL);
}
?>

(it's listing the availiable guest machines)

Now I've tried the same with AutoIt:

$IVirtualBox = ObjCreate("VirtualBox.VirtualBox")
If Not IsObj($IVirtualBox) Then
    ConsoleWriteError("Unable to instantiate VirtualBox" & @CRLF)
    Exit(1)
EndIf

$IMachine = $IVirtualBox.Machines
For $aMachine in $IMachine
    ConsoleWrite($aMachine.Name & @CRLF)
Next

But this one is not working:

!>12:06:54 AutoIT3.exe ended.rc:-1073741819

>Exit code: -1073741819 Time: 4.184

It is stopping at line 7 ("$IMachine = ...").

Well, other things like:

ConsoleWrite($IVirtualBox.Version & @CRLF)

are working.

Does anybody know what's the problem?

Link to comment
Share on other sites

Well... there was a COM error during runtime and AutoIt crashes when that happens. I suggest you register an AutoIt error handler to trap the error, look in the help file. The error handler they have there is perfect.

Personally, I allways thought autoit needs try/catch...... but

Edited 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

Personally, I allways thought autoit needs try/catch...... but

i think that error handling in autoit provides a pretty good balance of ease of use and power. Granted there could be an Opt(ErrorHandling) to allow for a try catch structure, but implementation of a full change to error handling would mean atleast a partial rewrite of every function and udf, and it would definitely make the language a little more complicated to pick up for new users as that's another structure they'd have to learn, not to mention the different types of errors that may have to be caught depending on what they have to do. It would be a non trivial change that would be detrimental to autoit's major strength which is how easily ANYONE can pick it up and do just about anything with a very high level programming language.
Link to comment
Share on other sites

I always thought that something akin to the vbscript On Error Resume Next would have been a nice addition, but I can live without it.

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Link to comment
Share on other sites

I always thought that something akin to the vbscript On Error Resume Next would have been a nice addition, but I can live without it.

the way that errors are handled now, execution is resumed after non fatal errors exactly like the On Error Resume Next... Most errors simply set @error and extended, and execution continues until you try to reference a non existent value, file, index, etc.
Link to comment
Share on other sites

The problem with the way it is now is that you may have an error in your script and not know it until you do try to reference whatever is in error. If it's a variable or something that only gets referenced rarely, you might not know about it until you release the program and then start getting error reports.

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Link to comment
Share on other sites

The problem with the way it is now is that you may have an error in your script and not know it until you do try to reference whatever is in error. If it's a variable or something that only gets referenced rarely, you might not know about it until you release the program and then start getting error reports.

Most of the standard functions and widely accepted UDF's make use of the standard error reporting, and it only takes a line or two to handle errors. You can even usually do error checking without even looking at @error, by validating your references before making them, for example, checking IsObj($oWhatever) before calling $oWhatever.DoNeatStuff(). Language revision is not a solution to bad programming practice ;)

***edit***

i didn't mean for that to come across as condescending, to this day i code for the obvious errors and then go back and check @error only after it doesn't do what i expect

Edited by cameronsdad
Link to comment
Share on other sites

i think that error handling in autoit provides a pretty good balance of ease of use and power.

I agree, but I'm still in denial simply because the idea that UDFs force me to register my error handler through their functions bothers me.

btw Wiedmann,

If you ever use IE.au3 or any other UDF which depends on COM, make sure that you register your error handler using their functions.

And on a different note, your for loop will also crash your program if $IMachine = $IVirtualBox.Machines doesn't return the list of machines. So you'll have to do the following:

$IMachine = $IVirtualBox.Machines 
$aMachine = ""
For $i=0 to Ubound($IMachine)-1
    $aMachine = $IMachine[$i]
 ConsoleWrite($aMachine.Name & @CRLF) Next

"When the power of love overcomes the love of power, the world will know peace"-Jimi Hendrix

Link to comment
Share on other sites

btw Wiedmann,

If you ever use IE.au3 or any other UDF which depends on COM, ...

Oh, I'm really new to AutoIt...

$IMachine = $IVirtualBox.Machines 
$aMachine = ""
For $i=0 to Ubound($IMachine)-1
    $aMachine = $IMachine[$i]
 ConsoleWrite($aMachine.Name & @CRLF) Next

This makes no difference. The script breaks at line:

$IMachine = $IVirtualBox.Machines

But I guess there is a problem with AutoIt and some VARIANT data types. e.g.:

$IVirtualBox = ObjCreate("VirtualBox.VirtualBox")
If Not IsObj($IVirtualBox) Then
    ConsoleWriteError("Unable to instantiate VirtualBox" & @CRLF)
    Exit(1)
EndIf

ConsoleWrite(VarGetType($IVirtualBox) & @CRLF)
ConsoleWrite(VarGetType($IVirtualBox.Version) & @CRLF)
ConsoleWrite(VarGetType($IVirtualBox.Machines) & @CRLF)
ConsoleWrite("End..." & @CRLF)

And the output is:

>Running:(3.3.6.1):C:\Programme\AutoIt3\autoit3.exe "test.au3"

Object

String

!>10:31:17 AutoIT3.exe ended.rc:-1073741819

>Exit code: -1073741819 Time: 11.756

$IVirtualBox is an object, type 9 (VT_DISPATCH)

$IVirtualBox.Version is a string, type 8 (VT_BSTR)

and $IVirtualBox.Machines is an array of objects, type 8201 (VT_ARRAY | VT_DISPATCH)

and it looks like AutoIt can't handle this type. :-/

Link to comment
Share on other sites

I just tried it and couldn't get it to work either... and for some reason the COM error handler failed to trap the error. Sorry can't help you with this one, but I've always used vboxmanage.exe to do all of my automation. Its safer and more portable that way.

"When the power of love overcomes the love of power, the world will know peace"-Jimi Hendrix

Link to comment
Share on other sites

  • 6 years later...
  • Developers

mmm... so you have the exact same code and the exact same code and issue or do you think you might need to share your case in more detail?

Jos

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Link to comment
Share on other sites

I tested the above code, and AutoIt fails to enumerate the array, hard crash. even tried to catch COM error, and that failed as well

This may be why:

Quote

and $IVirtualBox.Machines is an array of objects, type 8201 (VT_ARRAY | VT_DISPATCH)

 

What is what? What is what.

Link to comment
Share on other sites

AutoIt does not support safearray. You can do something like this:

#include "SafeArray.au3"



Global Const $sTag_IDispatch = _
        "GetTypeInfoCount hresult(dword*);" & _ ; Retrieves the number of type information interfaces that an object provides (either 0 or 1).
        "GetTypeInfo hresult(dword;dword;ptr*);" & _ ; Gets the type information for an object.
        "GetIDsOfNames hresult(ptr;ptr;dword;dword;ptr);" & _ ; Maps a single member and an optional set of argument names to a corresponding set of integer DISPIDs, which can be used on subsequent calls to Invoke.
        "Invoke hresult(dword;ptr;dword;word;ptr;ptr;ptr;ptr);" ; Provides access to properties and methods exposed by an object.


Global Const $sIID_IVirtualBox = "{0169423F-46B4-CDE9-91AF-1E9D5B6CD945}"
;Dummy v-table
Global Const $sTagIVirtualBox = $sTag_IDispatch & "Dummy1 hresult();Dummy2 hresult();Dummy3 hresult();Dummy4 hresult();Dummy5 hresult();Dummy6 hresult();Dummy7 hresult();Dummy8 hresult();" & _
        "Dummy9 hresult(); Dummy10 hresult();Machines hresult(ptr*)"

_Example()

Func _Example()

Local $oVirtualBox = ObjCreate("VirtualBox.VirtualBox")
If Not IsObj($oVirtualBox) Then Return 0
Local $oIVirtualBox = ObjCreateInterface($oVirtualBox, $sIID_IVirtualBox, $sTagIVirtualBox)

Local $pMachines = 0
$oIVirtualBox.Machines($pMachines)
Local $iDim = SafeArrayGetDim($pMachines)
Local $iUBound=0
SafeArrayGetUBound($pMachines, 1, $iUBound)
Local $tTypeArray = DllStructCreate($tagSAFEARRAY, $pMachines)
Local $iPtrSize = (DllStructGetData($tTypeArray, "cbElements"))


Local $paMachineArrayData = 0
Local $tMachine = 0
Local $poMachine = 0
Local $oMachine = Null

SafeArrayAccessData($pMachines, $paMachineArrayData)
For $i = 0 To $iUBound
    $tMachine = DllStructCreate("ptr", $paMachineArrayData + ($i * $iPtrSize))
    $poMachine = DllStructGetData($tMachine, 1)
    $oMachine = ObjCreateInterface($poMachine, "", Default, False)
    ConsoleWrite("Machine[" & $i & "].Name : " & $oMachine.Name & @CRLF)
    $poMachine = 0
    $tMachine = 0
    $oMachine = Null
Next
SafeArrayUnaccessData($pMachines)

EndFunc

 

It needs SafeArray.au3

 

Saludos

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...