VirtualBox

source: vbox/trunk/src/VBox/Main/testcase/tstVBoxAPIWin.cpp

Last change on this file was 106061, checked in by vboxsync, 2 months ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.0 KB
Line 
1/* $Id: tstVBoxAPIWin.cpp 106061 2024-09-16 14:03:52Z vboxsync $ */
2/** @file
3 *
4 * tstVBoxAPIWin - sample program to illustrate the VirtualBox
5 * COM API for machine management on Windows.
6 It only uses standard C/C++ and COM semantics,
7 * no additional VBox classes/macros/helpers. To
8 * make things even easier to follow, only the
9 * standard Win32 API has been used. Typically,
10 * C++ developers would make use of Microsoft's
11 * ATL to ease development.
12 */
13
14/*
15 * Copyright (C) 2006-2024 Oracle and/or its affiliates.
16 *
17 * This file is part of VirtualBox base platform packages, as
18 * available from https://www.virtualbox.org.
19 *
20 * This program is free software; you can redistribute it and/or
21 * modify it under the terms of the GNU General Public License
22 * as published by the Free Software Foundation, in version 3 of the
23 * License.
24 *
25 * This program is distributed in the hope that it will be useful, but
26 * WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
28 * General Public License for more details.
29 *
30 * You should have received a copy of the GNU General Public License
31 * along with this program; if not, see <https://www.gnu.org/licenses>.
32 *
33 * SPDX-License-Identifier: GPL-3.0-only
34 */
35
36/*
37 * PURPOSE OF THIS SAMPLE PROGRAM
38 * ------------------------------
39 *
40 * This sample program is intended to demonstrate the minimal code necessary
41 * to use VirtualBox COM API for learning puroses only. The program uses pure
42 * Win32 API and doesn't have any extra dependencies to let you better
43 * understand what is going on when a client talks to the VirtualBox core
44 * using the COM framework.
45 *
46 * However, if you want to write a real application, it is highly recommended
47 * to use our MS COM XPCOM Glue library and helper C++ classes. This way, you
48 * will get at least the following benefits:
49 *
50 * a) better portability: both the MS COM (used on Windows) and XPCOM (used
51 * everywhere else) VirtualBox client application from the same source code
52 * (including common smart C++ templates for automatic interface pointer
53 * reference counter and string data management);
54 * b) simpler XPCOM initialization and shutdown (only a single method call
55 * that does everything right).
56 *
57 * Currently, there is no separate sample program that uses the VirtualBox MS
58 * COM XPCOM Glue library. Please refer to the sources of stock VirtualBox
59 * applications such as the VirtualBox GUI frontend or the VBoxManage command
60 * line frontend.
61 */
62
63
64#include <stdio.h>
65#include <iprt/win/windows.h> /* Avoid -Wall warnings. */
66#include "VirtualBox.h"
67
68#define SAFE_RELEASE(x) \
69 if (x) { \
70 x->Release(); \
71 x = NULL; \
72 }
73
74int listVMs(IVirtualBox *virtualBox)
75{
76 HRESULT rc;
77
78 /*
79 * First we have to get a list of all registered VMs
80 */
81 SAFEARRAY *machinesArray = NULL;
82
83 rc = virtualBox->get_Machines(&machinesArray);
84 if (SUCCEEDED(rc))
85 {
86 IMachine **machines;
87 rc = SafeArrayAccessData(machinesArray, (void **) &machines);
88 if (SUCCEEDED(rc))
89 {
90 for (ULONG i = 0; i < machinesArray->rgsabound[0].cElements; ++i)
91 {
92 BSTR str;
93
94 rc = machines[i]->get_Name(&str);
95 if (SUCCEEDED(rc))
96 {
97 printf("Name: %S\n", str);
98 SysFreeString(str);
99 }
100 }
101
102 SafeArrayUnaccessData(machinesArray);
103 }
104
105 SafeArrayDestroy(machinesArray);
106 }
107
108 return 0;
109}
110
111
112int testErrorInfo(IVirtualBox *virtualBox)
113{
114 HRESULT rc;
115
116 /* Try to find a machine that doesn't exist */
117 IMachine *machine = NULL;
118 BSTR machineName = SysAllocString(L"Foobar");
119
120 rc = virtualBox->FindMachine(machineName, &machine);
121
122 if (FAILED(rc))
123 {
124 IErrorInfo *errorInfo;
125
126 rc = GetErrorInfo(0, &errorInfo);
127
128 if (FAILED(rc))
129 printf("Error getting error info! rc=%#lx\n", rc);
130 else
131 {
132 BSTR errorDescription = NULL;
133
134 rc = errorInfo->GetDescription(&errorDescription);
135
136 if (FAILED(rc) || !errorDescription)
137 printf("Error getting error description! rc=%#lx\n", rc);
138 else
139 {
140 printf("Successfully retrieved error description: %S\n", errorDescription);
141
142 SysFreeString(errorDescription);
143 }
144
145 errorInfo->Release();
146 }
147 }
148
149 SAFE_RELEASE(machine);
150 SysFreeString(machineName);
151
152 return 0;
153}
154
155
156int testStartVM(IVirtualBox *virtualBox)
157{
158 HRESULT rc;
159
160 /* Try to start a VM called "WinXP SP2". */
161 IMachine *machine = NULL;
162 BSTR machineName = SysAllocString(L"WinXP SP2");
163
164 rc = virtualBox->FindMachine(machineName, &machine);
165
166 if (FAILED(rc))
167 {
168 IErrorInfo *errorInfo;
169
170 rc = GetErrorInfo(0, &errorInfo);
171
172 if (FAILED(rc))
173 printf("Error getting error info! rc=%#lx\n", rc);
174 else
175 {
176 BSTR errorDescription = NULL;
177
178 rc = errorInfo->GetDescription(&errorDescription);
179
180 if (FAILED(rc) || !errorDescription)
181 printf("Error getting error description! rc=%#lx\n", rc);
182 else
183 {
184 printf("Successfully retrieved error description: %S\n", errorDescription);
185
186 SysFreeString(errorDescription);
187 }
188
189 SAFE_RELEASE(errorInfo);
190 }
191 }
192 else
193 {
194 ISession *session = NULL;
195 IConsole *console = NULL;
196 IProgress *progress = NULL;
197 BSTR sessiontype = SysAllocString(L"gui");
198 BSTR guid;
199
200 do
201 {
202 rc = machine->get_Id(&guid); /* Get the GUID of the machine. */
203 if (!SUCCEEDED(rc))
204 {
205 printf("Error retrieving machine ID! rc=%#lx\n", rc);
206 break;
207 }
208
209 /* Create the session object. */
210 rc = CoCreateInstance(CLSID_Session, /* the VirtualBox base object */
211 NULL, /* no aggregation */
212 CLSCTX_INPROC_SERVER, /* the object lives in the current process */
213 IID_ISession, /* IID of the interface */
214 (void**)&session);
215 if (!SUCCEEDED(rc))
216 {
217 printf("Error creating Session instance! rc=%#lx\n", rc);
218 break;
219 }
220
221 /* Start a VM session using the delivered VBox GUI. */
222 rc = machine->LaunchVMProcess(session, sessiontype,
223 NULL, &progress);
224 if (!SUCCEEDED(rc))
225 {
226 printf("Could not open remote session! rc=%#lx\n", rc);
227 break;
228 }
229
230 /* Wait until VM is running. */
231 printf("Starting VM, please wait ...\n");
232 rc = progress->WaitForCompletion(-1);
233
234 /* Get console object. */
235 session->get_Console(&console);
236
237 /* Bring console window to front. */
238 machine->ShowConsoleWindow(0);
239
240 printf("Press enter to power off VM and close the session...\n");
241 getchar();
242
243 /* Power down the machine. */
244 rc = console->PowerDown(&progress);
245
246 /* Wait until VM is powered down. */
247 printf("Powering off VM, please wait ...\n");
248 rc = progress->WaitForCompletion(-1);
249
250 /* Close the session. */
251 rc = session->UnlockMachine();
252
253 } while (0);
254
255 SAFE_RELEASE(console);
256 SAFE_RELEASE(progress);
257 SAFE_RELEASE(session);
258 SysFreeString(guid);
259 SysFreeString(sessiontype);
260 SAFE_RELEASE(machine);
261 }
262
263 SysFreeString(machineName);
264
265 return 0;
266}
267
268
269int main()
270{
271 /* Initialize the COM subsystem. */
272 CoInitialize(NULL);
273
274 /* Instantiate the VirtualBox root object. */
275 IVirtualBoxClient *virtualBoxClient;
276 HRESULT rc = CoCreateInstance(CLSID_VirtualBoxClient, /* the VirtualBoxClient object */
277 NULL, /* no aggregation */
278 CLSCTX_INPROC_SERVER, /* the object lives in the current process */
279 IID_IVirtualBoxClient, /* IID of the interface */
280 (void**)&virtualBoxClient);
281 if (SUCCEEDED(rc))
282 {
283 IVirtualBox *virtualBox;
284 rc = virtualBoxClient->get_VirtualBox(&virtualBox);
285 if (SUCCEEDED(rc))
286 {
287 listVMs(virtualBox);
288
289 testErrorInfo(virtualBox);
290
291 /* Enable the following line to get a VM started. */
292 //testStartVM(virtualBox);
293
294 /* Release the VirtualBox object. */
295 virtualBox->Release();
296 virtualBoxClient->Release();
297 }
298 else
299 printf("Error creating VirtualBox instance! rc=%#lx\n", rc);
300 }
301
302 CoUninitialize();
303 return 0;
304}
305
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette