Laufwerke und Laufwerkstypen ermitteln

Veröffentlicht: 10. Dez 2003 | Aktualisiert: 10. Nov 2004

Von Mathias Schiffer

In diesem MSDN Quickie lesen Sie, wie Sie unter Visual Basic .NET alle vorhandenen logischen Laufwerke sowie deren jeweiligen Typ ermitteln können.

Im MSDN Quickie "Vorhandene Laufwerke und Laufwerkstypen ermitteln" haben Sie erfahren, wie Sie unter Visual Basic 6.0 vorhandene logische Laufwerke auflisten können. Heute betrachten wir die gleiche Problemstellung unter Visual Basic .NET.

Unter Visual Basic 6.0 wurde das Ziel neben einer FileSystemObject-Variante im wesentlichen durch zwei Win32-API-Funktionen erreicht: Über die Funktion GetLogicalDrives ermittelt man aus einem Bitmuster vorhandene logische Laufwerke. Bei gesetzten Bits gewinnt man aus der Information etwas umständlich einen Laufwerksbuchstaben, der zur Abfrage des Laufwerkstyps mit Hilfe der Funktion GetDriveType benutzt wurde.

Unter Visual Basic .NET benötigen wir keine API-Funktion mehr, um eine Liste der logischen Laufwerke abzufragen: Die Class Library des .NET Frameworks stellt uns ein String-Array mit den Hauptverzeichnisangaben der logischen Laufwerke zur Verfügung (z.B. "javascript:void(null);"). Hierfür wird die Funktion GetLogicalDrives im Namespace System.Environment bemüht (unter Visual Basic 6 könnte man dieses Ergebnis durch Verwendung der API-Funktion GetLogicalDriveStrings und der VB-Funktion Split erreichen).

Dim Drive As String 
  ' Über alle logischen Laufwerke iterieren: 
  For Each Drive In System.Environment.GetLogicalDrives() 
 Console.WriteLine(Drive) 
  Next Drive

Erstaunlicherweise nicht in der Framework Class Library abgebildet ist hingegen die API-Funktion GetDriveType zur Bestimmung des Typs eines logischen Laufwerks auf Basis seines Laufwerksbuchstabens. So bleiben uns zwei Wege, dieses Ziel zu erreichen: Entweder rufen wir die Win32-API-Funktion über den P/Invoke-Mechanismus auf. Dafür bedarf es nicht mehr als der üblichen Deklarationszeile und eines einfachen Aufrufs der Funktion.

' GetDriveType (Win32 API) ermittelt nach Übergabe des 
' Wurzelverzeichnisses eines logischen Laufwerks dessen 
' Typ: 
Private Declare Function GetDriveType _ 
  Lib "kernel32" Alias "GetDriveTypeA" ( _ 
  ByVal RootDir As String _ 
  ) As Integer 
