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

时间:2016-02-17 15:24:42

标签: c# performancecounter hard-drive

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

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

有没有办法使用任何系统调用将“HarddiskVolume2”翻译为“Z”?

1 个答案:

答案 0 :(得分:4)

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

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)));

如果你只是假设只有一个映射的驱动器分辨率,你可以,只需选择第一个:

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;
}