Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 16.02.2015, 13:46   #1
Pozitivchik
 
Регистрация: 24.10.2012
Сообщений: 3
По умолчанию WMI и WM_DEVICECHANGE

Здравствуйте.
Мне необходимо отслеживать подключение флешки и сразу узнавать её серийный номер и букву присвоенную системой.
Отслеживаю подключение флешки через сообщение WM_DEVICECHANGE.
С буквой проблем не возникло, а вот с серийным номером не заладилось.
Нашел пример в интернете, как с помощью Wmi вытащить серийный номер. Но,если я отлавливаю сообщение DBT_DEVICEARRIVAL выдается ошибка
Код:
Не удается выполнить исходящий вызов, так как приложение обрабатывает входящий синхронный вызов.
При том при DBT_DEVNODES_CHANGED всё работает.
Код:
procedure TForm1.DEVICECHANGE(var Msg: TMessage);
var
  Enumerator: IEnumVariant;
  WbemLocator, WbemServices, WbemObjectSet : Variant;
  Properties : IEnumVariant;
  Property1, System : OleVariant;
  j : LongWord;
  sProperty : string;
  Vid, Pid, Serial : ShortString;
begin
  case Msg.WParam of
    DBT_DEVICEARRIVAL:
      begin
        Label1.Caption := 'Flash change';

        WbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
        WbemServices:= WbemLocator.ConnectServer;
        WbemObjectSet:= WbemServices.InstancesOf('Win32_usbhub');
        Enumerator := IEnumVariant(TVarData(WbemObjectSet._NewEnum).VDispatch);
        try
          while Enumerator.Next(1, System, j) = S_OK do
          try
            try
              if (System.Caption <> 'Запоминающее устройство для USB') then Continue;
            except end;
            Properties:= IEnumVariant(TVarData(System.Properties_._NewEnum).VDispatch);
            while Properties.Next(1, Property1, j) = S_OK do
            begin
              sProperty := VarToStr(Property1.Value);
              if(Property1.Name = 'DeviceID') then
              begin
                VID := Copy(sProperty, Pos('VID_', sProperty)+4,4);
                PID := Copy(sProperty, Pos('PID_', sProperty)+4,4);
                Serial := Copy(sProperty, Pos('PID_', sProperty)+9, Length(sProperty)-Pos('PID_', sProperty)+10);
                if ((Pos('\', Serial)>0)) then
                begin
                  Serial:=Copy(Serial, Pos('\' ,Serial)+1, Length(Serial)-Pos('\', Serial));
                end;
                lst1.Items.Add('Vid: '+VID + ' Pid: '+PID+ ' Serial: '+ Serial);
              end;
            end;
          except end;
        except end;

      end;
  end;
end;
Вобщем если кто сталкивался подскажите пожалуйста, либо посоветуйте, что лучше Wmi?
Pozitivchik вне форума Ответить с цитированием
Старый 16.02.2015, 14:05   #2
Streletz
Старожил
 
Регистрация: 03.01.2014
Сообщений: 2,870
По умолчанию

Можно попробовать воспользоваться WinAPI функцией GetVolumeInformation.
Streletz вне форума Ответить с цитированием
Старый 16.02.2015, 14:51   #3
Pozitivchik
 
Регистрация: 24.10.2012
Сообщений: 3
По умолчанию

GetVolumeInformation, как я понял, возвращает номер тома, который после формирования может измениться, а мне нужно привязаться именно к серийному номеру флешки.
Pozitivchik вне форума Ответить с цитированием
Старый 16.02.2015, 17:06   #4
Iron Monk
Форумчанин
 
Аватар для Iron Monk
 
Регистрация: 05.10.2007
Сообщений: 478
По умолчанию

Код:
procedure TForm1.Button1Click(Sender: TObject);
var
    VolumeName,
    FileSystemName: array[0..MAX_PATH - 1] of Char;
    VolumeSerialNo: DWord;
    MaxComponentLength,
    FileSystemFlags:Cardinal;
begin
    GetVolumeInformation('H:\', VolumeName, MAX_PATH, @VolumeSerialNo,
    MaxComponentLength, FileSystemFlags,
    FileSystemName, MAX_PATH);
    Memo1.Lines.Add('VName    = '  + VolumeName);
    Memo1.Lines.Add('SerialNo = $' + IntToHex(VolumeSerialNo, 8));
    Memo1.Lines.Add('CompLen  = '  + IntToStr(MaxComponentLength));
    Memo1.Lines.Add('Flags    = $' + IntToHex(FileSystemFlags, 4));
    Memo1.Lines.Add('FSName   = '  + FileSystemName);
end;

end.
Iron Monk вне форума Ответить с цитированием
Старый 16.02.2015, 18:43   #5
dron-s
Форумчанин
 
Регистрация: 04.03.2007
Сообщений: 615
По умолчанию

через консоль
выполнить->cmd->OK
cd c:\
wmic diskdrive
wmic logicaldisk

всё есть что тебе надо... далее парсишь полученную инфу и испльзуешь
dron-s вне форума Ответить с цитированием
Старый 17.02.2015, 14:12   #6
Pozitivchik
 
Регистрация: 24.10.2012
Сообщений: 3
По умолчанию

Спасибо большое, но это немного не то.Как я сказал, мне нужен серийный номер флешки, а не тома.
Wmic localdisk в VolumeSerialNumber хранит так же номер тома.
Тоесть после формирования флешки данные изменятся.
Обидно что Wmi не хочет работать сразу, тоесть она мне возвращает то что нужно.. Но приходится ставить задержку в 5 секунд.
Pozitivchik вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
WMI No_Comments Помощь студентам 3 19.10.2012 22:37
Трабл с WM_DEVICECHANGE dolphin705 Общие вопросы Delphi 0 09.02.2011 20:31
Хук wm_DeviceChange GenniY Общие вопросы Delphi 2 18.12.2009 16:35
Никак не могу разобраться с WM_DEVICECHANGE Никки Win Api 3 26.01.2009 11:08
Беда с Кардридером при помощи WM_DEVICECHANGE eriser Win Api 1 30.01.2008 17:39