Wykrywanie karty SD w czytniku kart pamięci

0

Witajcie mam problem z budową oprogramowania pod stacje dokującą.

Założenia:

  • komputer z dwoma kartami PCIE 4 porty USB3.0
  • 8 czytników kingston po 4 sloty na karty.
  • Automatyczne zgrywanie zawartosci włożonej karty SD w miejscie wczesniej okreslone.

Generalnie mam to oparte na batchach a główna konsola zarządzająca to 8 przycisków
które mają się uaktywniać w momencie kiedy program znajdzie kartę SD w napędzie.

Na początku próbowałem wykrywać litery dysków i wszystko byłoby dobrze gdyby nie fakt
że czytniki są podłączone na stałe i litery dysków wszystkie są dostępne i zczytywane.
Gdyby te urzadzenia były podpinane tak jak pendrive to wszystko byloby ok.

Problem wlasnie w tym ze kiedy karta jeszcze jest nie widziana w systemie i ktos kliknie
na konsoli przycisk do jej zgrywania to wywala błąd że nie ma karty.

Chciałbym żeby button do zgrywania uaktywniał się w momencie gdy karta jest już widziana przez system i gotowa do
użycia.

Każdy czytnik ma przypisaną literę dysku.

Pytanie moje. jak sprawdzić czy w systemie jest już widoczna karta SD w czytniku
Dodam że żadne eksperymenty typu sprawdzenie pliku na karcie czy proba zapisu czegos nie wchodza w gre
bo windows 7 wywal zeby wlozyc dysk. A nie oto mi chodzi.

0

Aaa i próbowałem jeszcze zrobić na kartach SD autoruna który w konkretnym folderze
utworzy plik o nazwie takiej jak litera dysku zabootowanej karty, wtedy programik zczytywałby
czy w danym folderze jest pliczek o danej nazwie a jak jest to uaktuwnial klawisz zgrywania.
Niestety Windows 7 blokuje autoran wiec droga zamknieta. chyba ze ma ktos pomysl jak jednak z zabootowanej
karty sd cosik uruchomić?

http://www.swissdelphicenter.ch/torry/showcode.php?id=2211

Wie ktoś może jak napisać wykrywanie w pętki kolejnych podłączonych kart SD i odczytywać ich litery dysków?

Ok skorzystałem z gotowej klasy USB:

unit USB;          { ..... unit written by Miguel Lucero ..... }

interface

uses
  Windows, Messages, SysUtils, Classes, Forms;

type
    PDevBroadcastHdr = ^DEV_BROADCAST_HDR;
    DEV_BROADCAST_HDR = packed record
      dbch_size: DWORD;
      dbch_devicetype: DWORD;
      dbch_reserved: DWORD;
    end;

    PDevBroadcastDeviceInterface = ^DEV_BROADCAST_DEVICEINTERFACE;
    DEV_BROADCAST_DEVICEINTERFACE = record
      dbcc_size: DWORD;
      dbcc_devicetype: DWORD;
      dbcc_reserved: DWORD;
      dbcc_classguid: TGUID;
      dbcc_name: short;
    end;

const
     GUID_DEVINTERFACE_USB_DEVICE: TGUID = '{A5DCBF10-6530-11D2-901F-00C04FB951ED}';
     DBT_DEVICEARRIVAL            = $8000;          // system detected a new device
     DBT_DEVICEREMOVECOMPLETE     = $8004;          // device is gone
     DBT_DEVTYP_DEVICEINTERFACE   = $00000005;      // device interface class

type

  TComponentUSB = class(TComponent)
  private
    FWindowHandle: HWND;
    FOnUSBArrival: TNotifyEvent;
    FOnUSBRemove: TNotifyEvent;
    procedure WndProc(var Msg: TMessage);
    function USBRegister: Boolean;
  protected
    procedure WMDeviceChange(var Msg : TMessage); dynamic;
  public
    constructor Create(AOwner : TComponent); override;
    destructor Destroy; override;
  published
    property OnUSBArrival: TNotifyEvent read FOnUSBArrival write FOnUSBArrival;
    property OnUSBRemove: TNotifyEvent read FOnUSBRemove write FOnUSBRemove;
  end;

implementation

constructor TComponentUSB.Create(AOwner : TComponent);
begin
     inherited Create(AOwner);
     FWindowHandle := AllocateHWnd(WndProc);
     USBRegister;
end;

destructor TComponentUSB.Destroy;
begin
     DeallocateHWnd(FWindowHandle);
     inherited Destroy;
end;

procedure TComponentUSB.WndProc(var Msg: TMessage);
begin
     if (Msg.Msg = WM_DEVICECHANGE) then begin
        try
           WMDeviceChange( Msg );
        except
              Application.HandleException(Self);
        end;
     end
     else
         Msg.Result := DefWindowProc( FWindowHandle, Msg.Msg, Msg.wParam, Msg.lParam);
end;

procedure TComponentUSB.WMDeviceChange(var Msg : TMessage);
var
   devType: Integer;
   Datos: PDevBroadcastHdr;
begin
     if (msg.WParam=DBT_DEVICEARRIVAL) or (msg.WParam=DBT_DEVICEREMOVECOMPLETE) then begin
        Datos := PDevBroadcastHdr(msg.LParam);
        devType := Datos^.dbch_devicetype;
        if devType=DBT_DEVTYP_DEVICEINTERFACE then begin // USB Device
           if msg.WParam=DBT_DEVICEARRIVAL then begin
              if Assigned( FOnUSBArrival ) then
                 FOnUSBArrival( Self );
           end else begin
               if Assigned( FOnUSBRemove ) then
                  FOnUSBRemove( Self );
           end;
        end;
     end;
end;

function TComponentUSB.USBRegister: Boolean;
var
   dbi: DEV_BROADCAST_DEVICEINTERFACE;
   size: Integer;
   r: Pointer;
begin
     Result := False;
     size := SizeOf(DEV_BROADCAST_DEVICEINTERFACE);
     ZeroMemory( @dbi, size );
     dbi.dbcc_size := size;
     dbi.dbcc_devicetype := DBT_DEVTYP_DEVICEINTERFACE;
     dbi.dbcc_reserved := 0;
     dbi.dbcc_classguid := GUID_DEVINTERFACE_USB_DEVICE;
     dbi.dbcc_name := 0;

     r := RegisterDeviceNotification( FWindowHandle,
                                      @dbi,
                                      DEVICE_NOTIFY_WINDOW_HANDLE
                                     );
     if Assigned( r ) then Result := True;

end;

end.

I mogę zrobić detekcję skryptem:

procedure TForm2.FormCreate(Sender: TObject);
var
  X: TComponentUSB;
begin
  X:=TComponentUSB.Create(Self);
 X.OnUSBArrival:=USBInserted;
 X.OnUSBRemove:=USBRemoved;
end;

procedure TForm2.USBInserted(Sender: TObject);
begin
  ShowMessage('USB Device has been insered!');
end;

procedure TForm2.USBRemoved(Sender: TObject);
begin
  ShowMessage('USB Device has been removed!');
end;

Jak wyciągnąć literę dysku podłączonego urzadzenia?

dodanie znaczników <code class="delphi"> - @furious programming

1 użytkowników online, w tym zalogowanych: 0, gości: 1