Seite 1 von 1

ExamineDrives() - Laufwerkliste mit Infos

Verfasst: 06.05.2009 17:53
von STARGÅTE
Tachchen,

Vorab danke an TS-Soft für ein paar Codes/Ideen

Ich habe mal das Auslesen von Laufwerken und deren Infos (die ich vllt noch erweitere) in den für PureBasic bekannten Stil gebracht.

Code: Alles auswählen

; Konstanten
#PB_Drive_Removable = 2
#PB_Drive_Fixed     = 3
#PB_Drive_Remote    = 4
#PB_Drive_CDRom     = 5
#PB_Drive_RamDisk   = 6


; Interne Struktur
Structure Drive_PBI
 Path$
 Type.i
 Name$
 Size.q
 Free.q
EndStructure 

; Interne Liste
Global NewList Drive_PBI.Drive_PBI()


; Ermittelt alle Laufwerke und deren Informationen
;  Flag gibt an, ob auch Infos von Wechseldatenträgern ermittelt werden sollen
Procedure ExamineDrives(Flag=#True)
 Protected Drives$ = "", Size
 Protected Bytes, Sectors, TotalClusters, FreeClusters
 ClearList(Drive_PBI())
 Size = GetLogicalDriveStrings_(0, @Drives$) 
 Drives$ = Space(Size) 
 GetLogicalDriveStrings_(Size, @Drives$)
 *Drives = @Drives$
 While Trim(PeekS(*Drives))
  AddElement(Drive_PBI())
  With Drive_PBI()
   \Path$ = Trim(PeekS(*Drives))
   \Type = GetDriveType_(\Path$) 
   If (Flag Or \Type = #PB_Drive_Fixed) 
    \Name$ = Space(#MAX_PATH) 
    If GetVolumeInformation_(\Path$, \Name$, #MAX_PATH, 0, 0, 0, 0, 0) 
     If GetDiskFreeSpace_(\Path$, @Sectors, @Bytes, @FreeClusters, @TotalClusters)
      \Size = TotalClusters * Sectors * Bytes
      \Free = FreeClusters * Sectors * Bytes
     EndIf
    EndIf
    \Name$ = Trim(\Name$)
   EndIf 
   *Drives + StringByteLength(\Path$) + SizeOf(Character) 
  EndWith
 Wend
 ResetList(Drive_PBI())
EndProcedure

; Springt zum nächsten Laufwerk
Macro NextDrive()
 NextElement(Drive_PBI())
EndMacro

; Gibt den Pfad des Laufwerks zurück ("C:\")
Macro DrivePath()
 Drive_PBI()\Path$
EndMacro

; Gibt den Namen des (Fix-)Laufwerks zurück ("BOOT")
Macro DriveName()
 Drive_PBI()\Name$
EndMacro

; Gibt den Typen des Laufwerks zurück (#PB_Drive_Fixed)
Macro DriveType()
 Drive_PBI()\Type
EndMacro

; Gibt den freien Speicherplatz zurück
;  Prefix bestimmt die Einheit: 0 - Byte ; 1 - KiloByte ; 2 - MegaByte ; 3 - GigaByte ; ...
Macro DriveFreeSize(Prefix=0)
 ( Drive_PBI()\Free / Pow(1024, Prefix) )
EndMacro

; Gibt den gesamt Speicherplatz zurück
;  Prefix bestimmt die Einheit: 0 - Byte ; 1 - KiloByte ; 2 - MegaByte ; 3 - GigaByte ; ...
Macro DriveTotalSize(Prefix=0)
 ( Drive_PBI()\Size / Pow(1024, Prefix) )
EndMacro
Hier dann ein Beispiel:

Code: Alles auswählen

ExamineDrives()
While NextDrive()
 Select DriveType()
  Case #PB_Drive_Removable
   Type$ = "Wechseldatenträger"
   Info$ = "  [ "+StrF(DriveFreeSize(2),2)+" MB Frei / "+StrF(DriveTotalSize(2),2)+" MB ]"
  Case #PB_Drive_Fixed
   Type$ = "Festplatte"
   Info$ = "  [ "+StrF(DriveFreeSize(3),2)+" GB Frei / "+StrF(DriveTotalSize(3),2)+" GB ]"
  Case #PB_Drive_Remote
   Type$ = "Netzlaufwerk"
   Info$ = "  [ "+StrF(DriveFreeSize(3),2)+" GB Frei / "+StrF(DriveTotalSize(3),2)+" GB ]"
  Case #PB_Drive_CDRom
   Type$ = "CD/DVD-Laufwerk"
   Info$ = "  [ "+StrF(DriveFreeSize(2),2)+" MB Frei / "+StrF(DriveTotalSize(2),2)+" MB ]"
  Case #PB_Drive_RamDisk
   Type$ = "RAM-Laufwerk"
   Info$ = "  [ "+StrF(DriveFreeSize(2),2)+" MB Frei / "+StrF(DriveTotalSize(2),2)+" MB ]"
  Default 
   Type$ = "Unbekannter Laufwerktyp"
   Info$ = ""
 EndSelect
 Debug Type$+"  ("+DriveName()+")  "+DrivePath()+Info$
Wend
Mögliche Ausgabe dann:
Wechseldatenträger () A:\ [ 0.04 MB Frei / 1.39 MB ]
Festplatte (BOOT) C:\ [ 4.84 GB Frei / 27.95 GB ]
Festplatte (BACKUP) D:\ [ 2.50 GB Frei / 25.03 GB ]
Festplatte (RECOVER) E:\ [ 0.79 GB Frei / 2.92 GB ]
CD/DVD-Laufwerk (G2ADDON1) F:\ [ 0.00 MB Frei / 697.60 MB ]
CD/DVD-Laufwerk () H:\ [ 0.00 MB Frei / 0.00 MB ]
Wechseldatenträger () I:\ [ 782.05 MB Frei / 993.48 MB ]
Festplatte (DATA) Q:\ [ 62.45 GB Frei / 149.05 GB ]
Netzlaufwerk (VAIO) Z:\ [ 26.31 GB Frei / 34.94 GB ]

Verfasst: 07.05.2009 17:33
von Andesdaf
sehr nützlich, danke! :allright:

Verfasst: 08.05.2009 09:49
von Dostej
Das ist nützlicher Code, danke.
Ich finds immer noch schade, das solche SAchen nicht PB nativ möglich sind. Das wäre für die Portierbarkeit von Code noch hilfreich...

Verfasst: 08.05.2009 12:08
von HeX0R
und so geht's auch im Unicodemodus:

Code: Alles auswählen

*Drives + StringByteLength(\Path$) + SizeOf(CHARACTER)

Verfasst: 08.05.2009 15:12
von PMTheQuick
sehr nützlich, ebenfalls danke :) hab gleich mal nen paar laufwerkchen drangehängt, und alles geht! :-) kann ich gut gebrauchen...

Bild

Gruss
PMTheQuick ;-)

Verfasst: 08.05.2009 20:00
von ts-soft
Den Unicode Fehler gibts in meinem Original auch nicht. Aber auch die
Stringreservierung von #MAX_PATH ist aus der Luft gegriffen, statt:

Code: Alles auswählen

Drives$ = Space(#MAX_PATH) 
Size = GetLogicalDriveStrings_(#MAX_PATH, @Drives$)
besser mit genau passendem Buffer:

Code: Alles auswählen

Drive$ = ""
Size = GetLogicalDriveStrings_(0, @Drives$)
Drive$ = Space(Size)
Size = GetLogicalDriveStrings_(Size, @Drive$)
Gruß

Thomas

Verfasst: 08.05.2009 20:12
von STARGÅTE
:oops:
oke, sah halt irgendwie komisch aus ... die funktion zweimal zu schreiben ...

habs geändert!

Verfasst: 08.05.2009 20:22
von ts-soft
STARGÅTE hat geschrieben::oops:
oke, sah halt irgendwie komisch aus ... die funktion zweimal zu schreiben ...

habs geändert!
Ist klar, es gibt diverse APIs, denen man einfach einen 0 Byte Buffer
übergibt, dann erhält man von der API die erforderliche Größe.

24 * 4, also #MAX_PATH würde immer reichen, aber meine Variante finde
ich sauberer :wink: