Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

Launching a script when a specific USB device is connected


  • Please log in to reply
16 replies to this topic
rktboy
  • Members
  • 8 posts
  • Last active: Jan 25 2010 11:14 AM
  • Joined: 18 Jan 2010
I realize this topic has been covered but I'm very new to AHK and coding and could use a push in the right direction.

As my subject line indicates, I'm looking to run a script when a specific USB device is connected. In my case, the device being connected is a Sony PSP running a homebrew app called PSPDisp, which allows it to function as a PC monitor. The idea is to have my PC automaticall detect the PSP being connected and to run a program to be displayed on the PSP.

I've already written a script to launch the program but am having trouble with working out how to set it to trigger on connection of the PSP.

Now, I've read through the excellent post by Maestr0 here:

http://www.autohotke...ight=detect usb

It looks like he was attempting to do something similar, albeit with a different device.

From what I understand so far, this script can be used to detect a USB being connected:

OnMessage(0x219, "notify_change") 
Return 

notify_change(wParam, lParam, msg, hwnd) 
{ 
MsgBox, %wParam% %lParam% %msg% %hwnd% 
}

As I understand it, OnMessage looks for a windows message, in this case 0x219 which is a device change message. This script then executes "notify_change" and obtains a number of paramaters and, in this script, displays those parameters in a message box. However, in my own tests, these parameters don't seem to change, regardless of what USB device is plugged in.

Maestr0's "Notifier" Script, which sits resident in the tray, has been modified to the following:

runwait kb_checker.ahk ; -- just in case the keyboard is connected when the script is started 
OnMessage(0x219, "notify_change") 
return 

notify_change(wParam, lParam, msg, hwnd) 
{ 
   ;outputdebug notify_change(%wParam%, %lParam%, %msg%, %hwnd%) 
   if msg = 537 
      runwait kb_checker.ahk 
}

So in this script, if I'm following correctly, the same OnMessage comand is used, triggering notify_change, and then, if the parameter "msg" is 537 (which I'm assuming has something to do with USB devices? It's always 537 in my tests anyways), runs Maestr0's kb_checker script.

...and it's here that I get a little lost. Can someone perhaps explain what Maestr0's script does from here and how it goes about identifying the correct device?

I've downloaded USBDeview and have all the information about the PSP:

Device Name: PSP Type C
Description: PSP Type C
Device Type: Vendor Specific
Connected: Yes
Safe To Unplug: Yes
Disabled: No
USB Hub: No
Drive Letter: N/A
Serial Number: N/A
Created Date: 12/25/2009 1:11:05 (I got the netbook for Christmas, lol)
VendorID: 054c
ProductID: 01ca
USB Class: ff
USB SubClass: 01
USB Protocol: ff
Hub/Port: Hub 0, Port 2
Computer Name: N/A
Vendor Name: N/A
Product Name: N/A
ParentID Prefix: N/A


Is any of the above information useful and, if so, how do I go about using it to identify the PSP specifically? If any further information is required, please let me know.

Thanks in advance for any help anyone is able to offer. I'm just new to all of this and am amazed to how versatile and powerful AHK is.

I'll look forward to reading your responses.

rktboy
  • Members
  • 8 posts
  • Last active: Jan 25 2010 11:14 AM
  • Joined: 18 Jan 2010
As a possible solution, USBDeview has a function which will Execute an exe when you insert a USB device as well as pass on certain parameters to that exe about the device. The one i'm most interested in is %device_name%

Can I use this to pass on the device name to a script compiled to an exe and have that script use the %device_name% variable to identify whether or not it should run?

I'm assuming the answer is yes, but how do I go about it? i.e. How do I get my script to use that parameter from USBDeview.

Z_Gecko
  • Guests
  • Last active:
  • Joined: --
http://www.autohotke...285.html#178285

rktboy
  • Members
  • 8 posts
  • Last active: Jan 25 2010 11:14 AM
  • Joined: 18 Jan 2010
Thankyou for the reply but I'm unclear on how this helps.

This script looks for a specific drive letter but I'm not mounting the PSP as a drive.

Maybe I'm missing something.

Z_Gecko
  • Guests
  • Last active:
  • Joined: --
the interesting part of the script is:
OnMessage(0x219, "notify_change")
i´m not shure if it´s triggered on drives only or on all devices, but it´s worth a try.
if it does not work, you could try using the WM_DEVICECHANGE Message

rktboy
  • Members
  • 8 posts
  • Last active: Jan 25 2010 11:14 AM
  • Joined: 18 Jan 2010
Thanks for the reply, Z_Gecko.

Um...0x219 IS the WM_DEVICECHANGE Message...I think.

It does work on all devices, not just drives/volumes, but only gets me half way there. It lets my script know that there's been a change to the hardware configuration, but nothing in the parameters it returns is specific to what the device is.

