-
Notifications
You must be signed in to change notification settings - Fork 160
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Windows GUI: Windows 11 File Explorer Context Menu #960
base: master
Are you sure you want to change the base?
Conversation
Note: Open source code licensed under GPL and MIT from Microsoft, NanaZip and Npp were referenced in the making of this PR. Although code in this PR is not identical to any of the referenced code, it should be ensured that there are no licensing issues. I am not a legal expert. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for you hard work on that.
In general this is OK but I would like some changes:
First I would like another PR with .gitignore, $(BDS) to ..\.. stuff, MSVC2019 to MSVC2022 stuff, BCB22 to BCB23 stuff (if relevant? we don't use version 12), Manifest.rc/xml deletion (not used?), Exec regsvr32 to ExecWait regsvr32.exe, Delete "$INSTDIR\MediaInfo_InfoTip.dll" to UnInstallLib, Refresh File Explorer.
It seems not related to the Win11 integration and I could independently validate them.
Then for this PR:
PNG should go in \Source\Resource\Image\Assets
.
Please add the following header to all (non automatically generated and not tiny helper) .cpp & .h files:
/* Copyright (c) MediaArea.net SARL. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license that can
* be found in the License.html file in the root of the source tree.
*/
A question, the project files for the new DLLs are only in MSVC2022. In that case how to go about in the installer script?
I put it there so that is is easier to re-generate the .pri file because everything has to be in the correct folder structure as what is in a MSIX. Do you still want to move it? |
It is not currently used by C++Builder, a default manifest from C++Builder's directory is used. I deleted it in the same commit as adding
This is replacing the default manifest from C++Builder's directory with the new |
d298b47
to
ad12639
Compare
Done most of the changes discussed. I've totally removed changes with the GUI. I still have no clear idea how to go about it so you can give it a look/try. |
If I understand correctly this is independent from the Win11 context menu and useful as standalone. If so please a separate PR.
It seems that we have a coherency problem, we should go with MSVC2022 everywhere, we check. cc @g-maxime.
I prefer to have all MediaInfo logs at the same place when not to complicated, and also I don't like to have the .pri (a binary file?) if not source in the source code. How is built the .pri? Would it make sense to have the logo files in the |
The manifest is for granting package identity to MediaInfo GUI. It goes along with the sparse package.
The .pri only needs to be rebuilt when there is a change to the resources. If you prefer to rebuild it everytime, I will let you make the change. Guide: https://learn.microsoft.com/en-us/windows/msix/desktop/desktop-to-uwp-manual-conversion#generate-a-package-resource-index-pri-file-using-makepri |
OK.
OK, let's keep as is for the moment, You already do a lot and we'll manage the rebuild on our side (no need to be automatic, usually it is done by a check if the source files are younger than the binary, anyway we'll manage that). I remark only now that we still build with MSVC2019 on our build farm, we'll migrate in order to be able to test this PR. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fine with that for the moment, but blocked because we don't have MSVC2022 on our build farm.
I change my mind: my understanding now is that it does not hurt to switch to this manifest even without building the sparse package. |
ad12639
to
9adcb57
Compare
Okay, tested the current state of this branch:
* = effect of updated manifest |
Theses ones were not expected. |
Let me try to explain in simple way how it works.
So what else needs to be done in this PR?
|
Took a look at the codes for handling old context menu again and came up with a better solution. Appears to work properly on Windows 11 now. No duplicate entries and can control appearance of the new shell extension. Just need to test on Windows 10 and portable to ensure there is no change to existing behaviour there. |
3e75f45
to
b7ce8ff
Compare
Note: we should consider adding notifying Windows Shell to refresh list of context menu upon installation/uninstallation. Else both the new and old menu entries will not appear after installation until Windows refreshes itself or something triggers a refresh althoough they are enabled by default. It will prevent issues like: https://sourceforge.net/p/mediainfo/support-requests/51/ Also, this bug: https://sourceforge.net/p/mediainfo/bugs/1161/ is reproducible and is now causing duplicate entries in 'classic' context menu for mp3 files etc. Seems there is some registry left behind for some file extensions even after uninstall There are issues with existing (old) context menu implementation. |
b7ce8ff
to
29f90e2
Compare
Force push adds avif, avs, heic, heif, iamf, ico, jxl and webp to extensions list in manifest and changes webm to lower case. |
IFACEMETHODIMP GetState(_In_opt_ IShellItemArray* items, _In_ BOOL okToBeSlow, _Out_ EXPCMDSTATE* cmdState) { | ||
// Provide state of File Explorer context menu entry | ||
// Hide it if registry setting indicates that it should be disabled, else it is enabled | ||
UNREFERENCED_PARAMETER(items); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My understanding he is that you have the items name so you can check if it is a directory or not, and ECS_HIDDEN
if there are only directories shell extension for directories is not activated, it does not seem too complicated.
Does it make sense?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably. Need to make sure it does not take too long or else need check okToBeSlow and I am not sure what will happen if okToBeSlow is false. Maybe you can add it later on.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need to make sure it does not take too long
A possibility is to launch the check only if there are few items.
Also, we stop the check when there is at least 1 file.
My guess is that slowness will be very rare, people usually don't select 100 folder, it is more a couple of files + folder so a file will be caught early.
if okToBeSlow is false
In that case we may just ignore the check.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Putting the link of the doc for this here for reference: https://learn.microsoft.com/en-us/windows/win32/api/shobjidl_core/nf-shobjidl_core-iexplorercommand-getstate
Thank you, it seems less complicated than the previous proposal.
Ha, I see! But so weird, indeed. I don't see an easy solution... Maybe just removing |
I agree with this. But issue now is making sure all unwanted registry entries are correctly removed on uninstall or upgrade of MediaInfo. |
Would you mind to add a PR about it? It seems that you see better than me the issue there. |
29f90e2
to
13642e6
Compare
Looks like the GUI is trying the wrong key that's why fail to disable for |
Also I think the old shell will be re-enabled everytime MediaInfo is updated for those who disabled it until they open MediaInfo. |
@JeromeMartinez I merged all my currently open PRs to a branch and made a test build. Everything seems to be in order now. Both context menu entry appears automatically after install, old one gets disabled on first launch of MediaInfo, no duplicate entries after that, can enable/disable shell extension and after uninstall, no registry entries that are written by MediaInfo are left behind. |
13642e6
to
741a75d
Compare
Just a rebase, so that can test properly without the other bugs. |
Integrate with Windows 11 File Explorer modern context menu by implementing required items:
New shell extension also has the benefit of opening multiple selected files in the same MediaInfo instance instead of in multiple windows.
Resolves #671
Explanation of approach chosen for this new context menu implementation
The sparse package is provisioned for all users by the installer during install and removed for all users during uninstall using a helper dll. This should ensure all users will have the context menu on login after install and a clean removal after uninstall.
The 'Assets' folder and
resources.pri
file are needed because when the app runs with app identity, the assets referenced by the sparse package manifest is used for the app icon. Since it is a sparse package, it itself does not contain assets and instead references the assets that are in the declared external location. Theresources.pri
is needed for the 'unplated' icons which are needed to prevent the icon from having accent-coloured plating as the background.In order to minimize the size of the DLL while ensuring it runs on clean Windows installations without Microsoft Visual C++ Redistributable installed,
vcruntime
is statically linked whileucrt
is dynamically linked. This results in something between using/MT
and/MD
. It is known as Hybrid CRT and is supported according to the CRT maintainer./PDBALTPATH:%_PDB%
is added to linker in release mode so that the PDB file path is not contained in the DLL. This ensures no path information leakage and reduces the size of DLL slightly while still enabling analysis that requires PDB files to be done, for example SizeBench.The shell extension is re-written from WRL to C++/WinRT. See 'Note' at https://learn.microsoft.com/en-us/cpp/cppcx/wrl/windows-runtime-cpp-template-library-wrl?view=msvc-170 for details on why.
Enabled security mitigations for new context menu
The following are enabled in the project file for the Explorer context menu shell extension DLL.
GS (Buffer Security Check), sdl (Additional Security Checks), NXCOMPAT (Data Execution Prevention), DYNAMICBASE (Address space layout randomization), HIGHENTROPYVA (64-Bit ASLR), guard:cf (Control Flow Guard), guard:ehcont (EH Continuation Metadata), Qspectre (Spectre variant 1 mitigation), CETCOMPAT (CET Shadow Stack)
References
Todo for MediaInfo team:
Update version update script for:
Source\GUI\VCL\Manifest.manifest
Source\WindowsSparsePackage\MSIX\AppxManifest.xml
Source\WindowsShellExtension\Resource.rc
Source\WindowsPackageHelper\Resource.rc
Update build script
make sparse package
makeappx pack /d "Source\WindowsSparsePackage\MSIX" /p "Project\MSVC2022\x64\Release\MediaInfo_SparsePackage.msix" /nv
build DLLs
sign sparse package MSIX and DLLs generated by above
Improve GUI to better handle the two types of context menus including behaviour when running as portable. Can also use the new shell extension DLL on all Windows versions but < Win10 Build19000 requires manually registering using registry without sparse package. > Win10 Build19000 should be able to use same method as Windows 11. At the moment (this PR), new one is only installed and configured for Windows 11 and above.