Reputation: 60411
When a user double clicks a file to start it, I need to carry out a custom action if the file meets certain criteria.
In WindowsXP, detours could be used to hook ShellExecuteEx in explorer.exe, and the file name was accessible. I need to do something similar in Windows 7 and 8.
How can I execute some code when files are double clicked, and have the name of the file available?
I need a method that will continue to work if Windows Updates patch explorer.
Upvotes: 4
Views: 2548
Reputation: 1377
I faced similar problem when i try to hook all the execution calls to a particular drive letter. Initially i hooked shellexecuteex with detour library. This failed in windows 7 as the explorer started using direct kernel32.dll or ntdll equivalent calls skipping the shell API layer. Better way to handle custom handling on the application execution is by implementing a shell folder. I hide the actual drive letter by adding a registry key. Then i implemented a shell folder which displays the content of the hidden drive letter content. By this method, i was able to get better control of the items displayed in the explorer eventually capture the double click. Eventhough you need to write a significant amount of code to the make the UI identical to explorer, this is the more appropriate & proper documented approach for your requirement.
Upvotes: 2
Reputation: 2111
So basically you want to do what an antivirus does, right? intercepting all I/O calls? You want something called filters
(Last time I used it was on my old XP machine). Filters are the way to go if you don't want to write your own driver!
This is far better than all those nasty API hooks. From MSDN:
you see that "Minifilter A"? That's probably where you wanna hangout for the next couple of days!
Upvotes: 4
Reputation: 2984
A brief check using procmon
shows that every time a file is activated by explorer (by either double clicking it or by pressing enter). Explorer searches for HKCR\*\ShellEx\DataHandler
.
DataHandler
is one of many types of windows shell extensions.
So while the documentation states that it's for drag&drop actions it seems that it always calls it when opening a file.
I've followed the How to Create Data Handlers tutorial on how to register one, just with one minor change: I've added the DataHandler
under HKCR\*\ShellEx\DataHandler
with a custom GUID and a corresponding CLSID
entry and linked it to a dll that does nothing. And now it was loaded every time I've clicked or "entered" a file. I didn't go as far as implementing all the required interfaces but according to the documentation:
The Shell initializes the handler through its IPersistFile interface. It uses this interface to request the handler's class identifier (CLSID) and provides it with the file's name.
So theoretically it should be accessible to a dll that implements the required interface, and you could just access the file name on each access execute the custom action and do nothing else.
I don't currently have the time to write such a dll myself( maybe later) but it looked like a nice direction that you can explore.
Upvotes: 8
Reputation: 10648
A bit out of my depth, but here goes. I read something ages ago that explorer calls SHELL32!CExecuteApplication::Execute
each time an application is double-clicked. No real documentation about it exists though. If you trace the call, it ends up calling CreateProcess
. I suppose you could hook that. However, CreateProcess
would not work if the application is already running and it is a single-instance application, like MS Outlook for example. This function only gets invoked if explorer needs to create a process.
Upvotes: 2