MediaArea / MediaInfo

Convenient unified display of the most relevant technical and tag data for video and audio files.
https://MediaArea.net/MediaInfo
BSD 2-Clause "Simplified" License
1.37k stars 160 forks source link

Compatible with Win11 new context menu (suggestion) #671

Open userzzzq opened 1 year ago

userzzzq commented 1 year ago

Compatible with Windows11 new context menu

cjee21 commented 1 year ago

It will be great if MediaInfo can integrate with the new Windows 11 context menu like other apps such as Mp3tag. Untitled

Looks like it can be implemented by non-Store apps too according to this post:

Apps extend the menu with IExplorerCommand + app identity. Unpackaged Win32 apps can use Sparse Manifests. IExplorerCommand support extends back to Windows 7.

JeromeMartinez commented 1 year ago

It will be great if MediaInfo can integrate with the new Windows 11 context menu like other apps such as Mp3tag.

We don't use (yet) Win11 I didn't remark that MediaInfo is hidden in the "Show more options" part :(.

Thermalzombie commented 10 months ago

Switched to Win11 no context menu item please fix and could you add a dark mode and I am using the installable version not store app version. Thankyou.

OlJohnny commented 5 months ago

bump

integration into the new win11 context menu would be really great!

if someone might me able to point into the right direction, i could try implementing it myself ^^

JeromeMartinez commented 5 months ago

if someone might me able to point into the right direction,

Main issue is this topic ;-).

OlJohnny commented 5 months ago

microsoft seems to have a sample project for win11 context menu stuff

cjee21 commented 5 months ago

if someone might me able to point into the right direction, i could try implementing it myself ^^

I don't have experience with sparse packages, Win11 context menu or MediaInfo codebase but from my understanding, the following is needed for an application that is not packaged as a MSIX.

Microsoft resources: https://blogs.windows.com/windowsdeveloper/2021/07/19/extending-the-context-menu-and-share-dialog-in-windows-11/ https://blogs.windows.com/windowsdeveloper/2019/10/29/identity-registration-and-activation-of-non-packaged-win32-apps/ https://learn.microsoft.com/en-us/windows/apps/desktop/modernize/grant-identity-to-nonpackaged-apps https://github.com/microsoft/AppModelSamples/tree/master/Samples/SparsePackages https://github.com/xandfis/W11ContextMenuDemo

For more examples, maybe can look at NanaZip although this one is a MSIX packaged app but it should be using IExplorerCommand.

Can also look at Visual Studio Code or Notepad++ which are unpackaged applications that use sparse manifests to add a Edit/Open with command on Win11 menu although I'm not sure if these two work properly.

cjee21 commented 5 months ago

if someone might me able to point into the right direction, i could try implementing it myself ^^

One more resource that might help: https://community.mp3tag.de/t/context-menu-on-windows-11/54629/7 Expand the "Implementation Details" section of that post.

cjee21 commented 5 months ago

@JeromeMartinez I have figured it out. It is possible. I made a PoC attached below. Tested to be working on a VM and it even works for folders.

Screenshot 2024-05-27 203922 Screenshot 2024-05-27 203948

It consists of two main things:

  1. MediaInfo_ContextMenu folder contains the Visual Studio solution that builds MediaInfo_ContextMenu.dll which is a shell extension for implementing IExplorerCommand to add the entry to context menu of File Explorer.
  2. MediaInfo_SparsePackage folder contains package_contents folder which is the contents of the sparse package/MSIX and MediaInfo_ContextMenu.msix which is built from package_contents by makeappx pack /d .\package_contents /p .\MediaInfo_ContextMenu.msix /nv

WARNING: only do the following on a test machine / VM. I cannot guarantee whether your Windows installation will be messed up or not. To make it work:

  1. Sign with signtool.exe at least MediaInfo_ContextMenu.msix with a certificate that is trusted by the test machine. MediaInfo_ContextMenu.dll should be signed too but not necessary to make it work.
  2. Copy MediaInfo_ContextMenu.dll and MediaInfo_ContextMenu.msix to the same folder as MediaInfo.exe and MediaInfo_i386.dll.
  3. Open a cmd in this folder and do rundll32.exe .\MediaInfo_ContextMenu.dll,RegisterSparsePackage.
  4. Verify installation with Get-AppxPackage -Name MediaInfo.
  5. Restart File Explorer or Windows and MediaInfo should appear in the context menu.
  6. To remove, rundll32.exe .\MediaInfo_ContextMenu.dll,UnregisterSparsePackage should work.

There are still things to do if this were to be integrated with official MediaInfo distribution.

  1. The code for the MediaInfo_ContextMenu.dll is made rapidly by copy pasting and modifying existing code from Visual Studio Code, Notepad++ and https://github.com/xandfis/W11ContextMenuDemo. It may need to be refined and also there may be copyright/licensing issues. My aim for this PoC was to get this working as fast as possible and not to write good/proper code.
  2. I am not sure if the code is robust enough since it is quick copy paste and I am not experienced in making shell extensions. In short, I cannot guarantee anything with this PoC, it is just a guide for someone else to implement.
  3. MediaInfo's existing code need to be changed to not use old method of context menu when this new one is in used.
  4. MediaInfo's installer and uninstaller has to be changed to install and uninstall the sparse package.
  5. The installer/uninstaller or the MediaInfo_ContextMenu.dll needs to check if the current Windows version supports sparse packages before attempting to install.
  6. The IExplorerCommand should work from Windows 7 onwards according to Microsoft but I do not know how to make it work on systems that do not support sparse packages. If can get it to work then probably can remove existing context menu implementation.

This is a minimal, very basic implementation. If you look at https://github.com/notepad-plus-plus/nppShell which is the current implementation used by Notepad++, it is very complex. I do not know how complex MediaInfo's implementation needs to be.

For more info about how it works and how to implement, please refer to my 2 posts above.

Mediainfo_context_menu_PoC.zip

cjee21 commented 5 months ago

I am not going to work on this anymore since I am not good at writing shell extensions and I also cannot do anything with the other parts that require changes to MediaInfo's existing context menu, build system, packaging, installer, signing etc. So MediaInfo's members or someone else should take over from here. You can ask me questions about the PoC though.

JeromeMartinez commented 5 months ago

@JeromeMartinez I have figured it out. It is possible. I made a PoC attached below. Tested to be working on a VM and it even works for folders.

@cjee21 thank you! We'll use it as a base when we have time for working on it.

cjee21 commented 4 months ago

Note that it is possible to make multiple files open in a single instance of MediaInfo instead of opening multiple windows when multiple files are selected before invoking the explorer context menu with some code changes if this is desirable.

JeromeMartinez commented 4 months ago

Note that it is possible to make multiple files open in a single instance of MediaInfo instead of opening multiple windows when multiple files are selected before invoking the explorer context menu with some code changes if this is desirable.

This (a single instance) is actually the expected behavior.

cjee21 commented 4 months ago

This (a single instance) is actually the expected behavior.

Outdated:

Then we need to make some changes to the PoC for this Windows 11 context menu when we implement it. Currently it is the same behavior as the existing context menu which opens multiple windows.

EDIT: We should enable Control-flow Enforcement Technology (CET) / Hardware-enforced Stack Protection for this too.

Now implemented in updated PoC. See below.

cjee21 commented 4 months ago

Here is an updated version of the PoC.

Changes:

Here is a video of it in action on a real (not VM) Windows 11 PC. It shows opening a folder, opening multiple files and opening a single file. As a bonus, it also shows the WebView2 PR in action towards the end.

https://github.com/MediaArea/MediaInfo/assets/77721854/d2d4ad47-95bb-46a4-8483-7434d8df096c

How it works is the DLL will be loaded and invoked by Windows File Explorer when the context menu entry is clicked. The DLL then parses the selected items and executes MediaInfo.exe, passing the item paths as command line arguments. Therefore, this should work on the Qt version as well.

A reminder that this PoC contains a lot of copy-pasted codes and even AI generated codes that are not thoroughly checked by me.

Mediainfo_context_menu_PoC_v2.zip

JeromeMartinez commented 4 months ago

