Why is IExplorerCommand::Invoke() no longer being called? - c++

I have created a File Explorer context menu extension that uses the IExplorerCommand interface to add menu commands to the Windows 11 context menu.
This has been working fine, but after the last Windows update, it no longer works properly.
Although the menu commands still appear, nothing happens when I click on any of them. I've added logging and I can see that IExplorerCommand::Invoke() is no longer being called.
Strangely, if I select the "Show more options" menu to get the legacy Windows 10 context menu, the commands work fine from that menu, it is only in the new Windows 11 context menu that they don't work.
I have tried running File Explorer in a debugger while selecting my menu commands, and I get lines like this in the output window when I click on the command:
onecore\com\combase\dcomrem\stdid.cxx(726)\combase.dll!00007FF9EB9947F5: (caller: 00007FF9C22E1E38) ReturnHr(2627) tid(67bc) 8001010E The application called an interface that was marshalled for a different thread.
I'm guessing this is the reason why my commands are not being called. Does anyone have any suggestions for what is causing this? Could it be a bug in File Explorer?
I've tried both STA and MTA threading models, and changing this made no difference.

Well, after wasting hours on this I finally have a solution!
My code was based on the PhotoStoreContextMenu sample code here:
https://github.com/microsoft/AppModelSamples/tree/master/Samples/SparsePackages/PhotoStoreContextMenu
This uses the Windows Runtime C++ Template Library (WRL), and defines the base classes used by the class like this:
class TestExplorerCommandBase : public RuntimeClass<RuntimeClassFlags<ClassicCom>, IExplorerCommand, IObjectWithSite>
The change that fixed it for my code was to use WinRtClassicComMix instead of ClassicCom, i.e.
class TestExplorerCommandBase : public RuntimeClass<RuntimeClassFlags<WinRtClassicComMix>, IExplorerCommand, IObjectWithSite>
I'm pretty sure this problem started when I installed KB5019509, which is the Windows update that changes File Explorer so that it now has tabs.
Note: this problem only happens for IExplorerCommands created in the plug-in for submenus, the top level commands that are defined in the APPX file work fine.
Also note that although this change does fix the problem with Invoke() not being called, it does introduce a new problem which is that IOleWindow::GetWindow() no longer works so it is not possible to get the parent HWND. (See Calling IOleWindow::GetWindow() from IExplorerCommand::Invoke() is giving error 8001010d (RPC_E_CANTCALLOUT_ININPUTSYNCCALL)).

Related

VS2022 Community crashes when adding Class to MFC Dialog

I am facing a very consistent and persistent problem with Visual Studio 2022 Community Edition.
In an MFC project I open the Resource File and add a new Dialog. Then I place some standard controls and rename the dialog resource from its default name to a new ID.
Then I save and try to assign a Class to the dialog by right-clicking on the dialog and choosing 'Add Class'. Then the 'Add MFC Class' window appears, I enter the Class Name and click [OK].
It appears it creates the class on the File System and then VS2022 crashes completely!
I have disabled all addins in case an addin could be causing the problem but it happens every (almost) every time even without plugins. The only time I manage to get it to work is if I save, close all code editors, exit VS2022, restart it and immediately try to add the class. Another piece of information is that I have changed the MFC dialog template with a different one but it does not seem to bother it when I get it to work. Also intelliSense is completely disabled.
How can I debug this and identify the root cause of this crash?
There's a fair chance that you can't do anything in an effective fashion. VS2022 isn't an open source project, where you can easily pinpoint a crash to a specific line of code and fix it yourself.
But the good thing is that you don't need to. Just use the feedback channel VS2022 provides:
Usually a Microsoft employee will reply within a few days and maybe a fix will be included in the next preview version. Only now and then it can take some month to get a bug resolved.

Windows 10 - Taskbar - Add item to context menu for each program

I need a context menu entry for each program in the taskbar. Want to add an entry which immediately terminates (UNIX/Linux-like signal SIGKILL) the process. There a lot of questions on this site, how it's done for the explorer or desktop. But is it also possible to add such an option to the context menu of the taskbar?
To clarify the question, according to my comments:
The current problem:
I have a program (not Firefox) which randomly crashes. The program is in fullscreen mode. But if I want to close the window of the program with Exit window, it takes a long time that Windows kill the program. When I try to open the Task Manager the program immediately grabs the user input and I have no chance to interact with the Task Manager. So my solution was to add a context menu item in the taskbar to quit the task of the program. According to a user comment, I test the option "Always on top" in the Task Manager. Didn't know that. But I haven't tried it yet. I'm also interested for further projects, if there is a function in WINAPI or Windows Registry to add an item.
To avoid down-votes:
I'm not interested to hack Windows or the application. Solutions with code injection are taboo for me. Want a clean solution, if even possible. I want improve my Windows version. Adding also some additional information (process information) in the context menu.
Have currently found this (Registering shell extension handlers).
Has anybody used this before? I think it's sound promising.
There is no API to extend this menu like that. Applications can customize the top of the menu with ICustomDestinationList but there is no way to add entries for all applications.
For a personal use project, you could inject a .dll in the taskbar instance of Explorer.exe and add your item after figuring out the address of the function where the menu is created. This address can of course change after you upgrade Windows so it is not a very generic solution. Using the public symbols might help but you still have to expect it to break from time to time when Microsoft changes part of their taskbar code.
You don't need to change code in explorer.exe, because you can close a program by doing the keyboard shortcut: Alt + F4.

