You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Windows中获取已挂载VHD/VHDX路径?需支持Windows 8系统

获取Windows 8及以上系统中挂载的VHD/VHDX路径的替代方案

由于GetAllAttachedVirtualDiskPhysicalPaths仅在Windows 8.1及更高版本可用,我这里提供几个兼容Windows 8的可靠方案,覆盖脚本和原生开发场景:

方法1:PowerShell + DiskPart(最简便的临时查询方案)

DiskPart工具从Windows 7开始就支持list vdisk命令,我们可以通过解析它的输出来提取已挂载的VHD/VHDX路径。这个方法不需要编译代码,直接在PowerShell中运行即可:

# 创建临时DiskPart脚本
$tempScript = Join-Path $env:TEMP "ListMountedVHDs.txt"
"list vdisk" | Out-File $tempScript -Encoding ASCII

# 执行DiskPart并捕获输出
$diskpartOutput = diskpart /s $tempScript

# 解析输出,筛选已挂载的VHD路径
$mountedVHDs = $diskpartOutput | Where-Object { $_ -match "^VHD PATH:\s+(.*)\s+MOUNTED" } | ForEach-Object { $matches[1].Trim() }

# 打印结果
Write-Host "已挂载的VHD/VHDX路径:"
$mountedVHDs

# 清理临时文件
Remove-Item $tempScript -Force

优点:零依赖,操作简单;缺点:依赖DiskPart的输出格式,若微软未来调整输出结构可能失效,但短期兼容性没问题。

方法2:PowerShell调用Virtual Disk API(更可靠的自动化方案)

如果需要更稳定的实现,可以通过PowerShell的P/Invoke直接调用Windows原生的Virtual Disk API,避免依赖输出格式:

Add-Type @"
using System;
using System.Runtime.InteropServices;

public class VirtualDiskUtils {
    // 定义虚拟磁盘信息结构体(仅保留需要的字段)
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct VIRTUAL_DISK_INFORMATION {
        public uint Version;
        public uint VirtualDiskId;
        public string VirtualDiskPath;
    }

    // 导入Virtual Disk API函数
    [DllImport("virtdisk.dll", CharSet = CharSet.Unicode)]
    public static extern int OpenVirtualDisk(
        ref IntPtr VirtualDiskHandle,
        string Path,
        uint AccessMask,
        uint OpenOptions,
        IntPtr Parameters,
        IntPtr Result
    );

    [DllImport("virtdisk.dll", CharSet = CharSet.Unicode)]
    public static extern int GetVirtualDiskInformation(
        IntPtr VirtualDiskHandle,
        ref uint VirtualDiskInformationSize,
        ref VIRTUAL_DISK_INFORMATION VirtualDiskInformation,
        IntPtr SizeUsed
    );

    [DllImport("virtdisk.dll")]
    public static extern int CloseVirtualDisk(
        IntPtr VirtualDiskHandle,
        uint CloseOptions,
        IntPtr Parameters
    );
}
"@

# 获取系统中所有物理磁盘
$allDisks = Get-WmiObject -Class Win32_DiskDrive
$mountedVHDs = @()

foreach ($disk in $allDisks) {
    $devicePath = $disk.DeviceID  # 格式如 \\.\PhysicalDriveX
    $vhdHandle = [IntPtr]::Zero
    $infoSize = [System.Runtime.InteropServices.Marshal]::SizeOf([Type][VirtualDiskUtils+VIRTUAL_DISK_INFORMATION])
    $vhdInfo = New-Object VirtualDiskUtils+VIRTUAL_DISK_INFORMATION
    $vhdInfo.Version = 1  # 使用VIRTUAL_DISK_INFORMATION_VERSION_1

    # 尝试将磁盘作为虚拟磁盘打开
    $openResult = [VirtualDiskUtils]::OpenVirtualDisk([ref]$vhdHandle, $devicePath, 0x00000001, 0, [IntPtr]::Zero, [IntPtr]::Zero)

    if ($openResult -eq 0) {
        # 获取虚拟磁盘信息
        $infoResult = [VirtualDiskUtils]::GetVirtualDiskInformation($vhdHandle, [ref]$infoSize, [ref]$vhdInfo, [IntPtr]::Zero)
        
        if ($infoResult -eq 0 -and ![string]::IsNullOrEmpty($vhdInfo.VirtualDiskPath)) {
            $mountedVHDs += $vhdInfo.VirtualDiskPath
        }

        # 关闭虚拟磁盘句柄
        [VirtualDiskUtils]::CloseVirtualDisk($vhdHandle, 0, [IntPtr]::Zero)
    }
}

