2010-05-16 19 views
13

Cuando uso System.IO.DriveInfo.GetDrives() y miro la propiedad .VolumeLabel de una de las unidades, veo "PATRIOT XT", que es de hecho la etiqueta de volumen de la unidad.Obtener etiqueta de unidad en C#

Si abro "Mi PC", en su lugar veo "TrueCrypt Traveler Disk", y parece que no puedo encontrar ninguna forma de recuperar programáticamente ese valor ya que ninguna de las propiedades DriveInfo tiene ese valor. También intenté consultar la información a través de WMI Win32_LogicalDisk, pero ninguna propiedad contenía ese valor allí tampoco.

¿Alguna idea de cómo se llama la etiqueta Mi PC se llama, y ​​más importante aún, cómo recuperarla programáticamente?

EDIT: Para que quede claro, aquí está el código que estoy usando, seguido de lo que da salida, seguido por lo que veo en Mi PC (que es lo que desea duplicar):

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

detalles Mi PC ver muestra:

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

Respuesta

0

no he probado this mí mismo, pero en el registro, buscan

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

continuación, leer la clave

DefaultLabel 

. También ¡ADVERTENCIA! escribir claves/valores no válidos en el registro puede dañar gravemente su sistema! Asegúrate de estar seguro de lo que estás haciendo antes de continuar. Here is a resource to help you with accessing the registry programmatically.

+0

¿Qué sistema operativo tiene? No hay una clave llamada "DriveIcons" en Win XP Home !! – Nayan

+0

@Nayan - Estoy usando Windows 7. –

+0

La clave no existe en Vista. – Pindatjuh

0

This parece que podría ser una solución.

+0

Gracias, pero Win32_DiskDrive y Win32_PhysicalMedia tampoco parecen contener los valores que estoy buscando. ¡He intentado varias de las clases de Win32 ahora, y ninguna de ellas parece hacerlo! – Rick

1

Parece que Mi PC mira la autorun.inf y usa la etiqueta = valor de la sección [ejecución automática].

Aún no estoy muy seguro de dónde vienen las etiquetas "DVD RW Drive" y "Floppy Disk Drive", pero supongo que pueden estar codificadas en función del tipo de unidad.

1

espero que el siguiente le ayudará a:

[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

Este código es malo en general y no muestra lo que el OP desea ver. Esta información es mucho más fácil obtenida de 'System.IO.DriveInfo.GetDrives()'. – GSerg

0

Se encuentra ubicado en la carpeta autorun.inf. Mi etiqueta de volumen para mi unidad flash es simplemente 16G, pero poniendo un archivo autorun.inf con el siguiente texto [autorun] etiqueta = 16 gigabytes mi Flash Drive

y luego usando attrib a + s + h + r el archivo, no aparece a menos que tenga mostrar los archivos ocultos Y mostrar los archivos del sistema en las opciones de carpeta/vista habilitada.

Para localizado mediante programación a través de este C#, sinceramente, no he intentado abrir el autorun.inf, pero debe ser sencillo, comprobar si File.Exists (unidad: \ autorun.inf) ignorando el hecho de que es + s + h + r (solo en caso de que alguien lo haya configurado), luego ábralo solo con y analiza la etiqueta = línea. Si, de hecho, el archivo está presente, utilice la etiqueta de ejecución automática en lugar de la etiqueta de volumen.

Todavía puedo cambiar el uso de la ejecución automática.inf label = tag incluso en Windows 7 para modificar la etiqueta.

3

Gracias por la pista sobre autorun.inf. Aquí está el fragmento de C# que creé para recuperar la etiqueta.

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

Desafortunadamente, para obtener esta información sin hacks y trucos extraños, debe usar la técnica P/Invoke. Hay 2 opciones:

  1. Obtenga la etiqueta real establecida por el usuario o el sistema. Esto podría ser "Nuevo volumen", "Instalar (\ Server)", "Disco de instalación de Contoso Pro 4" y así sucesivamente.
  2. Obtenga la etiqueta exactamente como se muestra en Explorer (Mi PC/Esta ventana de PC). Esto es lo mismo que (1) pero sigue las preferencias del usuario establecidas en el cuadro de diálogo Opciones de carpeta, p. "Ocultar letra de unidad". Ejemplo: "Nueva volumen (Q :)"

para obtener la información tal como se explica en la opción (1), tendrá que utilizar el siguiente código:

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

Para la opción (2), reemplace SIGDN.PARENTRELATIVEEDITING con SIGDN.PARENTRELATIVEEDITING o SIGDN.NORMALDISPLAY.

Nota: para la opción 2, también hay método 1-llamada con ShGetFileInfo(), pero llama a estos métodos de todos modos, y es menos flexible, por lo que no pongo aquí.

Nota 2: tenga en cuenta que la firma de SHGetNameFromIDList() está optimizada en este ejemplo. En caso de que la etiqueta de la unidad se use solo temporalmente (especialmente si se vuelve a leer de vez en cuando), este ejemplo introduce una pequeña pérdida de memoria. Para evitarlo, declarar último parámetro como out IntPtr, y luego usar algo como

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

Nota 3: esto funciona sobre Windows Shell, por lo que volverá lo que el usuario espera que, independientemente de la fuente de esta etiqueta - volumen etiqueta, edición del usuario, archivo Autorun.inf o cualquier otra cosa.

Cuestiones relacionadas