horrscht6 Posted July 18, 2008 Share Posted July 18, 2008 Hello guys!I am a german programmer and I need to detect if a specific USB stick is connected with the computer. If this USB stick is connected another actions can follow. First action of the user should be: Connecting the USB stick to the computer. Second action: Start the AutoItScript and following the script instructions.My problem is not to detect the authorized USB stick. The problem is to find out which drive letter have this USB stick on the computer (e.g. F:, H:, I:).I have used the function Func GetDriveLetterFromDisk($name) which I have found several times here in the topics. But I don't find the solution for my problem.Who can help me or give the completed code back for detecting the drive letter? Thank you very much in advance!!!!CODE$onlyThisStickIsPreferred = "USB\VID_0781&PID_540E\000016A0787491CB"$USBmassStorgageName1="USB-Massenspeicher"$USBmassStorgageName2="USB-Massenspeichergerät"$strComputer = "."$objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\CIMV2")$colItems = $objWMIService.ExecQuery("Select * From Win32_USBControllerDevice")If IsObj($colItems) then LogIt("++++++++++++++++++++++++") LogIt("!! USB objects exists !!") LogIt("++++++++++++++++++++++++") For $objDevice In $colItems $strDeviceName = $objDevice.Dependent $strQuotes = Chr(34) $strDeviceName = StringReplace($strDeviceName, $strQuotes, "") $arrDeviceNames = StringSplit($strDeviceName, "=") $strDeviceName = $arrDeviceNames[2] LogIt("======================================") LogIt("$arrDeviceNames[1]=" & $arrDeviceNames[1]) LogIt("$arrDeviceNames[2]=" & $arrDeviceNames[2]) $Drive0 = GetDriveLetterFromDisk($arrDeviceNames[2]) LogIt("Drive0 =" & $Drive0) $colUSBDevices = $objWMIService.ExecQuery("Select * From Win32_PnPEntity Where DeviceID = '" & $strDeviceName & "'") For $objUSBDevice in $colUSBDevices $Description = $objUSBDevice.Description $DeviceID = $objUSBDevice.DeviceID $DeviceName = $objUSBDevice.Name $PnPDeviceID = $objUSBDevice.PnPDeviceID LogIt("--------------------------------------") LogIt("Description: " & $Description) LogIt("DeviceId : " & $DeviceID) LogIt("DeviceName : " & $DeviceName) LogIt("PnPDeviceID: " & $PnPDeviceID) if ($Description = $USBmassStorgageName1) Or ($Description = $USBmassStorgageName2) Then if $DeviceID = $onlyThisStickIsPreferred Then LogIt("***** Authorized stick is used *****") ; Now I need the drive letter of this drive, but this is not functional $Drive = GetDriveLetterFromDisk($DeviceName) LogIt("Drive : " & $Drive) ; I get everytime a empty string EndIf EndIf NEXT LogIt(" ") NextElse LogIt("+++++++++++++++++++++++") LogIt("No USB Objects existing") LogIt("+++++++++++++++++++++++")Endif; ----------------------------------------------------Func LogIt($sText) IF @Compiled THEN DllCall("kernel32.dll", "none", "OutputDebugString", "str", $sText) Else ConsoleWrite($sText & @LF) EndIfEndFuncFunc GetDriveLetterFromDisk($name) Local $wbemFlagReturnImmediately = 0x10 Local $wbemFlagForwardOnly = 0x20 Local $strComputers = ".", $objEvent = 0 Local $objWMIServices = ObjGet("winmgmts:\\" & $strComputers & "\root\cimv2") $ans = "" $name = StringReplace($name,"\","\\") $oq_part = $objWMIServices.ExecQuery("ASSOCIATORS OF {Win32_DiskDrive.DeviceID=""" & $name & """} WHERE AssocClass = Win32_DiskDriveToDiskPartition", "WQL", $wbemFlagReturnImmediately + $wbemFlagForwardOnly) If IsObj($oq_part) Then For $obj_part In $oq_part $oq_disk = $objWMIServices.ExecQuery("ASSOCIATORS OF {Win32_DiskPartition.DeviceID=""" & $obj_part.DeviceID & """} WHERE AssocClass = Win32_LogicalDiskToPartition", "WQL", $wbemFlagReturnImmediately + $wbemFlagForwardOnly) If IsObj($oq_disk) Then For $obj_disk in $oq_disk $ans = $ans & $obj_disk.Name Next EndIf Next EndIf Return $ansEndFuncUSB mass storages in germany have following descriptions "USB-Massenspeicher" (Windows2000) or "USB-Massenspeichergerät" (WindowsXP)horrscht Link to comment Share on other sites More sharing options...
Xenobiologist Posted July 18, 2008 Share Posted July 18, 2008 Hi,es gibt auch www.autoit.de muttley Du kannst ja einfach durch alle LW iterieren und den DriveGetLabel prüfen oder auf eine bestimtme Datei auf dem Stick prüfen If FileExistes A:\bla.txt und wenn ja dann ... usw.Gibt da viele Möglichkeiten. Wenn du die Serial kennst, kannst du auch diese verwendenMega Scripts & functions Organize Includes Let Scite organize the include files Yahtzee The game "Yahtzee" (Kniffel, DiceLion) LoginWrapper Secure scripts by adding a query (authentication) _RunOnlyOnThis UDF Make sure that a script can only be executed on ... (Windows / HD / ...) Internet-Café Server/Client Application Open CD, Start Browser, Lock remote client, etc. MultipleFuncsWithOneHotkey Start different funcs by hitting one hotkey different times Link to comment Share on other sites More sharing options...
horrscht6 Posted July 18, 2008 Author Share Posted July 18, 2008 Hi Mega! Der VolumeName kann zu leicht abgeändert werden, wenn ich den VolumeName suche. Eine zu suchende Datei hat auch den Nachteil, dass sie evtl. auch mal gelöscht sein könnte => ich finde den Stick dann nicht mehr. Die eindeutige USB-ID versetzt mich in die Lage den User-Fehler von Verwaltungsangestellten in Grenzen zu halten. Mir fehlt jetzt nur noch die gezielte Ermittlung des Laufwerksbuchstaben vom eindeutig gefundenen Stick. Es ist in der Vergangenheit schon passiert, dass der USB-Stick aus irgendeinem Grund, dann mal nicht mehr der Laufwerksbuchstabe H: war, wie ich im restlichen (nicht veröffentlichten) Skript voraussetzte, sondern der Buchstabe I:, dann schlug der Rest fehl und ich bekam Anrufe von der Verwaltungsangestellten. Dennoch danke für Deinen Hinweis, mit der deutschen Webseite. Gruß, horrscht Link to comment Share on other sites More sharing options...
Xenobiologist Posted July 18, 2008 Share Posted July 18, 2008 Hi, was wäre denn für eindeutig an einem USB Stick? Selbst die ID ist nicht eindeutig bei Billiggerstellen. Mega Scripts & functions Organize Includes Let Scite organize the include files Yahtzee The game "Yahtzee" (Kniffel, DiceLion) LoginWrapper Secure scripts by adding a query (authentication) _RunOnlyOnThis UDF Make sure that a script can only be executed on ... (Windows / HD / ...) Internet-Café Server/Client Application Open CD, Start Browser, Lock remote client, etc. MultipleFuncsWithOneHotkey Start different funcs by hitting one hotkey different times Link to comment Share on other sites More sharing options...
horrscht6 Posted July 18, 2008 Author Share Posted July 18, 2008 Hi Mega! Es sind vier bauartgleiche Sticks vom gleichen Hersteller, mit alle der gleichen Größe, alle zum selben Zeitpunkt gekauft. Alle 4 Sticks haben eine jeweils eindeutige DeviceID mit der ich sie gemäß meines Skripts unterscheiden kann. Also es geht - sorry, wenn's blöd klingt - um die Beantwortung meiner Frage, weil unterscheiden kann ich die Sticks mit einem Skript. Ich gebe zu, dass diese Unterscheidung anhand der DeviceID bei manchem Stick fehlschlagen könnte, aber solche Sticks sind in der Firma nicht im Einsatz. Ich möchte schlicht nicht mehr Annrufe haben, dass das Skript fehlschlägt, nur weil - aus welchem Grund auch immer - der Laufwerksbuchstabe nicht wie vorgesehen zugewiesen wird. Gruß, horrscht Link to comment Share on other sites More sharing options...
SkinnyWhiteGuy Posted July 18, 2008 Share Posted July 18, 2008 (edited) Hey, I have no clue what either of you have said, so here's the solution I found to do something similar. expandcollapse popupGlobal Const $DBT_DEVICEARRIVAL = 0x00008000 Global Const $WM_DEVICECHANGE = 0x0219 Global Const $tagDEV_BROADCAST_HDR = "dword dbchsize;dword dbchdevicetype;dword dbchreserved" Global Const $DBT_DEVTYP_VOLUME = 0x00000002 Global Const $tagDEV_BROADCAST_VOLUME = "dword dbcvsize;dword dbcvdevicetype;dword dbcvreserved;dword dbcvunitmask;short dbcvflags" Global Const $DBTF_MEDIA = 0x0001 Global Const $DBTF_NET = 0x0002 ;Setup The GUI to watch for the DeviceChange Event GUICreate("Test") GUIRegisterMsg($WM_DEVICECHANGE, "DeviceChange") While 1 Sleep (1000) WEnd Func DeviceChange($hWndGUI, $MsgID, $WParam, $LParam) $iEvent = $WParam If $iEvent = $DBT_DEVICEARRIVAL Then $temp = DllStructCreate($tagDEV_BROADCAST_HDR, $LParam) $iDeviceType = DllStructGetData($temp, "dbchdevicetype") If $iDeviceType = $DBT_DEVTYP_VOLUME Then $struct = DllStructCreate($tagDEV_BROADCAST_VOLUME, $LParam) $iUnitMask = DllStructGetData($struct, "dbcvunitmask") $iFlags = DllStructGetData($struct, "dbcvflags") If Not BitAND($iFlags, $DBTF_MEDIA) And Not BitAND($iFlags, $DBTF_NET) Then $sDrive = FirstDriveFromMask($iUnitMask) ConsoleWrite($sDrive & ": was inserted!" & @CRLF) EndIf EndIf EndIf EndFunc ;==>DeviceChange Func FirstDriveFromMask($unitmask) Local $i For $i = 0 To 25 If BitAND($unitmask, 0x1) Then ExitLoop $unitmask = BitShift($unitmask, 1) Next Return Chr($i + Asc('A')) EndFunc Just as a warning, this will also trigger when a CD-Rom Device is installed, not when a CD is inserted, but when a CD drive is added to a machine (like a USB external drive, or the fake one some USB sticks use). You can easily add a check for that with DriveGetType(), if that's an issue for you. Edited July 18, 2008 by SkinnyWhiteGuy Link to comment Share on other sites More sharing options...
Xenobiologist Posted July 18, 2008 Share Posted July 18, 2008 Global $serial = 821811646 If _getDriveBySerial($serial) Then MsgBox(64, 'USB', 'Laufwerk --> ' & _getDriveBySerial($serial), 5) Else MsgBox(16, 'USB', 'Serial nicht gefunden', 5) EndIf Func _getDriveBySerial($serial) For $i = 65 To 90 If $serial = DriveGetSerial(Chr($i) & ':') Then Return Chr($i) & ':' Next Return 0 EndFunc ;==>_getDriveBySerial Scripts & functions Organize Includes Let Scite organize the include files Yahtzee The game "Yahtzee" (Kniffel, DiceLion) LoginWrapper Secure scripts by adding a query (authentication) _RunOnlyOnThis UDF Make sure that a script can only be executed on ... (Windows / HD / ...) Internet-Café Server/Client Application Open CD, Start Browser, Lock remote client, etc. MultipleFuncsWithOneHotkey Start different funcs by hitting one hotkey different times Link to comment Share on other sites More sharing options...
horrscht6 Posted July 18, 2008 Author Share Posted July 18, 2008 Hey, I have no clue what either of you have said, so here's the solution I found to do something similar.Hey!Thank you for suggestion, but your script detects a added drive while the scripts already runs. But I need to detect the drive and search the drive letter when first the stick is connected to the computer and afterwards the script is started. The reason is the employee starts the script more than one time while the USB stick is connected to the computer.My information of the detected USB stick is the following:Description: USB-MassenspeichergerätDeviceId: USB\VID_090C&PID_1000\20071101114010000382Exists a possibility to detect the drive letter of my obtained information of the USB disk??Greetings, horrscht Link to comment Share on other sites More sharing options...
horrscht6 Posted July 18, 2008 Author Share Posted July 18, 2008 Hi Mega!I write here in english due to the other forum users.Your suggestion is okay but can I detect or get the serial with my AutoIt-Script with a little change to my script shown above?$DeviceID = $objUSBDevice.DeviceID => This $DeviceID isn't the serial number, i think so?My value e.g. of an home office USB stick is:$DeviceID = "USB\VID_090C&PID_1000\20071101114010000382"Greetings, horrscht Link to comment Share on other sites More sharing options...
Xenobiologist Posted July 19, 2008 Share Posted July 19, 2008 As I said before, you need one thing to identify the usb stick. One thing would be the serialID. I have to search how to get this "USB\VID_090C&PID_1000\20071101114010000382" so, maybe it is easier to include the 4 serialIds which Autoit detects by DriveGetSerial. Mega Scripts & functions Organize Includes Let Scite organize the include files Yahtzee The game "Yahtzee" (Kniffel, DiceLion) LoginWrapper Secure scripts by adding a query (authentication) _RunOnlyOnThis UDF Make sure that a script can only be executed on ... (Windows / HD / ...) Internet-Café Server/Client Application Open CD, Start Browser, Lock remote client, etc. MultipleFuncsWithOneHotkey Start different funcs by hitting one hotkey different times Link to comment Share on other sites More sharing options...
ChrisL Posted July 19, 2008 Share Posted July 19, 2008 The reason is the employee starts the script more than one time while the USB stick is connected to the computer.Look up _Singleton() in the help file, this will allow only 1 running copy of the script [u]Scripts[/u]Minimize gui to systray _ Fail safe source recoveryMsgbox UDF _ _procwatch() Stop your app from being closedLicensed/Trial software system _ Buffering Hotkeys_SQL.au3 ADODB.Connection _ Search 2d Arrays_SplashTextWithGraphicOn() _ Adjust Screen GammaTransparent Controls _ Eventlogs without the crap_GuiCtrlCreateFlash() _ Simple Interscript communication[u]Websites[/u]Curious Campers VW Hightops Lambert Plant Hire Link to comment Share on other sites More sharing options...
rudi Posted July 19, 2008 Share Posted July 19, 2008 Hallo Horrscht muttleyWenn's Dir um den Laufwerksbuchstaben geht wirf mal einen Blick auf das hier:http://www.uwe-sieber.de/usbdlm.htmlsofern das hier zutrifft ist's sogar Free:<cite>USBDLM ist Freeware für die private Nutzung sowie im Bildungs-Bereich, also Schulen, Unis usw. Eine Bildungs-Einrichtung gilt als solche, wenn dort Schüler, Studenten, Auszubildende in der Mehrheit sind...Anderenfalls ist - nach einer 30-tägigen Testzeit - pro Computer eine Lizenz nötig, s.unten. </cite>Ansonsten braucht's das evtl. nur auf ausgewählten Workstations?Schönen Gruß, Rudi. Earth is flat, pigs can fly, and Nuclear Power is SAFE! Link to comment Share on other sites More sharing options...
ProgAndy Posted July 19, 2008 Share Posted July 19, 2008 (edited) Auf Win 2000 Professional , XP und Vista gibt es noch eine Möglichkeit: Die Volume-GUID muttleyhttp://msdn.microsoft.com/en-us/library/aa364994(VS.85).aspx$Buff = "" For $i = 0 To 100 $Buff &= " " Next $drives = DriveGetDrive("REMOVABLE") For $i = 1 To $drives[0] $drives[$i] = StringUpper($drives[$i]) $ret = DllCall("Kernel32.dll","long","GetVolumeNameForVolumeMountPoint","str",$drives[$i] & "\","str",$Buff,"dword",100) If Not @error And $ret[0] <> 0 Then ConsoleWrite($drives[$i] & " - GUID: " & $ret[2] & @CRLF) EndIf Next//Edit: With the DeviceID, I'm not sure. It could be, that the Mount-Point is in this string, too. So it could change, if you use an other USB-Port.//Edit: A few UDfs to use the VolumeNames :CODE_ListVolumeNames()Func _GetDriveByVolumeName($VolumeName,$Types="ALL") Local $i,$ret, $drives,$Buff = "" For $i = 0 To 100 $Buff &= " " Next $drives = DriveGetDrive($Types) If @error Then Return SetError(@error,@extended,0) For $i = 1 To $drives[0] $drives[$i] = StringUpper($drives[$i]) $ret = DllCall("Kernel32.dll","long","GetVolumeNameForVolumeMountPoint","str",$drives[$i] & "\","str",$Buff,"dword",100) If Not @error And $ret[0] <> 0 Then If StringStripWS($ret[2],3) = $VolumeName Then Return $drives[$i] EndIf Next Return SetError(2,0,"")EndFuncFunc _GetVolumeNameByDrive($Drive) If DriveStatus($Drive) = "INVALID" Or Not StringIsAlpha(StringLeft($Drive,1)) Then Return SetError(1,0,"") $Drive = StringLeft($Drive,1) & ":\" Local $ret,$Buff = "" For $i = 0 To 100 $Buff &= " " Next $ret = DllCall("Kernel32.dll","long","GetVolumeNameForVolumeMountPoint","str",$Drive,"str",$Buff,"dword",100) If Not @error And $ret[0] <> 0 Then Return StringStripWS($ret[2],3) EndIf Return SetError(2,0,"")EndFunc#include <Array.au3>Func _ListVolumeNames() Local $drives = DriveGetDrive("ALL") Local $list[$drives[0]+1][2] = [[$drives[0]]] For $i = 1 To $drives[0] $list[$i][0] = $drives[$i] $list[$i][1] = _GetVolumeNameByDrive($drives[$i]) Next _ArrayDisplay($list)EndFunc Edited July 19, 2008 by ProgAndy *GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes Link to comment Share on other sites More sharing options...
horrscht6 Posted July 19, 2008 Author Share Posted July 19, 2008 Hi @all, Hi Rudi, hi ProgAndi! Your ideas, script examples and links are great and helps enormous. @ProgAndi: Your script examples gives new ideas and maybe I will use now completely new scripts for my work in the youth organisation. @Rudi: I have been contacted the author of USBDLM because of license in our youth organisation. Greetings, horrscht Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now