Why does Windows Shell context menu handler break power-user menu (Win+x) on Windows 8/10? - windows

My custom Windows shell context menu handler works like a charm, for all Windows versions from XP to 7, but on Windows 8, 8.1 and 10, installing it breaks the Win+X menu (sometimes called "Power user menu", or "Quick Access menu", or "WinX menu"): when hitting Win+X, the menu is displayed as expected, but its items do not work anymore (nothing happens when I click on them), except for the last four items at the bottom which still work as expected ("Search", "Run", "Shut down/Sign out", "Desktop"):
I quickly found out on Google that it was a well known issue for a great number of shell extensions that were not "compatible" with Windows 8/10. But sadly, I only found application users talking about this issue and its "solutions", and no developer talking about this. And the two "solutions" proposed by these users were:
Unregistering this shell extension
Uninstalling the app that registered this shell extension (which leads to solution 1...)
See for example this, this, or this to read people talking about this issue.
Note: my shell extension is applied for the * file type, which means all files.
Several days later, I found the cause of this issue in the shell extension source code, so I thought it would help other developers to share it on StackOverflow, as a self-answered question (I didn't find this question). See answer above.

I first looked at the shell extension sample code provided by Microsoft (which doesn't cause this issue), compared it with my code, and progressively replaced parts of my code with Microsoft's code and testing it after each replacement.
I found out that what prevents power-user menu to work is what you return in method InvokeCommand() from IContextMenu interface: if your extension cannot handle the given verb, it shall always return E_FAIL so that Windows tries with other implementations of IContextMenu (see Microsoft documentation for more details). It seems that when a power-user menu item was clicked, Windows first called my extension (* file type), then since it didn't return E_FAIL for this unknown verb, Windows thought that my shell extension has processed this event, so it didn't process it through the nominal power-user menu callback.
By the way, three things seem very weird to me:
Why does Windows even try to process this power-user menu event with a shell file extension? Is this menu coded using the same design/mechanism as any other Explorer's file contextual menu?
Why does this bug didn't produce more side-effects yet? I mean this should have broken the whole shell extension system right from the beginning, no?
Why do so many applications has this bug? (meaning why so many applications do not return E_FAIL as expected?). It's been a while now that I've written this code, I can't really remember where it comes from, but I guess it comes from a Microsoft sample or any Microsoft employee tutorial (far too Microsoft-oriented to be coded by yourself). If it's the case, that may answer the question why so many shell extensions cause this issue...
I would be interested if someone has some ideas to share about this subject!
By the way, I hope my post can help other developers. When looking at the new Microsoft example that works like a charm, I was first afraid having to rewrite all my shell extension from their sample without knowing what was wrong in my code!

Related

Mimic Win 7 Favorites on Windows 10 (Shell Namespace Extension)

Hello dear stackoverflow friends
A few months ago I asked you a question about QuickAccess (Pin/Unpin). Unfortunately we are still facing this issue (Unable to unpin virtual objects). After having called Microsoft Support a few times, they replied us we should subscribe to premier support... Too expensive for a small company.
So we have decided to Mimic the Windows 7 Favorites in our Shell Namespace Extension.
No big deal in the Explorer, calling ShellExecuteEx with view's handle and lnk's target object absolute pidl works like a charm.
Too good to be true, yeah, as it is not working as expected in IFileDialogs...
First the lnks (wrapped in a virtual object, but parsing name is Filesystem Path) weren't for obvious reasons shown in the dialogs. So we tried with attributes such as "SFGAO_FOLDER", "SFGAO_FILESYSANCESTOR" etc. but then the shell was calling IShellFolder's EnumObjects and that's not what we want.
So we decided to have a go with the Interface IObjectWithSite, implementing it in our Favorites' folder. We were then able to consume events from IFileDialogs such as OnSelectionChange. Then we tried the same method as in the explorer, getting view handle (first querying IOleWindow interface, getting window handle, creating view in parent IShellFolder using window handle) and calling ShellExecuteEx... And the result is.. A big application (Notepad, Word etc.) crash and a new Explorer Window with the right virtual object selected.
Probably is my approach too complicated, have you got any ideas?
Thanks a lot!
Thank to Simon, I was able to find a solution, still work in progress. The issue is that the IContextMenu, IContextMenu2 and also IContextMenu3 interfaces are implemented in the solution. On Windows 7, the .lnk menu handler was called, fine, on Windows 10 on the other hand you need to call SHCreateDefaultContextMenu, then merging the menu handlers (SHCreateDefaultContextMenu will then Call IShellFolder::GetUIObjectOf with IID_IQueryAssociations). So the code was dated... Thanks!

Adding buttons to Finder toolbar?

Dropbox has the option of adding a button to the Finder toolbar. It even appears in the 'Customize Toolbar...' window.
 
I can't find any documentation on how this sort of thing is done.... Does anyone know how to do this, or can anyone point me towards some documentation or sample code?
EDIT ONE:
I guess a start would be finding the location of the existing icons, and any related code.
I noticed that Dropbox has files in Library/DropboxHelperTools/Dropbox_u501 called mach_inject_bundle_stub.bundle and FinderLoadBundle which might be doing the magic. Dropbox is also putting the 'tick' badge on Finder icons. This code might be involved: github.com/rentzsch/mach_star
EDIT TWO:
A Dropbox talk by Rian Hunter about the process is here, at around 15:30
http://blip.tv/pycon-us-videos-2009-2010-2011/pycon-2011-how-dropbox-did-it-and-how-python-helped-4896698
Looking in the DropboxBundle file in the Dropbox_u501 shows the icons and some compiled code. The code suggests that Rian Hunter is the author: http://twitter.com/timeserena
Rian has his own version of the Mach Star code on his github - https://github.com/rianhunter/mach_star - tho it seems much older
EDIT THREE
There was a 'Code Injection Workshop' at Stanford a few weeks ago - http://stanfordacm.com/past/ - hosted by Rian. If anyone has notes from this please let me know!
You can use Finder Sync app extension(Starting in OS X v10.10).
A Finder Sync extension can:
Add, remove, and update badges and labels on items in a monitored folder.
Display a contextual menu when the user Control-clicks an item inside a monitored folder.
Add a custom button to the Finder’s toolbar.
Dropbox was using undocumented magic. There's no officially supported way to do this; the closest you can get without reverse engineering is Services.
(Update: As of macOS 10.11, what Dropbox was doing is no longer possible at all. System Integrity Protection now prevents code from being injected into system processes, such as the Finder.)
Rian's talk at PyCon 2011 (on blip.tv) does not explain anything more than "We reverse-engineered Finder." Although the mach_star stuff is valuable, it still doesn't explain how to get a sidebar icon working. And the Stanford 'Code Injection Workshop' has not posted any content about this method.
I've nm'd and class-dump'd both bundles that Dropbox installs for each user under /Library/DropboxHelperTools, and the output provides good insight. If I get back to it, I'll finish my research and post it. Odds are, it won't be for some time, so here's hoping this nudge helps someone else.
An easy intermediate answer that may be adequate for some people is to simply create icons that look like buttons.
e.g. I created 'new text file here' and 'new terminal here icons' for my Finder:
The method can be found here.
The disadvantage is that they must be square and do not have animations/menus or show up in 'customize toolbar' etc.

IsWindow(activeX.GetSafeHwnd()) always false after upgrade to VS2010

I have an MFC application that uses an ancient (circa 1999) third-party ActiveX control.
Since upgrading the project from VS2008 to VS2010, I'm having problems...
In the OnSize handler of the parent dialog IsWindow always returns false for the handle returned by control.GetSafeHwnd(), even when GetSafeHwnd() returns a non-NULL value. The rest of the control's parent dialog is displayed fine, but it doesn't seem to respond to any input.
I've seen this article, but GetSafeHwnd() isn't returning NULL in this case (after the first time that it is called, which is before the control is instantiated).
The control does cause the trace message "Control wants to be windowless" to be output when it's loaded. However it also does this when compiled in VS2008, so this may be a red herring. Searching for this message points me to creating a class derived from COleControlSite, and denying the control windowless-ness, but it seems there are no good example of this available, and as I say, it's not clear that this is really the cause of the problem.
I've also found this issue mentioned on MSDN's VS2010 porting page:
"An ActiveX control compiled by using Visual C++ 6.0, when embedded in
a dialog box in a project developed by using Visual C++ 2010, may
cause your program to assert at run time. In this situation, open the
ATL or MFC project associated with the ActiveX control in Visual C++
2010, and recompile it.. The assert will be in the file occcont.cpp,
on this line in source: ASSERT(IsWindow(pTemp->m_hWnd))."
I assume that there's something about VS6-compiled ActiveX controls that causes the window handles to be treated as invalid by the current Win32 implementation of IsWindow. The suggested solution is of course unhelpful as it's a third-party control, and we can't recompile it.
Has anyone managed to get around this?
I've already found solutions for VS2010 projects not running on Windows 2000, and errors linking to ODBC, but don't seem to be able to find anything on this one.
Thanks,
Chris
I didn't find a solution to this in the end - upgraded the controls to a VS2010-compatible version.
For what it's worth: if you don't care whether the control will appear transparent or not, you may force the control to have a window anyway - even though it can operate without a window.
You see, the ActiveX control must first ask the container (the window which will host the control) if it's okay to be activated without a window. This is simply because not all containers support windowless activation.
If this interface (IOleInPlaceSiteWindowless) returns okay then it proceeds with this special windowless activation, if not a window will be created for the control as normal.
Disclaimer:
I don't know if this 'unnecessary' window will make the assertion failure go away. In other words: I don't know if the window handle is passed down 'deep' enough into the AX control.
More about the IOleInPlaceSiteWindowless interface:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms682300(v=vs.85).aspx

Tools/code to automatically click ok on dialogs

We have an 'enterprisey' system with a scheduling component which gets floored if any dialogs come up. If any modal dialogs come up in the processes it is running, it gets 'paused' and can't kick off any new processes.
Excuse me a minute ...
*goes outside*
*laughs*
*cries*
*comes back*
.. ahem ... so anyway we need some sort of tool/technique that can lurk in the background and automatically detect specific dialogs and click OK on them. Any recommendations?
The offending system is running in Windows XP.
(NB: changing the third-party-enterprisey system or making its developers sit on the naughty step until they improve it are not options in the short term)
From this similar question I found:
Buzof by Basta Computing
which did the trick.
There is also a product called DialogDevil which looked promising but didn't work in our situation for some reason.
AutoIT is absolutely perfect for this. You can use the tool to help identify the dialog, write your own simple code and distribute the "auto clicker" via exe. It lurks in the background by running from the task tray.
DialogDavil will require exact same parameters on your dialog (for which you want buttons to be autoclicked) every time that same dialog pops up. And thats why it didnt work for me in first pass. Then i changed the control file at the following path to remove the changing items (a text box text in my case)
C:\Users\userName\AppData\Roaming\DAIR\DialogDevil\control.xml
And then it worked like a charm.
HTH,

Windows7 explorer context strip hook?

Hy everybody,
I'm wondering if it's possible to add a new button via C++ or C# to windows 7 explorer "context strip"(don't know if this is correct name) - like on picture below.
My reason for this is because a lot of times I'm switching on&off "Show hidden files, folders and drives" functionality under Tools->Folder option->View. Therefore i want to simplify this process with a click of a button.
I was looking into ShellExecteEx function, but I am not sure I can do that. Can Anybody direct me in right direction?
thanks,
regards
I highly recommend using AutoIt for this task. Second URL comes complete with examples of how to insert buttons in various programs - however, be sure to read complete topic for misc. updates to the provided code.
See:
http://www.autoitscript.com/forum/index.php?showtopic=9517
Btw: I misread topic to begin with; gui 'context' related material in Windows is often taken to deal with right-click menus
Edit: limit on urls for new users on Stack Overflow mean I had to cut out some of less essential links - google away.
To answer part of the question, I think it is possible as for quite some time we've seen small programs to add a "New Folder" button to the explorer. I think those still works with Win 7.
Look at http://tools.tortoisesvn.net/StExBar for example
[Edit] Forgot to clarify that Source Code for StExBar is on Google Code

Resources