To be honest, I'm sort of shocked that there isn't an "off-the-shelf" app out there to do this. Surely I'm not the first person to want to open a particular program every time a specific USB device is connected. Heck, itunes pops up every time I stick in my ipod, so it's possible.

Anyone else have any ideas?

Z_Gecko
  • Guests
  • Last active:
  • Joined: --

but nothing in the parameters it returns is specific to what the device is.

according to MSDN it should be.
every WM_DEVICECHANGE message with wParam set to DBT_DEVICEARRIVAL should get as lParam a pointer to a structure identifying the device inserted.
http://msdn.microsof...y/aa363205.aspx

http://msdn.microsof...y/aa363246.aspx

rktboy
  • Members
  • 8 posts
  • Last active: Jan 25 2010 11:14 AM
  • Joined: 18 Jan 2010
Hmmm, ok. I think we're making progress.

Alright, using this script...

OnMessage(0x219, "notify_change") 
Return 

notify_change(wParam, lParam, msg, hwnd) 
{ 
MsgBox, %wParam% %lParam% %msg% %hwnd% 
}

...and adding (or removing) a USB device, I get these Parameters:

wParam = 7
lParam = 0
msg = 537
hwnd = 3998316

hwnd is a windows handle so I'm not really concerned with that one.

The msg parameter identifies the message as a WM_DEVICECHANGE message, but we already knew that

The wParam is always 7 in my tests, which is DBT_DEVNODES_CHANGED (A device has been added to or removed from the system) and then the lParam is always 0 (which it always is when the wParam is DBT_DEVNODES_CHANGED).

Sooooo, how do I go about getting that wParam changed to 0 (DBT_DEVICEARRIVAL) so that I can the lParam which, hopefully, will identify the specific device?

I realize I probably sound like a noob, but I'm trying, honest!
.
.
.
.
I just had a thought. During my tests, If the above script has opend a message window, it seems to ignore other messages until I close it. Is it possible that that's getting in the way of me getting the info I need? Like, is the message with the wParam of 0 coming along right after the other but it doesn't show because the message window is still open from the first message? Is there a way to modify the above script to only look for a WM_DEVICECHANGE message that contains a wParam of 0?

rktboy
  • Members
  • 8 posts
  • Last active: Jan 25 2010 11:14 AM
  • Joined: 18 Jan 2010
Harumph,
I tried modifying the script to this:

OnMessage(0x219, "notify_change") 
Return 

notify_change(wParam, lParam, msg, hwnd) 
{ 
    if wParam = 0
         MsgBox, %wParam% %lParam% %msg% %hwnd% 
}

But now no message pops up when I insert or remove a USB device, which means no message with that wParam is being sent.

Do I have to do something else to get the WM_DEVICECHANGE message that contains a wParam of 0?

garry
  • Members
  • 2955 posts
  • Last active: Today, 08:57 AM
  • Joined: 19 Apr 2005
another idea, 3 possibilities which device is connected on USB (here : NokiaE51 mobilphone)
----- 3 possibilities to search=
-serialnumber=1664430621                         ;--- sd-cardnumber in nokia
-run %comspec% /k label e: Nokia_E51             ;--- write name to sd-card
-directory  e:\others\contacts                   ;--- existing directory

<!-- m -->http://www.autohotke...013.html#320013<!-- m -->



rktboy
  • Members
  • 8 posts
  • Last active: Jan 25 2010 11:14 AM
  • Joined: 18 Jan 2010
Thanks for the reply, but the way I'm using the PSP, it doesn't mount as a drive/volume.

To come at this from another angle, is there some way I can use devcon.exe? For instance, can I use the data produced by a devcon command in a script?

I've noticed that using the command devcon status * produces a list of all the devices attached to the computer that are currently active. Sure enough, the PSP shows up when it's connected, and doesn't when it's not. Is there a way to take that list and use it in my script? For example:

-OnMessage(0x219)
-run, devcon status *
-If PSP exists, continue. If it isn't, don't
-Run rest of script yadda yadda

I know most of that isn't proper syntax but it's the gist of what I'd like to do. What would a script to do that look like?

garry
  • Members
  • 2955 posts
  • Last active: Today, 08:57 AM
  • Joined: 19 Apr 2005
sorry, no idea about devcon, search also in forum

<!-- m -->http://support.microsoft.com/kb/311272<!-- m --> ; german

Device Console Help: (Hilfe zu DevCon)
devcon.exe [-r] [-m:\\<machine>] <command> [<arg>...]
-r if specified will reboot machine after command is complete, if needed. (Nach Ausführen des Befehls neu starten)
<machine> is name of target machine. (<machine> = Name des Zielcomputers)
<command> is command to perform (see below). (<command> = auszuführender Befehl)
<arg>... is one or more arguments if required by command. (<arg> = Befehlsargumente)
For help on a specific command, type: (Für Hilfe zu einem bestimmten Befehl Folgendes eingeben) devcon.exe help <command>
classfilter          Allows modification of class filters. (zum Ändern der Klassenfilter)
classes              List all device setup classes. (Anzeigen aller Setupklassen)
disable              Disable devices that match the specific hardware or 
                       instance ID. (Deaktivieren der Geräte mit entsprechender Hardware- oder Instanz-ID)
