Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Über alle USB Anschlüsse iterieren, um ein bestimmtes Gerät zu finden (https://www.delphipraxis.net/175863-ueber-alle-usb-anschluesse-iterieren-um-ein-bestimmtes-geraet-zu-finden.html)

Luckie 24. Jul 2013 16:12

Über alle USB Anschlüsse iterieren, um ein bestimmtes Gerät zu finden
 
Ich habe ein GPS Empfänger, den ich regelmäßig mit neuen Daten (GPX-Dateien) bestücke. Der GPSEmpfänger wird per USB an den Rechner angeschlossen. Um nun neue GPX-Dateien auf das gerät zu kopieren sind folgende Schritte notwendig:

1. Dateien runter laden (gepackt)
2. entpacken
3. alte Dateien auf dem Gerät löschen
4. neue Dateien auf das Gerät kopieren.

Dies wollte ich jetzt automatisieren. Ich wähle nur noch das Archiv aus und den Rest macht das Programm von alleine. Da aber nicht immer sicher gestellt ist, dass das Gerät auch immer den gleichen Laufwerksbuchstaben bekommt, muss ich wissen welchen Laufwerksbuchstaben es hat, wenn es angeschlossen ist. Dazu müsste ich über alle USB Ports iterieren und bei jedem gucken, ob es das gewünschte Gerät ist.

Meine Frage, hat jemand schon mal so was gemacht bzw. mit welchen API Funktionen würde man das machen?

Der schöne Günther 24. Jul 2013 16:23

AW: Über alle USB Anschlüsse iterieren, um ein bestimmtes Gerät zu finden
 
Selbst wenn man ein Gerät an einem "Port" findet, bringt einen das doch zunächst nicht wirklich weiter, wenn man im Endeffekt doch eine Datei auf ein Laufwerk schieben will? Allein von dort aus weiter zu kommen stelle ich mir schon ziemlich schwierig vor.

Wenn du von "Laufwerk" sprichst, dann bindet sich das USB-Teil doch als FAT oder NTFS-Massenspeicher ein? Ich hätte einmal eine (unsichtbare?) Textdatei auf das Laufwerk gespackt um es wiederzuerkennen :stupid:

Ich hätte in meinem Programm dann ein "Gerät für Automatismus einrichten", der packt dann im Endeffekt nur einmal eine autorun.ini mit einem coolen Symbol auf das Laufwerk und um es beim Synchronisieren wiederzufinden muss ich nur mir nur Windows-Laufwerke anschauen, egal ob USB oder sonstwas.


Wahrscheinlich rede ich gerade Dünpfiff.

Luckie 24. Jul 2013 16:29

AW: Über alle USB Anschlüsse iterieren, um ein bestimmtes Gerät zu finden
 
Ja es erscheint im Explorer als Laufwerk. Und ich brauche jetzt den Laufwerksbuchstaben.

Nein, ist kein Dünnpfiff. Ich könnte über alle Laufwerke iterieren und den Namen abfragen, bis ich das Laufwerk mit dem richtigen Namen gefunden habe.

WM_CLOSE 24. Jul 2013 18:27

AW: Über alle USB Anschlüsse iterieren, um ein bestimmtes Gerät zu finden
 
MSDN-Library durchsuchenGetVolumeInformation liefert den Namen des Volumes:
http://msdn.microsoft.com/en-us/libr...=vs.85%29.aspx

Andreas Schilling 25. Jul 2013 06:02

AW: Über alle USB Anschlüsse iterieren, um ein bestimmtes Gerät zu finden
 
Um USB-Laufwerke zu finden benutze ich immer folgenden Code.
Delphi-Quellcode:
  uses windows

procedure ...
  var
    strUSB_Drive : string;
    DriveList : TStringList;
    s: Char;
  //-----------------------------
  function GetDrives(var LW_List : TStringlist; DriveType:BYTE):byte;
    var Drives : array [1..255] of char;
        LWListe : TStringList;
        i        : byte;
        Len    : DWord;
  begin
    LWListe:=TStringList.Create;
    {Alle Laufwerke ermitteln}
    Len:=GetLogicalDriveStrings(255,@Drives);
    for i:=1 to Len-2 do
      if (i mod 4)=1 then
        LWListe.Add(copy(Drives,i,3));
    {Laufwerke des angegebenen Typs zählen}
    Result:=0;
    LW_list.Clear;
    for i:=0 to LWListe.Count-1 do begin
      if GetDriveType(PChar(LWListe[i]))= DriveType
      then begin
        Result:=Result+1;
        LW_List.Add(copy(LWListe[i],1,2))
      end;
    end;
    LWListe.Destroy;
  end;
  //------------------
begin
  DriveList:=TStringLIst.Create;
  {Wechselplatten:}
  GetDrives(Drivelist, DRIVE_REMOVABLE);

  if DriveList.count > 0
  then begin
    strUSB_Drive := '';
    for i := 0 to drivelist.count - 1
    do begin
      if (DriveList[i] <> 'A:')
      and (DriveList[i] <> 'B:')
      then strUSB_Drive := DriveList[i];
    end;
    if strUSB_Drive = ''
    then begin
      ShowMessage('Kein Wechseldatenträger an diesem Rechner angeschlossen');
      exit;
    end;

    S := strusb_Drive[1];
  end
  else begin
    ShowMessage('Kein Wechseldatenträger an diesem Rechner angeschlossen');
    exit;
  end;

  DriveList.Free;

  ....
end;
Wobei damals davon ausgegangen wurde, das immer nur ein USB-Stick am Rechner hängt. Mußt halt den Quelltext entsprechend anpassen.

Gruß Andreas

Aphton 25. Jul 2013 06:24

AW: Über alle USB Anschlüsse iterieren, um ein bestimmtes Gerät zu finden
 
Sofern du es wirklich voll automatisch haben und nicht ständig pollen willst, dann schau dir mal WM_DEVICECHANGE an..

Delphi-Quellcode:
type
  TForm1 = class(TForm)
  public
    procedure DeviceChange(var Msg: TMessage); message WM_DEVICECHANGE;
  end;

// ......

const
  DBT_DEVICEARRIVAL = $8000;
  DBT_DEVTYP_VOLUME = $02;

type
  _DEV_BROADCAST_HDR = record
    dbch_size: DWORD;
    dbch_devicetype: DWORD;
    dbch_reserved: DWORD;
  end;
  PDevBroadcastHdr = ^TDevBroadcastHdr;
  TDevBroadcastHdr = _DEV_BROADCAST_HDR;

  _DEV_BROADCAST_VOLUME = record
    dbcv_size: DWORD;
    dbcv_devicetype: DWORD;
    dbcv_reserved: DWORD;
    dbcv_unitmask: DWORD;
    dbcv_flags: WORD;
  end;
  PDevBroadcastVolume = ^TDevBroadcastVolume;
  TDevBroadcastVolume = _DEV_BROADCAST_VOLUME;

function BitScanForward(Value: Integer): Integer;
asm
  bsf eax, eax
end;

procedure TForm1.DeviceChange(var Msg: TMessage);
var
  DriveLetter: Char;
begin
  case Msg.WParam of
    DBT_DEVICEARRIVAL:
      if PDevBroadcastHdr(Msg.LParam).dbch_devicetype = DBT_DEVTYP_VOLUME then
      begin
        DriveLetter := Char(65 + BitScanForward(PDevBroadcastVolume(Msg.LParam).dbcv_unitmask));
        ShowMessage('New device plugged in: ' + DriveLetter);
//        ShowMessage('DriveType: ' + IntToStr(GetDriveType(pChar(DriveLetter + ':'))));
      end;
  end;
end;

hathor 25. Jul 2013 07:21

AW: Über alle USB Anschlüsse iterieren, um ein bestimmtes Gerät zu finden
 
Zitat:

Zitat von Luckie (Beitrag 1222540)
...Da aber nicht immer sicher gestellt ist, dass das Gerät auch immer den gleichen Laufwerksbuchstaben bekommt, muss ich wissen welchen Laufwerksbuchstaben es hat, wenn es angeschlossen ist. Dazu müsste ich über alle USB Ports iterieren und bei jedem gucken, ob es das gewünschte Gerät ist.


Delphi-Quellcode:
function DriveExists(DriveByte: Byte): Boolean;
begin
  Result := GetLogicalDrives and (1 shl DriveByte) <> 0;
end;

function FileDirExists(const FileOrDir: String): Boolean;
var
  FindFileData: TWIN32FindData;
begin
  FindFileData.dwFileAttributes := INVALID_FILE_ATTRIBUTES;
  Windows.FindClose(FindFirstFile(PChar(FileOrDir), FindFileData));
  Result := FindFileData.dwFileAttributes = INVALID_FILE_ATTRIBUTES;
end;

Function FindGPS: String;
var dirName: String; i : Integer;
begin
dirName:= 'F-Hathor'; //Dir, das sonst nirgendwo existiert ausser im GPS-Empfänger
Result:='GPS-Empfänger NICHT gefunden.';
  for i:=0 to 25 do
    begin
      if DriveExists(i) then
//      if DirectoryExists(dirName) then //geht bei mir nicht !!! UAC ???
        if FileDirExists(dirName) then
        begin
          Result:= 'GPS-Empfänger gefunden bei '+ IntToStr(i);
        end;
    end;
    Form1.Label1.caption:=Result;
end;

Luckie 25. Jul 2013 08:33

AW: Über alle USB Anschlüsse iterieren, um ein bestimmtes Gerät zu finden
 
Vielen Dank. Eigentlich wollte ich ja nur einen Denkanstoß haben. ;)

