Allgemeine Fragen zur PROFAN Programmierung
Views (Heute): 243083 (4519)
  Suchen
 Zurück zur Übersicht
 AutorThema: DiskFree + DiskSize
Horst Horn
Datum:31.03.02 14:01 Antwortenals Email verschicken (info@web-treffpunkt.de) 


Hallo zusammen und Frohes Osterfest

Mein Problem ist folgendes:
Ich habe eine Festplatte mit 40 Gb partioniert.
Windows-ME gibt mir für C: 15,9 Gb
und für D: 24 Gb - Soweit so gut
Benutze ich jetzt die beiden PROFAN²-Funktionen
'DiskSize' und 'DiskFree', bekomme ich bei
beiden Funktionen auf beiden Laufwerken 21 Gb
angezeigt. Kann es sein, dass die Funktionen
unter -ME nicht richtig rechnen können ?
Danke für eine Antwort
CU horst horn


Stefan Schnell
Datum:31.03.02 19:22 Antwortenals Email verschicken (mail@stschnell.de) 


Hallo Horst,
habe gerade mal bei mir getestet und folgende Erkenntnis genommen:

1. Festplatte mit 2 GB, wird sowohl die Festplattengröße als auch der freie Speicherbereich korrekt angezeigt. Verglichen mit CHKDSK in der DOS-Box.

2. Festplatte mit 6 GB, es wird die Festplattengröße von 2 GB angezeigt (obwohl 6 GB) und der freie Speicherbereich wird auch mit 2 GB angezeigt (obwohl ca. 5 GB).

Mir scheint dass hier 2 GB eine Grenze darstellt. Vermute mal die Variable ist LongInt mit max. 2.147.483.648 bzw. 2.147.155.968.

Tschüss
Stefan Schnell


Stefan Schnell
Datum:31.03.02 20:46 Antwortenals Email verschicken (mail@stschnell.de) 


Hallo Horst,
habe gerade nochmal folgenden Versuch unternommen:

$H Windows.ph

Declare Result%
Declare Drive$, SectorsPerCluster&, BytesPerSector&

Declare FreeClusters#
Dim FreeClusters#, 4

Declare Clusters#
Dim Clusters#, 4

Drive$ = "E:\\" + @Chr$(0)

