不幸的是,要在不使用 hack 和奇怪技巧的情况下获取此信息,您需要使用 P/Invoke 技术。有2个选项:
- 获取用户或系统设置的真实标签。这可能是“新卷”、“安装 (\Server) ”、“ Contoso Pro 安装磁盘 4 ”等。
- 获取与资源管理器(我的电脑/此 PC 窗口)中显示的完全一致的标签。这与 (1) 相同,但它遵循在文件夹选项对话框中设置的用户首选项,例如“隐藏驱动器号”。示例:“新卷(Q:) ”
要获取选项 (1) 中说明的信息,您必须使用以下代码:
public const string SHELL = "shell32.dll";
[DllImport(SHELL, CharSet = CharSet.Unicode)]
public static extern uint SHParseDisplayName(string pszName, IntPtr zero, [Out] out IntPtr ppidl, uint sfgaoIn, [Out] out uint psfgaoOut);
[DllImport(SHELL, CharSet = CharSet.Unicode)]
public static extern uint SHGetNameFromIDList(IntPtr pidl, SIGDN sigdnName, [Out] out String ppszName);
public enum SIGDN : uint
{
NORMALDISPLAY = 0x00000000,
PARENTRELATIVEPARSING = 0x80018001,
DESKTOPABSOLUTEPARSING = 0x80028000,
PARENTRELATIVEEDITING = 0x80031001,
DESKTOPABSOLUTEEDITING = 0x8004c000,
FILESYSPATH = 0x80058000,
URL = 0x80068000,
PARENTRELATIVEFORADDRESSBAR = 0x8007c001,
PARENTRELATIVE = 0x80080001
}
//var x = GetDriveLabel(@"C:\")
public string GetDriveLabel(string driveNameAsLetterColonBackslash)
{
IntPtr pidl;
uint dummy;
string name;
if (SHParseDisplayName(driveNameAsLetterColonBackslash, IntPtr.Zero, out pidl, 0, out dummy) == 0
&& SHGetNameFromIDList(pidl, SIGDN.PARENTRELATIVEEDITING, out name) == 0
&& name != null)
{
return name;
}
return null;
}
对于选项 (2),替换SIGDN.PARENTRELATIVEEDITING
为SIGDN.PARENTRELATIVE
或SIGDN.NORMALDISPLAY
。
注意:对于选项 2,还有 1-call 方法 using ShGetFileInfo()
,但它无论如何都会调用这些方法,并且灵活性较差,所以我不在这里发布它。
注意 2:请记住,SHGetNameFromIDList()
在此示例中优化了 的签名。如果驱动器标签只是临时使用(特别是如果不时重新读取),此示例会引入少量内存泄漏。为避免这种情况,请将最后一个参数声明为out IntPtr
,然后使用类似
var tmp = Marshal.PtrToStringUni(ppszName);
Marshal.FreeCoTaskMem(ppszName);
注意 3:这适用于 Windows shell,因此无论此标签的来源如何 - 卷标、用户编辑、Autorun.inf 文件或其他任何内容,它都会返回用户期望的内容。