我正在尝试使用.NET Core中的NTFS创建虚拟硬盘。
我发现DiscUtils NuGet软件包及其GitHub page上的示例代码可以很好地创建具有FAT格式的VHD。
long diskSize = 30 * 1024 * 1024; //30MB
using (Stream vhdStream = File.Create(@"C:\TEMP\mydisk.vhd"))
{
Disk disk = Disk.InitializeDynamic(vhdStream, diskSize);
BiosPartitionTable.Initialize(disk, WellKnownPartitionType.WindowsFat);
using (FatFileSystem fs = FatFileSystem.FormatPartition(disk, 0, null))
{
fs.CreateDirectory(@"TestDir\CHILD");
// do other things with the file system...
}
}
但是对于我的用例,我需要大于2 GB的文件。因为无论如何我们都使用Windows,所以NTFS可以。所以我尝试了这段代码
long diskSize = 300 * 1024 * 1024; //300 MB
var vhdPath = Path.Combine(Path.GetTempPath(), Path.ChangeExtension(Path.GetRandomFileName(), "vhd"));
using (Stream vhdStream = File.Create(vhdPath))
{
var disk = DiscUtils.Vhd.Disk.InitializeFixed(vhdStream, Ownership.None, diskSize);
BiosPartitionTable.Initialize(disk, WellKnownPartitionType.WindowsNtfs);
using (var ntfs = NtfsFileSystem.Format(vhdStream, "Virtual NTFS drive", Geometry.FromCapacity(diskSize), 0, diskSize / Sizes.Sector))
{
ntfs.CreateDirectory(@"TestDir\CHILD");
// do other things with the file system...
}
}
这段代码创建了一个300 MB的VHD,我可以使用7zip打开它,但是它包含一个〜300 MB * .mbr文件。如果我尝试打开它,它将在temp文件夹中打开一个新的7zip窗口。 如果我将VHD倍频,则会出现Windows错误 “驱动器映像未初始化,包含无法识别的分区或包含未分配给驱动器号的卷。 使用驱动器管理插件来确保驱动器,分区和卷处于可用状态。”(从德语免费翻译)
此后,由于某些Windows进程仍在忙碌,我无法访问该文件。
我在这里误解了什么?
还有使用C#和.NET Core创建/挂载VHD的另一种方法吗?
答案 0 :(得分:0)
我从EricZimmerman得到了有关项目GitHub page的答案:
var diskSize = 2000 * 1024 * 1024;
var asVhd = false;
using (var fs = new FileStream(_vhfxFileName, FileMode.OpenOrCreate))
{
VirtualDisk destDisk = Disk.InitializeDynamic(fs, Ownership.None, diskSize);
if (asVhd)
{
destDisk = DiscUtils.Vhd.Disk.InitializeDynamic(fs, Ownership.None, diskSize);
}
BiosPartitionTable.Initialize(destDisk, WellKnownPartitionType.WindowsNtfs);
var volMgr = new VolumeManager(destDisk);
var label = $"ZZZZZZ ({dateStamp})";
using (var destNtfs = NtfsFileSystem.Format(volMgr.GetLogicalVolumes()[0], label, new NtfsFormatOptions()))
{
destNtfs.NtfsOptions.ShortNameCreation = ShortFileNameOption.Disabled;
var destDirectory = Path.GetDirectoryName(@"Some file");
destNtfs.CreateDirectory(destDirectory, nfo);
using (Stream source = new FileStream(@"Some file2", FileMode.Open, FileAccess.Read))
{
var destFileName = @"foo";
using (Stream dest = destNtfs.OpenFile(destFileName, FileMode.Create, FileAccess.ReadWrite))
{
source.CopyTo(dest);
dest.Flush();
}
}
//do more stuff here
}
//commit everything to the stream before closing
fs.Flush();
}
为我工作!享受:)