Result% = ~GetDiskFreeSpace(@Addr(Drive$), @Addr(SectorsPerCluster&), \
@Addr(BytesPerSector&), FreeClusters#, Clusters#)

If Result%
Print "Sektoren pro Cluster: "; SectorsPerCluster&
Print "Bytes pro Sektoren: "; BytesPerSector&
Print "Bytes pro Cluster: "; @Int(SectorsPerCluster& * BytesPerSector&)
Print "Anzahl freier Cluster: "; @Long(FreeClusters#, 0)
Print "Bytes in freien Cluster: "; @Int(@Long(FreeClusters#, 0) * SectorsPerCluster& * BytesPerSector&)
Print "Anzahl aller Cluster: "; @Long(Clusters#, 0)
Print "Bytes aller Cluster: "; @Int(@Long(Clusters#, 0) * SectorsPerCluster& * BytesPerSector&)
EndIf

WaitKey

End

Rufe hier via WinAPI die Funktion GetDiskFreeSpace auf, die jedoch auch nicht mehr 65526 Cluster zurückliefert, und damit die Grenze bei 2 GB liegt. Ob es hier am WinAPI oder an Profan liegt weiss ich nicht.

Tschüss
Stefan Schnell


Stefan Schnell
Datum:01.04.02 12:14 Antwortenals Email verschicken (mail@stschnell.de) 


Hallo Horst,
Schritt für Schritt kommen wir weiter. Hat ein Laufwerk mehr als 2 GByte freien Speicher oder Größe, so werden 2 GByte angezeigt. Dies liegt in der Historie von Windows 95: Bis Windows 95a gab es nur FAT16, mit einer Obergrenze von 2 GByte. Ab Windows 95b gibt es auch FAT32, das 2GByte-Limit wurde aufgehoben. Der Standard verwendet jedoch weiterhin die alte Funktion GetDiskFreeSpace. Richtig ist es jedoch, die Funktion GetDiskFreeSpaceEx zu verwenden, die die Beschränkung nicht mehr aufweist. Ein Versuch diese Funktion zu verwenden endete jedoch mit einem Ausnahmefehler, da die Funktion natürlich etwas größeres als LongInt zurückliefert und das kann Profan nicht aufnehmen. Hier müsste wohl eine externe DLL zum Zuge kommen, die die Angaben als String bzw. Pointer auf einen String zurückliefert. Vielleicht hat ja schon jemand diese Funktion verwendet und kann einen Programmrumpf anbieten?
Tschüss
Stefan Schnell



Sebastian König
Datum:01.04.02 13:43 Antwortenals Email verschicken (webmaster@sekoenig.de) 


Hallo,

man kann GetDiskFreeSpaceEx() auch mit reinem Profan² verwenden. Als Parameter 2,3 und 4 erwartet die Funktion Zeiger auf 64bit-Integer. Hier kann man einfach entsprechend dimensionierte Bereichsvariablen benutzen.

Hier ein kurzer Beispiel-Code (zeigt nur den Aufruf von GetDiskFreeSpaceEx(), die Ergebnisse werden noch nicht aus den Bereichsvariablen ausgelesen):
DEF GetDiskFreeSpaceEx(4) !"KERNEL32","GetDiskFreeSpaceExA"

declare drive#
declare FreeBytesToCaller#
declare TotalBytes#
declare TotalFreeBytes#

dim drive#,16
dim FreeBytesToCaller#,64
dim TotalBytes#,64
dim TotalFreeBytes#,64

string drive#,0 = "C:\\"

cls
print "GetDiskFreeSpaceEx: ",GetDiskFreeSpaceEx(drive#,FreeBytesToCaller#,TotalBytes#,TotalFreeBytes#)
print
      
'Ergebnisse anzeigen...
'[...]

print "Mit Tastendruck beenden!"
waitkey

dispose drive#
dispose FreeBytesToCaller#
dispose TotalBytes#
dispose TotalFreeBytes#

end

MfG

Sebastian


Stefan Schnell
Datum: 01.04.02 19:24 Antwortenals Email verschicken (mail@stschnell.de) 


Hallo Sebastian und Horst,
der Tip von Sebastian mit den Pointern war sehr hilfreich, ich habe vermutet, dass hier die 64-bit-Variablen direkt übermittelt werden, deshalb bin ich auf die externe DLL gekommen.
Okay wie dem auch sei, hier ist die Lösung für Horst sein Problem, basierend auf Sebastians Ansatz:

Def GetDiskFreeSpaceEx(4) !"KERNEL32","GetDiskFreeSpaceExA"

Declare drive$
Declare FreeBytesToCaller#
Declare TotalBytes#, TotalBytes!
Declare TotalFreeBytes#, TotalFreeBytes!

Dim FreeBytesToCaller#,8
Dim TotalBytes#,8
Dim TotalFreeBytes#,8

Drive$ = "E:\\" + @Chr$(0)

Cls
GetDiskFreeSpaceEx(@Addr(Drive$), FreeBytesToCaller#, TotalBytes#, TotalFreeBytes#)

Decimals 0

Clear TotalBytes!, TotalFreeBytes!

WhileLoop 7, 0, -1
TotalBytes! = TotalBytes! + @Byte(TotalBytes#, &loop) * (256^&loop)
EndWhile

WhileLoop 7, 0, -1
TotalFreeBytes! = TotalFreeBytes! + @Byte(TotalFreeBytes#, &loop) * (256^&loop)
EndWhile

Print "Die Festplatte ist ";TotalBytes!;" Bytes groß."
Print "Es sind ";TotalFreeBytes!;" Bytes auf der Festplatte frei."

WaitKey

Dispose FreeBytesToCaller#
Dispose TotalBytes#
Dispose TotalFreeBytes#

End

Tschüss
Stefan Schnell


 Zurück zur Übersicht