Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Namen von Wechseldatenträger ermitteln (https://www.delphipraxis.net/181091-namen-von-wechseldatentraeger-ermitteln.html)

Takeo 15. Jul 2014 11:11

Namen von Wechseldatenträger ermitteln
 
Hallo liebe Community,

ich arbeite mit Delphi XE2 und habe folgendes Problem:

Ich möchte eine Combobox mit allen angeschlossenen USB-Sticks oder SD-Karten füllen. Dafür frage ich mit GetDriveType alle Laufwerkbuchstaben durch und fülle eine Liste mit allen, die auf "2" zutreffen (also Removeable_Drive).

Nun möchte ich dazu noch die Namen der Datenträger abfragen. Durch die Suche bin ich auf GetVolumeInformation gestoßen, was mir allerdings nur die Namen meiner Festplattenpartitionen zeigt und die Namen der Sticks bleiben leer.

Wie kann ich die Namen richtig abfragen? Gibt es eine Möglichkeit an die Namen aus der Registry zu gelangen? (Diese stehen ja als "FriendlyName" Schlüssel unter HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\S CSI für SD Karten)


Vielen Dank für eure Mithilfe,
Gruß Takeo :hi:


Was ich habe, aber nicht richtig funktioniert:

Delphi-Quellcode:
procedure TForm1.GetDrives;
var
  Drive: Char;
  DriveMask: Integer;
  Flag: Integer;
  FileInfo: SHFILEINFO;

begin
  DriveMask := GetLogicalDrives; //Bitmaske holen
  flag := 1; //Startflag setzen
  for Drive := 'A' to 'Z' do //Jeden Buchstaben gegenprüfen
  begin
    if (flag and DriveMask) <> 0 then
    begin
      if (GetDriveType(PChar(Format('%S:',[Drive]) ) ) = 2) then begin
         ComboPath.Add(Drive);                                         //Laufwerkbuchstaben speichern
         ComboNames.Add(GetVolumeName(Drive));                        //Name zum Laufwerk zuordnen

         SHGetFileInfo(PChar(Format('%S:\',[Drive])), 0, FileInfo, SizeOf(FileInfo), SHGFI_ICON or SHGFI_LARGEICON);
         ComboIcons.Add(IconToBitmap(FileInfo.hIcon),nil);

      end;

    end;
    flag := flag shl 1; //Ein Bit weiter nach links gehen ( = flag * 2)
  end;
end;

function TForm1.GetVolumeName(DriveLetter: Char): string;
var
   dummy: DWORD;
   buffer: array[0..MAX_PATH] of Char;
   oldmode: LongInt;
begin
   oldmode := SetErrorMode(SEM_FAILCRITICALERRORS);
   try
     GetVolumeInformationW(PChar(DriveLetter + ':\'),
                          buffer,
                          SizeOf(buffer),
                          nil,
                          dummy,
                          dummy,
                          nil,
                          0);
     Result := StrPas(buffer);
   finally
     SetErrorMode(oldmode);
   end;
end;

Der schöne Günther 15. Jul 2014 11:27

AW: Namen von Wechseldatenträger ermitteln
 
Liste der Anhänge anzeigen (Anzahl: 1)
Beispiel mit Spring4D:

Delphi-Quellcode:
program drives;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils,
  Spring.Utils,
  Spring.Utils.IO;

var
   drive: Spring.Utils.IO.TDriveInfo;

begin
  try

   for drive in TDriveInfo.GetDrives() do
      WriteLn(drive.Name+' is a '+TEnum.GetName(drive.DriveType));

  except
   on E: Exception do
     Writeln(E.ClassName, ': ', E.Message);
  end;

  readln;
end.
Muss man sich keine Arbeit mehr mit machen 8-)

Perlsau 15. Jul 2014 11:34

AW: Namen von Wechseldatenträger ermitteln
 
Für meinen Medienscanner verwende ich folgende Methode:
Delphi-Quellcode:
Function TUtily.GetPartitionName(Const ADrive: Char): String;
Var
  Unused : Cardinal;
  Buffer : array[0..19] of Char;

begin
  If (GetDriveType(PChar(Format('%S:\',[ADrive]))) >1) And
     (GetVolumeInformation(PChar(ADrive+':\'),
                           @buffer[0], SizeOf(buffer),
                           nil,
                           unused,
                           unused,
                           nil,
                           0)) Then
    Result := buffer          Else
    Begin
      Result := '';
      RaiseLastOSError;
    End;
end;

himitsu 15. Jul 2014 11:39

AW: Namen von Wechseldatenträger ermitteln
 
GetVolumeInformation gibt nunmal den Partitions-Namen zurück und wenn deine Sticks keinen haben, dann ist das halt leer.

Windows zeigt aber nicht immer den Partitionsnamen im Explorer an.
Man kann die Anzeigenamen komplet überschreiben und was vollkommen Anderes anzeigen,
aber standardmäßig nimmt Windows den Partitionsnamen und wenn der leer ist, dann den Hardwarenamen.

http://www.delphipraxis.net/77654-la...e-windows.html


PS: du hast noch viel mehr falsch:
* Man mischt keine statischen und dynamischen Funktionen :!:
* * entweder die xxxA- oder xxxW-APIs nur zusammen mit AnsiChar/PAnsiChar oder WideChar/PWideChar
* * oder die dynamischen xxx-Funktionen, ohne A und W, nur zusammen mit Char/PChar
* Außerdem will GetVolumeInformation die Pufferlängern in "Chars" (Length) und nicht in Bytes (SizeOf)
* * und, man mag es nicht glauben, aber die Funktion hat einen Result-Wert, das man auswerten kann

Takeo 15. Jul 2014 12:50

AW: Namen von Wechseldatenträger ermitteln
 
Hallo,

danke für die Antworten.

himitsu dein Link hat mir eine gute Antwort geliefert! Das mit SHGetFileInfo funktioniert.


Ehrlich gesagt habe ich den Code irgendwo aus dem Internet kopiert und da ich mich erst seit ner Woche mit Delphi beschäftige sehe ich nicht sofort, ob alles passt. Für mich reicht es erstmal wenn die Funktionalität gegeben ist, alles weitere kommt noch :-D

Gruß Takeo

himitsu 15. Jul 2014 14:15

AW: Namen von Wechseldatenträger ermitteln
 
Grade das SizeOf-Length-Problem kann schnell mal zu einem Bufferoverflow führen, denn man sagt ja es hätten X Zeichen im Puffer Platz, aber es sind nur X Bytes, also bei Unicode wäre der Speicher nur halb so groß und im Extremfall könnten somit nochmal soviele Bytes dahinter einfach überschrieben werden.

Takeo 15. Jul 2014 15:18

AW: Namen von Wechseldatenträger ermitteln
 
Achso alles klar. Hab es ja jetzt eh ohne die Funktion gelöst. Ich hoff meine Lösung ist "gut" programmiert:

Delphi-Quellcode:
procedure TForm1.GetDrives;
var
  Drive: Char;
  DriveMask: Integer;
  Flag: Integer;
  FileInfo: TSHFileInfo;

begin
  DriveMask := GetLogicalDrives; //Bitmaske holen
  flag := 1; //Startflag setzen
  for Drive := 'A' to 'Z' do //Jeden Buchstaben gegenprüfen
  begin
    if (flag and DriveMask) <> 0 then
    begin
      if (GetDriveType(PChar(Format('%S:',[Drive]) ) ) = 2) then begin
         ComboPath.Add(Drive);

         SHGetFileInfo(PChar(Format('%S:\',[Drive])), 0, FileInfo, SizeOf(FileInfo), SHGFI_ICON or SHGFI_LARGEICON or SHGFI_TYPENAME or SHGFI_DISPLAYNAME or SHGFI_SYSICONINDEX);

         ComboIcons.Add(IconToBitmap(FileInfo.hIcon),nil); //Icons zu einer ImageList hinzufügen
         ComboNames.Add(FileInfo.szDisplayName);           //Namen zu einer StringList hinzufügen
      end;

    end;
    flag := flag shl 1; //Ein Bit weiter nach links gehen ( = flag * 2)
  end;

end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:12 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz