![]() |
Delphi-Version: 11 Alexandria
Laufwerkgrössen ermitteln
Liste der Anhänge anzeigen (Anzahl: 1)
Hi zusammen
Mit folgendem Code (/von hier) ermittle ich meine Laufwerke und deren freien Speicher:
Delphi-Quellcode:
Und so sieht das dann aus:
function TPopUpWindow.DedectBiggestFreeSpace: Char;
var i :integer; PopupWindow: TPopupWindow; begin PopupWindow := TPopupWindow.Create(Self); PopupWindow.PopupMode := pmExplicit; PopupWindow.PopupParent := HomeOfficerFeMain; PopupWindow.RzPageControl1.ActivePage := PopupWindow.RzPageControl1.Pages[0]; PopUpWindow.Position := poMainFormCenter; PopUpWindow.GetAllDrives; end; function TPopUpWindow.GetAllDrives: TStringDynArray; var i: Integer; space : Int64; begin Result := TDirectory.GetLogicalDrives; for i:=Low(Result) to High(Result) do begin Result[i] := GetOneDrive(Result[i]); space := DiskFree(i); RzRadioGroup1.Items.Add(Result[i] +' -- ' + Inttostr(space)); end; end; function TPopUpWindow.GetOneDrive(const Drive: string): string; {Returns the display name for the drive with the given root path.} var FI: TSHFileInfo; // info about drive begin if ShellAPI.SHGetFileInfo(PChar(Drive), 0, FI, SizeOf(FI), ShellAPI.SHGFI_DISPLAYNAME ) = 0 then RaiseLastOSError; Result := FI.szDisplayName; end; Anhang 54532 Der Grund dafür: ![]() Und nun? Wie geht es verünftig weiter? Gruss Delbor PS: Ich denk, ich hab eine Teilantwort gefunden: D: und E: sind Partitionen auf F:. Der User soll mit diesem Dialog einen Speicherort für eine Anwendungsgebundene SQLite-DB festlegen. |
AW: Laufwerkgrössen ermitteln
Wie kann die Laufwerksnummer der Laufwerksbuchstabe ungültig sein, wenn es doch vorhanden sein soll?
Wenn es nicht da ist, dann stimmt die Rückgabe ja. Natürlich kann man auch direkt ![]() ABER: Ich denke eher mal deine Schleife ist falsch. Nicht von Low to High, sondern nur durch das, was in dem Set drin steckt. Und hier stimmt der Index i des Arrays nunmal garnicht mit dem Laufwerksindize überein. * Entweder du nimmst dir den Laufwerksburchstaben und rechnest ihn in einen Index um (
Delphi-Quellcode:
)
Ord(Result[i][1]) - Ord('A')
* oder du nimmst eine Funktion, welcher du direkt das laufwerk geben kannst, z.B. ![]()
Delphi-Quellcode:
, wenn ich mich richtig erinnere)
\
|
AW: Laufwerkgrössen ermitteln
Zitat:
Ohne eingelegten Datenträger scheitern aber DiskFree und Co. |
AW: Laufwerkgrössen ermitteln
Hallo
So ähnlich hatte ich das vor Jahren mal gemacht da meine zusätzlichen Festplatten alle in Verzeichnissen bereit gestellt werden und die meisten Tools so etwas nicht anzeigen. Erstellt mit Hilfe von ![]()
Delphi-Quellcode:
// -----------------------------------------------------------------------------------------------------
// This code was generated by the Wmi Delphi Code Creator (WDCC) Version 1.9.9.482 // http://code.google.com/p/wmi-delphi-code-creator/ // Blog http://theroadtodelphi.wordpress.com/wmi-delphi-code-creator/ // Author Rodrigo Ruz V. (RRUZ) Copyright (C) 2011-2015 // ----------------------------------------------------------------------------------------------------- // // LIABILITY DISCLAIMER // THIS GENERATED CODE IS DISTRIBUTED "AS IS". NO WARRANTY OF ANY KIND IS EXPRESSED OR IMPLIED. // YOU USE IT AT YOUR OWN RISK. THE AUTHOR NOT WILL BE LIABLE FOR DATA LOSS, // DAMAGES AND LOSS OF PROFITS OR ANY OTHER KIND OF LOSS WHILE USING OR MISUSING THIS CODE. // // ---------------------------------------------------------------------------------------------------- program GetWMI_Info; {$APPTYPE CONSOLE} uses SysUtils, ActiveX, ComObj, Windows, Variants; // Die Klasse "Win32_Volume" stellt einen Speicherbereich auf einer Festplatte // dar. Die Klasse gibt lokale Volumes wieder, die formatiert, unformatiert, // bereitgestellt oder offline sind. Ein Volume wird unter Verwendung eines // Dateisystems, wie z. B. FAT oder NTFS, formatiert, und dem Volume kann eine // Laufwerkbuchstabe zugewiesen werden. Eine einzelne Festplatte kann mehrere // Volumes enthalten, und Volumes können über mehrere Datenträger übergreifen. Die // Klasse "Win32_Volume" unterstützt die Diskettenlaufwerkverwaltung nicht. procedure GetWin32_VolumeInfo; const WbemUser = ''; WbemPassword = ''; WbemComputer = 'localhost'; wbemFlagForwardOnly = $00000020; var FSWbemLocator: OLEVariant; FWMIService: OLEVariant; FWbemObjectSet: OLEVariant; FWbemObject: OLEVariant; oEnum: IEnumvariant; iValue: LongWord; begin; FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator'); FWMIService := FSWbemLocator.ConnectServer(WbemComputer, 'root\CIMV2', WbemUser, WbemPassword); FWbemObjectSet := FWMIService.ExecQuery('SELECT * FROM Win32_Volume', 'WQL', wbemFlagForwardOnly); oEnum := IUnknown(FWbemObjectSet._NewEnum) as IEnumvariant; while oEnum.Next(1, FWbemObject, iValue) = 0 do begin if pos(':', String(FWbemObject.Name)) > 0 then begin Writeln(Format('Name %s', [String(FWbemObject.Name)])); // String Writeln(Format('FileSystem %s', [String(FWbemObject.FileSystem)])); // String Writeln(Format('Capacity %d', [int64(FWbemObject.Capacity)])); // Uint64 Case Integer(FWbemObject.DriveType) of DRIVE_UNKNOWN: Writeln('DriveType Unknown'); DRIVE_REMOVABLE: Writeln('DriveType Removable'); DRIVE_FIXED: Writeln('DriveType Fixed'); DRIVE_REMOTE: Writeln('DriveType Network'); DRIVE_CDROM: Writeln('DriveType CD-ROM'); DRIVE_RAMDISK: Writeln('DriveType RAM Disk'); end; Writeln(Format('FreeSpace %d', [int64(FWbemObject.FreeSpace)])); // Uint64 Writeln('-------------------------------------------------------'); End; FWbemObject := Unassigned; end; end; begin try CoInitialize(nil); try GetWin32_VolumeInfo; finally CoUninitialize; end; except on E: EOleException do Writeln(Format('EOleException %s %x', [E.Message, E.ErrorCode])); on E: Exception do Writeln(E.Classname, ':', E.Message); end; Writeln('Press Enter to exit'); Readln; end. |
AW: Laufwerkgrössen ermitteln
Zitat:
Wer unbedingt 0 will, kann auch gern ein Max einfügen. |
AW: Laufwerkgrössen ermitteln
Hi himitsu
Zitat:
Zitat:
![]() ![]() Zitat:
Kann es sein, dass Diskfree nur Nummer und die Grösse des freien Speichers von Laufwerken ermitteln kann, nicht aber von Partitionen? Gruss Delbor |
AW: Laufwerkgrössen ermitteln
Ja, das ist bissl verwirrend, aber auch recht einfach.
Laufwerke haben zwar eine ID (GUID), aber diese Laufwerksnummer hier ist einfach nur stumpf durchgezählt ... ich denke mal, das ist noch ein Überbleibsel aus DOS. A = 0 B = 1 C = 2 usw.
Code:
* das Laufwerk
* dein I * der richtige Index C:\ 0 2 D:\ 1 3 E:\ 2 4 S:\ 3 18
Delphi-Quellcode:
entspricht einem
Chr(i+64)
Delphi-Quellcode:
(binär ist es das Selbe ... nur das eine ist etwas Verständlicher)
Chr(i + Ord('A'))
und siehe oben, andersrum kann man auch aus einem Laufwerksbuchstaben die Laufwerksnummer berechnen, also
Delphi-Quellcode:
.
Ord(C) - Ord('A')
Wofür die Nummer allerdings gut ist, das sieht man an ![]()
Delphi-Quellcode:
.
set of 0..31
Aber als
Delphi-Quellcode:
(eigentlich
set of 'A'..'Z'
Delphi-Quellcode:
, da ja mehr Felder, als Buchstaben), wäre es wieder verständlicher gewesen.
set of 'A'..'`'
|
AW: Laufwerkgrössen ermitteln
Liste der Anhänge anzeigen (Anzahl: 1)
Hi zusammen
Vor einiger Zeit hab ich auch ![]() Im Moment komme ich jedenfalls keinen Schritt weiter. Gruss Delbor |
AW: Laufwerkgrössen ermitteln
Es dürfte sich um ein Festplatte mit ca. 4 TB handeln.
Fraglich ist halt, ob man zur Berechnung die 1. Variante 1 kb = 1024 Byte 1 mb = 1024 kb 1 gb = 1024 mb 1 tb = 1024 gb oder die 2. Variante 1 kb = 1000 Byte 1 mb = 1000 kb 1 gb = 1000 mb 1 tb = 1000 gb nutzt. Das von Dir gefundene Programm nutzt die zweite Variante und die Abweichungen gegenüber der ersten sind im Terrabytebereich dann schon mal nicht eben so ganz unerheblich. Statt
Delphi-Quellcode:
mal mit
Label11.Caption := FormatFloat('0.00', (SectPerCls * BytesPerCls *
TotCls)/1000000) + ' MB'; Label12.Caption := FormatFloat('0.00', (SectPerCls * BytesPerCls * FreeCls)/1000000) + ' MB';
Delphi-Quellcode:
probieren. Entsprechen die Ergebnisse dann eher Deinen Vorstellungen?
Label11.Caption := FormatFloat('0.00', (SectPerCls * BytesPerCls *
TotCls) / (1024 * 1024)) + ' MB'; Label12.Caption := FormatFloat('0.00', (SectPerCls * BytesPerCls * FreeCls) / (1024 * 1024)) + ' MB'; Das Betriebssysteme nutzt die erste Variante. Festplattenhersteller nutzen für die Kapazitätsangaben gerne die zweite Variante. Durch diesen "Rechenunterschied" hat eine 1 TB-Platte mit Herstellerangaben nach Variante 2 beim Betriebssystem dann "nur noch" eine Kapazität von 909,49 GB. Bei einer 4 TB-Platte bleiben dann "nur noch" 3,64 TB übrig (ergibt eine Abweichung von etwa 9%). Zitat:
Hätte den Vorteil, dass man eine Vorstellung vom Fehler (und seiner Größenordnung) bekommen könnte. |
AW: Laufwerkgrössen ermitteln
Hi Delphi.Narium
Zitat:
@himitsu:
Delphi-Quellcode:
Wenn ich das richtig interpretiere, sollte ich das Array zB. mit einer Whileschleife durchlaufen können und erst ab dem 2.Index reagieren. Soweit nicht wirklich unverständlich - das letzte Element bliebe so oder so nach diesem Beispiel Laufwerk S.
* das Laufwerk
* dein I * der richtige Index C:\ 0 2 D:\ 1 3 E:\ 2 4 S:\ 3 18 Die Sache scheint mir aber einen Haken zu haben: Die Laufwerke, die statt einer Grössenangabe ein '-1' ausweisen, befinden sich so oder so mitten im Array. Gruss Delbor |
AW: Laufwerkgrössen ermitteln
Liste der Anhänge anzeigen (Anzahl: 3)
Hi zusammen
Inzwischen hab ich auch noch weiter gesucht, auch in Sachen Bit&Byte-Umrechnung und versucht, mit der gefundenen Demo auf 'einen grünen Zweig' zu kommen. Was ich dabei gefunden habe: GetDiskFreeSpace ist offenbar veraltet. Zumindest hab ich im Embarcadero-Wikki vergebens danach gesucht. Hingegen hab ich eine Bool-Funktion ![]() Mal zum Vergleich die gefundene Anwendung und die Anzeige des Explorers: Anhang 54541 Anhang 54540 Der Code zu der Ausgabe dieses Programmes:
Delphi-Quellcode:
...und ShowMessage:
GetDiskFreeSpace(PChar(drv), SectPerCls, BytesPerCls, FreeCls, TotCls);
Showmessage( 'SectPerCls := ' + IntToStr(SectPerCls) + sLineBreak + 'BytesPerCls := ' + IntToStr(BytesPerCls) + sLineBreak + ' FreeCls := ' + IntToStr(FreeCls) + sLineBreak + ' TotCls := ' + IntToStr(TotCls)); Label11.Caption := FormatFloat('0.00', (SectPerCls * BytesPerCls * TotCls)/(1024*1024*1024)) + ' GB'; Label12.Caption := FormatFloat('0.00', (SectPerCls * BytesPerCls * FreeCls)/(1024*1024*1024)) + ' GB'; Anhang 54542 Gruss Delbor |
AW: Laufwerkgrössen ermitteln
Das sucht man auch nicht im Delphi, sondern beim Hersteller.
![]() ![]() Und wenn eine API noch nicht im Delphi drin ist, dann entweder einen fremden API-Header suchen (z.B. JEDI) oder einfach selbermachen ... steht ja beim Hersteller, wie es aussehen muß. (braucht man nur noch von C++ nach Pascal/Delphi zu übersetzen) |
AW: Laufwerkgrössen ermitteln
Zitat:
|
AW: Laufwerkgrössen ermitteln
|
AW: Laufwerkgrössen ermitteln
Zitat:
Ich würde ja denken "wenn es fehlt, dann berechnen" :stupid: Und bei den Schweizern .... Warum vergessen eigentlich immer alle die Rückgabewerte von Funktionen auszuwerten? |
AW: Laufwerkgrössen ermitteln
Zitat:
Delphi-Quellcode:
Ist doch drin - oder?
procedure TForm1.Button1Click(Sender: TObject);
var free_size, total_size: Int64; begin if GetDiskSize(DriveComboBox1.Drive, free_size, total_size) then ShowMessage('free space =' + IntToStr(free_size) + #13 + 'total size=' + IntToStr(total_size)) else ShowMessage('No disk in drive!'); end; (Abgesehen davon, dass ich dieses Beispiel nicht wirklich "schön" finde) |
AW: Laufwerkgrössen ermitteln
ähhhhmmm nein?
Zitat:
|
AW: Laufwerkgrössen ermitteln
Zitat:
|
AW: Laufwerkgrössen ermitteln
Zitat:
"i" iteriert über die Elemente des Arrays, und diesen Index übergibst Du an DiskFree(i):
Delphi-Quellcode:
Du musst aber die Nummer des Laufwerks übergeben, wobei 1=A, 2=B usw. bedeutet. Also den Inhalt des Arrayelements an der Stelle "i", und nicht "i" selber:
Result := TDirectory.GetLogicalDrives;
for i:=Low(Result) to High(Result) do begin Result[i] := GetOneDrive(Result[i]); space := DiskFree(i); <-- falscher Parameter!
Delphi-Quellcode:
.
LDrive := Ord(Result[i][1]) - Ord('A') + 1;
space := DiskFree(LDrive); Oder aber direkt GetDiskFreeSpaceEx(Result[i], Space, ...) verwenden. Diese API-Funktion arbeitet direkt mit Laufwerksbuchstaben bzw. Ordnernamen. |
AW: Laufwerkgrössen ermitteln
Liste der Anhänge anzeigen (Anzahl: 1)
Hi zusammen
Ich habe ![]()
Delphi-Quellcode:
Das funktioniert einwandfei, wenn ich es so wie gesehen in einen Buttonklick-Event packe. Die Probleme beginnen erst später.
procedure TForm1.Button1Click(Sender: TObject);
var freeCaller, total: Int64; begin GetDiskFreeSpaceEx('C:', freeCaller, total, nil); label1.caption:='Freier Speicher: '+IntToStr(freeCaller)+' Bytes'; label2.caption:='Gesamter Speicher: '+IntToStr(total)+' Bytes'; end; Meine derzeitiger Umsetzungsversuch:
Delphi-Quellcode:
Und schliesslich GetDiskNumbers:
function TPopUpWindow.DedectBiggestFreeSpace: Char;
var i :integer; PopupWindow: TPopupWindow; begin PopupWindow := TPopupWindow.Create(Self); PopupWindow.PopupMode := pmExplicit; PopupWindow.PopupParent := HomeOfficerFeMain; PopupWindow.RzPageControl1.ActivePage := PopupWindow.RzPageControl1.Pages[0]; PopUpWindow.Position := poMainFormCenter; PopUpWindow.GetAllDrives; end; function TPopUpWindow.GetAllDrives: TStringDynArray; var total, freeCaller: int64; i: Integer; UsedSpace, TotalSpace, DriveLetter, FreeSpace, Space: String; DrivesArray : TStringDynArray; begin DrivesArray := TDirectory.GetLogicalDrives; //Result enthält all Laufwerke, auch die Partitionen for i:=Low(DrivesArray) to High(DrivesArray) do begin DriveLetter := GetOneDrive(DrivesArray[i]); GetDiskNumbers(DriveLetter); end; end; function TPopUpWindow.GetOneDrive(const Drive: string): string; {Returns the display name for the drive with the given root path.} var FI: TSHFileInfo; // info about drive begin if ShellAPI.SHGetFileInfo(PChar(Drive), 0, FI, SizeOf(FI), ShellAPI.SHGFI_DISPLAYNAME ) = 0 then RaiseLastOSError; Result := FI.szDisplayName; end;
Delphi-Quellcode:
procedure TPopUpWindow.GetDiskNumbers(DriveLetter: String);
var freeCaller, total : Int64; Freespace, Totalspace, UsedSpace :String; begin GetDiskFreeSpaceEx(PChar(DriveLetter), freeCaller, total, nil); LbxVolumen.Items.Add('Disk: '+ DriveLetter); LbxVolumen.Items.Add('Freier Speicher: '+IntToStr(freeCaller)+' Bytes'); LbxVolumen.Items.Add('Gesamter Speicher: '+IntToStr(total)+' Bytes'); LbxVolumen.Items.Add('----'); LbxVolumen.Items.Add('Freier Speicher: ' + FormatFloat('000.00', (freeCaller)/(1024*1024*1024)) + ' GB'); LbxVolumen.Items.Add('Gesamter Speicher: ' + FormatFloat('0.00', (total)/(1024*1024*1024)) + ' GB'); LbxVolumen.Items.Add('--------------------'); end; Im gegenzug nach dem Beispiel von Delphitreff:
Delphi-Quellcode:
Hier ist nichts anders mit Ausnahme der Variablen DriveLetter und der Format-Anweisung. Trotzdem funktioniert mein Code nicht:
procedure TPopUpWindow.Button1Click(Sender: TObject);
var freeCaller, total: Int64; begin GetDiskFreeSpaceEx('C:', freeCaller, total, nil); label1.caption:='Freier Speicher: '+IntToStr(freeCaller)+' Bytes'; label2.caption:='Gesamter Speicher: '+IntToStr(total)+' Bytes'; end; Anhang 54568 Was mache ich falsch? Die Formatumrechnung in Gigabyte ist ziemlich der des Explorers und sogar noch genauer. Gruss Delbor |
AW: Laufwerkgrössen ermitteln
@Delbor:
Du solltest dir mal genauer anschauen, was die Funktionen jeweils zurückgeben und was sie an Eingaben (Parameter) erwarten. TDirectory.GetLogicalDrives gibt - laut Doku - ein Array von Laufwerksbuchstaben zurück. Deine Funktion GetOneDrive ist daher IMO überflüssig. GetDiskFreeSpaceEx erwartet bestimmt keine Angabe ala "Lokaler Datenträger (C:)" als ersten Parameter lpDirectoryName, vor allem, wenn man das mit dem von dir zitierten Beispielcode vergleicht, in dem "C:" reingegeben wird. Empfehlung: schrittweise durchsteppen und Rückgabewerte der Funktionen auswerten. Das gilt auch für GetDiskFreeSpaceEx. Ein nachfolgendes GetLastError bei Misserfolg hätte sicherlich verraten, woran es genau klemmt. Grüße Dalai |
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:31 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz