2010-05-16 44 views
13

當我使用System.IO.DriveInfo.GetDrives()並查看其中一個驅動器的.VolumeLabel屬性時,我看到「PATRIOT XT」,它確實是驅動器的卷標。獲取C#中的驅動器標籤

如果我打開「我的電腦」,而是看到「TrueCrypt Traveler Disk」,而我似乎無法找到任何方式以編程方式檢索該值,因爲沒有任何DriveInfo屬性擁有該值。我也嘗試通過WMI的Win32_LogicalDisk查詢信息,但沒有任何屬性也包含那個值。

因此,任何想法我的電腦使用的標籤被稱爲,更重要的是,如何以編程方式檢索它?

編輯:要清楚,這裏是我使用的代碼,然後什麼輸出,其次是我在我的電腦看(這是我想複製的):

foreach (DriveInfo DI in DriveInfo.GetDrives()) 
    richTextBox1.AppendText(
     (
      DI.IsReady ? 
      (DI.VolumeLabel.Length == 0 ? DI.DriveType.ToString() : DI.VolumeLabel) : 
      DI.DriveType.ToString() 
     ) 
     + 
     " (" + DI.Name.Replace("\\", "") + ")" 
     + Environment.NewLine 
    ); 
 
Removable (A:) 
Fixed (C:) 
CDRom (D:) 
PATRIOT XT (E:) 
Backup (Y:) 
Data (Z:) 

我的電腦的詳細信息視圖顯示:

 
Floppy Disk Drive (A:) 
Local Disk (C:) 
DVD RW Drive (D:) 
TrueCrypt Traveler Disk (E:) 
Backup (Y:) 
Data (Z:) 

回答

0

我還沒試過this自己,但在註冊表中,查找

HKLM/Software/Microsoft/Windows/CurrentVersion/Explorer/DriveIcons/[Drive-Letter]/ 

然後讀取

DefaultLabel 

關鍵。另外警告!將無效的鍵/值寫入註冊表可能會嚴重損壞您的系統!在繼續之前,確保你確定你在做什麼。 Here is a resource to help you with accessing the registry programmatically.

+0

你有什麼操作系統? Win XP Home沒有名爲「DriveIcons」的密鑰! – Nayan 2010-05-16 13:53:47

+0

@Nayan - 我正在使用Windows 7. – 2010-05-16 13:55:55

+0

Vista中不存在密鑰。 – Pindatjuh 2010-05-16 13:59:19

0

This看起來可能是一個解決方案。

+0

謝謝,但Win32_DiskDrive和Win32_PhysicalMedia似乎並沒有保留我正在尋找的值。我已經嘗試了幾個Win32類,而且他們都沒有看到! – Rick 2010-05-16 19:53:29

1

看起來我的電腦看着autorun.inf並使用[autorun]部分的label = value。

還是不太確定「DVD RW Drive」和「Floppy Disk Drive」標籤來自哪裏,但我猜可能是根據驅動器類型進行硬編碼的。

1

我希望以下將幫助您:

[DllImport("kernel32.dll", CharSet = CharSet.Auto)] 
    static extern bool GetVolumeInformation(string Volume, 
     StringBuilder VolumeName, uint VolumeNameSize, 
     out uint SerialNumber, out uint SerialNumberLength, out uint flags, 
     StringBuilder fs, uint fs_size); 

    private void Form1_Load(object sender, EventArgs e) 
    { 
     uint serialNum, serialNumLength, flags; 
     StringBuilder volumename = new StringBuilder(256); 
     StringBuilder fstype = new StringBuilder(256); 
     bool ok = false; 
     Cursor.Current = Cursors.WaitCursor; 
     foreach (string drives in Environment.GetLogicalDrives()) 
     { 
      ok = GetVolumeInformation(drives, volumename, (uint)volumename.Capacity - 1, out serialNum, 
            out serialNumLength, out flags, fstype, (uint)fstype.Capacity - 1); 
      if (ok) 
      { 
       lblVolume.Text = lblVolume.Text + "\n Volume Information of " + drives + "\n"; 
       lblVolume.Text = lblVolume.Text + "\nSerialNumber of is..... " + serialNum.ToString() + " \n"; 
       if (volumename != null) 
       { 
        lblVolume.Text = lblVolume.Text + "VolumeName is..... " + volumename.ToString() + " \n"; 
       } 
       if (fstype != null) 
       { 
        lblVolume.Text = lblVolume.Text + "FileType is..... " + fstype.ToString() + " \n"; 
       } 
      } 
      ok = false; 
     } 
     Cursor.Current = Cursors.Default; 
    } 
+0

此代碼通常不好,並且不顯示OP想要查看的內容。這個信息從'System.IO.DriveInfo.GetDrives()'獲得很容易。 – GSerg 2017-04-19 13:57:52

0

它位於在autorun.inf的文件夾中。我對我的閃存驅動器卷標僅僅是16G, 而是通過把一個autorun.inf文件以下列文本 [自動運行] 標籤=我的16 GB的閃存驅動器

,然後使用ATTRIB至+ S + H +該文件,它不會顯示,除非我有 顯示隱藏的文件和顯示啓用文件夾選項/視圖下的系統文件。

要通過C#編程位於此,我真的沒試過開的autorun.inf, 但它應該是直線前進,檢查是否File.Exists(驅動器:\ autorun.inf的)忽略 的事實,它是+ s + h + r(以防萬一某人設置了它),然後只打開它 並解析標籤=行。如果實際上存在該文件,請使用自動運行標籤而不是 卷標。

我仍然可以改變使用自動運行。inf label = tag即使在Windows 7中也可以修改標籤。

3

感謝您提供關於autorun.inf的提示。這是我創建的用於檢索標籤的C#片段。

private string GetDriveLabelFromAutorunInf(string drivename) 
    { 
     try 
     { 
      string filepathAutorunInf = Path.Combine(drivename, "autorun.Inf"); 
      string stringInputLine = ""; 
      if (File.Exists(filepathAutorunInf)) 
      { 
       StreamReader streamReader = new StreamReader(filepathAutorunInf); 
       while ((stringInputLine = streamReader.ReadLine()) != null) 
        { 
         if (stringInputLine.StartsWith("label=")) 
          return stringInputLine.Substring(startIndex:6); 
        } 
       return ""; 
      } 
      else return ""; 
     } 
     #region generic catch exception, display message box, and terminate 
     catch (Exception exception) 
     { 
      System.Diagnostics.StackTrace trace = new System.Diagnostics.StackTrace(exception, true); 
      MessageBox.Show(string.Format("{0} Exception:\n{1}\n{2}\n\n{3}\n\nMethod={4} Line={5} Column={6}", 
        trace.GetFrame(0).GetMethod().Module, 
        exception.Message, 
        exception.StackTrace, 
        exception.ToString(), 
        trace.GetFrame(0).GetMethod().Name, 
        trace.GetFrame(0).GetFileLineNumber(), 
        trace.GetFrame(0).GetFileColumnNumber()), 
       "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); 
      Environment.Exit(1); 
      return "";  // to keep compiler happy 
     } 
     #endregion 
    } 
2

不幸的是,要得到這個信息而不用黑客和怪異的技巧,你需要使用P/Invoke技術。 有2個選項:

  1. 獲取用戶或系統設置的真實標籤。這可以是「新卷」,「安裝(\ Server)」,「Contoso Pro安裝盤4」等。
  2. 完全按照它在資源管理器中顯示的標籤(我的電腦/此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.PARENTRELATIVEEDITINGSIGDN.NORMALDISPLAY代替SIGDN.PARENTRELATIVEEDITING

注意:對於第二種情況,有也使用ShGetFileInfo() 1調用方法,但無論如何,它調用這些方法,以及不夠靈活,所以我不張貼在這裏。

注意2:請記住,在此示例中優化SHGetNameFromIDList()的簽名。如果驅動器標籤僅用於臨時(特別是在不時重新讀取的情況下),則此示例引入小內存泄漏。爲了避免它,最後一個參數聲明爲out IntPtr,然後使用類似

 var tmp = Marshal.PtrToStringUni(ppszName); 
    Marshal.FreeCoTaskMem(ppszName); 

注3:這個作品在Windows外殼,所以它會返回所期待的用戶,不管這種標籤的來源 - 卷標籤,用戶編輯,Autorun.inf文件或其他任何東西。