不幸的是,要在不使用 hack 和奇怪技巧的情况下获取此信息,您需要使用 P/Invoke 技术。
有两种选择:
- 获取用户或系统设置的真实标签。这可能是“New volume”、“Install (\Server)”、“Contoso Pro Installation disk 4”等等。李>
- 获取与资源管理器(我的电脑/这台电脑窗口)中显示的完全一致的标签。这与 (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,也有使用ShGetFileInfo()的1-call方法,但它无论如何都会调用这些方法,并且灵活性较差,所以我不在这里发布。
注意 2:请记住,SHGetNameFromIDList() 的签名在此示例中进行了优化。如果驱动器标签只是临时使用(尤其是不时重新读取),此示例会引入少量内存泄漏。为避免这种情况,请将最后一个参数声明为out IntPtr,然后使用类似
var tmp = Marshal.PtrToStringUni(ppszName);
Marshal.FreeCoTaskMem(ppszName);
注意 3:这适用于 Windows shell,因此无论此标签的来源如何 - 卷标、用户编辑、Autorun.inf 文件或其他任何内容,它都会返回用户期望的内容。