我正在使用 Hyper-V WMI 界面,并尝试使用 C# 创建我的本地 Hyper-V VM 之一的快照。我试图在不使用 System.Management 的情况下做到这一点。相反,我使用的是 Microsoft.Management.Infrastructure。原因是 .NET Core 支持它。此外,System.Management.Infrastructure 似乎是 System.Management 的预期替代品。
我无法将正确的参数传递给 CIM_VirtualSystemSnapshotService 类上的“CreateSnapshot”方法的正确参数。
列出的输入参数:
uint32 CreateSnapshot([in] CIM_ComputerSystem REF AffectedSystem, [in] string
SnapshotSettings, [in] uint16
SnapshotType, [in, out] CIM_VirtualSystemSettingData REF ResultingSnapshot, [out] CIM_ConcreteJob REF Job);
但是,这并没有指定哪些是强制性的,是否可以传递 NULL 值等。
我尝试使用的 C# 方法:
public static void CreateSnapshot()
{
const string hvNamespace = @"root\virtualization\v2";
var sessionOptions = new DComSessionOptions
{
Timeout = TimeSpan.FromSeconds(30)
};
var cimSession = CimSession.Create("localhost", sessionOptions);
var vmSnapshotService = new CimInstance(cimSession.GetClass(hvNamespace, "CIM_VirtualSystemSnapshotService"));
// CimInstance of CIM_ComputerSystem. QueryInstances returns Msvm_ComputerSystem
var vm = cimSession.QueryInstances(hvNamespace, "WQL", $"SELECT * FROM CIM_ComputerSystem WHERE ElementName = 'Android'").First();
var snapshotSettingDataClass = cimSession.GetClass(hvNamespace, "CIM_VirtualSystemSettingData");
var snapshotSettingData = new CimInstance(snapshotSettingDataClass);
var snapshotParameters = new CimMethodParametersCollection();
snapshotParameters.Add(CimMethodParameter.Create("AffectedSystem", vm, CimFlags.In));
snapshotParameters.Add(CimMethodParameter.Create("SnapshotSettings", "", CimFlags.In));
snapshotParameters.Add(CimMethodParameter.Create("SnapshotType", 2, CimFlags.In));
snapshotParameters.Add(CimMethodParameter.Create("ResultingSnapshot", snapshotSettingData, CimFlags.Out));
cimSession.InvokeMethod(namespaceName: hvNamespace, instance: vmSnapshotService, methodName: "CreateSnapshot", methodParameters: snapshotParameters);
//Microsoft.Management.Infrastructure.CimException: 'Invalid parameter '
Console.WriteLine($"Snapshot created!");
}
这给出了错误“无效参数”。很难具体。
我试图在 Powershell 中重建它:
$session = New-CimSession
$hvNamespace = "root\virtualization\v2"
$snapshotservice = Get-CimClass -ClassName "CIM_VirtualSystemSnapshotService" -Namespace $hvNamespace
$vm = Get-CimInstance -Namespace $hvNamespace -Query "SELECT * FROM CIM_ComputerSystem WHERE ElementName = 'Android'" -QueryDialect WQL
Invoke-CimMethod -ClassName "Msvm_VirtualSystemSnapshotService" -MethodName "CreateSnapshot" -Namespace $hvNamespace -Arguments @{ "AffectedSystem" = $vm ; "SnapshotSettings" = "" ; "SnapshotType" = 2 }
这给出了这个错误:
Invoke-CimMethod : 参数“AffectedSystem”的类型不匹配在 line:1 char:1 + Invoke-CimMethod -ClassName "Msvm_VirtualSystemSnapshotService" -Meth ... + ~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~ + CategoryInfo : InvalidType: (root\virtualiza...SnapshotService :String) [Invoke-CimMethod], CimException + FullyQualifiedErrorId : HRESULT 0x80041005,Microsoft.Management.Infrast
ructure.CimCmdlets.InvokeCimMethodCommand
因此,看起来该方法需要一个 CIM_ComputerSystem。但是,我将它传递给 Msvm_ComputerSystem。在 C# 中,它“只是”另一个 CIMInstance。所以,我不能像使用“普通”课程那样从一个班级转换到另一个班级。
我有什么办法可以将 Msvm_ComputerSystem“转换”为 CIM_ComputerSystem?或者,我是在追逐一条大红鲱鱼吗?