corgano

Help / Reading usb controller with _WinAPI_RegisterRawInputDevices

11 posts in this topic

#1 ·  Posted (edited)

Edit: If you already read this post, I updated it to better fit the scope of what I want to do.

My goal is to be able to read the raw output from a usb type controller (or mouse or keyboard, don't want it to be controller-only) so i can see how / what changes when i hit buttons. I've gotten as far as finding HID page documentation and documentation for the device Struct, but I don't know where to go from here

  • How do I tell what and Useage to use for any given controller / Keyboard / Mouse?
  • How do I get a list of all HID devices connected and their UsagePage / Usage?
  • How do I register multiple devices / get raw input from multiple devices at once?

Here is the modified example script i am using:

#include <APISysConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WinAPIGdi.au3>
#include <WinAPIMisc.au3>
#include <WinAPISys.au3>
#include <WindowsConstants.au3>

Opt('TrayAutoPause', 0)

Global $iFlagsOld = 0, $iDataOld = 0


; Create GUI
Global $g_hForm = GUICreate('Test ' & StringReplace(@ScriptName, '.au3', '()'), 160, 212, @DesktopWidth - 179, @DesktopHeight - 283, BitOR($WS_CAPTION, $WS_POPUP, $WS_SYSMENU), $WS_EX_TOPMOST)


; To obtain the values of "UsagePage" and "Usage" members of this structure read HID Usage Tables documentation
; http://www.usb.org/developers/devclass_docs/HID1_11.pdf

;   Disregaurd that, official USB documention = useless. Here is a human/normal-person friendly list
;       http://www.freebsddiary.org/APC/usb_hid_usages.php
;   Information on the Struct (eg what Flags and hTarget do) can be found here
;       https://msdn.microsoft.com/en-us/library/ms645565(v=vs.85).aspx
Local $tRID = DllStructCreate($tagRAWINPUTDEVICE)
DllStructSetData($tRID, 'UsagePage', 0x01) ; Generic Desktop Controls
DllStructSetData($tRID, 'Usage', 0x06) ; Mouse
DllStructSetData($tRID, 'Flags', $RIDEV_INPUTSINK) ; This flag makes window hTarget accept input even when it's not active. MUST define hTarget
DllStructSetData($tRID, 'hTarget', $g_hForm) ; The target window that will be sent events, used with some Flags

; Register HID input to obtain row input
_WinAPI_RegisterRawInputDevices($tRID)

; Register WM_INPUT message
GUIRegisterMsg($WM_INPUT, 'WM_INPUT')

;~ GUISetState(@SW_SHOW)

Do
Until GUIGetMsg() = $GUI_EVENT_CLOSE

Func WM_INPUT($hWnd, $iMsg, $wParam, $lParam)
    #forceref $iMsg, $wParam

    Switch $hWnd
        Case $g_hForm
            Local $tRIM = DllStructCreate($tagRAWINPUTMOUSE)
            If _WinAPI_GetRawInputData($lParam, $tRIM, DllStructGetSize($tRIM), $RID_INPUT) Then
                Local $iFlags = DllStructGetData($tRIM, 'Flags')

                Local $sFlag = "", $sData = ""

                $iFlags = DllStructGetData($tRIM, 'ButtonFlags')
                If $iFlags <> $iFlagsOld Then
                    $sFlag = $iFlags
                    $iFlagsOld = $iFlags
                EndIf

                $iData = DllStructGetData($tRIM, 'ButtonData')
                If $iData <> $iDataOld Then
                    $sData = $iData
                    $iDataOld = $iData
                EndIf

                If $sFlag&$sData <> "" Then
                    ConsoleWrite($sFlag&"   "&$sData&@CRLF)
                EndIf

            EndIf
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_INPUT


Old post:

Spoiler

I am looking for help with _WinAPI_RegisterRawInputDevices, more specifically a simpler example than the one provided in the help file. What I want is an example script that will show a list of HID devices, let me select one, and then show me the hex readout of the device (so i can push buttons and see how it changes). 

MY end goal is to read outputs from a USB HID game controller

So far, I've looked through a few threads about RawInput.au3 and that eventually lead me to _WinAPI_RegisterRawInputDevices. I have a very basic understanding of structs / pointers, but if someone could explain in a bit more detail how this works it would be greatly appreciated.

 

Edited by corgano

0x616e2069646561206973206c696b652061206d616e20776974686f7574206120626f64792c20746f206669676874206f6e6520697320746f206e657665722077696e2e2e2e2e

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

I've been reading through http://www.usb.org/developers/devclass_docs/HID1_11.pdf (the link in the help file is WRONG, needs to be updated to the correct link at http://www.usb.org/developers/hidpage/HID1_11.pdf) to try and make sense of "UseagePage" and "Useage" - to try and make it read the keyboard or a usb HID controller instead, but have not had any luck so far.

EDIT: Found a more readable list here: http://www.freebsddiary.org/APC/usb_hid_usages.php. I have no idea how or where in the documentation linked from the help file this info is.
EDIT2: https://msdn.microsoft.com/query/dev10.query?appId=Dev10IDEF1&l=EN-US&k=k(RegisterRawInputDevices);k(DevLang-C);k(TargetOS-WINDOWS)&rd=true has good info on what the flags do

I also have a second question, the help file says 

Quote

A pointer to an array of $tagRAWINPUTDEVICE structures

Does that mean I can have it listen to multiple things, say the keyboard AND a usb controller? If so, how do I accomplish this?

Edited by corgano

0x616e2069646561206973206c696b652061206d616e20776974686f7574206120626f64792c20746f206669676874206f6e6520697320746f206e657665722077696e2e2e2e2e

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

DllStructSetData($tRID, 'Usage', 0x06) ; Mouse

isnt 0x06 for keyboard and 0x02 for mouse?

Edited by Nikolas92

Share this post


Link to post
Share on other sites

I've hit a wall. I can use _WinAPI_EnumRawInputDevices() to get a list of devices and device handles, but I can't see any way to use _WinAPI_RegisterRawInputDevices() with a device handle, and I can't figure out how to get the Struct _WinAPI_RegisterRawInputDevices() needs from the device handle. I need help from someone who actually knows what they are doing :(


0x616e2069646561206973206c696b652061206d616e20776974686f7574206120626f64792c20746f206669676874206f6e6520697320746f206e657665722077696e2e2e2e2e

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

18 hours ago, Nikolas92 said:

 

DllStructSetData($tRID, 'Usage', 0x06) ; Mouse

isnt 0x06 for keyboard and 0x02 for mouse?

Somehow i missed this comment. Yes, 0x02 is mouse I was trying to experiment by seeing my keyboard. As per this list, 06 is keyboard. Indeed i was also able to see when i hit keys on my keyboard.... but not when i released them! I am obviously missing something, or am I wrong to assume a HID keyboard would send a code for both pressing and releasing a key?

Edited by corgano

0x616e2069646561206973206c696b652061206d616e20776974686f7574206120626f64792c20746f206669676874206f6e6520697320746f206e657665722077696e2e2e2e2e

Share this post


Link to post
Share on other sites

My main goal is to read gamepads, not just keyboards, but I'll read through and see what I can learn from that doc. Thanks for the link.

I JUST found this tool and it shows me EXACTLY the data I am after. Perhaps my understanding isn't right, but I am looking for this exact data, but directly from autoit. Link here: http://www.virtualdj.com/download/hidtrace.exe
P1San6U.png
I want to get exactly this data in autoit, but how?


0x616e2069646561206973206c696b652061206d616e20776974686f7574206120626f64792c20746f206669676874206f6e6520697320746f206e657665722077696e2e2e2e2e

Share this post


Link to post
Share on other sites

#8 ·  Posted (edited)

2 hours ago, corgano said:

Indeed i was also able to see when i hit keys on my keyboard.... but not when i released them!

Cool, was addressing this statement.  Good Luck,

kylomas

P.S. Was going to suggest that there are easier ways to get KB input but suspected that you already knew that.

Edited by kylomas

Forum Rules         Procedure for posting code

Share this post


Link to post
Share on other sites

I think I'm trying to do something similar, What I want to do is capture raw data from a barcode reader (it acts like a keyboard)  and send it to one guictrl

and all other keyboard input to the appropriate active control.   So I need to be able to separate data based upon the HWID of the device.

My program is pretty sequential, (only first window of mult-window program, actually needs barcode input, and no other input on that page) so that I can call DEVCon to remove the HID  device when I don't need it and rescan to add it back in.  but that is more of a hack then a solution. 

You are farther than I am, so I'm hoping that you can help.

 

Share this post


Link to post
Share on other sites

#10 ·  Posted (edited)

Off topic, but I posted how i captured barcode scanner output here:

TL:DR my scanner let me configure on the scanner itself a pre- and -post scan action. I set the pre-scan action to be send F9 and wait 100ms, the post-scan action to be hit enter.
Then made F9 trigger an inputBox() with a timeout of 500ms to get input. It worked well enough, and made both the program and software plug-and-play without having to worry about device ID's. 

Edited by corgano

0x616e2069646561206973206c696b652061206d616e20776974686f7574206120626f64792c20746f206669676874206f6e6520697320746f206e657665722077696e2e2e2e2e

Share this post


Link to post
Share on other sites

#11 ·  Posted

Thank you,  but that is not what I'm trying to do.  I can read the Scanner without issues. My problem is that the Barcode scanner is actually a badge reader that is customer facing. When someone badges in to the Kios or selects [Login] button  a screen on the other side of the customer window is opened (Employee) and mirrored back to the customer .  The Employee has the Keyboard and will type notes etc.   but if the customer rescans their badge while the employee is typing, the notes include the badge number.

So what I wanted to do is separate any text that is being scanned into using the badge reader and deal with it, ether ignore it after login or update a hidden input control. but still allow the Employee to input test in the kios form cleanly using his keyboard.

I can use Devcon to remove the device after input and Rescan when I allow the device to be used  that will to add it back in, but that is a hack and it limits some functionality.

 

Share this post


Link to post
Share on other sites

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 account

Sign in

Already have an account? Sign in here.


Sign In Now

  • Similar Content

    • mikkokh
      How found COM port number using USB COM adapter details
      By mikkokh
      Hi.
       
      I have several different devices connected to my desktop PC with USB COM adapters.
       
      Sometimes there is some error that will cut my USB COM device communication (usualy caused by lose USB connector)... After reconnecting that USB COM adapter, by some reason, Windows will give it different COM port number.
      I know there are some devices with integrated COM port circuit and they are used by client programs that can found them and only them by some USB hardware relate details and then use their COM port to communicate with correct COM device.
      It would be better to define some known and static hardware related string from device managers USB COM adapter details to my script config file, than always redefine different COM port to it.
       
      How can I do this trick with autoit?
       
      I communicate COM devices with cfxUDF.au3 AutoIt UDF.
    • j0kky
      _WinApi_GetLogicalProcessorInformation
      By j0kky
      Hi guys,
      thanks to this request, I wrote my version of GetLogicalProcessorInformation UDF for x86 e x64:
      ; #FUNCTION# ======================================================================================================================== ; Name...........: _WinAPI_GetLogicalProcessorInformation ; Description ...: Retrieves information about logical processors and related hardware. ; Syntax.........: _WinAPI_GetLogicalProcessorInformation() ; Return values .: On success it returns a bidimensional array: on rows there is the list of processor sets, these are the columns: ; |[0] - A logical processor affinity mask, which indicates the logical processors that the information applies to. ; |[1] - If setted, then the specified logical processors share a single processor core. ; |[2] - How many active processors that share functional units are in the relationship ; (it is setted only if the previous element is setted too) ; |[3] - If setted, it identifies the NUMA node (it can be 0). ; |[4] - If setted, the specified logical processors share a physical package. ; |[5] - A bidimensional array: on rows there is the cache list, these are the columns: ; |[0] - The cache level ; |[1] - The cache associativity ; |[2] - The cache line size, in bytes ; |[3] - The cache size, in bytes ; |[4] - The cache type ; On failure it returns -1 and sets @error to non zero: ; |-1 - internal error ; |-2 - missing DLL (Ws2_32.dll) ; Remarks .......: Search GetLogicalProcessorInformation in MSDN Library. ; Author ........: j0kky ; Modified ......: 1.0.0 ; Links .........: https://msdn.microsoft.com/it-it/library/windows/desktop/ms683194(v=vs.85).aspx ; ==================================================================================================================================== Func _WinAPI_GetLogicalProcessorInformation() Local $hDll = DllOpen("kernel32.dll") If @error Then Return SetError(-2, 0, -1) Local Const $ERROR_INSUFFICIENT_BUFFER = 122 Local $aRet = DllCall($hDll, "BOOL", "GetLogicalProcessorInformation", "ptr", Null, "dword*", 0) If @error Or Not (DllCall($hDll, "DWORD", "GetLastError")[0] = $ERROR_INSUFFICIENT_BUFFER) Then DllClose($hDll) Return SetError(-1, 0, -1) EndIf Local $nReturnLength = $aRet[2] Local $tBuffer = DllStructCreate("byte[" & $nReturnLength & "]") Local $pBuffer = DllStructGetPtr($tBuffer) $aRet = DllCall($hDll, "BOOL", "GetLogicalProcessorInformation", "ptr", $pBuffer, "dword*", $nReturnLength) If @error Or Not $aRet[0] Then DllClose($hDll) Return SetError(-1, 0, -1) EndIf Local Const $tagSYSTEM_LOGICAL_PROCESSOR_INFORMATION = "ULONG_PTR ProcessorMask; INT_PTR Relationship; BYTE UnionBuffer[16]" Local $tSYSTEM_LOGICAL_PROCESSOR_INFORMATION = DllStructCreate($tagSYSTEM_LOGICAL_PROCESSOR_INFORMATION, $pBuffer) Local $nSize = DllStructGetSize($tSYSTEM_LOGICAL_PROCESSOR_INFORMATION), $tCACHE_DESCRIPTOR, _ $aResult[1][6], _ ;mask, core, logical, numa, package, cache $aCacheModel[0][5], _ ;level, associativity, line size, size, processor cache type $nOffset = 0, $nArraySize, $aCache, $vProcessor, $nProcessorMask $aResult[0][0] = $tSYSTEM_LOGICAL_PROCESSOR_INFORMATION.ProcessorMask $aResult[0][5] = $aCacheModel Do $tSYSTEM_LOGICAL_PROCESSOR_INFORMATION = DllStructCreate($tagSYSTEM_LOGICAL_PROCESSOR_INFORMATION, $pBuffer + $nOffset) $nProcessorMask = $tSYSTEM_LOGICAL_PROCESSOR_INFORMATION.ProcessorMask $nArraySize = UBound($aResult) For $i = 0 To ($nArraySize - 1) If $aResult[$i][0] = $nProcessorMask Then $vProcessor = $i ExitLoop EndIf Next If $vProcessor = Null Then ReDim $aResult[$nArraySize + 1][6] $aResult[$nArraySize][0] = $nProcessorMask $aResult[$nArraySize][5] = $aCacheModel $vProcessor = $nArraySize EndIf Switch $tSYSTEM_LOGICAL_PROCESSOR_INFORMATION.Relationship Case 0 ;RelationProcessorCore $aResult[$vProcessor][1] += 1 If (DllStructCreate("byte Flags", DllStructGetPtr($tSYSTEM_LOGICAL_PROCESSOR_INFORMATION, "UnionBuffer")).Flags) = 1 Then For $i = 1 To (($nSize = 24) ? 32 : 64) $aResult[$vProcessor][2] += (Mod($nProcessorMask, 2) ? 1 : 0) $nProcessorMask = Floor($nProcessorMask / 2) Next EndIf Case 1 ;RelationNumaNode $aResult[$vProcessor][3] = DllStructCreate("dword NodeNumber", DllStructGetPtr($tSYSTEM_LOGICAL_PROCESSOR_INFORMATION, "UnionBuffer")).NodeNumber Case 2 ;RelationCache $tCACHE_DESCRIPTOR = DllStructCreate("byte Level; byte Associativity; word LineSize; dword Size; INT Type", _ DllStructGetPtr($tSYSTEM_LOGICAL_PROCESSOR_INFORMATION, "UnionBuffer")) $aCache = $aResult[$vProcessor][5] $nArraySize = UBound($aCache) ReDim $aCache[$nArraySize + 1][5] $aCache[$nArraySize][0] = $tCACHE_DESCRIPTOR.Level $aCache[$nArraySize][1] = $tCACHE_DESCRIPTOR.Associativity $aCache[$nArraySize][2] = $tCACHE_DESCRIPTOR.LineSize $aCache[$nArraySize][3] = $tCACHE_DESCRIPTOR.Size $aCache[$nArraySize][4] = $tCACHE_DESCRIPTOR.Type $aResult[$vProcessor][5] = $aCache Case 3 ;RelationProcessorPackage $aResult[$vProcessor][4] += 1 EndSwitch $nOffset += $nSize $vProcessor = Null Until $nOffset = $nReturnLength DllClose($hDll) Return $aResult EndFunc ;==>_WinAPI_GetLogicalProcessorInformation Usage example:
      #include <array.au3> $array = _WinAPI_GetLogicalProcessorInformation() _ArrayDisplay($array, "Processor set list:") For $i = 0 To UBound($array) - 1 _ArrayDisplay($array[$i][5], "Processor set " & $i + 1 & " cache:") Next
    • powerbass4
      WINAPI GetLogicalProcessorInformation
      By powerbass4
      Hi, I need the help of some "C++ Pros" of you....

      The "WINAPI GetLogicalProcessorInformation" function does not exists in the AutoIt Includes, so I decided to build it on my own ....no success so far.
      I adapted easy functions, but this one seems to be odd and unfamiliar.

      I hope somebody can help me.... and after that this function should be added to the Includes (WinAPISys.au3).
       
      BOOL WINAPI GetLogicalProcessorInformation( _Out_ PSYSTEM_LOGICAL_PROCESSOR_INFORMATION Buffer, _Inout_ PDWORD ReturnLength ); https://msdn.microsoft.com/en-us/library/windows/desktop/ms683194(v=vs.85).aspx
       
      typedef struct _SYSTEM_LOGICAL_PROCESSOR_INFORMATION { ULONG_PTR ProcessorMask; LOGICAL_PROCESSOR_RELATIONSHIP Relationship; union { struct { BYTE Flags; } ProcessorCore; struct { DWORD NodeNumber; } NumaNode; CACHE_DESCRIPTOR Cache; ULONGLONG Reserved[2]; }; } SYSTEM_LOGICAL_PROCESSOR_INFORMATION, *PSYSTEM_LOGICAL_PROCESSOR_INFORMATION; https://msdn.microsoft.com/en-us/library/windows/desktop/ms686694(v=vs.85).aspx
    • queensoft
      Portable device (Android phone) - copy files
      By queensoft
      Connect Android phone > enable USB file transfer > go to My Computer, there's an icon, but no drive letter - this is normal.
      Open phone icon > go to Internal Storage > go to DCIM > copy all files and folders to computer.
      Now, I want a quick AutoIt script / windows batch to do this automatically.
      Get USB path with this - it works OK:
      #include <WinAPICom.au3> Global Const $sCLSID_PortableDeviceManager = "{0af10cec-2ecd-4b92-9581-34f6ae0637f3}" Global Const $sIID_IPortableDeviceManager = "{a1567595-4c2f-4574-a6fa-ecef917b9a40}" Global Const $sTagIPortableDeviceManager = "GetDevices hresult(ptr;dword*); RefreshDeviceList hresult(); " & _ "GetDeviceFriendlyName hresult(wstr;wstr;dword*); GetDeviceDescription hresult(wstr;wstr;dword*); " & _ "GetDeviceManufacturer hresult(wstr;wstr;dword*); GetDeviceManufacturer hresult(wstr;wstr;ptr;dword*dword*); " & _ "GetPrivateDevices hresult(ptr;dword*)" Global Enum $eDevID, $eDevName, $eDevManufacturer, $eDevDescription Local $aPnPDevices = GetPortableDevices() If IsArray($aPnPDevices) Then _ArrayDisplay($aPnPDevices) ;~ Success: Return 0 ;~ Failure: Return 2DArray [n][4] |;[n][0]$eDevID, [n][1]$eDevName, [n][2]$eDevManufacturer,[n][3] $eDevDescription Func GetPortableDevices() Local $aDevicesInfo[0][0] ;[n][0]$eDevID, [n][1]$eDevName, [n][2]$eDevManufacturer,[n][3] $eDevDescription Local $oPortableDeviceManager = 0 Local $SizeofArray = 0 Local $hr = 0x80004005 ;E_Fail Just to Initialized <0 Local $taPnPDeviceIDs = 0 Local $tName = 0 $oPortableDeviceManager = ObjCreateInterface($sCLSID_PortableDeviceManager, $sIID_IPortableDeviceManager, $sTagIPortableDeviceManager) If Not IsObj($oPortableDeviceManager) Then Return 0 If FAILED($oPortableDeviceManager.GetDevices(Null, $SizeofArray)) Then Return 0 If $SizeofArray < 1 Then Return 0 $taPnPDeviceIDs = DllStructCreate("ptr[" & $SizeofArray & "]") If FAILED($oPortableDeviceManager.GetDevices(DllStructGetPtr($taPnPDeviceIDs), $SizeofArray)) Then Return 0 ReDim $aDevicesInfo[$SizeofArray][4] For $i = 0 To $SizeofArray - 1 $tName = DllStructCreate("wchar[512]", DllStructGetData($taPnPDeviceIDs, 1, $i + 1)) $aDevicesInfo[$i][$eDevID] = DllStructGetData($tName, 1) $aDevicesInfo[$i][$eDevName] = _GetFriendlyName($oPortableDeviceManager, $aDevicesInfo[$i][$eDevID]) $aDevicesInfo[$i][$eDevManufacturer] = _GetDeviceManufacturer($oPortableDeviceManager, $aDevicesInfo[$i][$eDevID]) $aDevicesInfo[$i][$eDevDescription] = _GetDeviceDescription($oPortableDeviceManager, $aDevicesInfo[$i][$eDevID]) $tName = 0 _WinAPI_CoTaskMemFree(DllStructGetData($taPnPDeviceIDs, 1, $i + 1)) Next Return $aDevicesInfo EndFunc ;==>GetPortableDevices Func _GetDeviceManufacturer($oInterface, $PnPDeviceID) Local $sString = "" $oInterface.GetDeviceManufacturer($PnPDeviceID, $sString, 128) Return $sString EndFunc ;==>_GetDeviceManufacturer Func _GetDeviceDescription($oInterface, $PnPDeviceID) Local $sString = "" Local Const $Size = 128 $oInterface.GetDeviceDescription($PnPDeviceID, $sString, 128) Return $sString EndFunc ;==>_GetDeviceDescription Func _GetFriendlyName($oInterface, $PnPDeviceID) Local $sString = "" Local Const $Size = 128 $oInterface.GetDeviceFriendlyName($PnPDeviceID, $sString, 128) Return $sString EndFunc ;==>_GetFriendlyName Func _GetProperty($oInterface, $PnPDeviceID) Local $sString = "" Local Const $Size = 128 $oInterface.GetDeviceFriendlyName($PnPDeviceID, $sString, 128) Return $sString EndFunc ;==>_GetProperty Func FAILED($hr) Return ($hr < 0) EndFunc ;==>FAILED Path looks like this:
      \\?\usb#vid_0e8d&pid_201d&mi_00#7&37c4bb9&0&0000#{6ac27878-a6fa-4155-ba85-f98f491d4f33} I can open this in a Windows Explorer windows and it works ok.
      Now, search for files using AutoIt - does not work:
      #include <GUIConstantsEx.au3> #include <Array.au3> #include <File.au3> Local $f $f = _RecFileListToArray("\\?\usb#vid_0e8d&pid_201d&mi_00#7&37c4bb9&0&0000#{6ac27878-a6fa-4155-ba85-f98f491d4f33}", "*.*", 0, 1, 1) _ArrayDisplay($f) ; Name...........: _RecFileListToArray ; Description ...: Lists files and\or folders in a specified path (Similar to using Dir with the /B Switch) ; Syntax.........: _RecFileListToArray($sPath[, $sFilter = "*"[, $iFlag = 0[, $iRecur = 0[, $iFullPath = 0]]]]) ; Parameters ....: $sPath - Path to generate filelist for. ; $sFilter - Optional the filter to use, default is *. Search the Autoit3 helpfile for the word "WildCards" For details. ; $iFlag - Optional: specifies whether to return files folders or both ; |$iFlag=0 (Default) Return both files and folders ; |$iFlag=1 Return files only ; |$iFlag=2 Return Folders only ; $iRecur - Optional: specifies whether to search in subfolders ; |$iRecur=0 (Default) Do not search in subfolders ; |$iRecur=1 Search in subfolders ; $iFullPath - Optional: specifies whether to include initial path in result string ; |$iFullPath=0 (Default) Do not include initial path ; |$iFullPath=1 Include initial path ; Return values .: @Error - 1 = Path not found or invalid ; |2 = Invalid $sFilter ; |3 = Invalid $iFlag ; |4 = Invalid $iRecur ; |5 = Invalid $iFullPath ; |6 = No File/Folder Found ; Author ........: SolidSnake <MetalGX91 at GMail dot com> ; Modified.......: 22 Jan 09 by Melba23 - added recursive search and full path options ; Remarks .......: The array returned is one-dimensional and is made up as follows: ; $array[0] = Number of Files\Folders returned ; $array[1] = 1st File\Folder ; $array[2] = 2nd File\Folder ; $array[3] = 3rd File\Folder ; $array[n] = nth File\Folder ; Related .......: ; Link ..........; ; Example .......; Yes ; ==================================================================================================== ;Special Thanks to Helge and Layer for help with the $iFlag update ; speed optimization by code65536 ;=============================================================================== Func _RecFileListToArray($sPath, $sFilter = "*", $iFlag = 0, $iRecur = 0, $iFullPath = 0) Local $asFileList[1], $sFullPath If Not FileExists($sPath) Then Return SetError(1, 1, "") If StringRight($sPath, 1) <> "\" Then $sPath = $sPath & "\" If (StringInStr($sFilter, "\")) Or (StringInStr($sFilter, "/")) Or (StringInStr($sFilter, ":")) Or (StringInStr($sFilter, ">")) Or (StringInStr($sFilter, "<")) Or (StringInStr($sFilter, "|")) Or (StringStripWS($sFilter, 8) = "") Then Return SetError(2, 2, "") If Not ($iFlag = 0 Or $iFlag = 1 Or $iFlag = 2) Then Return SetError(3, 3, "") If Not ($iRecur = 0 Or $iRecur = 1) Then Return SetError(4, 4, "") If $iFullPath = 0 Then $sFullPath = $sPath ElseIf $iFullPath = 1 Then $sFullPath = "" Else Return SetError(5, 5, "") EndIf _FLTA_Search($sPath, $sFilter, $iFlag, $iRecur, $sFullPath, $asFileList) If $asFileList[0] = 0 Then Return SetError(6, 6, "") Return $asFileList EndFunc ;==>_FileListToArray ; #INTERNAL_USE_ONLY#================================================================================= ; Name...........: _FLTA_Search ; Description ...: Searches folder for files and then recursively searches in subfolders ; Syntax.........: _FLTA_Search($sStartFolder, $sFilter, $iFlag, $iRecur, $sFullPath, ByRef $asFileList) ; Parameters ....: $sStartFolder - Value passed on from UBound($avArray) ; $sFilter - As set in _FileListToArray ; $iFlag - As set in _FileListToArray ; $iRecur - As set in _FileListToArray ; $sFullPath - $sPath as set in _FileListToArray ; $asFileList - Array containing found files/folders ; Return values .: None ; Author ........: Melba23 based on code from _FileListToArray by SolidSnake <MetalGX91 at GMail dot com> ; Modified.......: ; Remarks .......: This function is used internally by _FileListToArray. ; Related .......: ; Link ..........; ; Example .......; ; ==================================================================================================== Func _FLTA_Search($sStartFolder, $sFilter, $iFlag, $iRecur, $sFullPath, ByRef $asFileList) Local $hSearch, $sFile If StringRight($sStartFolder, 1) <> "\" Then $sStartFolder = $sStartFolder & "\" ; First look for filtered files/folders in folder $hSearch = FileFindFirstFile($sStartFolder & $sFilter) If $hSearch > 0 Then While 1 $sFile = FileFindNextFile($hSearch) If @error Then ExitLoop Switch $iFlag Case 0; Both files and folders If $iRecur And StringInStr(FileGetAttrib($sStartFolder & $sFile), "D") <> 0 Then ContinueLoop Case 1; Files Only If StringInStr(FileGetAttrib($sStartFolder & $sFile), "D") <> 0 Then ContinueLoop Case 2; Folders only If StringInStr(FileGetAttrib($sStartFolder & $sFile), "D") = 0 Then ContinueLoop EndSwitch If $iFlag = 1 And StringInStr(FileGetAttrib($sStartFolder & $sFile), "D") <> 0 Then ContinueLoop If $iFlag = 2 And StringInStr(FileGetAttrib($sStartFolder & $sFile), "D") = 0 Then ContinueLoop _FLTA_Add($asFileList, $sFullPath, $sStartFolder, $sFile) WEnd FileClose($hSearch) ReDim $asFileList[$asFileList[0] + 1] EndIf If $iRecur = 1 Then ; Now look for subfolders $hSearch = FileFindFirstFile($sStartFolder & "*.*") If $hSearch > 0 Then While 1 $sFile = FileFindNextFile($hSearch) If @error Then ExitLoop If StringInStr(FileGetAttrib($sStartFolder & $sFile), "D") And ($sFile <> "." Or $sFile <> "..") Then ; If folders needed, add subfolder to array If $iFlag <> 1 Then _FLTA_Add($asFileList, $sFullPath, $sStartFolder, $sFile) ; Recursive search of this subfolder _FLTA_Search($sStartFolder & $sFile, $sFilter, $iFlag, $iRecur, $sFullPath, $asFileList) EndIf WEnd FileClose($hSearch) EndIf EndIf EndFunc ; #INTERNAL_USE_ONLY#================================================================================= ; Name...........: _FLTA_Add ; Description ...: Searches folder for files and then recursively searches in subfolders ; Syntax.........: _FLTA_Add(ByRef $asFileList, $sFullPath, $sStartFolder, $sFile) ; Parameters ....: $asFileList - Array containing found files/folders ; $sFullPath - $sPath as set in _FileListToArray ; $sStartFolder - Value passed on from UBound($avArray) ; $sFile - Full path of file/folder to add to $asFileList ; Return values .: Function only changes $asFileList ByRef ; Author ........: Melba23 based on code from _FileListToArray by SolidSnake <MetalGX91 at GMail dot com> ; Modified.......: ; Remarks .......: This function is used internally by _FileListToArray. ; Related .......: ; Link ..........; ; Example .......; ; ==================================================================================================== Func _FLTA_Add(ByRef $asFileList, $sFullPath, $sStartFolder, $sFile) Local $sAddFolder $asFileList[0] += 1 If UBound($asFileList) <= $asFileList[0] Then ReDim $asFileList[UBound($asFileList) * 2] If $sFullPath = "" Then $sAddFolder = $sStartFolder Else $sAddFolder = StringReplace($sStartFolder, $sFullPath, "") EndIf $asFileList[$asFileList[0]] = $sAddFolder & $sFile EndFunc File copy using Autoit - does not work:
      FileCopy("\\?\usb#vid_0e8d&pid_201d&mi_00#7&37c4bb9&0&0000#{6ac27878-a6fa-4155-ba85-f98f491d4f33}\Internal storage\DCIM\Camera MX\PHOTO_20161007_123935.jpg", 'd:\Diverse 2\654\0\') Copy using Windows batch - does not work:
      xcopy /Y /E "\\?\usb#vid_0e8d&pid_201d&mi_00#7&37c4bb9&0&0000#{6ac27878-a6fa-4155-ba85-f98f491d4f33}\Internal storage\DCIM\*.*" "d:\Diverse 2\654\0\"  
    • samozaparola
      Simulate custom ultrasound machine keystrokes
      By samozaparola
      I have a Windows XP based ultrasound machine that besides the keyboard has a console with custom controls such as zoom, pause, measure, caliper, etc. As far as I understand, these custom  keys "don't send key combinations; instead, they have their own usage IDs in the HID". So is there a way to simulate pressing these keys in AutoIt?