Page 1 of 1

[Solved] Guest property not persistent

PostPosted: 19. Jun 2018, 23:10
by calind
I'm facing this problem: I'm setting a guest property using VBox API (C++). I can see the value being set OK using VBoxManage. But as soon as I close the VM (from the GUI or programmatically) the property reverts to a previous value.

If I do this from VBoxManage everything works fine.

I don't have the code at hand (will post tomorow) but the sequence is based on VBoxManage source code: find machine, lock, set, unlock. My app runs as admin. There is a similar bug from 5 years ago but I believe it's been solved meanwhile: https://www.virtualbox.org/ticket/11719

Re: Guest property not persistent

PostPosted: 21. Jun 2018, 12:43
by calind
Edit: this is embarrassing. Turns out I missed the SaveSettings() call. Funny how you always seem to find these small errors as soon as you ask.

Here's my code. It uses the ComPtr implementation of VBox SDK but using the Microsoft-provided CComPtr works the same. I can read the property but it gets deleted as soon as UnlockMachine() gets called. As mentioned previously my app run as admin.

Code: Select all   Expand viewCollapse view
    HRESULT hRes;

    hRes = CoInitializeEx(0, COINIT_MULTITHREADED);

    ComPtr<IVirtualBoxClient> virtualBoxClient;
    ComPtr<IVirtualBox> virtualBox;
    ComPtr<ISession> session;

    hRes = virtualBoxClient.createInprocObject(CLSID_VirtualBoxClient);
    hRes = virtualBoxClient->get_VirtualBox(virtualBox.asOutParam());
    hRes = session.createInprocObject(CLSID_Session);

    ComPtr<IProgress> progressL;
    ComPtr<IMachine> machine;

    hRes = virtualBox->FindMachine(_bstr_t(L"Windows 10 64-bit 1803 Test 2"), machine.asOutParam());
    hRes = machine->LockMachine(session, LockType_Shared);
    hRes = session->get_Machine(machine.asOutParam());

    // Property is set ok, tested with VBoxManage
    hRes = machine->SetGuestPropertyValue(_bstr_t(L"SomeProp"), _bstr_t(L"SomeVal"));

    // Property is deleted as soon as this call returns
    hRes = session->UnlockMachine();



This is how VBoxManage does it:
Code: Select all   Expand viewCollapse view
    ComPtr<IMachine> machine;
    CHECK_ERROR(a->virtualBox, FindMachine(Bstr(a->argv[0]).raw(),
                                           machine.asOutParam()));
    if (machine)
    {
        /* open a session for the VM - new or existing */
        CHECK_ERROR_RET(machine, LockMachine(a->session, LockType_Shared), RTEXITCODE_FAILURE);

        /* get the mutable session machine */
        a->session->COMGETTER(Machine)(machine.asOutParam());

        if (!pszFlags)
            CHECK_ERROR(machine, SetGuestPropertyValue(Bstr(pszName).raw(),
                                                       Bstr(pszValue).raw()));
        else
            CHECK_ERROR(machine, SetGuestProperty(Bstr(pszName).raw(),
                                                  Bstr(pszValue).raw(),
                                                  Bstr(pszFlags).raw()));

        if (SUCCEEDED(rc))
            CHECK_ERROR(machine, SaveSettings());

        a->session->UnlockMachine();
    }