MSFT_Volume格式化方法,在WinPE中
MSFT_Volume Format Method, in WinPE
我希望可能有一些见解,也许对我的查询有所帮助。
我正在尝试将最后一个模块写入自定义 Windows 恢复环境,基于 Windows 10 的 WinPE。
该解决方案目前利用 DiskPart 创建磁盘分区(符合 Microsoft 的建议 here),更改为不提供 WinRE 分区。
在对 MSDN 上找到的项目进行大量研究和修改后,我设法获得了一个工作项目,该项目将 clear/partition 并使用 WMI 格式化磁盘(MSFT_Disk,MSFT_Partition & MSFT_Volume).这在 15 GiB 大小的虚拟磁盘上 Windows 10 内完全有效。
当我在 WinPE 中尝试它时(因为这将是它将在其上使用的 OS),它在多个元素上失败,即使方法被报告为在那里)。 (MSFT_Disk::清除,MSFT_Volume::Format)。
检查我在 DiskPart 中的工作结果时,我注意到即使 MSFT_Volume::Format 的 return 值为 2 "Unknown Error" 它实际上格式化了数据分区(NTFS,集群大小 4096)。但是,当将 Format 方法应用于 ESP(FAT32,簇大小 512/1024/4096)时,它会完全失败,文件系统仍被报告为 RAW,但会应用 AccessPath。 "ExtendedStatus" 只有 return 错误 2(除非我没有正确访问它)。
有没有其他人遇到过这个问题并设法解决了这个问题?多次 Google 搜索排除了可能存在 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 created\r\n");
string partition = ((ManagementBaseObject)res["CreatedPartition"])["__PATH"] as string;
var MSFT_Partition = new ManagementObject(@"root\Microsoft\Windows\Storage", 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;
FillInvokationParamters:
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}\r\n", _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 结果的屏幕截图:
Format Disk Console output
DiskPart Results
任何 help/insights 将不胜感激。
此致
里奇
请注意,对于 Windows 10 的较新版本,有多个 ADK 版本...请务必使用最新和最好的版本。我们在 dism.exe 和 diskpart.exe 上遇到了与您类似的问题。有一次,(早期赢得 10 个 adks)我们从一个 8.1 adk 得到了 dism.exe 和 diskpart.exe。虽然很老套,但你必须做你必须做的事:-)
更新:
与支持小组核实...事实证明,我搞混了版本。第一个 win 10 adk 有一个可用的 dism 和 diskpart(adk for windows 10 1503)...我们一直无法在 PE 中使用 newer ...所以我们仍然从新的 ADK 部署一个新的 winpe - 但从 1503 adk 中复制了 diskpart 和 dism。我们从未部署过 8.1 版本——我的错。仍然 - 像所有 git 一样 hacky。
据我们所知,它只在房子的一侧出现问题...要么是 BIOS+MBR,要么是 UEFI+GPT...但我们 none 记得是哪一个。
我希望可能有一些见解,也许对我的查询有所帮助。
我正在尝试将最后一个模块写入自定义 Windows 恢复环境,基于 Windows 10 的 WinPE。
该解决方案目前利用 DiskPart 创建磁盘分区(符合 Microsoft 的建议 here),更改为不提供 WinRE 分区。
在对 MSDN 上找到的项目进行大量研究和修改后,我设法获得了一个工作项目,该项目将 clear/partition 并使用 WMI 格式化磁盘(MSFT_Disk,MSFT_Partition & MSFT_Volume).这在 15 GiB 大小的虚拟磁盘上 Windows 10 内完全有效。
当我在 WinPE 中尝试它时(因为这将是它将在其上使用的 OS),它在多个元素上失败,即使方法被报告为在那里)。 (MSFT_Disk::清除,MSFT_Volume::Format)。
检查我在 DiskPart 中的工作结果时,我注意到即使 MSFT_Volume::Format 的 return 值为 2 "Unknown Error" 它实际上格式化了数据分区(NTFS,集群大小 4096)。但是,当将 Format 方法应用于 ESP(FAT32,簇大小 512/1024/4096)时,它会完全失败,文件系统仍被报告为 RAW,但会应用 AccessPath。 "ExtendedStatus" 只有 return 错误 2(除非我没有正确访问它)。
有没有其他人遇到过这个问题并设法解决了这个问题?多次 Google 搜索排除了可能存在 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 created\r\n");
string partition = ((ManagementBaseObject)res["CreatedPartition"])["__PATH"] as string;
var MSFT_Partition = new ManagementObject(@"root\Microsoft\Windows\Storage", 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;
FillInvokationParamters:
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}\r\n", _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 结果的屏幕截图:
Format Disk Console output
DiskPart Results
任何 help/insights 将不胜感激。
此致
里奇
请注意,对于 Windows 10 的较新版本,有多个 ADK 版本...请务必使用最新和最好的版本。我们在 dism.exe 和 diskpart.exe 上遇到了与您类似的问题。有一次,(早期赢得 10 个 adks)我们从一个 8.1 adk 得到了 dism.exe 和 diskpart.exe。虽然很老套,但你必须做你必须做的事:-)
更新:
与支持小组核实...事实证明,我搞混了版本。第一个 win 10 adk 有一个可用的 dism 和 diskpart(adk for windows 10 1503)...我们一直无法在 PE 中使用 newer ...所以我们仍然从新的 ADK 部署一个新的 winpe - 但从 1503 adk 中复制了 diskpart 和 dism。我们从未部署过 8.1 版本——我的错。仍然 - 像所有 git 一样 hacky。
据我们所知,它只在房子的一侧出现问题...要么是 BIOS+MBR,要么是 UEFI+GPT...但我们 none 记得是哪一个。