driverfiles          List driver files installed for devices. (Anzeigen der für Geräte installierten Treiberdateien)
drivernodes          Lists all the driver nodes of devices. (Anzeigen aller Treiberknoten der Geräte)
enable               Enable devices that match the specific hardware or 
                       instance ID. (Aktivieren der Geräte mit entsprechender Hardware- oder Instanz-ID)
find                 Find devices that match the specific hardware or 
                       instance ID. (Suchen von Geräten mit entsprechender Hardware- oder Instanz-ID)
findall              Find devices including those that are not present. (Suchen aller Geräte)
help                 Display this information. (Anzeigen dieser Informationen)
hwids                Lists hardware ID's of devices. (Anzeigen der Hardware-IDs)
install              Manually install a device. (Gerät manuell installieren)
listclass            List all devices for a setup class. (Anzeigen aller Geräte einer Setupklasse)
reboot               Reboot local machine. (Neustart)
remove               Remove devices that match the specific hardware or 
                       instance ID. (Entfernen der Geräte mit entsprechender Hardware- oder Instanz-ID)
rescan               Scan for new hardware. (Nach neuen Geräten suchen)
resources            Lists hardware resources of devices. (Anzeigen der Hardwareressourcen)
restart              Restart devices that match the specific hardware or 
                       instance ID. (Neustarten der Geräte mit entsprechender Hardware- oder Instanz-ID)
stack                Lists expected driver stack of devices. (Anzeigen des Treiberstapels)
status               List running status of devices. (Anzeigen des aktuellen Gerätestatus)
update               Manually update a device. (Manuelles Aktualisieren eines Geräts)
UpdateNI            Manually update a device without user prompt (Manuelles Aktualisieren eines Geräts ohne Benutzerinteraktion)
SetHwID              Adds, deletes, and changes the order of hardware IDs of root-enumerated devices. (Hinzufügen, Löschen und Ändern der Reihenfolge von Hardware-IDs)


dmatch
  • Members
  • 255 posts
  • Last active: Today, 02:23 PM
  • Joined: 15 Oct 2007
I don't know if this helps, but this link:

<!-- m -->http://www.dotnet247... ... 17435.aspx<!-- m -->

shows that wParam should be 0x8000 for the DBT_DEVICEARRIVAL. When that wParam shows up then lParam should have a pointer (non-zero of course) to a DEV_BROADCAST_HEADER.

The link is to a post from a person doing C++ programming who had a similar desire to detect when a new device arrived. Sure wish I knew more about it so that I could help more but....I'm not very good at and don't know much about C++.

Actually, all l really knew how to do was google:

value DBT_DEVICEARRIVAL

HTH,

dmatch

dmatch
  • Members
  • 255 posts
  • Last active: Today, 02:23 PM
  • Joined: 15 Oct 2007
Here is a link to the MSDN info for WM_DEVICECHANGE:

<!-- m -->http://msdn.microsof.../aa363480(VS.85<!-- m -->).aspx

It shows DBT_DEVICEARRIVAL to be 0x8000 also.

I see the same results as you, where the only 0x219 messages I am getting have wParam=7 and lParam=0. Those would be DBT_DEVNODES_CHANGED events. About those it is said:

Remarks

There is no additional information about which device has been added to or removed from the system. Applications that require more information should register for device notification using the RegisterDeviceNotification function.


However, about RegisterDeviceNotification it says:

The DBT_DEVICEARRIVAL and DBT_DEVICEREMOVECOMPLETE events are automatically broadcast to all top-level windows for port devices. Therefore, it is not necessary to call RegisterDeviceNotification for ports, and the function fails if the dbch_devicetype member is DBT_DEVTYP_PORT.


So, it "appears" that we are not getting the DBT_DEVICEARRIVAL event notification from Autohotkey. I am not using the latest Autohotkey so maybe someone else (or you) can verify that the latest version acts the same. Also, it appears that RegisterDeviceNotification would be of no use.

I have used Winspector Spy to track messages to a test GUI and it shows no DBT_DEVICEARRIVAL events at all.

I too have a need for doing something similar to what you are trying to do so I will keep looking into it.

dmatch

rktboy
  • Members
  • 8 posts
  • Last active: Jan 25 2010 11:14 AM
  • Joined: 18 Jan 2010
I wonder what "top-level windows" means. Why is AHK not a "top-level window"? Can it be made into one?