Jak w Win98 przechwycić moment podłączenia dysku USB?

0

Pytanie jak w temacie: Czyli jak z poziomu Delphi wykryć moment podłączenia konkretnego urządzenia USB na Win98 (chodzi tu o PenDrive) i pobrac jego litere (niestety zmienia sie ona w zaleznosci od tego czy urzadzenie bylo podlaczone przed uruchomianiem systemu, czy w trakcie jego dzialania)

Chce napisac program, ktory bedzie rezydowal w trayu i po podlaczeniu dysku USB automatycznie kopiowal z/na niego pliki. (cos jak Sony ImageTransfer - jezeli ktos kojarzy, tylko dzialajacy w dwie strony)

Pozdrawiam,
..::..

0

metoda łopatologiczna:
sprawdzaj co jakiś czas, czy w systemie nie pojawiły się nowe dyski. jeśli się pojawiły i trzymasz gdzieś starą listę dysków - to dysk nie figurujący na tej liście będzie dyskiem usb. ponadto explorer wysyła zdarzenie związane ze zmianą struktury katalogów (w tym i dysków), możesz się pod nie podczepić.

gorzej jeśli dysk został podłączony przed startem systemu. możesz wtedy sprawdzać ile na którym dysku jest dostępnego miejsca, i jeśli np.: jest to 128MB, to możesz założyć, że jest to pen drive.

innej metody nie widzę, poza napisaniem własnego sterownika.

0

ponadto explorer wysyła zdarzenie związane ze zmianą struktury katalogów (w tym i dysków), możesz się pod nie podczepić.

Jakie to dokładnie zdarzenie? (w sensie: jak je przechwycić?). Swoją drogą to teoretycznie mógłbym identyfikować ten dysk po nazwie, tyle że program nie byłby wtedy wystarczająco userproof :-P .
No i czy Windows nie wysyła jakiegoś komunikatu po dołączeniu nowego urządzenia? Może dałoby się jakoś pod niego podczepić i wykryć ten dysk np. po jego numerze seryjnym (albo czymś podobnym)?

0

Na stronie:
http://www.delphi3000.com/articles/article_4077.asp
masz artykul dotyczacy wykrywania momentu podlaczania urzadzenia.

0

Wielkie dzięki... to posunęło mnie o dobre kilka kroków do przodu... Pozostał jeszcze problem rozróżnienia czy mam faktycznie do czynienia z dyskiem USB (a nie innym urządzeniem) no i pobranie jego litery.

Jak dotąd wymyśliłem, że może dobrze byłoby wyszukać wszystkie dyski oznaczone flagą "removable", usunąć spośród nich stację dyskietek i byłoby duże prawdopodobieństwo że mam literę mojego PenDrive'a. Niestety ten pomysł nie obejmuje sytuacji podłączenia kilku dysków wymiennych...
Czy istnieje jakiś niezawodny sposób rozpoznania że mam do czynienia z dyskiem USB? (chodzi mi tu o konkretny dysk USB, a nie dysk USB w ogóle)

0

Nie znam sie na tego typu urzadzeniach (nawet nie mam nic na usb).
Sproboj wykorzystac kontroler HID.

Wchodza w sklad pakietu JVCL
http://jcl.sf.net/daily
http://jvcl.sf.net/daily

lub sciagnij z jak oddzielny pakiet
http://www.soft-gems.net/Controls.php

Za jego pomoca odczytasz VendorID i ProductID (ograniczysz sie do swojego producenta i produktu), dzieki temu wykryjesz czy Twoje urzadzenie zostalo podlaczone.

Dodano: Pomin to co napisalem wyzej
Human Interface Devices - usługa umożliwia dostęp do urządzeń interfejsu HID (daje możliwość obsługi przycisków akcji w urządzeniach multimedialnych). W przypadku zatrzymania usługi, przyciski obsługiwane przez tę usługę nie będą dostępne. Usługa dostępna w systemach Windows XP/2003.W przypadku niekorzystania z urządzeń wyposażonych w klawisze akcji, zalecane jest wyłączenie usługi.

0

Na razie postanowiłem jednak wykrywać ten dysk za pomocą nazwy, ale nawet na tym etapie coś mi się nie udaje. Robię tak:

procedure TMainForm.ComponentUSB1USBArrival(Sender: TObject);
begin
  TWatek.Create;
end;

constructor TWatek.Create;
begin
  inherited Create(False);
end;

procedure TWatek.Execute;
var
  i : Integer;
  Drive_Type : Integer;
  Volume : array[0..255] of char;
  MaxComponentLength, Flag : DWORD;

begin
  FreeOnTerminate := True;

Sleep(1000);
  for I:= Ord('B') to Ord('Z') do
  begin
    Drive_Type := GetDriveType(PChar(Chr(i) + ':\'));
    if (Drive_Type <> 0) and (Drive_Type <> 1) then
    begin
      {pobierz etykietę}
      GetVolumeInformation(PChar(Chr(i) + ':\'), Volume, SizeOf(Volume), nil,
      MaxComponentLength, Flag, nil, 0);
      if (Drive_Type = DRIVE_REMOVABLE) and 
         (Volume = MainForm.Edt_Nazwa.Text) then
      begin
        ShowMessage('TO JEST DOBRY USB ' + Volume); 
        {tu w przyszłości będą procedury wykonywane po podłączeniu dysku USB}
      end;
    end;
  end;
end;

No i problem z tym jest taki, że dostaję komunikat Canvas does not allow drawing....
Najprawdopodobniej namieszałem coś z tym wątkiem i proszę o pomoc...

Małe wyjaśnienie: postanowiłęm dodać 2 wątek, gdyż kiedy blok instrukcji umieszczałem w procedurze zdarzeniowej wykonywanej po wykryciu urządzenia USB, to dysk nie był jeszcze widoczny w systemie (moja aplikacja przechwyciła komunikat o jego podłączeniu). Da to się chyba zrobić prościej, np. przekazując dalej ten komunikat, ale tak się zakręciłęm że już nie wiam jak to zrobić....

0

Teraz to kompletnie zgłupiałem... [wstyd]
Jak dodałem przed ShowMessage kod

MessageBox(Application.Handle,'hh','hh',MB_OK);

to wszystko zadziałało (bezproblemowo pojawiły się OBA komunikaty...
Czy ktoś mi może powiedzieć o co w tym chodzi? Czyżby ShowMessage niemożnaby uruchamiać z poziomu wątku?

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