' ... 
Dim DriveType As Integer 
  ' Ermittlung per P-Invoke (Win32 API): 
  DriveType = GetDriveType(Left$(Drive, 1) & ":\")

Alternativ bietet sich "Windows Management Instrumentation" (WMI) an, das sich unter .NET mit Hilfe der zusätzlich als Referenz aufzunehmenden Bibliothek System.Management verwenden lässt. Nachteilig an diesem Vorgehen ist der notwendige Zeitaufwand.

Dim DriveType As Integer 
  ' Ermittlung per WMI (aufwendig, zusätzliche 
  ' Referenz auf System.Management notwendig): 
  Dim Drv As System.Management.ManagementObject _ 
 = New System.Management.ManagementObject( _ 
 "win32_logicaldisk.deviceid=""" _ 
 & Left$(Drive, 1) & ":""") 
  DriveType = Convert.ToInt32(Drv("DriveType"))

Ist der Typ eines Laufwerks bestimmt, so bedarf es nur noch einer kleinen Ausgaberoutine, um einen vollständigen Beispielcode zur Verfügung zu haben. Im folgenden finden Sie diesen mit allen notwendigen Deklarationen. Seine Methode ListDrives listet alle logischen Laufwerke und deren jeweiligen Typ im Output-Fenster (oder für Konsolenanwendungen im Konsolenfenster) auf. Experimentieren Sie ruhig auch mit der auskommentierten WMI-Alternative - vergessen Sie dafür aber nicht, System.Management zu referenzieren.

  ' Rückgabewerte für GetDriveType: 
  Private Const DRIVE_UNKNOWN = 0  ' unbekannter Laufwerkstyp 
  Private Const DRIVE_NO_ROOT_DIR = 1 ' kein Hauptverzeichnis 
  Private Const DRIVE_REMOVABLE = 2   ' Wechselmedium 
  Private Const DRIVE_FIXED = 3 ' Festplatte 
  Private Const DRIVE_REMOTE = 4   ' Netzwerklaufwerk 
  Private Const DRIVE_CDROM = 5 ' CD/DVD 
  Private Const DRIVE_RAMDISK = 6  ' RAM-Disk 
  ' GetDriveType (Win32 API) ermittelt nach Übergabe des 
  ' Wurzelverzeichnisses eines logischen Laufwerks dessen 
  ' Typ: 
  Private Declare Function GetDriveType _ 
 Lib "kernel32" Alias "GetDriveTypeA" ( _ 
 ByVal RootDir As String _ 
 ) As Integer 
  Public Sub ListDrives() 
 ' Listet alle logischen Laufwerke eines Systems auf und 
 ' bestimmt ihren Typ. 
 Dim Drive As String 
 Dim DriveType As Integer 
 ' Über alle logischen Laufwerke iterieren: 
 For Each Drive In System.Environment.GetLogicalDrives() 
   ' Ermittlung per P-Invoke (Win32 API): 
   DriveType = GetDriveType(Left$(Drive, 1) & ":\") 
   '' Ermittlung per WMI (aufwendig, zusätzliche 
   '' Referenz auf System.Management notwendig): 
   'Dim Drv As System.Management.ManagementObject _ 
   '  = New System.Management.ManagementObject( _ 
   '  "win32_logicaldisk.deviceid=""" _ 
   '  & Left$(Drive, 1) & ":""") 
   'DriveType = Convert.ToInt32(Drv("DriveType")) 
   ' Auswertung des ermittelten Laufwerktyps 
   Select Case DriveType 
  Case DRIVE_UNKNOWN   ' Typ unbekannt 
 Console.WriteLine("Laufwerk {0} ist ein {1} Laufwerk.", _ 
 Left$(Drive, 1), "typunbekanntes") 
  Case DRIVE_NO_ROOT_DIR  ' kein Hauptverzeichnis 
 Console.WriteLine("Laufwerk {0} ist ein {1} Laufwerk.", _ 
 Left$(Drive, 1), "hauptverzeichnisloses") 
  Case DRIVE_REMOVABLE ' Wechseldatenträger (Diskette, ZIP,...) 
 Console.WriteLine("Laufwerk {0} ist ein {1} Laufwerk.", _ 
 Left$(Drive, 1), "Wechselmedium") 
  Case DRIVE_FIXED  ' Festplatte 
 Console.WriteLine("Laufwerk {0} ist ein {1} Laufwerk.", _ 
 Left$(Drive, 1), "Festplatten") 
  Case DRIVE_REMOTE ' Netzwerklaufwerk 
 Console.WriteLine("Laufwerk {0} ist ein {1} Laufwerk.", _ 
 Left$(Drive, 1), "Netzwerk") 
  Case DRIVE_CDROM  ' CD-ROM/DVD-ROM/Brenner 
 Console.WriteLine("Laufwerk {0} ist ein {1} Laufwerk.", _ 
 Left$(Drive, 1), "CD/DVD") 
  Case DRIVE_RAMDISK   ' RAM-Disk 
 Console.WriteLine("Laufwerk {0} ist ein {1} Laufwerk.", _ 
 Left$(Drive, 1), "RAM") 
   End Select 
 Next Drive 
  End Sub