Что нового

Обнаружение подключения USB устройств

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Для запуска понадобится незаменимая библиотека WinAPIEx.au3.

Код:
#Include <WinAPIEx.au3>

Opt('MustDeclareVars', 1)
Opt('TrayAutoPause', 0)

Global Const $DBT_DEVICEARRIVAL = 0x00008000
Global Const $DBT_DEVICEREMOVECOMPLETE = 0x00008004
Global Const $DBT_DEVTYP_VOLUME = 0x00000002

Global Const $WM_DEVICECHANGE = 0x0219

Global $hForm = GUICreate('')
Global $Drives, $Volume = _WinAPI_GetLogicalDrives()
Global $Device = 1

GUIRegisterMsg($WM_DEVICECHANGE, 'WM_DEVICECHANGE')

While 1
	Sleep(100)
	If $Device Then
		$Drives = _GetDriveLetter($Volume)
		$Device = 0
		$Volume = 0
		For $j = 1 To $Drives[0]
			_USBCheck($Drives[$j])
		Next
	EndIf
WEnd

Func _GetDriveLetter($iMask)

	Local $Drive[27] = [0]

	If $iMask Then
		For $i = 0 To 25
			If BitAND(BitShift($iMask, $i), 1) Then
				$Drive[$Drive[0] + 1] = Chr(65 + $i) & ':'
				$Drive[0] += 1
			EndIf
		Next
	EndIf
	ReDim $Drive[$Drive[0] + 1]
	Return $Drive
EndFunc   ;==>_GetDriveLetter

Func _USBCheck($sVolume)

	Local $hDrive, $tData, $iBus, $iRes, $Fs

	$iBus = _WinAPI_GetDriveBusType($sVolume)
	Switch $iBus
		Case $DRIVE_BUS_TYPE_USB
			$hDrive = _WinAPI_CreateFileEx('\\.\' & $sVolume, 3, 0, 0)
			If Not $hDrive Then
				Return
			EndIf
			$tData = DllStructCreate('dword DeviceType;ulong DeviceNumber;ulong PartitionNumber')
			$iRes = _WinAPI_DeviceIoControl($hDrive, $IOCTL_STORAGE_GET_DEVICE_NUMBER, 0, 0, DllStructGetPtr($tData), DllStructGetSize($tData))
			_WinAPI_CloseHandle($hDrive)
			If (Not $iRes) Or (Not (DllStructGetData($tData, 'DeviceType') = 7)) Then
				Return
			EndIf
;~			$Fs = DriveGetFileSystem($sVolume)
;~			Switch $Fs
;~				Case 'FAT32', 'NTFS'
;~
;~				Case Else
;~					Return
;~			EndSwitch
		Case Else
			Return
	EndSwitch
	ConsoleWrite('USB device found: ' & $sVolume & @CR)
EndFunc   ;==>_USBCheck

Func WM_DEVICECHANGE($hWnd, $iMsg, $wParam, $lParam)
	Switch $hWnd
		Case $hForm
			Switch $wParam
				Case $DBT_DEVICEARRIVAL, $DBT_DEVICEREMOVECOMPLETE

					Local $tDBV = DllStructCreate('dword Size;dword DeviceType;dword Reserved;dword Mask;ushort Flags', $lParam)
					Local $Type = DllStructGetData($tDBV, 'DeviceType')
					Local $Item

					Switch $Type
						Case $DBT_DEVTYP_VOLUME
							If Not DllStructGetData($tDBV, 'Flags') Then
								Switch $wParam
									Case $DBT_DEVICEARRIVAL
										$Volume = BitOR($Volume, DllStructGetData($tDBV, 'Mask'))
										$Device = 1
									Case Else

								EndSwitch
							EndIf
						Case Else

					EndSwitch
			EndSwitch
	EndSwitch
	Return 'GUI_RUNDEFMSG'
EndFunc   ;==>WM_DEVICECHANGE
 

FlatX007

Tattoo!
Сообщения
197
Репутация
35
Программа iKey кладезь разных поленостей ;)
 
Автор
Yashied

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Обновил код.

:smile:
 

WSWR

AutoIT Гуру
Сообщения
941
Репутация
363
А что, собственно, делает этот скрипт? При запущенном скрипте я подключаю-отключаю usb-устройства(флешки), и ничего не происходит.
 
Автор
Yashied

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Запускай из SciTE.

Код:
ConsoleWrite('USB device found: ' &  $sVolume  & @CR)
 

WSWR

AutoIT Гуру
Сообщения
941
Репутация
363
Yashied сказал(а):
Запускай из SciTE.
Из SciTE и запускаю - ничего, на 2 компьютерах проверял


...так, странно - взял другую флешку - находит, а эту нет, причем она рабочая
 
Автор
Yashied

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Я изначально делал проверку только флешек с FAT32 и NTFS. Сейчас будет работать для любых файловых систем. Попробуй.
 

WSWR

AutoIT Гуру
Сообщения
941
Репутация
363
Yashied сказал(а):
Я изначально делал проверку только флешек с FAT32 и NTFS. Сейчас будет работать для любых файловых систем. Попробуй.
Да, теперь работает, действительно, эта флешка загрузочная, отформатирована как-то по-особому.

Есть еще вопрос по этой теме - есть внешний жесткий диск, на одном компе с семеркой определяется нормально, а на другом с ХР - нет, т.е. виден в "Управлении дисками" и как USB-устройство, но буква ему не назначается и в эксплорере он не отражается (некий глюк ОС). Скрипт из этой темы тоже его не видит. Если назначить букву вручную - открыть диск можно, но после перезагрузки он опять пропадает.
Так вот, возможно ли с помощью Autoit назначать букву такому диску автоматически(или по горячей клавише и т.д.), без необходимости каждый раз залезать в "Управление дисками" ?
 
Автор
Yashied

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
А если переформатировать в XP?
 

Redline

AutoIT Гуру
Сообщения
506
Репутация
375
А можно при подключении устройства в порт USB узнать его спецификацию(1.1 или 2.0) без замера скорости копирования(ведь устройство может быть сканером ;))?
 
Автор
Yashied

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Код:
If (Not $iRes) Or (Not (DllStructGetData($tData, 'DeviceType') = 7)) Then


Здесь значение 7 идентифицирует дисковой накопитель. Для сканера будет другое значение.
 

cobra2029

Новичок
Сообщения
54
Репутация
0
Здравствуйте!

Возникла необходимость отлавливать подключение и отключение флешки.
Была написана програмулина на C#, но по независящим от меня обстоятельствам от неё пришлось отказаться. Решил накидать что то похожее на autoit.
Каково же было мое удивление когда вот в этой теме данный вопрос уже был решен.
Скопипастил я код, много уважаемого Yashied, а он не работает.

В чем проблема?

Windows 7, AutoIt: 3.3.8.x, _WinAPIEx Версия: 3.8


P.S. т.к. не пользовался давно autoit полностью обновил все компоненты
 
Верх