musicman56 25. Jul 2013 10:25

AW: Über alle USB Anschlüsse iterieren, um ein bestimmtes Gerät zu finden
 
@hathor

Zitat:

// if DirectoryExists(dirName) then //geht bei mir nicht !!! UAC ???
Das verunsichert mich jetzt total. Ich verwende DirectoryExists sehr intensiv und hatte auf meinen Rechnern noch nie Probleme damit. Und auch von meinen Kunden habe ich noch keine Fehler-Rückmeldungen erhalten die darauf schließen würden, dass DirectoryExists die Ursache sein könnte.

hathor 25. Jul 2013 11:25

AW: Über alle USB Anschlüsse iterieren, um ein bestimmtes Gerät zu finden
 
WIN 8 - 64Bit
DELPHI 2009

Vielleicht gibt es unterschiedliche Versionen.
Meine sieht so aus:

Delphi-Quellcode:
function DirectoryExists(const Directory: string): Boolean; //SysUtils.pas in Delphi 2009
var
  Code: Cardinal;
begin
  Code := GetFileAttributes(PChar(Directory));
  Result := (Code <> INVALID_FILE_ATTRIBUTES) and (FILE_ATTRIBUTE_DIRECTORY and Code <> 0);
end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 06:10 Uhr.
Seite 1 von 2  1 2      

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