API through Visual Basic Script (VB Script) -- outdated sample

Discussion about using the VirtualBox API, Tutorials, Samples.
Post Reply
jprogman
Posts: 7
Joined: 21. Jan 2022, 04:20
Primary OS: MS Windows 10
VBox Version: PUEL
Guest OSses: Win XP Home

API through Visual Basic Script (VB Script) -- outdated sample

Post by jprogman »

I'm looking through the SDK to find samples for using the API through MSCOM by using VBscript. The sample code is provided at... sdk\bindings\mscom\vbs\sample\vboxinfo.vbs -- However, the code is outdated as it was still using openRemoteSession(uuidMachine, ...) which was obsolete at API version 4.0.

So, naturally, I have to make one up on a whim. So far, I got this for launching a VM...

Code: Select all

' vmtest.vbs -- VBScript test -- launch a vm

Dim vb
Set vb = CreateObject("VirtualBox.VirtualBox")
Wscript.Echo "VirtualBox version: " & vb.version
Wscript.Echo "package: " & vb.packageType
Wscript.Echo "API version: " & vb.APIVersion

Dim mch
Set mch = vb.FindMachine("new_wXP")
Wscript.Echo "Machine: " & mch.name

Dim ses
Set ses = CreateObject("VirtualBox.Session")

Dim prog

' this is where it throws a "type mismatch" exception...
Set prog = mch.launchVMProcess(ses,"gui","")

' haven't got this far...
prog.waitForCompletion(-1)
session.close()
Unfortunately, when I was running the script through CSCRIPT on Windows Command Prompt, a runtime error happens once it got to "launch vm process". I had also tried running it as administrator. Here's the output when running the VBscript...

Code: Select all

D:\virtualbox\scripts>cscript vmtest.vbs
Microsoft (R) Windows Script Host Version 5.812
Copyright (C) Microsoft Corporation. All rights reserved.

VirtualBox version: 6.1.30
package: WINDOWS_64BITS_GENERIC
API version: 6_1
Machine: new_wXP
D:\virtualbox\scripts\vmtest.vbs(23, 1) Microsoft VBScript runtime error: Type mismatch: 'launchVMProcess'


D:\virtualbox\scripts>
Perhaps I'm too naïve with VBscript, but I couldn't figure out what I'm doing wrong. I couldn't find any solutions online on launching a virtual machine by using VBscript. Perhaps I can use Python, but I wanted to find out -- just to save me some work, is if the API still works with VBscript. Because, ultimately, the sample source code provided in the SDK is too old.


Here are my specs...
OS: Windows 10 (64-bit) Home 21H1 19043.1466
VirtualBox Version: 6.1.30 (as shown by running script)
API Version: 6.1 (as shown by running script)
CSCRIPT version: 5.812
scottgus1
Site Moderator
Posts: 20965
Joined: 30. Dec 2009, 20:14
Primary OS: MS Windows 10
VBox Version: PUEL
Guest OSses: Windows, Linux

Re: API through Visual Basic Script (VB Script) -- outdated sample

Post by scottgus1 »

I haven't tried launching a VM with VBscript, but I do a lot of VBscripting.

Type Mismatch is when a value (text, number, object, etc) is passed to a command that does not expect that type of value.

For example:

Code: Select all

dummy = 0
teststr = "test"
if teststr > 2 then dummy = 1
msgbox dummy
This VBscript will throw a Type Mismatch over "teststr" in this line:

if teststr > 2 then dummy = 1

because teststr is a string and strings can't compare with numbers. VBscript will try to turn the string into a number, fail and throw the error. Whereas this:

Code: Select all

dummy = 0
teststr = "0"
if teststr > 2 then dummy = 1
msgbox dummy
will run because the contents of teststr can turn into a number and can compare.

In your code, this:

Set prog = mch.launchVMProcess(ses,"gui","")

is expecting something that it's not getting. I don't know the SDK, so you'll have to check the documentation, but I'd guess that method "launchVMProcess" for object "mch" doesn't expect an object in the first value or text values in the second and third values. Or maybe "mch.launchVMProcess" doesn't provide the object that "prog" expects. Just guesses from a Virtualbox SDK standpoint.

As a further guess after reading your script more, what happens if you try this for the failing line?

Set prog = ses.launchVMProcess(mch,"gui","")

And I'd guess that "session.close" should be "ses.close"?
jprogman
Posts: 7
Joined: 21. Jan 2022, 04:20
Primary OS: MS Windows 10
VBox Version: PUEL
Guest OSses: Win XP Home

Re: API through Visual Basic Script (VB Script) -- outdated sample

Post by jprogman »

I found out someone posted a ticket explaining the exact same problem about a month ago: https://www.virtualbox.org/ticket/20750 Hopefully it'll get some attention.

Only the IMachine has the function launchVMProcess(), so, naturally, trying to call that function from ses will just throw "Object doesn't support this property or method: 'launchVMProcess'"

Here's what the SDK document says:

Code: Select all

IProgress IMachine::launchVMProcess(
   [in] ISession session,
   [in] wstring name,
   [in] wstring environmentChanges[])
So far: ses is a "blank" ISession object; "gui" is the name of the front-end; and, because I got nothing for environmentChanges, I left an empty string -- but should it be something else? As for mch, it's an IMachine object.

Looking further into the SDK manual, there's also IVirtualBoxSDS class that has launchVMProcess() too, but couldn't work on VBScript. I tried to use CreateObject("VirtualBox.VirtualBoxSDS"), while it didn't throw any errors, the object type is Unknown via TypeName(). So, I've tried it out anyway, but no luck getting that to work either.

A little detail about the class IVirtualBoxSDS:

"The IVirtualBoxSDS interface represents the system-wide directory service helper.
It exists only on Windows host, and its purpose is to work around design flaws in Microsoft’s
(D)COM, in particular the local server instantiation behavior."

Note: This interface is not supported in the web service.

Code: Select all

unsigned long IVirtualBoxSDS::launchVMProcess(
   [in] wstring machine,
   [in] wstring comment,
   [in] wstring frontend,
   [in] wstring environmentChanges[],
   [in] wstring cmdOptions,
   [in] unsigned long sessionId)
Sebastian Weber
Posts: 5
Joined: 3. May 2017, 13:12

Re: API through Visual Basic Script (VB Script) -- outdated sample

Post by Sebastian Weber »

I found out someone posted a ticket explaining the exact same problem about a month ago
Well, that was me. I also just wrote a post here at that time.

It's April now, but it seems nobody has had a look at that ticket.

I'm wondering if the COM interface is really that unimportant. It is straight forward and lightweight.
While using the webservice allows to control VMs via network, it also adds lots of overhead.
(and then, there's the command line interFACE...)
noteirak
Site Moderator
Posts: 5229
Joined: 13. Jan 2012, 11:14
Primary OS: Debian other
VBox Version: OSE Debian
Guest OSses: Debian, Win 2k8, Win 7
Contact:

Re: API through Visual Basic Script (VB Script) -- outdated sample

Post by noteirak »

The session object must be fetched from the VirtualBoxManager, not created manually. The 3rd argument for the launchVMProgress should be null (or equivalent?).
Equivalent code in Java: https://github.com/hyperbox/server/blob ... e.java#L53
Hyperbox - Virtual Infrastructure Manager - https://apps.kamax.lu/hyperbox/
Manage your VirtualBox infrastructure the free way!
jprogman
Posts: 7
Joined: 21. Jan 2022, 04:20
Primary OS: MS Windows 10
VBox Version: PUEL
Guest OSses: Win XP Home

Re: API through Visual Basic Script (VB Script) -- outdated sample

Post by jprogman »

noteirak wrote:The session object must be fetched from the VirtualBoxManager, not created manually. The 3rd argument for the launchVMProgress should be null (or equivalent?).
Equivalent code in Java: https://github.com/hyperbox/server/blob ... e.java#L53
MSCOM doesn't look like it has VirtualBoxManager, so that'll won't work under vbscript.
CreateObject is SUPPOSED to create a Session object but I do not know if that is working nor know if it properly instantiated.
noteirak
Site Moderator
Posts: 5229
Joined: 13. Jan 2012, 11:14
Primary OS: Debian other
VBox Version: OSE Debian
Guest OSses: Debian, Win 2k8, Win 7
Contact:

Re: API through Visual Basic Script (VB Script) -- outdated sample

Post by noteirak »

jprogman wrote: MSCOM doesn't look like it has VirtualBoxManager, so that'll won't work under vbscript.
CreateObject is SUPPOSED to create a Session object but I do not know if that is working nor know if it properly instantiated.
You got your VirtualBoxManager equivalent already!

Code: Select all

Set vb = CreateObject("VirtualBox.VirtualBox")
you need to fetch a session object from it, not create it yourself. The point is that the VirtualBox global object will allocate / lock down a set of ressources when creating a session and giving it back to you.
Creating a Session object is no-use since it doesn't actually refer to a created session with ressources.
Hyperbox - Virtual Infrastructure Manager - https://apps.kamax.lu/hyperbox/
Manage your VirtualBox infrastructure the free way!
jprogman
Posts: 7
Joined: 21. Jan 2022, 04:20
Primary OS: MS Windows 10
VBox Version: PUEL
Guest OSses: Win XP Home

Re: API through Visual Basic Script (VB Script) -- outdated sample

Post by jprogman »

noteirak wrote:
jprogman wrote: MSCOM doesn't look like it has VirtualBoxManager, so that'll won't work under vbscript.
CreateObject is SUPPOSED to create a Session object but I do not know if that is working nor know if it properly instantiated.
You got your VirtualBoxManager equivalent already!

Code: Select all

Set vb = CreateObject("VirtualBox.VirtualBox")
you need to fetch a session object from it, not create it yourself. The point is that the VirtualBox global object will allocate / lock down a set of ressources when creating a session and giving it back to you.
Creating a Session object is no-use since it doesn't actually refer to a created session with ressources.
If you know how, let me know exactly. But, based on your Java -code example, I feel you are misunderstanding something. I'm not doing server-related stuff, so using something like getSessionobject is not the answer because they are unavailable when doing client-side scripting.
I'm reading the SDK document and it seems Ivirtualbox doesn't have a direct way to get session objects. I'm lost by your statement saying Ivirtualbox is the equivalent of virtualboxmanager, simply because there are no working examples in vb script to support your claim. Granted you had provided that Java example, but that's totally different than vb script. I'll confess that I'm no expert in vb script, which is why I would like more clarity rather than just claiming it can be done yet I don't see any proof -- specifically in vb script.

I know you are trying to help, but I really like to get relevant support. This is dragging on for too long. Maybe I'm asking at the wrong place?
noteirak
Site Moderator
Posts: 5229
Joined: 13. Jan 2012, 11:14
Primary OS: Debian other
VBox Version: OSE Debian
Guest OSses: Debian, Win 2k8, Win 7
Contact:

Re: API through Visual Basic Script (VB Script) -- outdated sample

Post by noteirak »

Indeed you're right, I forgot about that part as I basically never deal with the MSCOM.

Taken from the reference documentation:
When using the COM API directly, an object of the Session class from the VirtualBox type library needs to be created. In regular COM C++ client code, this can be done by calling createLocalObject(), a standard COM API. This object will then act as a local session object in further calls to open a session.
You might want to open a ticket on the VirtualBox bug tracker because it seems you're doing it right. Only the devs themselves can help at this point I think.
Hyperbox - Virtual Infrastructure Manager - https://apps.kamax.lu/hyperbox/
Manage your VirtualBox infrastructure the free way!
noteirak
Site Moderator
Posts: 5229
Joined: 13. Jan 2012, 11:14
Primary OS: Debian other
VBox Version: OSE Debian
Guest OSses: Debian, Win 2k8, Win 7
Contact:

Re: API through Visual Basic Script (VB Script) -- outdated sample

Post by noteirak »

Or maybe this can help: IVirtualBoxClient which is
At the moment only available for clients of the local API (not usable via the webservice). Once the session logic is redesigned this might change.
Seems like the local equivalent of the VirtualBoxManager?
Hyperbox - Virtual Infrastructure Manager - https://apps.kamax.lu/hyperbox/
Manage your VirtualBox infrastructure the free way!
jprogman
Posts: 7
Joined: 21. Jan 2022, 04:20
Primary OS: MS Windows 10
VBox Version: PUEL
Guest OSses: Win XP Home

Re: API through Visual Basic Script (VB Script) -- outdated sample

Post by jprogman »

noteirak wrote:Or maybe this can help: IVirtualBoxClient which is
At the moment only available for clients of the local API (not usable via the webservice). Once the session logic is redesigned this might change.
Seems like the local equivalent of the VirtualBoxManager?
That might be better. It said to create Ivirturalboxclient as a singleton, so I hope calling CreateObject won't ruin things.

FYI, here's the link in the repository that documented the outdated VBscript source code: https://www.virtualbox.org/browser/vbox ... oxinfo.vbs
jprogman
Posts: 7
Joined: 21. Jan 2022, 04:20
Primary OS: MS Windows 10
VBox Version: PUEL
Guest OSses: Win XP Home

Re: API through Visual Basic Script (VB Script) -- outdated sample

Post by jprogman »

Just a thought: because launchvmprocess() needs a string array, I'm hearing things about how vbscript arrays and c or c++ arrays are different. So, maybe the type mismatch error has something to do with that?

I did a typevar() of an array with one empty string, it comes up as array+variant. Perhaps it needs to be array+string? Calling all VBscript experts here :)

EDIT: I'm believing because VBscript makes every array as a safearray, launchVMProcess() won't marshal safearrays into a specific generic array type i.e. array full of strings. Does VirtualBox API have anything that could marshal -- or convert -- safearrays?
The VarType function never returns the value for Array by itself. It is always added to some other value to indicate an array of a particular type. The value for Variant is only returned when it has been added to the value for Array to indicate that the argument to the VarType function is an array. For example, the value returned for an array of integers is calculated as 2 + 8192, or 8194. If an object has a default property, VarType (object) returns the type of its default property. -- VarType - MicroFocus.com
Post Reply