MSFT_Volume格式方法,在WinPE中



我希望能对我的查询有所了解和帮助。

我正在尝试编写最后一个模块到一个自定义的Windows恢复环境,基于Windows10的WinPE。

该解决方案目前使用DiskPart创建磁盘分区(此处与Microsoft建议一致(,但更改为不提供WinRE分区。

在对MSDN上的一个项目进行了大量的研究和修补后,我设法找到了一个可以使用WMI(MSFT_disk、MSFT_partition和MSFT_Volume(清除/分区和格式化磁盘的工作项目。这是在Windows10中15GiB大小的虚拟磁盘上完全工作的。

当我在WinPE中尝试它时(因为这将是它将要使用的操作系统(,它在多个元素上失败了,尽管方法在那里被报道(。(MSFT_Disk::Clear,MSFT_Volume::Format(。

在检查我在DiskPart中的工作结果时,我注意到,尽管MSFT_Volume::Format的返回值为2"未知错误",但它实际上已经格式化了数据分区(NTFS,ClusterSize 4096(。但是,当Format方法应用于ESP(FAT32,簇大小512/1024/4096(时,它会完全失败,文件系统仍报告为RAW,但将应用AccessPath。"ExtendedStatus"只返回错误2(除非我没有正确访问它(。

其他人有没有遇到过这个问题并设法解决了这个问题?多次谷歌搜索都抛出了可能存在WMI错误的想法,但在PowerShell中,并没有像C#/C++中那样编码。以下是一些代码片段和屏幕截图:

创建分区:

try
{
parameters = disk.GetMethodParameters("CreatePartition");
}
catch (Exception e)
{
Console.WriteLine("Exception in Line 88: " + e.Message);
}
if (PartitionType != "PRIMARY")
{
FillInvocationParameters(parameters, new Dictionary<string, object> { { "Size", _partitionSize.ToString() },
    { "AssignDriveLetter", false },
    { "GpTType", _partitionType} });
} 
else
{
FillInvocationParameters(parameters, new Dictionary<string, object> { { "UseMaximumSize", true },
    { "AssignDriveLetter", false },
    { "GpTType", _partitionType} });
}
try
{
res = disk.InvokeMethod("CreatePartition", parameters, null);
objresult = res["ReturnValue"]; //write error handliong routine for the objResult.
Int32.TryParse(objresult.ToString(), out intRes);
}
catch (Exception e)
{
Console.WriteLine("Exception in Line 146: " + e.Message);
ErrorID = Marshal.GetLastWin32Error();
return false;
}
if (intRes != 0)
{
Console.Write("CreatePartition {0} failed with the result: {1} Line 111.", PartitionType, objresult.ToString());
Console.ReadKey();
ErrorID = Marshal.GetLastWin32Error();
return false;
}
//this is the format point for EFI System Disk.. MSFTPARTITIONtoVOLUME MSFT VOLUME::FORMAT
Console.Write($"{PartitionType} Partition has been createdrn");
string partition   = ((ManagementBaseObject)res["CreatedPartition"])["__PATH"] as string;
var MSFT_Partition = new ManagementObject(@"rootMicrosoftWindowsStorage", partition, null);
var partitionIndex = partition.IndexOf(@"ObjectId=");
partition      = partition.Substring(partitionIndex);
partitionIndex = partition.IndexOf(@"}\");
partitionIndex = partitionIndex + 1;
partition      = partition.Substring(0, partitionIndex);
var strMSFTPartition = partition;
partition = partition.Replace("root", "ROOT");
var partitionGuid = MSFT_Partition["Guid"] as string;
Console.WriteLine("Line 138: New Partition GUID: " + partitionGuid);

参数声明为:

ManagementBaseObject parameters = null;

FillInvokationParameters:

private static void FillInvocationParameters(ManagementBaseObject InvocationParameters, IDictionary<string, object> parameters)
{
foreach (var pair in parameters)
{
string stringParamValue;
var managementObjectParam = pair.Value as ManagementObject;
var arrayParam = pair.Value as string;
if (managementObjectParam != null)
{
stringParamValue = managementObjectParam.GetText(TextFormat.CimDtd20);
InvocationParameters[pair.Key] = stringParamValue;
}
else if (arrayParam != null)
InvocationParameters[pair.Key] = arrayParam;
else if (pair.Value != null)
{
stringParamValue = pair.Value.ToString();
InvocationParameters[pair.Key] = stringParamValue;
}
}
}

和格式化方法调用:

try
{
Console.Write("Line 174: Attempting to Format with MSFT_Volume::Format FileSystem {0}, Label: {1}, ClusterSize: {2}rn", _FileSystem, _VolumeLable, _allocationUnit.ToString());
parameters = MSFTVolume.GetMethodParameters("Format");
FillInvocationParameters(parameters, new Dictionary<string, object>{ { "FileSystem", _FileSystem },
       { "AllocationUnitSize", _allocationUnit },
       { "FileSystemLabel", _VolumeLable },
       { "Full", false} });
res = MSFTVolume.InvokeMethod("Format", parameters, null);
objresult = res["ReturnValue"];
Int32.TryParse(objresult.ToString(), out intReslt);
}
catch (Exception e)
{
Console.WriteLine("Line: 189 The Following error occured while attmpeting to Format the Volume: " + e.Message);
ErrorID = Marshal.GetLastWin32Error();
return false;
}

对于ESP,以下内容适用:

switch(PartitionType)
{
case "EFI":
{
_partitionType  = "{c12a7328-f81f-11d2-ba4b-00a0c93ec93b}";
_partitionSize  = 260 /*bytes*/ *1024 /*Kilobytes*/ *1024 /*Megabytes*/;
_FileSystem     = "FAT32";
_allocationUnit = 1024;
_VolumeLable    = "System";
break;
}
}

我的控制台应用程序和磁盘部件结果的屏幕截图:

格式化磁盘控制台输出

DiskPart结果

如有任何帮助/见解,我们将不胜感激。

问候

Richie

请注意,对于Windows 10的较新版本,有几个ADK版本…请确保使用最新和最棒的版本。我们在dism.exe和diskpart.exe方面都遇到了与您类似的问题。有一次,(在早期赢得10个adk时(我们从8.1个adk中获得了dism.exe与diskpart.exe。糟糕透顶,但你必须做你必须做的事:-(

更新

已与支持小组核实。。。事实证明,我把版本搞混了。第一场胜利10 adk有一个工作的dism和磁盘部分(adk为windows 10 1503(。。。我们无法使用PE中的,因为。。。因此,我们仍在从新的ADK部署一个新的winpe,但从1503 ADK中复制磁盘部分和dism。我们从未部署8.1版本——我的错。还是很生气。

据我们所知,它只在房子的一侧出现了问题。。。BIOS+MBR或UEFI+GPT。。。但我们谁也不记得是哪一个。

最新更新