# 输出结果
Write-Host "已挂载的VHD/VHDX路径:"
$mountedVHDs

这个方法直接调用官方API,兼容性和稳定性更好,适合集成到自动化脚本中。

方法3:C++原生代码(适合桌面应用开发)

如果是开发C++桌面应用,可以直接使用Virtual Disk API遍历所有磁盘,判断是否为虚拟磁盘并提取路径:

#include <windows.h>
#include <virtdisk.h>
#include <vector>
#include <string>
#include <iostream>

#pragma comment(lib, "virtdisk.lib")

std::vector<std::wstring> GetMountedVirtualDiskPaths() {
    std::vector<std::wstring> vhdPaths;

    // 遍历所有物理磁盘
    DWORD diskNumber = 0;
    while (true) {
        WCHAR devicePath[256];
        swprintf_s(devicePath, L"\\\\.\\PhysicalDrive%d", diskNumber);

        // 打开物理磁盘
        HANDLE hPhysicalDisk = CreateFileW(
            devicePath,
            GENERIC_READ,
            FILE_SHARE_READ | FILE_SHARE_WRITE,
            nullptr,
            OPEN_EXISTING,
            0,
            nullptr
        );

        if (hPhysicalDisk == INVALID_HANDLE_VALUE) {
            if (GetLastError() == ERROR_FILE_NOT_FOUND) {
                break;  // 遍历完所有磁盘
            }
            diskNumber++;
            continue;
        }

        // 尝试将磁盘作为虚拟磁盘打开
        VIRTUAL_DISK_HANDLE vhdHandle = nullptr;
        OPEN_VIRTUAL_DISK_PARAMETERS openParams = {0};
        openParams.Version = OPEN_VIRTUAL_DISK_VERSION_1;

        DWORD result = OpenVirtualDisk(
            &vhdHandle,
            devicePath,
            VIRTUAL_DISK_ACCESS_READ,
            OPEN_VIRTUAL_DISK_FLAG_NONE,
            &openParams,
            nullptr
        );

        if (result == ERROR_SUCCESS) {
            // 获取虚拟磁盘信息
            DWORD infoSize = sizeof(VIRTUAL_DISK_INFORMATION);
            VIRTUAL_DISK_INFORMATION vhdInfo = {0};
            vhdInfo.Version = VIRTUAL_DISK_INFORMATION_VERSION_1;

            result = GetVirtualDiskInformation(
                vhdHandle,
                &infoSize,
                &vhdInfo,
                nullptr
            );

            if (result == ERROR_SUCCESS && vhdInfo.VirtualDiskPath != nullptr) {
                vhdPaths.emplace_back(vhdInfo.VirtualDiskPath);
            }

            // 关闭虚拟磁盘句柄
            CloseVirtualDisk(vhdHandle, 0, nullptr);
        }

        CloseHandle(hPhysicalDisk);
        diskNumber++;
    }

    return vhdPaths;
}

int main() {
    auto mountedVHDs = GetMountedVirtualDiskPaths();
    std::wcout << L"已挂载的VHD/VHDX路径:\n";
    for (const auto& path : mountedVHDs) {
        std::wcout << path << L"\n";
    }
    return 0;
}

编译时需要链接virtdisk.lib,这个方案完全基于Windows原生API,性能和兼容性最佳,适合需要嵌入到应用中的场景。


内容的提问来源于stack exchange,提问作者Isso

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 03:45:45