CRichEditCtrl from resource loads 1.0 instead of 2.0

I'm trying to update my application to use RichEdit 2.0; it's been using 1.0 since forever. Per the Microsoft documentation, I've changed AfxInitRichEdit() to AfxInitRichEdit2(), and I changed the class in the resource file from RICHEDIT to RichEdit20A (which is correct for this application). There is only one richedit in the resource file.
The application fails when I try to do anything with the window that includes this richedit. The dialog creation fails somewhere inside of ::CreateDialogIndirect(), and although I put breakpoints in CRichEditCtrl::Create and also on the class I derive from it, those breakpoints do not trip.
Out of frustration I tried calling AfxInitRichEdit() again and also calling AfxInitRichEdit2(). The application works! The breakpoints I put in do trip--but only on controls I create dynamically, not the one from the resource file. And when I run Active Window Spy, I see that the richedit created from the resource file somehow has a class of RICHEDIT even though I explicitly said RichEdit20A, and yet the dynamic ones are RichEdit20A as intended.
_RICHEDIT_VER is 0x210, and I'm using Visual Studio 2013.
I just can't figure out why CreateDialogIndirect() is making a RICHEDIT control--or trying to make one and failing, if I don't call AfxInitRichEdit()--instead of a RichEdit20A in spite of explicit instructions to the contrary. Any ideas?
Well, I feel stupid. There's a script that runs as part of the build process to update some resources, and for some reason that script has sometimes gotten confused between the debug and release versions, and copied resources from the release build into the debug build. I don't know why that happens and it's an issue for another day, but the upshot is the .rc file I had changed was getting replaced with another one.
Building the release version with the changes, and then building the debug version again, solved the problem.

Change selection in explorer window?

I have a "Show in folder" button which executes the following:
explorer.exe /select,"C:\dir\somefile.txt"
In Win7 this works great, a new window is always opened, but in XP, if "C:\dir" is already open, this window is reused but the selection is not changed to "somefile.txt".
This is not the expected behaviour from the point of view of the user, he expects to see "somefile.txt", but instead sees another file, and that might confuse him. At worst, he might assume that something went wrong and the file was not created.
So I need to somehow force Explorer in XP to always select the file I give it in the cmd line, or not to reuse the window.
Can anyone suggest a way to do this (different cmd parameters, maybe COM automation)?
As I don't have Windows 7, I can't confirm if this works the way you expect on subsequent Windows versions. But on my XP machine:
explorer.exe /e,/select,"C:\dir\somefile.txt"
Works exactly the way I think you'd want by opening a new explorer window each time with the right selection and avoids that confusing behavior you described.

How to hide/collapse main menu in a win32/mfc application

I always been interested on how we can accomplish this (hide/show the main menu using the alt key), and now some applications do this very often. One that really please me is the visual studio 2010 with this plugin:
http://visualstudiogallery.msdn.microsoft.com/bdbcffca-32a6-4034-8e89-c31b86ad4813?SRC=VSIDE
(firefox also do this, but i think that is in a different way)
Can anyone explain me how this can be achieved or if you known of any sample project that demonstrate this please tell me.
(what i can see in some replies here in stack is that we have to destroy the menu when is to hide and create it when is to show?! but this seems a bit bad solution...)
Thanks
The SetMenu function lets you add/remove the menu from the window. It does not destroy the menu.
Note that most applications which have the dynamic menu hide/show behavior are not really showing a menu. They're showing a custom control that looks like a menu.
You might also take a look at MFC support for auto hiding menus. I used this technique and it worked really well.
in CMainFrame::OnCreate I did
m_wndMenuBar.ShowWindow(SW_HIDE);
which actually works fine in our project
I stumbled across a related pit fall that will show a hidden main frame without your consent:
Whenever the focus for a child window in an MDI application changes (e.g. due to right clicking in it), the function CMDIChildWnd::OnMDIActivate will be called, which in turn shows the main menu (even if it was removed or destroyed previously) of the MDI application.
This works basically by adding the saved main manu from the underlying's CMDIChildWnd m_hMenuShared variable.
A quick&dirty hack to prevent this, is setting m_hMenuShared to NULL (it's protected in CMDIChildWnd so this needs a custom derived child class of CMDIChildWnd) for all child frames.