无法使用 VBox 获取 VirtualBox 机器的 IP API

Cannot get VirtualBox machine's IP using the VBox API

我有一台带有 Ubuntu 的 VirtualBox 机器,它连接了一个桥接适配器。

我想做的是获取机器的IP。

如果我手动启动机器并像这样使用 VBoxManage 实用程序:

VBoxManage guestproperty get "Ubuntu Test Machine" /VirtualBox/GuestInfo/Net/0/V4/IP

它工作正常。

但是,我需要的是使用 VBox SDK 以编程方式获取 IP。 这是代码中最重要的部分(我将 post 整个代码放在最后):

HRESULT hr = machine->GetGuestPropertyValue(L"/VirtualBox/GuestInfo/Net/0/V4/IP", &ip);
if (SUCCEEDED(hr))
{
    printf("The machine's IP is: %s", ip);
}
else
    printf("Error retrieving machine IP! rc = 0x%x\n", hr);

我收到以下错误:

Error retrieving machine IP! rc = 0x80070057

显然错误代码意味着参数无效

谁能告诉我那个参数有什么问题吗?或者如果我做错了什么?

完整代码如下(基本上是 VBox SDK 示例目录中的示例代码,稍作修改):

int testStartVM(IVirtualBox *virtualBox)
{
    HRESULT rc;

    IMachine *machine = NULL;
    BSTR machineName = SysAllocString(L"Ubuntu Test Machine");

    rc = virtualBox->FindMachine(machineName, &machine);

    if (FAILED(rc))
    {
        // this code is verbose and not relevant
    }
    else
    {
        ISession *session = NULL;
        IConsole *console = NULL;
        IProgress *progress = NULL;
        BSTR sessiontype = SysAllocString(L"headless");
        BSTR guid;

        do
        {
            rc = machine->get_Id(&guid); /* Get the GUID of the machine. */
            if (!SUCCEEDED(rc))
            {
                printf("Error retrieving machine ID! rc = 0x%x\n", rc);
                break;
            }

            /* Create the session object. */
            rc = CoCreateInstance(CLSID_Session,        /* the VirtualBox base object */
                                  NULL,                 /* no aggregation */
                                  CLSCTX_INPROC_SERVER, /* the object lives in a server process on this machine */
                                  IID_ISession,         /* IID of the interface */
                                  (void**)&session);
            if (!SUCCEEDED(rc))
            {
                printf("Error creating Session instance! rc = 0x%x\n", rc);
                break;
            }

            /* Start a VM session using the delivered VBox GUI. */
            rc = machine->LaunchVMProcess(session, sessiontype,
                                          NULL, &progress);
            if (!SUCCEEDED(rc))
            {
                printf("Could not open remote session! rc = 0x%x\n", rc);
                break;
            }

            /* Wait until VM is running. */
            printf("Starting VM, please wait ...\n");
            rc = progress->WaitForCompletion(-1);

            /* Get console object. */
            session->get_Console(&console);

            /* Bring console window to front. */
            machine->ShowConsoleWindow(0);

            // give it a few seconds just to be sure everything has been started
            Sleep(40 * 1000);
            BSTR ip;

            **// this line fails**
            HRESULT hr = machine->GetGuestPropertyValue(L"/VirtualBox/GuestInfo/Net/0/V4/IP", &ip);
            if (SUCCEEDED(hr))
            {
                printf("The machine's IP is: %s", ip);
            }
            else
                printf("Error retrieving machine IP! rc = 0x%x\n", hr);

            printf("Press enter to power off VM and close the session...\n");
            getchar();

            /* Power down the machine. */
            rc = console->PowerDown(&progress);

            /* Wait until VM is powered down. */
            printf("Powering off VM, please wait ...\n");
            rc = progress->WaitForCompletion(-1);

            /* Close the session. */
            rc = session->UnlockMachine();

        } while (0);

        SAFE_RELEASE(console);
        SAFE_RELEASE(progress);
        SAFE_RELEASE(session);
        SysFreeString(guid);
        SysFreeString(sessiontype);
        SAFE_RELEASE(machine);
    }

    SysFreeString(machineName);

    return 0;
}


int main(int argc, char *argv[])
{
    HRESULT rc;
    IVirtualBox *virtualBox;

    /* Initialize the COM subsystem. */
    CoInitialize(NULL);

    /* Instantiate the VirtualBox root object. */
    rc = CoCreateInstance(CLSID_VirtualBox,       /* the VirtualBox base object */
                            NULL,                   /* no aggregation */
                            CLSCTX_LOCAL_SERVER,    /* the object lives in a server process on this machine */
                            IID_IVirtualBox,        /* IID of the interface */
                            (void**)&virtualBox);

    if (!SUCCEEDED(rc))
    {
        printf("Error creating VirtualBox instance! rc = 0x%x\n", rc);
        return 1;
    }

    listVMs(virtualBox);

    testStartVM(virtualBox);

    /* Release the VirtualBox object. */
    virtualBox->Release();

    CoUninitialize();

    getchar();
    return 0;
}

我找到问题了。显然 GetGuestPropertyValue 函数不知道如何自动将 wchar_t* 转换为 BSTR。我需要给它一个实际的 BSTR。

正确的方法是:

BSTR val = SysAllocString(L"/VirtualBox/GuestInfo/Net/0/V4/IP");

HRESULT hr = machine->GetGuestPropertyValue(val, &ip);
if (SUCCEEDED(hr))
{
    wprintf(L"The machine's IP is: %s", ip);
}
else
    printf("Error retrieving machine IP! rc = 0x%x\n", hr);

SysFreeString(val);