0

我希望可能对我的查询有所帮助。

我正在尝试将最后一个模块写入基于 Windows 10 的 WinPE 的自定义 Windows 恢复环境。

该解决方案目前使用 DiskPart 创建磁盘分区(此处符合 Microsoft的建议),更改为不提供 WinRE 分区。

在对 MSDN 上的一个项目进行了大量研究和修改后,我设法获得了一个可以使用 WMI(MSFT_Disk、MSFT_Partition 和 MSFT_Volume)清除/分区和格式化磁盘的工作项目。这完全可以在 Windows 10 的 15 GiB 大小的虚拟磁盘上运行。

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

在检查我在 DiskPart 中的工作结果时,我注意到即使 MSFT_Volume::Format 的返回值为 2“Unknown Error”,它实际上已经格式化了数据分区(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 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;

填充调用参数:

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 结果的屏幕截图:

格式化磁盘控制台输出

磁盘部分结果

任何帮助/见解将不胜感激。

问候

里奇

4

1 回答 1

0

请注意,对于较新的 Windows 10 版本,有多个 ADK 版本……请务必使用最新最好的版本。对于 dism.exe 和 diskpart.exe,我们遇到了与您类似的问题。有一次,(在早期的 win 10 adk 上)我们从 8.1 adk 中获得了 dism.exe 和 diskpart.exe。哈克,但你必须做你必须做的:-)

更新

与支持小组核对...结果,我把版本搞混了。第一个 win 10 adk 有一个可以工作的 dism 和 diskpart(adk for windows 10 1503)...从那以后我们就无法在 PE 中使用较新的...所以我们仍在部署新的 winpe新的 ADK - 但是从 1503 adk 中保存的 diskpart 和 dism 中的复制。我们从未部署过 8.1 版本——我的错。仍然 - hacky,因为所有人都退出了。

我们记得最好,它只在房子的一侧出现了问题……BIOS+MBR 或 UEFI+GPT……但我们都不记得是哪个。

于 2018-07-19T12:52:16.093 回答