C# CIMInstance中的铸造参数
我正在使用Hyper-V WMI接口,并尝试使用C#创建我的一个本地Hyper-V VM的快照。我正在尝试在不使用系统管理的情况下执行此操作。相反,我使用的是Microsoft.Management.Infrastructure。原因是.NETCore上支持它。此外,System.Management.Infrastructure似乎是System.Management的预期替代品 我无法将正确的参数传递给CIM_VirtualSystemSnapshotService类上的“CreateSnapshot”方法的正确参数 这里有记录: 输入参数如下所示: uint32创建快照([in]CIM_ComputerSystem REF 受影响的系统,[in]字符串C# CIMInstance中的铸造参数,c#,wmi,hyper-v,cim,C#,Wmi,Hyper V,Cim,我正在使用Hyper-V WMI接口,并尝试使用C#创建我的一个本地Hyper-V VM的快照。我正在尝试在不使用系统管理的情况下执行此操作。相反,我使用的是Microsoft.Management.Infrastructure。原因是.NETCore上支持它。此外,System.Management.Infrastructure似乎是System.Management的预期替代品 我无法将正确的参数传递给CIM_VirtualSystemSnapshotService类上的“CreateSna
快照设置,[in]uint16
快照类型,[in,out]CIM_VirtualSystemSettingData REF 结果快照,[out]CIM_ConcreteJob REF Job) 但是,这并没有指定哪些是必需的,是否可以传递空值,等等 我尝试使用的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 }
这会产生以下错误:
调用CimMethod:处参数“AffectedSystem”的类型不匹配
行:1字符:1
+调用CimMethod-类名“Msvm_VirtualSystemSnapshotService”-方法。。。
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+CategoryInfo:InvalidType:(根\virtualiza…快照服务:字符串)[调用CimMethod],
CimException
+FullyQualifiedErrorId:HRESULT 0x80041005,Microsoft.Management.Infraststructure.CimCmdlets.InvokeCimMethodCommand 因此,该方法似乎需要一个CIM_计算机系统。然而,我正在通过一个Msvm_计算机系统。 从C#,它“只是”另一个CIMInstance。所以,我不能像对待“普通”类那样,从一个类转换到另一个类
我有没有办法将Msvm_计算机系统“转换”为CIM_计算机系统?或者,我是在追求一条大的红鲱鱼吗?好吧,我花了一段时间才找到时间再做这件事 我终于解决了 CIM/WMI框架中有些东西的工作方式似乎与您预期的有所不同 最终,解决方案是“简单的”。在调用CimMethodParameter.Create时,可以指定CimType。将该值设置为正确的值,该方法将起作用。任何偏差将立即导致“无效参数”或“未找到”。例如,传递int而不是uint8会导致错误 此外,似乎没有必要预先定义输出变量。输出由从InvokeMethod返回的CimMethodResult对象返回 我已经包括了下面的完整程序。运行前,从Nuget安装Microsoft.Management.Infrastructure
using System;
using System.Linq;
using Microsoft.Management.Infrastructure;
using Microsoft.Management.Infrastructure.Options;
namespace TestApp
{
class Program
{
public static void CreateSnapshot()
{
const string hvNamespace = @"root\virtualization\v2";
var sessionOptions = new DComSessionOptions
{
Timeout = TimeSpan.FromSeconds(30)
};
var cimSession = CimSession.Create("localhost", sessionOptions);
// Get an instance of the VM to snapshot
var vm = cimSession.QueryInstances(hvNamespace, "WQL", $"SELECT * FROM CIM_ComputerSystem WHERE ElementName = 'MyTestVM'").First();
// Get the instance of Msvm_VirtualSystemSnapshotService. There is only one.
var vmSnapshotService = cimSession.EnumerateInstances(hvNamespace, "Msvm_VirtualSystemSnapshotService").First();
// Set the snapshot parameters by creating a Msvm_VirtualSystemSnapshotSettingData
var snapshotSettings = new CimInstance("Msvm_VirtualSystemSnapshotSettingData");
snapshotSettings.CimInstanceProperties.Add(CimProperty.Create("ConsistencyLevel", 1, CimType.UInt8, CimFlags.ReadOnly));
snapshotSettings.CimInstanceProperties.Add(CimProperty.Create("IgnoreNonSnapshottableDisks", true, CimFlags.ReadOnly));
// Put all of these things into a CimMethodParametersCollection.
// Note; no need to specify the "Out" parameters. They will be returned by the call to InvokeMethod.
var methodParameters = new CimMethodParametersCollection
{
CimMethodParameter.Create("AffectedSystem", vm, CimType.Reference, CimFlags.In),
CimMethodParameter.Create("SnapshotSettings", snapshotSettings.ToString(), CimType.String, CimFlags.In),
CimMethodParameter.Create("SnapshotType", 2, CimType.UInt16, CimFlags.In),
};
cimSession.InvokeMethod(hvNamespace, vmSnapshotService, "CreateSnapshot", methodParameters);
Console.WriteLine($"Snapshot created!");
}
static void Main(string[] args)
{
CreateSnapshot();
Console.ReadLine();
}
}
}
嘿,谢谢你。您知道如何查询现有快照了吗?快照是与VM关联的实例。因此,要查询它们,您可以使用类似cimSession.EnumerateAssociatedInstances(hvNameSpace,vm,…)的东西,其中“vm”是保存您的vm的CimInstance。您找到设置快照名称的方法了吗?老实说,没有。我已经尝试过,但似乎不起作用。作为一种解决方法,您可以在创建快照后立即获取并重命名它。