Question

I am trying to replicate the following PowerShell in C#:

# Details from here are not particularly important but needed for full sample
$vms = gwmi -namespace "root\virtualization\v2" Msvm_ComputerSystem
$vm = $vms[3]
$snapshot = ($vm.GetRelated("Msvm_VirtualSystemSettingData") | Where { $_.ElementName -eq "SnapshotName" })[0]
# end unimportant 

$VMSS = Get-WMiObject -class Msvm_VirtualSystemSnapshotService -namespace root\virtualization\v2
$VMSS.ApplySnapshot($snapshot, $null)

This code works fine - the snapshot applies as expected.

I have no problem getting the Msvm_VirtualSystemSettingData instance or a Msvm_VirtualSystemSnapshostService instance in C#. However, I can't seem to get the call to ApplySnapshot right - no matter what I give it I get an InvalidOperationException. I'm using generated WMI code from Visual Studio for the call:

public uint ApplySnapshot(ref System.Management.ManagementPath Job, System.Management.ManagementPath Snapshot) {
    if ((isEmbedded == false)) {
        System.Management.ManagementBaseObject inParams = null;
        inParams = PrivateLateBoundObject.GetMethodParameters("ApplySnapshot");
        // following line has been through variations as well with no change -
        // commenting it out, setting to null
        inParams["Job"] = ((System.Management.ManagementPath)(Job)).Path;
        inParams["Snapshot"] = ((System.Management.ManagementPath)(Snapshot)).Path;
        System.Management.ManagementBaseObject outParams = PrivateLateBoundObject.InvokeMethod("ApplySnapshot", inParams, null);
        Job = ((System.Management.ManagementPath)(outParams.Properties["Job"].Value));
        return System.Convert.ToUInt32(outParams.Properties["ReturnValue"].Value);
    }
    else {
        return System.Convert.ToUInt32(0);
    }
}

I'm not sure what to pass for the Job parameter either, since we get a job back - it's very unusual to have a ref for that instead of an out but I've tried a bunch of different variations around that (including setting the parameter to null and not setting it at all) with no luck. I've also tried setting inParams[Job] to null with no luck for that either.

What should I change to make this work?

Was it helpful?

Solution

I believe your problem is that you are passing in the job to start with when it is an outbound parameter. That parameter will return from the invocation. Something like..

ManagementBaseObject inParams = null;

inParams = PrivateLateBoundObject.GetMethodParameters("ApplySnapshot");
inParams["Snapshot"] = ((System.Management.ManagementPath)(Snapshot)).Path;

ManagementBaseObject outParams = PrivateLateBoundObject.InvokeMethod("ApplySnapshot", inParams, null);

// i left this as i assume this is vs generated though this isn't how i would normally
// get my jobs back.
Job = ((ManagementPath)(outParams.Properties["Job"].Value));

return Convert.ToUInt32(outParams.Properties["ReturnValue"].Value);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top