Reputation: 3258
I am trying to load the Hyper-V system definition from an export on a Windows 8 system using WMI. So far, I have this:
var managementScope = new ManagementScope(@"root\virtualization\v2");
var invokeMethodOptions = new InvokeMethodOptions();
invokeMethodOptions.Timeout = new TimeSpan(0, 0, 10);
using (var managementService = WmiUtilities.GetVirtualMachineManagementService(managementScope)) {
var inParameters = managementService.GetMethodParameters(@"ImportSystemDefinition");
inParameters["SystemDefinitionFile"] = filePath;
inParameters["SnapshotFolder"] = snapshotPath;
inParameters["GenerateNewSystemIdentifier"] = false;
ManagementBaseObject outParameters = managementService.InvokeMethod(@"ImportSystemDefinition", inParameters, invokeMethodOptions);
foreach (var value in outParameters.Properties) {
Console.WriteLine("{0}: {1}", value.Name, value.Value);
}
return (ManagementBaseObject) outParameters["ImportedSystem"];
}
When I run this, the return code is 4096
, indicating a job has started successfully, and I get a job value back - for example:
ImportedSystem:
Job: \\COREI7\root\virtualization\v2:Msvm_ConcreteJob.InstanceID="B1DC90B6-14A1-42C0-924E-225660E6EC98"
ReturnValue: 4096
I have the following questions:
I apologize if these questions are too basic - I'm just having no luck finding the answers.
Thanks!
[Edit] I'm looking into adding a ManagementOperationObserver
to tell me when it's done, although it's not clear why I need to force it asynchronous when it seems to be doing that anyway.
Upvotes: 0
Views: 1160
Reputation: 3258
OK, so I worked this out, sort of.
First, the job was completing with an error. The 4096
was telling me that it had started but hadn't finished because it had failed. I still don't know how to quickly get that out from that code above, but experimenting in PowerShell made it clear that's what was happening.
Second, I completely revamped the code. It's possible to have Visual Studio generate strongly-typed WMI classes from Server Explorer: http://msdn.microsoft.com/en-us/library/ms257357.aspx. Doing this twice to get ROOT.virtualization.v2.Msvm_PlannedComputerSystem.cs
and ROOT.virtualization.v2.Msvm_VirtualSystemManagementService.cs
lets me do the following code, which is much clearer:
var managementScope = new ManagementScope(@"root\virtualization\v2");
using (var managementService = new VirtualSystemManagementService(WmiUtilities.GetVirtualMachineManagementService(managementScope))) {
PlannedComputerSystem importedSystem;
ConcreteJob job;
var importResults = managementService.ImportSystemDefinition(
GenerateNewSystemIdentifier: false,
SystemDefinitionFile: filePath,
SnapshotFolder: snapshotPath,
ImportedSystem: out importedSystem,
Job: out job
);
if (importResults != 0) {
MessageBox.Show(String.Format("Error on import of {0}: {1}", filePath, job.ErrorDescription));
}
}
Note that the generated code has to be changed a bit to get the nicer strongly typed objects back from the ImportSystemDefinition
call:
ImportedSystem = null;
Job = null;
if (outParams == null) {
return 0;
} else {
if (outParams.Properties["ImportedSystem"].Value != null) {
ImportedSystem = new PlannedComputerSystem(new ManagementObject(outParams.Properties["ImportedSystem"].Value.ToString()));
}
if (outParams.Properties["Job"].Value != null) {
Job = new ConcreteJob(new ManagementObject(outParams.Properties["Job"].Value.ToString;
}
return Convert.ToUInt32(outParams.Properties["ReturnValue"].Value);
}
Upvotes: 1