从 Windows NT 设备路径转换为驱动器号路径

问题描述 投票:0回答:2

如何解析设备路径中带有驱动器盘符的路径?

例如转换

\Device\HarddiskVolume4\Windows\System32\RuntimeBroker.exe

进入

C:\Windows\System32\RuntimeBroker.exe

假设

HarddiskVolume4
映射到此计算机上的
C:

我找到了这个问题,但我想在C#中使用它。

c# windows winapi path drive-letter
2个回答
3
投票
string devicePath = @"\Device\HarddiskVolume4\Windows\System32\RuntimeBroker.exe";
string driveLetterPath = DevicePathMapper.FromDevicePath(devicePath);

// driveLetterPath == C:\Windows\System32\RuntimeBroker.exe

由于我们想要一个带有驱动器号的路径,因此我们需要将

\Device\HarddiskVolume4
替换为正确的驱动器号,例如
C:
。为此,请使用
QueryDosDevice
并将 dos 设备映射到每个驱动器号。然后我们就可以搜索并替换dos设备路径了。

这是一个可能的实现。它使用内部扩展方法:

public static class DevicePathMapper {
    [DllImport("Kernel32.dll", CharSet = CharSet.Unicode)]
    private static extern uint QueryDosDevice([In] string lpDeviceName, [Out] StringBuilder lpTargetPath, [In] int ucchMax);

    public static string FromDevicePath(string devicePath) {
        var drive = Array.Find(DriveInfo.GetDrives(), d => devicePath.StartsWith(d.GetDevicePath(), StringComparison.InvariantCultureIgnoreCase));
        return drive != null ?
            devicePath.ReplaceFirst(drive.GetDevicePath(), drive.GetDriveLetter()) :
            null;
    }

    private static string GetDevicePath(this DriveInfo driveInfo) {
        var devicePathBuilder = new StringBuilder(128);
        return QueryDosDevice(driveInfo.GetDriveLetter(), devicePathBuilder, devicePathBuilder.Capacity + 1) != 0 ?
            devicePathBuilder.ToString() :
            null;
    }

    private static string GetDriveLetter(this DriveInfo driveInfo) {
        return driveInfo.Name.Substring(0, 2);
    }

    private static string ReplaceFirst(this string text, string search, string replace) {
        int pos = text.IndexOf(search);
        if (pos < 0) {
            return text;
        }
        return text.Substring(0, pos) + replace + text.Substring(pos + search.Length);
    }
}

0
投票

我无法向 Bruno Zell 答案添加评论,因此添加为答案... 他的代码没问题,直到我们有超过 10 个磁盘:

X:硬盘卷1

Y:硬盘卷11

“\device\harddiskvolume11\starfield\starfield.exe” 卷 11 是磁盘 Y,因此当此代码获取字母时,它会显示 X,因为它以 *\device\harddiskvolume1* starts

所以我们必须更改 FromDevicePath 方法并添加如下内容:

    var allDrives = Array.FindAll(DriveInfo.GetDrives(), d => devicePath.StartsWith(d.GetDevicePath(), StringComparison.InvariantCultureIgnoreCase));
    int lastDriveIdx = 0;
    if (allDrives is not null)
    {
        lastDriveIdx = allDrives.Length - 1;
        return devicePath.ReplaceFirst(allDrives[lastDriveIdx].GetDevicePath(), allDrives[lastDriveIdx].GetDriveLetter());
    }
    return null;
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.