Here is an updated version of the PoC.

Thank you a lot, it helps to have a PoC.

How it works is the DLL will be loaded and invoked by Windows File Explorer when the context menu entry is clicked.

We could add the new DLL entry point to our "mouse over" DLL, as we already have a DLL loaded by MediaInfo (when the option is active).

A reminder that this PoC contains a lot of copy-pasted codes and even AI generated codes that are not thoroughly checked by me.

We'll peek what is really useful and understood by us.

cjee21 commented 4 months ago

We could add the new DLL entry point to our "mouse over" DLL, as we already have a DLL loaded by MediaInfo (when the option is active).

From my understanding (I'm not an expert in this), this new context menu DLL can also be used for Windows 7 and newer. So maybe can completely replace the current context menu implementation and gain the advantage of opening multi files in a single instance for all Windows versions. However, seems that to achieve that, we need two different methods of registering the DLL as starting with some version of Windows 10 and later, it is done by registering a signed sparse package (this method is needed to appear on Windows 11 new menu) while older Windows use traditional DLL registration. The Notepad++ project's latest implementation seems to be doing this. This PoC is not based on their latest implementation.

cjee21 commented 4 months ago

Also remember to remove the current context menu implementation when using this new DLL implementation or else there will be duplicate entries in the 'classic'/'Show more options' context menu. Screenshot 2024-06-21 011707

cjee21 commented 1 month ago

Since it seems there is no much progress on this issue and there are currently many active PRs on the GUI side (don't want to make more changes there and risk many merge conflicts), I spent some time on this issue and brought the previous PoC into a deploy-able state for testing and as more proof of concept of what is possible. I've put it here: https://github.com/cjee21/MediaInfo/tree/Windows-GUI-test. More details are in the README of that branch.

At the moment, the new context menu shell extension is only implemented for Windows 11. The shell extensions settings in MediaInfo preferences is not yet updated to handle this new shell extension so toggling that on Windows 11 may have unintended effects.

JeromeMartinez commented 1 month ago

Since it seems there is no much progress on this issue and there are currently many active PRs on the GUI side (don't want to make more changes there and risk many merge conflicts),

Sorry about the delay in handling your PR (which are very appreciated), it is a matter of agenda issue on our side, I hope to handle them soon.

I've put it here

thank you!

At the moment, the new context menu shell extension is only implemented for Windows 11. The shell extensions settings in MediaInfo preferences is not yet updated to handle this new shell extension so toggling that on Windows 11 may have unintended effects.

this is part of the reasons we are cautious, it can be messy for lot of people if we don't implement it well.

cjee21 commented 1 month ago

Here is a video of the current state of the branch linked above. It shows from before installation to after uninstallation on a physical Windows 11 build 22631 PC.

https://github.com/user-attachments/assets/d3a81984-0b2f-40d5-bd30-d8318f2e736d

The README of the branch has been updated with mode details too.

JeromeMartinez commented 1 month ago

Here is a video of the current state of the branch linked above.

thank you!

cjee21 commented 3 weeks ago

Made some more changes to the branch. The README is updated with details.

Now the preferences for Explorer extension is greyed out on Windows 11 since shell extensions are part of the application package on Windows 11 and will always be enabled as long as the application is installed. The previous context menu is disabled on Windows 11 to ensure no duplicate entries. On previous Windows versions, the old context menu and behaviour is maintained. Screenshot 2024-10-02 215816

The sparse package and app identity is now implemented properly unlike some other apps/examples on GitHub. The application has an app identity / package name as can be seen in Task Manager and its taskbar icon is displayed properly too. Screenshot 2024-10-02 165945

The MSIX is only 4KB while the shell extension DLL is 116KB. No idea how Google end up with such large ones for their Nearby/Quick Share... Screenshot 2024-10-02 220831

Overall, I am satisfied with the state of this MediaInfo context menu now and am actually using the version built from this branch on my primary PC. So far did not encounter any issues even with files that have paths longer than 260 characters, paths containing spaces and non-latin characters as well as opening a hundred files at once. It also survived the upgrade from Windows 11 23H2 to 24H2.

JeromeMartinez commented 3 weeks ago

Thank you for the update.

Now the preferences for Explorer extension is greyed out on Windows 11 since shell extensions are part of the application package on Windows 11

Hum, I would prefer to control the integration here because some people may complain about the extension, but not a big deal right now.

The previous context menu is disabled on Windows 11 to ensure no duplicate entries.

Great!

Related in the readme:

It is only used on Windows 11 at the moment. It should be possible to use it for older Windows versions too to enable opening multiple files in the same instance of MediaInfo and phase out the old registry-based implementation.

do you mean that this method is also available for Win7-Win10?

The application has an app identity / package name as can be seen in Task Manager and its taskbar icon is displayed properly too.

Ho, wasn't it the case with the current version? I didn't check much, i need to.

The MSIX is only 4KB while the shell extension DLL is 116KB. No idea how Google end up with such large ones for their Nearby/Quick Share...

This is great because it is same for me, I prefer to avoid big package. I don't get a company like Google can not do this for their packages, I guess that the reason is that 99.999% of users don't care, anyway I prefer to keep small binaries when it is doable.

Overall, I am satisfied with the state of this MediaInfo context menu now

I am super late but don't forget all the work you did, I want to integrate it, I just have to finish some work before it but again, it is in my mind that I need to review then merge that.

cjee21 commented 3 weeks ago

Hum, I would prefer to control the integration here because some people may complain about the extension, but not a big deal right now.

Should be possible since the Store version of Mp3tag can toggle the context menu in settings. I think it is done by writing code in the shell extension DLL which checks whether it should show or not when File Explorer triggers it. Perhaps it is the GetState function. It should not be done by uninstalling and installing the sparse package as done by some apps.

At the moment, if someone complains, they can disable it by manually uninstalling the sparse package using PowerShell since we are not using the package for any other features at the moment. It will stay disabled until a new MediaInfo update re-enables it.

It is only used on Windows 11 at the moment. It should be possible to use it for older Windows versions too to enable opening multiple files in the same instance of MediaInfo and phase out the old registry-based implementation.

do you mean that this method is also available for Win7-Win10?

According to Microsoft, IExplorerCommand extends back to Windows 7 (maybe even Vista). So I think it is possible to use the same DLL shell extension for context menu in all Windows versions. The advantage would be consistency in how multiple files are opened in a single instance and also ability to remove the registry handling codes for the old implementation. However, to register it, only WIndows 10 build 19000 onwards supports the sparse package method. On older versions, probably need to use the traditional registry/regserver method which I do not know how.

The application has an app identity / package name as can be seen in Task Manager and its taskbar icon is displayed properly too.

Ho, wasn't it the case with the current version? I didn't check much, i need to.

Now MediaInfo is an unpackaged app so it does not have an app identity (Package name is blank). With the sparse package, although it is still unpackaged, it is now a little like a packaged Store app. The taskbar icon is now handled like a packaged app and it has app/package identity which grants access to the new Windows 11 context menu, the Windows share sheet, the Windows App SDK notifications API and more.

The taskbar icon is displayed properly now. I am comparing to other apps like Google's Nearby Share which has missing icons when launched from context menu as the sparse package / app identity is not implemented properly. It does not have package name in task manager also. Same with Notepad++ and VSCode which resorted to putting it in a subfolder to solve the missing icon and thus the main app does not have package identity. The correct way is to put the icon assets in the app folder. I think many apps package the icons in the MSIX, that's why theirs is large. A sparse package is supposed to be sparse. All resources that it references are supposed to be in the 'external location' that we declare during install and not in the package itself.

I am super late but don't forget all the work you did, I want to integrate it, I just have to finish some work before it but again, it is in my mind that I need to review then merge that.

The priority is PR916 which contains minor changes for bug fixes. This should be merge-able without issues and any other changes. I noticed there are also some security-related MediaInfoLib issues such as overflow and crashing which I think should be given priority too.

This Windows 11 context menu stuff I will only make a PR if you are okay with how it is done and if you want me to make a PR since it is a larger change than the other PRs and contains code based on other repositories' code. I have checked through every line of the code and it is also modified at this stage so technically it should be okay (I trust it enough to be running it on my main PC) but I am not sure about licensing (some code is based on GPL and MIT code but I have already modified them). I may also have to explain more / work it though with you because it requires changes to the build system/script to build and sign the new things.

I am also now using C++Builder 12 and MSVC 2022 so if the other two PRs and this context menu does not build with existing build farm, then either the build farm is upgraded or changes have to be made.

I understand there are likely more important things on MediaInfoLib side that you are currently busy with. I will wait patiently. Just give me a mention when you want to start working on this and the other two PRs (they likely need rebase/changes and changes to build farm) and I'll be here. PR916 should be merge-able as it is without needing me.

cjee21 commented 3 weeks ago

New video

https://github.com/user-attachments/assets/d672d565-2bdf-45c9-9994-e30a62c9f661

Made some minor changes to the branch. The README has been updated too. The most noticeable change is that now there is no PowerShell window pop-up during uninstall.

JeromeMartinez commented 3 weeks ago

The most noticeable change is that now there is no PowerShell window pop-up during uninstall.

Great, thank you!

cjee21 commented 2 weeks ago

FYI I have re-based the branch to latest master. Now it only contains Windows 11 context menu stuff. I have also re-written the shell extension DLL using C++/WinRT, tidy up the codes and updated the README. It still works the same.

cjee21 commented 2 weeks ago

Some updates on the branch.

  1. It is no longer implemented 100% the way intended by Microsoft documentations. Now use subfolder like Notepad++ and VSCode but for a different reason from them. It is to prevent another strange behaviour caused by package identity. More details in README.

  2. It should be now installed for all user accounts (including newly created ones) by the installer and uninstalled for all as well (but needs testing as I only have single account). No longer need to launch MediaInfo once to get the context menu but currently logged-in user may need to re-login or wait some time for it to appear.

  3. README updated.

JeromeMartinez commented 2 weeks ago

currently logged-in user may need to re-login or wait some time for it to appear.

Was it also the case in previous version? Also with npp? This limitation is pretty annoying :(.

by the way:

It cannot be disabled on Windows 11

Is also a strong limitation, lot of users disable it. Is it also the case with npp?

Effect of workaround: MediaInfo no longer has app identity.

:(. Anyway, it looks like that it is complicated to have something stable, so better than nothing for the moment.

cjee21 commented 2 weeks ago

Was it also the case in previous version? Also with npp? This limitation is pretty annoying :(.

I don't know. I don't use npp. But if you look at their implementation, very very complicated and not bug-free. VSCode seems to have issue with installation too since they have not rolled it out to stable channel. Right now the new installation method for MediaInfo is inspired by a commit from npp that is not merged yet and is different than what VSCode does but results in a provisioned package similar to Adobe Acrobat (they are using it for share sheet, not context menu).

I have put command to refresh File Explorer after provisioning but seems it refreshed before the package is registered. It will appear if a refresh is triggered by something else (the old shell extension code in MediaInfo seems to do the trick) or File Explorer is restarted (like a re-login).

It cannot be disabled on Windows 11

Is also a strong limitation, lot of users disable it. Is it also the case with npp?

Mp3tag can be disabled. Microsoft's built-in apps doesn't seem to be able to disable. This can be done later on, Probably need to use registry (The rough idea is to make MediaInfo write a registry value when disabled in Preferences, then DLL checks registry and return ECS_HIDDEN in GetState if registry says to disable. The registry needs to be for current user so it will be left behind on uninstall?). Right now since the Preferences is linked to the old registry-based context menu, I am not sure how to go about it since I don't really understand the old code for the registry section.

Effect of workaround: MediaInfo no longer has app identity.

:(. Anyway, it looks like that it is complicated to have something stable, so better than nothing for the moment.

We don't need app identity at the moment anyway since not using things like share sheet or notifications API. The only thing is no package name appear in task manager or process explorer.

At the moment, after this most recent update, it is stable on my system. The only thing I am concerned is the installation/updating part especially on systems with different configurations (need others to test to find out). The context menu itself I am quite confident of the stability.

JeromeMartinez commented 2 weeks ago

We don't need app identity at the moment anyway since not using things like share sheet or notifications API. The only thing is no package name appear in task manager or process explorer.

As you are there, is it possible to have app identity for MI program and a second one for the menu? I like the idea to go as far as possible, so if we can have the package name appear in task manager or process explorer, it is also good.

cjee21 commented 2 weeks ago

As you are there, is it possible to have app identity for MI program and a second one for the menu? I like the idea to go as far as possible, so if we can have the package name appear in task manager or process explorer, it is also good.

I don't think it is a good idea to do this just to get something to appear in task manager. The sparse package seems to have some strange behaviour/bugs in Windows. The size of the installation will also increase with more files to have two. If want package identity and eliminate installation/uninstallation issues, better to package the whole app as MSIX than to use sparse package in my opinion. If it is possible to package whole app as MSIX, there should be no issues with the context menu like Mp3tag store version or Microsoft's pre-installed apps. Adobe Acrobat, Npp, VSCode, Google Nearby Share etc. all implement sparse package differently and none seems to have identity on the main app.

cjee21 commented 2 weeks ago

btw if a file has a path longer than 260 characters, only the new context menu and file open dialog can open it in MediaInfo. Drag/drop to window or drag/drop to MediaInfo shortcut does not work. Opening the folder containing the file via new context menu or via folder open dialog results in an empty file entry in MediaInfo.

JeromeMartinez commented 2 weeks ago

Opening the folder containing the file via new context menu or via folder open dialog results in an empty file entry in MediaInfo.

I guess that there is a way to get the long path, but yet another code to add after having found the right API :(.

cjee21 commented 2 weeks ago

I guess that there is a way to get the long path, but yet another code to add after having found the right API :(.

When it opens properly via new context menu or file open dialog, the path starts with \\?\.

MPC-BE recently added long path support: https://github.com/Aleksoid1978/MPC-BE/blob/7979fc78d63f52f883ef6054fe7db14f8cbce854/docs/Changelog.txt#L23 It says need enable in registry but opening video from File Explorer works right away on Windows 11 after updating without needing any registry edits. The path shows as starting with \\?\ too.

Edit: I think I get the idea. Opening with \\?\ path is separate from the registry key which seems to be needed for retrieving files with long paths from a folder. MediaInfo already handles \\?\ but MPC-BE only recently supports it along with the other type.

cjee21 commented 2 weeks ago

currently logged-in user may need to re-login or wait some time for it to appear.

This limitation is pretty annoying :(.

I tested this again. After installing, without launching MediaInfo or doing anything else, File Explorer seems to refresh itself and the context menu entry appears within less than a minute.

I have questions after looking through the installer script:


Update: Made changes to installer script in the branch. Now the new context menu entry appears right after install for the user who installs (even before the installer window is closed). Now the uninstaller also no longer has a 3 second delay and is super fast to complete. Also used absolute path when calling regsvr32 to prevent any possibility of hijacking (no idea how Exec function searches for an executable but we won't want any possibility of something like this).


Update 2:

It cannot be disabled on Windows 11

Is also a strong limitation, lot of users disable it.

The branch is now updated with feature to disable the context menu entry. Just set HKCU\Software\MediaArea\MediaInfo\HideExplorerContextMenu DWORD to anything other than 0 to disable it. If it is 0 or value does not exist, it will be enabled. The GUI Preferences is not yet updated to set this registry value. I think it is better for the original author of the shell extension part of the GUI to refactor it and integrate this new context menu since I do not really understand what is going on there (many registry operations) and would not want to break anything.

cjee21 commented 1 week ago

Updated branch again. Now can enable and disable the new context menu via GUI Preferences. It is implemented without touching the old code. It may be possible to integrate it better with the old code or use the DLL for all Windows versions by modifying the old code but I will not be doing that as I did not take time to understand the old registry handling codes that are long.

Here is the new video:

https://github.com/user-attachments/assets/f8da9135-3e76-4695-be19-42c2f7d1e2d5

JeromeMartinez commented 1 week ago

Now can enable and disable the new context menu via GUI Preferences.

Great! thank you.