将低级磁盘名称转换为高级磁盘名称

Translate Low level disk name to high level disk name

我正在编写一个基本的诊断工具来向高级用户展示他们计算机中的瓶颈所在(因此他们明白获得更多 ram/faster 处理器并不能解决他们的问题)。到目前为止,我一直相当依赖 .NET 环境中的性能计数器 class,它运行良好。

然而,在使用逻辑磁盘驱动器时,我遇到了一个小问题。在我的计算机上,我有一个办公室共享文档驱动器 (Z) 的网络驱动器,但是性能计数器将该驱动器称为 "HarddiskVolume2"。我知道在幕后这就是逻辑驱动器的实际命名,"Z:" 的别名实际上只是为了用户的利益,但如果我离开,用户将不知道 "HarddiskVolume2" 是什么它。

有什么方法可以使用任何系统调用将 "HarddiskVolume2" 转换为 "Z" 吗?

如果您想查看所有映射驱动器及其解析路径的列表:

Console.WriteLine(String.Join(Environment.NewLine,
    GetUNCDrives().Select(kvp => 
        string.Format("{0} => {1}", kvp.Key, kvp.Value))));

如果您想获取路径的可能较短分辨率的列表:

var longPath = @"\HarddiskVolume2\ent\RRPSTO\foobar\file.txt";

Console.WriteLine(string.Join(Environment.NewLine, GetShortPaths(longPath)));

如果您假设只有一个映射驱动器分辨率,您可以 select 第一个:

var shortPaths = GetShortPaths(longPath);
var path = shortPaths.Length > 0 ? shortPaths[0] : longPath;

或者您可以根据网络地图的深度从列表中进行选择。因此,要获得最短映射路径(不是最短路径名),您只需计算路径中有多少个“/”即可。

或者你可以作弊,只取路径名最短的那个。但这不能保证是最简单的路径。

无论您想做什么,下面的代码都是使上面的代码起作用的原因。 你需要这些人:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Management;
using System.IO;

您还需要在项目参考中包含 System.Management.dll

代码:

/// <summary>Gets array of all possible shorter paths for provided path.</summary>
/// <param name="path">The path to find alternate addresses for.</param>
static string[] GetShortPaths(string path)
{
    return GetUNCDrives()
        .Where(kvp => path.StartsWith(kvp.Value))
        .Select(kvp => Path.Combine(kvp.Key, path.Substring(kvp.Value.Length + 1)))
        .ToArray();
}

/// <summary>Gets all mapped drives and resolved paths.</summary>
/// <returns>Dictionary: Key = drive, Value = resolved path</returns>
static Dictionary<string, string> GetUNCDrives()
{
    return DriveInfo.GetDrives()
        .Where(di => di.DriveType == DriveType.Network)
        .ToDictionary(di => di.RootDirectory.FullName
                    , di => GetUNCPath(di.RootDirectory.FullName.Substring(0, 2)));
}

/// <summary>Attempts to resolve the path/root to mapped value.</summary>
/// <param name="path">The path to resolve.</param>
static string GetUNCPath(string path)
{
    if (path.StartsWith(@"\"))
        return path;

    var mo = new ManagementObject(string.Format("Win32_LogicalDisk='{0}'", path));

    return Convert.ToUInt32(mo["DriveType"]) == (UInt32)DriveType.Network 
            ? Convert.ToString(mo["ProviderName"]) 
            : path;
}