如何阅读映射网络共享的“友好名称”?

时间:2014-02-25 13:42:31

标签: c# wmi directoryinfo

基础:针对Dot Net 4的C#WinForms桌面应用程序。

我使用System.IO.DriveInfo枚举系统上的所有驱动器。这很好用,也可以告诉我它是什么类型的驱动器(固定/网络/ CD-ROM等)。它还可以为我提供VolumeLabel - 这在本地驱动器上可以正常工作,但对于映射的网络驱动器,它可以为您提供主机上定义的逻辑磁盘的VolumeLabel。在Windows资源管理器中,您可以为任何映射的驱动器提供友好名称。有没有办法以编程方式检索此友好名称?这个名称显然是使用计算机的人所熟悉的名称。

例如,在下图中,“Critical”和“NonCritical”可能是同一逻辑磁盘上的不同共享,主机名上的卷名为“Data”。查询VolumeName的WMI返回“Data”,其他查询只返回驱动器号,或者什么也不返回。

Example

我查看了通过WMI提供的信息(请参阅:How to programmatically discover mapped network drives on system and their server names?),但似乎没有返回此友好名称的属性。我查看了Caption,Description,SystemName和VolumeName - 就像这样:

private void NetworkDrives()
{
    try
    {
        var searcher = new ManagementObjectSearcher(
            "root\\CIMV2",
            "SELECT * FROM Win32_MappedLogicalDisk");

        TreeNode share;
        TreeNode property;

        foreach (ManagementObject queryObj in searcher.Get())
        {
            share = new TreeNode("Name:" + queryObj["Name"]);                    
            share.Nodes.Add("Caption: " + queryObj["Caption"]);
            share.Nodes.Add("Description: " + queryObj["Description"]);
            share.Nodes.Add("SystemName: " + queryObj["SystemName"]);
            share.Nodes.Add("VolumeName: " + queryObj["VolumeName"]);
            share.Nodes.Add("DeviceID: " + queryObj["DeviceID"]);
            treeView1.Nodes.Add(share);
        }
    }
    catch (ManagementException ex)
    {
        MessageBox.Show("An error occurred while querying for WMI data: " + ex.Message);
    }
}

提前致谢。

2 个答案:

答案 0 :(得分:2)

使用Win32_Logicaldisk你得到了:

DeviceID     : P:
DriveType    : 4
ProviderName : \\localhost\download\Chic
FreeSpace    : 26406707200
Size         : 500000878592
VolumeName   :

对于DriveType 4,您将在UNC名称的最后部分找到卷。你必须使用常规的exprssion才能得到它。


根据您的评论进行编辑。

使用PowerShell(离C#不远)可以写成:

cd HKCU:
Get-ChildItem HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\MountPoints2 | where {$_.name -like '*##localhost#download#Chic'} | % {(Get-ItemProperty -LiteralPath $_.name -Name _LabelFromReg)._LabelFromReg} 

答案 1 :(得分:1)

正确的值存储在注册表中,密钥_LabelFromReg的值为HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\MountPoints‌​2\##ServerName#ShareName。如果您已重新标记该份额,则此值仅适用于共享。

编辑:这是一个工作示例,尽管没有正确的错误检查。感谢JPBlanc使用HKEY_CURRENT_USER\etc代替HKEY_USERS\<SID>\etc的注册表快捷方式。

private string GetDriveLabel(DriveInfo drv)
{
    string drvName;
    string drvLabel;
    string pvdr = "";

    //Start off with just the drive letter
    drvName = "(" + drv.Name.Substring(0,2) + ")";

    //Use the volume label if it is not a network drive
    if (drv.DriveType != DriveType.Network)
    {
        drvLabel = drv.VolumeLabel;
        return drvLabel + " " + drvName;
    }

    //Try to get the network share name            
    try
    {
        var searcher = new ManagementObjectSearcher(
            "root\\CIMV2",
            "SELECT * FROM Win32_MappedLogicalDisk WHERE Name=\"" + drv.Name.Substring(0,2) + "\"");

        foreach (ManagementObject queryObj in searcher.Get())
        {
            pvdr = @queryObj["ProviderName"].ToString();
        }
    }
    catch (ManagementException ex)
    {
        pvdr = "";
    }

    //Try to get custom label from registry
    if (pvdr != "")
    {   
        pvdr = pvdr.Replace(@"\", "#");
        drvLabel = (string)Registry.GetValue(@"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\MountPoints2\" + pvdr, "_LabelFromReg", "");
        if (string.IsNullOrEmpty(drvLabel))
        {
            //If we didn't get the label from the registry, then extract the share name from the provider
            drvLabel = pvdr.Substring(pvdr.LastIndexOf("#") + 1);
        }
        return drvLabel + " " + drvName;
    }
    else
    {
        //No point in trying the registry if we don't have a provider name
        return drvName;
    }
}