OSDN Git Service

Shell Extension for Windows 11 or later (#954)
authorTakashi Sawanaka <sdottaka@users.sourceforge.net>
Mon, 13 Sep 2021 00:06:22 +0000 (09:06 +0900)
committerGitHub <noreply@github.com>
Mon, 13 Sep 2021 00:06:22 +0000 (09:06 +0900)
75 files changed:
.gitignore
ALL.vs2017.sln
ALL.vs2019.sln
BuildArc.cmd
DownloadDeps.cmd
Installer/InnoSetup/WinMergeARM64.is6.iss
Installer/InnoSetup/WinMergeX64.is6.iss
Installer/InnoSetup/WinMergeX64.iss
Installer/InnoSetup/WinMergeX64NonAdmin.iss
ShellExtension/BuildArc.cmd
ShellExtension/BuildBin.vs2017.cmd
ShellExtension/BuildBin.vs2019.cmd
ShellExtension/CreateWinMergeContextMenuPackage.bat [new file with mode: 0644]
ShellExtension/CreateWinMergeContextMenuPackage.ps1 [new file with mode: 0644]
ShellExtension/CreateWinMergeContextMenuSelfSignedPackage.bat [new file with mode: 0644]
ShellExtension/RegisterWinMergeContextMenuPackage.bat [new file with mode: 0644]
ShellExtension/RegisterWinMergeContextMenuX64DebugPackage.bat [new file with mode: 0644]
ShellExtension/ShellExtension.vs2017.sln
ShellExtension/ShellExtension.vs2019.sln
ShellExtension/UnregisterWinMergeContextMenuPackage.bat [new file with mode: 0644]
ShellExtension/WinMergeContextMenu/Source.def [new file with mode: 0644]
ShellExtension/WinMergeContextMenu/WinMergeContextMenu.rc [new file with mode: 0644]
ShellExtension/WinMergeContextMenu/WinMergeContextMenu.vcxproj [new file with mode: 0644]
ShellExtension/WinMergeContextMenu/WinMergeContextMenu.vcxproj.filters [new file with mode: 0644]
ShellExtension/WinMergeContextMenu/dllmain.cpp [new file with mode: 0644]
ShellExtension/WinMergeContextMenu/framework.h [new file with mode: 0644]
ShellExtension/WinMergeContextMenu/packages.config [new file with mode: 0644]
ShellExtension/WinMergeContextMenu/pch.cpp [new file with mode: 0644]
ShellExtension/WinMergeContextMenu/pch.h [new file with mode: 0644]
ShellExtension/WinMergeContextMenu/resource.h [new file with mode: 0644]
ShellExtension/WinMergePkg/AppxManifest.xml.in [new file with mode: 0644]
Src/ConfigLog.cpp
Src/Merge.rc
Src/PropShell.cpp
Src/PropShell.h
Src/resource.h
Translations/TranslationsStatus.html
Translations/TranslationsStatus.md
Translations/TranslationsStatus.xml
Translations/WinMerge/Arabic.po
Translations/WinMerge/Basque.po
Translations/WinMerge/Brazilian.po
Translations/WinMerge/Bulgarian.po
Translations/WinMerge/Catalan.po
Translations/WinMerge/ChineseSimplified.po
Translations/WinMerge/ChineseTraditional.po
Translations/WinMerge/Croatian.po
Translations/WinMerge/Czech.po
Translations/WinMerge/Danish.po
Translations/WinMerge/Dutch.po
Translations/WinMerge/English.pot
Translations/WinMerge/Finnish.po
Translations/WinMerge/French.po
Translations/WinMerge/Galician.po
Translations/WinMerge/German.po
Translations/WinMerge/Greek.po
Translations/WinMerge/Hungarian.po
Translations/WinMerge/Italian.po
Translations/WinMerge/Japanese.po
Translations/WinMerge/Korean.po
Translations/WinMerge/Lithuanian.po
Translations/WinMerge/Norwegian.po
Translations/WinMerge/Persian.po
Translations/WinMerge/Polish.po
Translations/WinMerge/Portuguese.po
Translations/WinMerge/Romanian.po
Translations/WinMerge/Russian.po
Translations/WinMerge/Serbian.po
Translations/WinMerge/Sinhala.po
Translations/WinMerge/Slovak.po
Translations/WinMerge/Slovenian.po
Translations/WinMerge/Spanish.po
Translations/WinMerge/Swedish.po
Translations/WinMerge/Turkish.po
Translations/WinMerge/Ukrainian.po

index 1a09ba7..2383b77 100644 (file)
@@ -51,12 +51,19 @@ Docs/Manual/Tools/ReadMe_ENG.html
 Testing/Data/ShellFileOpTest/File1.txt
 Testing/result-*.txt
 Translations/WinMerge/MergeLang.lastbuild
 Testing/Data/ShellFileOpTest/File1.txt
 Testing/result-*.txt
 Translations/WinMerge/MergeLang.lastbuild
-ShellExtension/src/*_i.c
-ShellExtension/src/*_p.c
-ShellExtension/src/dlldata.c
-ShellExtension/src/ShellExtension.h
-ShellExtension/src/ShellExtension_i.c
-ShellExtension/src/ShellExtension_p.c
+ShellExtension/ShellExtension/*_i.c
+ShellExtension/ShellExtension/*_p.c
+ShellExtension/ShellExtension/dlldata.c
+ShellExtension/ShellExtension/ShellExtension.h
+ShellExtension/ShellExtension/ShellExtension_i.c
+ShellExtension/ShellExtension/ShellExtension_p.c
+ShellExtension/selfsigncert.cer
+ShellExtension/selfsigncert.pfx
+ShellExtension/WinMergeContextMenuPackage.msix
+ShellExtension/WinMergePkg/resources.pri
+ShellExtension/WinMergePkg/AppxManifest.xml
+ShellExtension/publisher.txt
+packages/
 Plugins/**/dlldata.c
 Plugins/**/*_i.c
 Plugins/**/*_i.h
 Plugins/**/dlldata.c
 Plugins/**/*_i.c
 Plugins/**/*_i.h
@@ -71,4 +78,3 @@ Plugins/src_VCPP/IgnoreFieldsComma/IgnoreFieldsComma.h
 Plugins/src_VCPP/IgnoreFieldsTab/IgnoreFieldsTab.h
 Plugins/src_VCPP/WatchBeginningOfLog/WatchBeginningOfLog.h
 Plugins/src_VCPP/WatchEndOfLog/WatchEndOfLog.h
 Plugins/src_VCPP/IgnoreFieldsTab/IgnoreFieldsTab.h
 Plugins/src_VCPP/WatchBeginningOfLog/WatchBeginningOfLog.h
 Plugins/src_VCPP/WatchEndOfLog/WatchEndOfLog.h
-
index 4fe37f6..2a6c5d4 100644 (file)
@@ -377,6 +377,33 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ildasm", "ildasm", "{64739D
                Plugins\Commands\ildasm\ildasm.bat = Plugins\Commands\ildasm\ildasm.bat
        EndProjectSection
 EndProject
                Plugins\Commands\ildasm\ildasm.bat = Plugins\Commands\ildasm\ildasm.bat
        EndProjectSection
 EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ShellExtension", "ShellExtension", "{578C2837-33B3-4F33-ABDC-CA588BE05983}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WinMergeContextMenu", "ShellExtension\WinMergeContextMenu\WinMergeContextMenu.vcxproj", "{16746B0C-5840-4ED4-AEDF-1ABB617827FD}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "WinMergePkg", "WinMergePkg", "{F4ED7659-7C4E-4962-B83A-A1F3E1F7B8DE}"
+       ProjectSection(SolutionItems) = preProject
+               ShellExtension\WinMergePkg\AppxManifest.xml.in = ShellExtension\WinMergePkg\AppxManifest.xml.in
+       EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Scripts", "Scripts", "{14C9D43A-1727-4BEE-B2A2-A6BAED7E7154}"
+       ProjectSection(SolutionItems) = preProject
+               ShellExtension\BuildArc.cmd = ShellExtension\BuildArc.cmd
+               ShellExtension\BuildBin.vs2017.cmd = ShellExtension\BuildBin.vs2017.cmd
+               ShellExtension\BuildBin.vs2019.cmd = ShellExtension\BuildBin.vs2019.cmd
+               ShellExtension\CreateWinMergeContextMenuPackage.bat = ShellExtension\CreateWinMergeContextMenuPackage.bat
+               ShellExtension\CreateWinMergeContextMenuPackage.ps1 = ShellExtension\CreateWinMergeContextMenuPackage.ps1
+               ShellExtension\CreateWinMergeContextMenuSelfSignedPackage.bat = ShellExtension\CreateWinMergeContextMenuSelfSignedPackage.bat
+               ShellExtension\Register.bat = ShellExtension\Register.bat
+               ShellExtension\RegisterPerUser.bat = ShellExtension\RegisterPerUser.bat
+               ShellExtension\RegisterWinMergeContextMenuPackage.bat = ShellExtension\RegisterWinMergeContextMenuPackage.bat
+               ShellExtension\RegisterWinMergeContextMenuX64DebugPackage.bat = ShellExtension\RegisterWinMergeContextMenuX64DebugPackage.bat
+               ShellExtension\SignShellExtension.bat = ShellExtension\SignShellExtension.bat
+               ShellExtension\UnRegister.bat = ShellExtension\UnRegister.bat
+               ShellExtension\UnRegisterPerUser.bat = ShellExtension\UnRegisterPerUser.bat
+               ShellExtension\UnregisterWinMergeContextMenuPackage.bat = ShellExtension\UnregisterWinMergeContextMenuPackage.bat
+       EndProjectSection
+EndProject
 Global
        GlobalSection(SharedMSBuildProjectFiles) = preSolution
                Externals\googletest\googletest\googletest.vcxitems*{0a3727b1-51e7-4702-ad0c-8aee317ea510}*SharedItemsImports = 4
 Global
        GlobalSection(SharedMSBuildProjectFiles) = preSolution
                Externals\googletest\googletest\googletest.vcxitems*{0a3727b1-51e7-4702-ad0c-8aee317ea510}*SharedItemsImports = 4
@@ -1026,6 +1053,22 @@ Global
                {E11617CA-2D87-4571-B22A-48C922D9A0F9}.Test|ARM64.ActiveCfg = Debug|ARM64
                {E11617CA-2D87-4571-B22A-48C922D9A0F9}.Test|Win32.ActiveCfg = Release|Win32
                {E11617CA-2D87-4571-B22A-48C922D9A0F9}.Test|x64.ActiveCfg = Release|x64
                {E11617CA-2D87-4571-B22A-48C922D9A0F9}.Test|ARM64.ActiveCfg = Debug|ARM64
                {E11617CA-2D87-4571-B22A-48C922D9A0F9}.Test|Win32.ActiveCfg = Release|Win32
                {E11617CA-2D87-4571-B22A-48C922D9A0F9}.Test|x64.ActiveCfg = Release|x64
+               {16746B0C-5840-4ED4-AEDF-1ABB617827FD}.Debug|ARM64.ActiveCfg = Debug|ARM64
+               {16746B0C-5840-4ED4-AEDF-1ABB617827FD}.Debug|ARM64.Build.0 = Debug|ARM64
+               {16746B0C-5840-4ED4-AEDF-1ABB617827FD}.Debug|Win32.ActiveCfg = Debug|x64
+               {16746B0C-5840-4ED4-AEDF-1ABB617827FD}.Debug|x64.ActiveCfg = Debug|x64
+               {16746B0C-5840-4ED4-AEDF-1ABB617827FD}.Debug|x64.Build.0 = Debug|x64
+               {16746B0C-5840-4ED4-AEDF-1ABB617827FD}.Release|ARM64.ActiveCfg = Release|ARM64
+               {16746B0C-5840-4ED4-AEDF-1ABB617827FD}.Release|ARM64.Build.0 = Release|ARM64
+               {16746B0C-5840-4ED4-AEDF-1ABB617827FD}.Release|Win32.ActiveCfg = Release|x64
+               {16746B0C-5840-4ED4-AEDF-1ABB617827FD}.Release|x64.ActiveCfg = Release|x64
+               {16746B0C-5840-4ED4-AEDF-1ABB617827FD}.Release|x64.Build.0 = Release|x64
+               {16746B0C-5840-4ED4-AEDF-1ABB617827FD}.Test|ARM64.ActiveCfg = Debug|ARM64
+               {16746B0C-5840-4ED4-AEDF-1ABB617827FD}.Test|ARM64.Build.0 = Debug|ARM64
+               {16746B0C-5840-4ED4-AEDF-1ABB617827FD}.Test|Win32.ActiveCfg = Debug|ARM64
+               {16746B0C-5840-4ED4-AEDF-1ABB617827FD}.Test|Win32.Build.0 = Debug|ARM64
+               {16746B0C-5840-4ED4-AEDF-1ABB617827FD}.Test|x64.ActiveCfg = Debug|x64
+               {16746B0C-5840-4ED4-AEDF-1ABB617827FD}.Test|x64.Build.0 = Debug|x64
        EndGlobalSection
        GlobalSection(SolutionProperties) = preSolution
                HideSolutionNode = FALSE
        EndGlobalSection
        GlobalSection(SolutionProperties) = preSolution
                HideSolutionNode = FALSE
@@ -1046,6 +1089,7 @@ Global
                {AA88B46E-B2E2-4B03-8CD5-1E9D60DB6AB2} = {AA9C3A4D-4CD6-46BE-A266-A5FE7BE52F65}
                {A948A08A-3AF4-4860-8D13-8C425E56806F} = {AA9C3A4D-4CD6-46BE-A266-A5FE7BE52F65}
                {4A3F0C35-6B6D-44B3-84FD-7E2168398361} = {AA9C3A4D-4CD6-46BE-A266-A5FE7BE52F65}
                {AA88B46E-B2E2-4B03-8CD5-1E9D60DB6AB2} = {AA9C3A4D-4CD6-46BE-A266-A5FE7BE52F65}
                {A948A08A-3AF4-4860-8D13-8C425E56806F} = {AA9C3A4D-4CD6-46BE-A266-A5FE7BE52F65}
                {4A3F0C35-6B6D-44B3-84FD-7E2168398361} = {AA9C3A4D-4CD6-46BE-A266-A5FE7BE52F65}
+               {76A538A1-9D2C-49CB-AE9F-72548CE37F88} = {578C2837-33B3-4F33-ABDC-CA588BE05983}
                {AF985E3F-14EE-420E-90FE-AAA844797D36} = {AA9C3A4D-4CD6-46BE-A266-A5FE7BE52F65}
                {D490276C-363D-4996-B365-28A08877387C} = {AA9C3A4D-4CD6-46BE-A266-A5FE7BE52F65}
                {36365C8C-04A0-4892-9B83-AD6E05D50D67} = {0B7E421E-A8CA-444C-B650-D1D7F1D55688}
                {AF985E3F-14EE-420E-90FE-AAA844797D36} = {AA9C3A4D-4CD6-46BE-A266-A5FE7BE52F65}
                {D490276C-363D-4996-B365-28A08877387C} = {AA9C3A4D-4CD6-46BE-A266-A5FE7BE52F65}
                {36365C8C-04A0-4892-9B83-AD6E05D50D67} = {0B7E421E-A8CA-444C-B650-D1D7F1D55688}
@@ -1095,6 +1139,9 @@ Global
                {9EE35458-B145-444F-92B7-27FF72112C42} = {EEFF904A-CA86-4FB8-BAC5-D508CBF586AA}
                {B22D4554-B639-44BA-BC70-9FD7CCC5B424} = {BB290B2D-F5B9-4552-AE32-9319C03E41C0}
                {64739D83-1BDF-409F-81F3-9320494A199A} = {BB290B2D-F5B9-4552-AE32-9319C03E41C0}
                {9EE35458-B145-444F-92B7-27FF72112C42} = {EEFF904A-CA86-4FB8-BAC5-D508CBF586AA}
                {B22D4554-B639-44BA-BC70-9FD7CCC5B424} = {BB290B2D-F5B9-4552-AE32-9319C03E41C0}
                {64739D83-1BDF-409F-81F3-9320494A199A} = {BB290B2D-F5B9-4552-AE32-9319C03E41C0}
+               {16746B0C-5840-4ED4-AEDF-1ABB617827FD} = {578C2837-33B3-4F33-ABDC-CA588BE05983}
+               {F4ED7659-7C4E-4962-B83A-A1F3E1F7B8DE} = {578C2837-33B3-4F33-ABDC-CA588BE05983}
+               {14C9D43A-1727-4BEE-B2A2-A6BAED7E7154} = {578C2837-33B3-4F33-ABDC-CA588BE05983}
        EndGlobalSection
        GlobalSection(ExtensibilityGlobals) = postSolution
                SolutionGuid = {CC2E4F75-FADC-4F44-BD62-47A321828081}
        EndGlobalSection
        GlobalSection(ExtensibilityGlobals) = postSolution
                SolutionGuid = {CC2E4F75-FADC-4F44-BD62-47A321828081}
index 58a8c10..937e223 100644 (file)
@@ -377,6 +377,33 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ildasm", "ildasm", "{64739D
                Plugins\Commands\ildasm\ildasm.bat = Plugins\Commands\ildasm\ildasm.bat
        EndProjectSection
 EndProject
                Plugins\Commands\ildasm\ildasm.bat = Plugins\Commands\ildasm\ildasm.bat
        EndProjectSection
 EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ShellExtension", "ShellExtension", "{578C2837-33B3-4F33-ABDC-CA588BE05983}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WinMergeContextMenu", "ShellExtension\WinMergeContextMenu\WinMergeContextMenu.vcxproj", "{16746B0C-5840-4ED4-AEDF-1ABB617827FD}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "WinMergePkg", "WinMergePkg", "{F4ED7659-7C4E-4962-B83A-A1F3E1F7B8DE}"
+       ProjectSection(SolutionItems) = preProject
+               ShellExtension\WinMergePkg\AppxManifest.xml.in = ShellExtension\WinMergePkg\AppxManifest.xml.in
+       EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Scripts", "Scripts", "{14C9D43A-1727-4BEE-B2A2-A6BAED7E7154}"
+       ProjectSection(SolutionItems) = preProject
+               ShellExtension\BuildArc.cmd = ShellExtension\BuildArc.cmd
+               ShellExtension\BuildBin.vs2017.cmd = ShellExtension\BuildBin.vs2017.cmd
+               ShellExtension\BuildBin.vs2019.cmd = ShellExtension\BuildBin.vs2019.cmd
+               ShellExtension\CreateWinMergeContextMenuPackage.bat = ShellExtension\CreateWinMergeContextMenuPackage.bat
+               ShellExtension\CreateWinMergeContextMenuPackage.ps1 = ShellExtension\CreateWinMergeContextMenuPackage.ps1
+               ShellExtension\CreateWinMergeContextMenuSelfSignedPackage.bat = ShellExtension\CreateWinMergeContextMenuSelfSignedPackage.bat
+               ShellExtension\Register.bat = ShellExtension\Register.bat
+               ShellExtension\RegisterPerUser.bat = ShellExtension\RegisterPerUser.bat
+               ShellExtension\RegisterWinMergeContextMenuPackage.bat = ShellExtension\RegisterWinMergeContextMenuPackage.bat
+               ShellExtension\RegisterWinMergeContextMenuX64DebugPackage.bat = ShellExtension\RegisterWinMergeContextMenuX64DebugPackage.bat
+               ShellExtension\SignShellExtension.bat = ShellExtension\SignShellExtension.bat
+               ShellExtension\UnRegister.bat = ShellExtension\UnRegister.bat
+               ShellExtension\UnRegisterPerUser.bat = ShellExtension\UnRegisterPerUser.bat
+               ShellExtension\UnregisterWinMergeContextMenuPackage.bat = ShellExtension\UnregisterWinMergeContextMenuPackage.bat
+       EndProjectSection
+EndProject
 Global
        GlobalSection(SharedMSBuildProjectFiles) = preSolution
                Externals\googletest\googletest\googletest.vcxitems*{0a3727b1-51e7-4702-ad0c-8aee317ea510}*SharedItemsImports = 4
 Global
        GlobalSection(SharedMSBuildProjectFiles) = preSolution
                Externals\googletest\googletest\googletest.vcxitems*{0a3727b1-51e7-4702-ad0c-8aee317ea510}*SharedItemsImports = 4
@@ -1026,6 +1053,22 @@ Global
                {E11617CA-2D87-4571-B22A-48C922D9A0F9}.Test|ARM64.ActiveCfg = Debug|ARM64
                {E11617CA-2D87-4571-B22A-48C922D9A0F9}.Test|Win32.ActiveCfg = Release|Win32
                {E11617CA-2D87-4571-B22A-48C922D9A0F9}.Test|x64.ActiveCfg = Release|x64
                {E11617CA-2D87-4571-B22A-48C922D9A0F9}.Test|ARM64.ActiveCfg = Debug|ARM64
                {E11617CA-2D87-4571-B22A-48C922D9A0F9}.Test|Win32.ActiveCfg = Release|Win32
                {E11617CA-2D87-4571-B22A-48C922D9A0F9}.Test|x64.ActiveCfg = Release|x64
+               {16746B0C-5840-4ED4-AEDF-1ABB617827FD}.Debug|ARM64.ActiveCfg = Debug|ARM64
+               {16746B0C-5840-4ED4-AEDF-1ABB617827FD}.Debug|ARM64.Build.0 = Debug|ARM64
+               {16746B0C-5840-4ED4-AEDF-1ABB617827FD}.Debug|Win32.ActiveCfg = Debug|x64
+               {16746B0C-5840-4ED4-AEDF-1ABB617827FD}.Debug|x64.ActiveCfg = Debug|x64
+               {16746B0C-5840-4ED4-AEDF-1ABB617827FD}.Debug|x64.Build.0 = Debug|x64
+               {16746B0C-5840-4ED4-AEDF-1ABB617827FD}.Release|ARM64.ActiveCfg = Release|ARM64
+               {16746B0C-5840-4ED4-AEDF-1ABB617827FD}.Release|ARM64.Build.0 = Release|ARM64
+               {16746B0C-5840-4ED4-AEDF-1ABB617827FD}.Release|Win32.ActiveCfg = Release|x64
+               {16746B0C-5840-4ED4-AEDF-1ABB617827FD}.Release|x64.ActiveCfg = Release|x64
+               {16746B0C-5840-4ED4-AEDF-1ABB617827FD}.Release|x64.Build.0 = Release|x64
+               {16746B0C-5840-4ED4-AEDF-1ABB617827FD}.Test|ARM64.ActiveCfg = Debug|ARM64
+               {16746B0C-5840-4ED4-AEDF-1ABB617827FD}.Test|ARM64.Build.0 = Debug|ARM64
+               {16746B0C-5840-4ED4-AEDF-1ABB617827FD}.Test|Win32.ActiveCfg = Debug|ARM64
+               {16746B0C-5840-4ED4-AEDF-1ABB617827FD}.Test|Win32.Build.0 = Debug|ARM64
+               {16746B0C-5840-4ED4-AEDF-1ABB617827FD}.Test|x64.ActiveCfg = Debug|x64
+               {16746B0C-5840-4ED4-AEDF-1ABB617827FD}.Test|x64.Build.0 = Debug|x64
        EndGlobalSection
        GlobalSection(SolutionProperties) = preSolution
                HideSolutionNode = FALSE
        EndGlobalSection
        GlobalSection(SolutionProperties) = preSolution
                HideSolutionNode = FALSE
@@ -1046,6 +1089,7 @@ Global
                {AA88B46E-B2E2-4B03-8CD5-1E9D60DB6AB2} = {AA9C3A4D-4CD6-46BE-A266-A5FE7BE52F65}
                {A948A08A-3AF4-4860-8D13-8C425E56806F} = {AA9C3A4D-4CD6-46BE-A266-A5FE7BE52F65}
                {4A3F0C35-6B6D-44B3-84FD-7E2168398361} = {AA9C3A4D-4CD6-46BE-A266-A5FE7BE52F65}
                {AA88B46E-B2E2-4B03-8CD5-1E9D60DB6AB2} = {AA9C3A4D-4CD6-46BE-A266-A5FE7BE52F65}
                {A948A08A-3AF4-4860-8D13-8C425E56806F} = {AA9C3A4D-4CD6-46BE-A266-A5FE7BE52F65}
                {4A3F0C35-6B6D-44B3-84FD-7E2168398361} = {AA9C3A4D-4CD6-46BE-A266-A5FE7BE52F65}
+               {76A538A1-9D2C-49CB-AE9F-72548CE37F88} = {578C2837-33B3-4F33-ABDC-CA588BE05983}
                {AF985E3F-14EE-420E-90FE-AAA844797D36} = {AA9C3A4D-4CD6-46BE-A266-A5FE7BE52F65}
                {D490276C-363D-4996-B365-28A08877387C} = {AA9C3A4D-4CD6-46BE-A266-A5FE7BE52F65}
                {36365C8C-04A0-4892-9B83-AD6E05D50D67} = {0B7E421E-A8CA-444C-B650-D1D7F1D55688}
                {AF985E3F-14EE-420E-90FE-AAA844797D36} = {AA9C3A4D-4CD6-46BE-A266-A5FE7BE52F65}
                {D490276C-363D-4996-B365-28A08877387C} = {AA9C3A4D-4CD6-46BE-A266-A5FE7BE52F65}
                {36365C8C-04A0-4892-9B83-AD6E05D50D67} = {0B7E421E-A8CA-444C-B650-D1D7F1D55688}
@@ -1095,6 +1139,9 @@ Global
                {9EE35458-B145-444F-92B7-27FF72112C42} = {EEFF904A-CA86-4FB8-BAC5-D508CBF586AA}
                {B22D4554-B639-44BA-BC70-9FD7CCC5B424} = {BB290B2D-F5B9-4552-AE32-9319C03E41C0}
                {64739D83-1BDF-409F-81F3-9320494A199A} = {BB290B2D-F5B9-4552-AE32-9319C03E41C0}
                {9EE35458-B145-444F-92B7-27FF72112C42} = {EEFF904A-CA86-4FB8-BAC5-D508CBF586AA}
                {B22D4554-B639-44BA-BC70-9FD7CCC5B424} = {BB290B2D-F5B9-4552-AE32-9319C03E41C0}
                {64739D83-1BDF-409F-81F3-9320494A199A} = {BB290B2D-F5B9-4552-AE32-9319C03E41C0}
+               {16746B0C-5840-4ED4-AEDF-1ABB617827FD} = {578C2837-33B3-4F33-ABDC-CA588BE05983}
+               {F4ED7659-7C4E-4962-B83A-A1F3E1F7B8DE} = {578C2837-33B3-4F33-ABDC-CA588BE05983}
+               {14C9D43A-1727-4BEE-B2A2-A6BAED7E7154} = {578C2837-33B3-4F33-ABDC-CA588BE05983}
        EndGlobalSection
        GlobalSection(ExtensibilityGlobals) = postSolution
                SolutionGuid = {CC2E4F75-FADC-4F44-BD62-47A321828081}
        EndGlobalSection
        GlobalSection(ExtensibilityGlobals) = postSolution
                SolutionGuid = {CC2E4F75-FADC-4F44-BD62-47A321828081}
index 1e0624f..34da0cc 100644 (file)
@@ -93,11 +93,19 @@ echo Copy ShellExtension...
 if not "%1" == "ARM64" (
   copy "Build\ShellExtension\ShellExtensionU.dll" "%DISTDIR%\%PLATFORMH%zip-version\WinMerge\" > NUL
   copy "Build\ShellExtension\ShellExtensionX64.dll" "%DISTDIR%\%PLATFORMH%zip-version\WinMerge\" > NUL
 if not "%1" == "ARM64" (
   copy "Build\ShellExtension\ShellExtensionU.dll" "%DISTDIR%\%PLATFORMH%zip-version\WinMerge\" > NUL
   copy "Build\ShellExtension\ShellExtensionX64.dll" "%DISTDIR%\%PLATFORMH%zip-version\WinMerge\" > NUL
+  copy "Build\ShellExtension\x64\WinMergeContextMenu.dll" "%DISTDIR%\%PLATFORMH%zip-version\WinMerge\" > NUL
 )
 if "%1" == "ARM64" (
   copy "Build\ShellExtension\ShellExtensionARM64.dll" "%DISTDIR%\%PLATFORMH%zip-version\WinMerge\" > NUL
 )
 if "%1" == "ARM64" (
   copy "Build\ShellExtension\ShellExtensionARM64.dll" "%DISTDIR%\%PLATFORMH%zip-version\WinMerge\" > NUL
+  copy "Build\ShellExtension\ARM64\WinMergeContextMenu.dll" "%DISTDIR%\%PLATFORMH%zip-version\WinMerge\" > NUL
 )
 )
-copy ShellExtension\*Register*.bat "%DISTDIR%\%PLATFORMH%zip-version\WinMerge\" > NUL
+copy ShellExtension\Register.bat "%DISTDIR%\%PLATFORMH%zip-version\WinMerge\" > NUL
+copy ShellExtension\RegisterPerUser.bat "%DISTDIR%\%PLATFORMH%zip-version\WinMerge\" > NUL
+copy ShellExtension\RegisterWinMergeContextMenuPackage.bat "%DISTDIR%\%PLATFORMH%zip-version\WinMerge\" > NUL
+copy ShellExtension\UnRegister.bat "%DISTDIR%\%PLATFORMH%zip-version\WinMerge\" > NUL
+copy ShellExtension\UnRegisterPerUser.bat "%DISTDIR%\%PLATFORMH%zip-version\WinMerge\" > NUL
+copy ShellExtension\UnregisterWinMergeContextMenuPackage.bat "%DISTDIR%\%PLATFORMH%zip-version\WinMerge\" > NUL
+copy "Build\ShellExtension\WinMergeContextMenuPackage.msix" "%DISTDIR%\%PLATFORMH%zip-version\WinMerge\" > NUL
 
 rem Translations
 echo Copy Translations...
 
 rem Translations
 echo Copy Translations...
index aa3843a..7614c88 100644 (file)
@@ -11,7 +11,7 @@ if not %ERRORLEVEL% == 0 (
 set downloadsdir=%~dp0\build\WinMergeDownloadDeps
 set urls_destdirs=^
 https://github.com/WinMerge/winmerge/releases/download/winmerge_manual_another_build_tools_v2/winmerge_manual_another_build_tools_v2.zip!Docs\Manual\Tools ^
 set downloadsdir=%~dp0\build\WinMergeDownloadDeps
 set urls_destdirs=^
 https://github.com/WinMerge/winmerge/releases/download/winmerge_manual_another_build_tools_v2/winmerge_manual_another_build_tools_v2.zip!Docs\Manual\Tools ^
-https://github.com/WinMerge/winmerge/releases/download/ShellExtension-1.17.16.0/ShellExtension-1.17.16.0.zip!Build ^
+https://github.com/WinMerge/winmerge/releases/download/ShellExtension-1.17.17.0/ShellExtension-1.17.17.0.zip!Build ^
 https://github.com/WinMerge/winmerge/releases/download/Merge7z1900.5/Merge7z1900.5-win32.zip!Build ^
 https://github.com/WinMerge/winmerge/releases/download/Merge7z1900.5/Merge7z1900.5-x64.zip!Build\X64 ^
 https://github.com/WinMerge/winmerge/releases/download/Merge7z1900.5/Merge7z1900.5-ARM64.zip!Build\ARM64 ^
 https://github.com/WinMerge/winmerge/releases/download/Merge7z1900.5/Merge7z1900.5-win32.zip!Build ^
 https://github.com/WinMerge/winmerge/releases/download/Merge7z1900.5/Merge7z1900.5-x64.zip!Build\X64 ^
 https://github.com/WinMerge/winmerge/releases/download/Merge7z1900.5/Merge7z1900.5-ARM64.zip!Build\ARM64 ^
@@ -68,6 +68,7 @@ for %%i in (Build Build\X64 Build\ARM64) do (
     xcopy /s/y ColorSchemes %%i\%%j\ColorSchemes\
     xcopy /s/y Plugins\dlls\*.sct %%i\%%j\MergePlugins\
     xcopy /s/y Plugins\Plugins.xml %%i\%%j\MergePlugins\
     xcopy /s/y ColorSchemes %%i\%%j\ColorSchemes\
     xcopy /s/y Plugins\dlls\*.sct %%i\%%j\MergePlugins\
     xcopy /s/y Plugins\Plugins.xml %%i\%%j\MergePlugins\
+    xcopy /s/y Build\ShellExtension\WinMergeContextMenuPackage.msix %%i\%%j
     if "%%i" == "Build" (
       copy Build\WinIMerge\bin\WinIMergeLib.dll %%i\%%j\WinIMerge\
       copy Plugins\dlls\*.dll %%i\%%j\MergePlugins\
     if "%%i" == "Build" (
       copy Build\WinIMerge\bin\WinIMergeLib.dll %%i\%%j\WinIMerge\
       copy Plugins\dlls\*.dll %%i\%%j\MergePlugins\
index 269d3f4..db592b8 100644 (file)
@@ -49,6 +49,7 @@
 
 #define AppVersion GetFileVersion(SourcePath + "\..\..\Build\ARM64\Release\WinMergeU.exe")
 #define ShellExtensionVersion GetFileVersion(SourcePath + "..\..\Build\ShellExtension\ShellExtensionARM64.dll")
 
 #define AppVersion GetFileVersion(SourcePath + "\..\..\Build\ARM64\Release\WinMergeU.exe")
 #define ShellExtensionVersion GetFileVersion(SourcePath + "..\..\Build\ShellExtension\ShellExtensionARM64.dll")
+#define WinMergeContextMenuVersion GetFileVersion(SourcePath + "..\..\Build\ShellExtension\ARM64\WinMergeContextMenu.dll")
 
 [Setup]
 AppName=WinMerge
 
 [Setup]
 AppName=WinMerge
@@ -422,6 +423,8 @@ Source: ..\..\Plugins\WinMerge32BitPluginProxy\Release\WinMerge32BitPluginProxy.
 ;Source: ..\..\Build\ShellExtension\ShellExtensionU.dll; DestDir: {app}; Flags: uninsrestartdelete restartreplace promptifolder; MinVersion: 0, 4; Components: ShellExtension32bit; Check: not AreSourceAndDestinationOfShellExtensionSame(ExpandConstant('{app}\ShellExtensionU.dll'))
 ; 64-bit version of ShellExtension
 Source: ..\..\Build\ShellExtension\ShellExtensionARM64.dll; DestDir: {app}; Flags: uninsrestartdelete restartreplace promptifolder 64bit; MinVersion: 0,5.01.2600; Check: IsWin64 and not AreSourceAndDestinationOfShellExtensionSame(ExpandConstant('{app}\ShellExtensionARM64.dll'))
 ;Source: ..\..\Build\ShellExtension\ShellExtensionU.dll; DestDir: {app}; Flags: uninsrestartdelete restartreplace promptifolder; MinVersion: 0, 4; Components: ShellExtension32bit; Check: not AreSourceAndDestinationOfShellExtensionSame(ExpandConstant('{app}\ShellExtensionU.dll'))
 ; 64-bit version of ShellExtension
 Source: ..\..\Build\ShellExtension\ShellExtensionARM64.dll; DestDir: {app}; Flags: uninsrestartdelete restartreplace promptifolder 64bit; MinVersion: 0,5.01.2600; Check: IsWin64 and not AreSourceAndDestinationOfShellExtensionSame(ExpandConstant('{app}\ShellExtensionARM64.dll'))
+Source: ..\..\Build\ShellExtension\ARM64\WinMergeContextMenu.dll; DestDir: {app}; Flags: uninsrestartdelete restartreplace promptifolder 64bit; MinVersion: 0,5.01.2600; Check: IsWin64 and not AreSourceAndDestinationOfWinMergeContextMenuSame(ExpandConstant('{app}\WinMergeContextMenu.dll')) and UnregisterWinMergeContextMenuPackage
+Source: ..\..\Build\ShellExtension\WinMergeContextMenuPackage.msix; DestDir: {app}; Flags: uninsrestartdelete restartreplace promptifolder 64bit; MinVersion: 0,5.01.2600; Check: IsWin64 and not AreSourceAndDestinationOfWinMergeContextMenuSame(ExpandConstant('{app}\WinMergeContextMenuPackage.msix'))
 
 ; ArchiveSupport
 ;Please do not reorder the 7z Dlls by version they compress better ordered by platform and then by version
 
 ; ArchiveSupport
 ;Please do not reorder the 7z Dlls by version they compress better ordered by platform and then by version
@@ -732,21 +735,22 @@ Filename: {win}\Explorer.exe; Description: {cm:ViewStartMenuFolder}; Parameters:
 
 Filename: {app}\WinMergeU.exe; Description: {cm:LaunchProgram,WinMerge}; Flags: nowait postinstall skipifsilent runmaximized
 
 
 Filename: {app}\WinMergeU.exe; Description: {cm:LaunchProgram,WinMerge}; Flags: nowait postinstall skipifsilent runmaximized
 
-;Filename: {syswow64}\regsvr32.exe; Parameters: "/s ""{app}\ShellExtensionU.dll"""; Flags: waituntilidle; Check: IsAdminInstallMode; Components: ShellExtension32bit
-;Filename: {syswow64}\regsvr32.exe; Parameters: "/s /n /i:user ""{app}\ShellExtensionU.dll"""; Flags: waituntilidle; Check: not IsAdminInstallMode; Components: ShellExtension32bit
-Filename: {sys}\regsvr32.exe; Parameters: "/s ""{app}\ShellExtensionARM64.dll"""; Flags: waituntilidle; Check: IsAdminInstallMode
-Filename: {sys}\regsvr32.exe; Parameters: "/s /n /i:user ""{app}\ShellExtensionARM64.dll"""; Flags: waituntilidle; Check: not IsAdminInstallMode
+;Filename: {syswow64}\regsvr32.exe; Parameters: "/s ""{app}\ShellExtensionU.dll"""; Flags: waituntilterminated; Check: IsAdminInstallMode; Components: ShellExtension32bit
+;Filename: {syswow64}\regsvr32.exe; Parameters: "/s /n /i:user ""{app}\ShellExtensionU.dll"""; Flags: waituntilterminated; Check: not IsAdminInstallMode; Components: ShellExtension32bit
+Filename: {sys}\regsvr32.exe; Parameters: "/s ""{app}\ShellExtensionARM64.dll"""; Flags: waituntilterminated; Check: IsAdminInstallMode and not IsWindows11OrLater
+Filename: {sys}\regsvr32.exe; Parameters: "/s /n /i:user ""{app}\ShellExtensionARM64.dll"""; Flags: waituntilterminated; Check: not IsAdminInstallMode and not IsWindows11OrLater
 Filename: {app}\WinMerge32BitPluginProxy.exe; Parameters: "/RegServer"; Flags: waituntilidle; Check: IsAdminInstallMode
 Filename: {app}\WinMerge32BitPluginProxy.exe; Parameters: "/RegServerPerUser"; Flags: waituntilidle; Check: not IsAdminInstallMode
 Filename: {app}\WinMerge32BitPluginProxy.exe; Parameters: "/RegServer"; Flags: waituntilidle; Check: IsAdminInstallMode
 Filename: {app}\WinMerge32BitPluginProxy.exe; Parameters: "/RegServerPerUser"; Flags: waituntilidle; Check: not IsAdminInstallMode
+Filename: powershell.exe; Parameters: "-c ""$host.ui.RawUI.WindowTitle = 'Registering WinMergeContextMenu package...'; if ((Get-AppxPackage -name WinMerge) -eq $null) {{ Add-AppxPackage '{app}\WinMergeContextMenuPackage.msix' -ExternalLocation '{app}'}"""; Flags: waituntilterminated; Check: IsWindows11OrLater
 
 [UninstallRun]
 
 [UninstallRun]
-;Filename: {syswow64}\regsvr32.exe; Parameters: "/s /u ""{app}\ShellExtensionU.dll"""; Flags: waituntilidle; Check: IsAdminInstallMode; Components: ShellExtension32bit
-;Filename: {syswow64}\regsvr32.exe; Parameters: "/s /u /n /i:user ""{app}\ShellExtensionU.dll"""; Flags: waituntilidle; Check: not IsAdminInstallMode; Components: ShellExtension32bit
-Filename: {sys}\regsvr32.exe; Parameters: "/s /u ""{app}\ShellExtensionARM64.dll"""; Flags: waituntilidle; Check: IsAdminInstallMode
-Filename: {sys}\regsvr32.exe; Parameters: "/s /u /n /i:user ""{app}\ShellExtensionARM64.dll"""; Flags: waituntilidle; Check: not IsAdminInstallMode
+;Filename: {syswow64}\regsvr32.exe; Parameters: "/s /u ""{app}\ShellExtensionU.dll"""; Flags: waituntilterminated; Check: IsAdminInstallMode; Components: ShellExtension32bit
+;Filename: {syswow64}\regsvr32.exe; Parameters: "/s /u /n /i:user ""{app}\ShellExtensionU.dll"""; Flags: waituntilterminated; Check: not IsAdminInstallMode; Components: ShellExtension32bit
+Filename: {sys}\regsvr32.exe; Parameters: "/s /u ""{app}\ShellExtensionARM64.dll"""; Flags: waituntilterminated; Check: IsAdminInstallMode
+Filename: {sys}\regsvr32.exe; Parameters: "/s /u /n /i:user ""{app}\ShellExtensionARM64.dll"""; Flags: waituntilterminated; Check: not IsAdminInstallMode
 Filename: {app}\WinMerge32BitPluginProxy.exe; Parameters: "/UnregServer"; Flags: waituntilidle; Check: IsAdminInstallMode
 Filename: {app}\WinMerge32BitPluginProxy.exe; Parameters: "/UnregServerPerUser"; Flags: waituntilidle; Check: not IsAdminInstallMode
 Filename: {app}\WinMerge32BitPluginProxy.exe; Parameters: "/UnregServer"; Flags: waituntilidle; Check: IsAdminInstallMode
 Filename: {app}\WinMerge32BitPluginProxy.exe; Parameters: "/UnregServerPerUser"; Flags: waituntilidle; Check: not IsAdminInstallMode
-
+Filename: powershell.exe; Parameters: "-c ""$host.ui.RawUI.WindowTitle = 'Unregistering WinMergeContextMenu package...'; Get-AppxPackage -name WinMerge | Remove-AppxPackage"""; Flags: waituntilterminated
 
 [UninstallDelete]
 ;Remove 7-zip integration dlls possibly installed (by hand or using separate installer)
 
 [UninstallDelete]
 ;Remove 7-zip integration dlls possibly installed (by hand or using separate installer)
@@ -977,6 +981,18 @@ begin
     Result := false;
 end;
 
     Result := false;
 end;
 
+function AreSourceAndDestinationOfWinMergeContextMenuSame(Filename: String) : Boolean;
+var
+  ver: String;
+begin
+  ver := ''
+  GetVersionNumbersString(Filename, ver);
+  if ver = ExpandConstant('{#WinMergeContextMenuVersion}') then
+    Result := true
+  else
+    Result := false;
+end;
+
 procedure RegisterPreviousData(PreviousDataKey: Integer);
 begin
   SetPreviousData(PreviousDataKey, 'UseAs3WayMergeTool', BooleanToString(g_CheckListBox.Checked[0]));
 procedure RegisterPreviousData(PreviousDataKey: Integer);
 begin
   SetPreviousData(PreviousDataKey, 'UseAs3WayMergeTool', BooleanToString(g_CheckListBox.Checked[0]));
@@ -1006,3 +1022,26 @@ begin
   g_CheckListBox.AddRadioButton(ExpandConstant('{cm:MergeAtLeftPane}'), '', 1, StringToBoolean(GetPreviousData('MergeAtLeftPane', 'false')), True, nil);
   g_CheckListBox.AddCheckBox(ExpandConstant('{cm:AutoMergeAtStartup}'), '', 1, StringToBoolean(GetPreviousData('AutoMergeAtStartup', 'true')), True, False, True, nil);
 end;
   g_CheckListBox.AddRadioButton(ExpandConstant('{cm:MergeAtLeftPane}'), '', 1, StringToBoolean(GetPreviousData('MergeAtLeftPane', 'false')), True, nil);
   g_CheckListBox.AddCheckBox(ExpandConstant('{cm:AutoMergeAtStartup}'), '', 1, StringToBoolean(GetPreviousData('AutoMergeAtStartup', 'true')), True, False, True, nil);
 end;
+
+Function IsWindows11OrLater(): Boolean;
+Var
+  OSVersion: TWindowsVersion;
+Begin
+  GetWindowsVersionEx(OSVersion);
+  if OSVersion.Major > 10 then
+    Result := true
+  else if (OSVersion.Major = 10) and (OSVersion.Minor > 0) then
+    Result := true
+  else if (OSVersion.Major = 10) and (OSVersion.Build >= 22000) then
+    Result := true
+  else
+    Result := false;
+End;
+
+Function UnregisterWinMergeContextMenuPackage: Boolean;
+var
+  ResultCode: Integer;
+Begin;
+  Exec('powershell.exe', '-c "$host.ui.RawUI.WindowTitle = ""Unregistering WinMergeContextMenu package...""; Get-AppxPackage -name WinMerge | Remove-AppxPackage"', '', SW_SHOW, ewWaitUntilTerminated, ResultCode);  
+  Result := true;
+End;
\ No newline at end of file
index a231969..e873cc8 100644 (file)
@@ -49,6 +49,7 @@
 \r
 #define AppVersion GetFileVersion(SourcePath + "\..\..\Build\X64\Release\WinMergeU.exe")\r
 #define ShellExtensionVersion GetFileVersion(SourcePath + "..\..\Build\ShellExtension\ShellExtensionX64.dll")\r
 \r
 #define AppVersion GetFileVersion(SourcePath + "\..\..\Build\X64\Release\WinMergeU.exe")\r
 #define ShellExtensionVersion GetFileVersion(SourcePath + "..\..\Build\ShellExtension\ShellExtensionX64.dll")\r
+#define WinMergeContextMenuVersion GetFileVersion(SourcePath + "..\..\Build\ShellExtension\x64\WinMergeContextMenu.dll")\r
 \r
 [Setup]\r
 AppName=WinMerge\r
 \r
 [Setup]\r
 AppName=WinMerge\r
@@ -421,6 +422,8 @@ Source: ..\..\Plugins\WinMerge32BitPluginProxy\Release\WinMerge32BitPluginProxy.
 Source: ..\..\Build\ShellExtension\ShellExtensionU.dll; DestDir: {app}; Flags: uninsrestartdelete restartreplace promptifolder; MinVersion: 0, 4; Components: ShellExtension32bit; Check: not AreSourceAndDestinationOfShellExtensionSame(ExpandConstant('{app}\ShellExtensionU.dll'))\r
 ; 64-bit version of ShellExtension\r
 Source: ..\..\Build\ShellExtension\ShellExtensionX64.dll; DestDir: {app}; Flags: uninsrestartdelete restartreplace promptifolder 64bit; MinVersion: 0,5.01.2600; Check: IsWin64 and not AreSourceAndDestinationOfShellExtensionSame(ExpandConstant('{app}\ShellExtensionX64.dll'))\r
 Source: ..\..\Build\ShellExtension\ShellExtensionU.dll; DestDir: {app}; Flags: uninsrestartdelete restartreplace promptifolder; MinVersion: 0, 4; Components: ShellExtension32bit; Check: not AreSourceAndDestinationOfShellExtensionSame(ExpandConstant('{app}\ShellExtensionU.dll'))\r
 ; 64-bit version of ShellExtension\r
 Source: ..\..\Build\ShellExtension\ShellExtensionX64.dll; DestDir: {app}; Flags: uninsrestartdelete restartreplace promptifolder 64bit; MinVersion: 0,5.01.2600; Check: IsWin64 and not AreSourceAndDestinationOfShellExtensionSame(ExpandConstant('{app}\ShellExtensionX64.dll'))\r
+Source: ..\..\Build\ShellExtension\x64\WinMergeContextMenu.dll; DestDir: {app}; Flags: uninsrestartdelete restartreplace promptifolder 64bit; MinVersion: 0,5.01.2600; Check: IsWin64 and not AreSourceAndDestinationOfWinMergeContextMenuSame(ExpandConstant('{app}\WinMergeContextMenu.dll')) and UnregisterWinMergeContextMenuPackage\r
+Source: ..\..\Build\ShellExtension\WinMergeContextMenuPackage.msix; DestDir: {app}; Flags: uninsrestartdelete restartreplace promptifolder 64bit; MinVersion: 0,5.01.2600; Check: IsWin64 and not AreSourceAndDestinationOfWinMergeContextMenuSame(ExpandConstant('{app}\WinMergeContextMenuPackage.msix'))\r
 \r
 ; ArchiveSupport\r
 ;Please do not reorder the 7z Dlls by version they compress better ordered by platform and then by version\r
 \r
 ; ArchiveSupport\r
 ;Please do not reorder the 7z Dlls by version they compress better ordered by platform and then by version\r
@@ -731,21 +734,22 @@ Filename: {win}\Explorer.exe; Description: {cm:ViewStartMenuFolder}; Parameters:
 \r
 Filename: {app}\WinMergeU.exe; Description: {cm:LaunchProgram,WinMerge}; Flags: nowait postinstall skipifsilent runmaximized\r
 \r
 \r
 Filename: {app}\WinMergeU.exe; Description: {cm:LaunchProgram,WinMerge}; Flags: nowait postinstall skipifsilent runmaximized\r
 \r
-Filename: {syswow64}\regsvr32.exe; Parameters: "/s ""{app}\ShellExtensionU.dll"""; Flags: waituntilidle; Check: IsAdminInstallMode; Components: ShellExtension32bit\r
-Filename: {syswow64}\regsvr32.exe; Parameters: "/s /n /i:user ""{app}\ShellExtensionU.dll"""; Flags: waituntilidle; Check: not IsAdminInstallMode; Components: ShellExtension32bit\r
-Filename: {sys}\regsvr32.exe; Parameters: "/s ""{app}\ShellExtensionX64.dll"""; Flags: waituntilidle; Check: IsAdminInstallMode\r
-Filename: {sys}\regsvr32.exe; Parameters: "/s /n /i:user ""{app}\ShellExtensionX64.dll"""; Flags: waituntilidle; Check: not IsAdminInstallMode\r
+Filename: {syswow64}\regsvr32.exe; Parameters: "/s ""{app}\ShellExtensionU.dll"""; Flags: waituntilterminated; Check: IsAdminInstallMode; Components: ShellExtension32bit\r
+Filename: {syswow64}\regsvr32.exe; Parameters: "/s /n /i:user ""{app}\ShellExtensionU.dll"""; Flags: waituntilterminated; Check: not IsAdminInstallMode; Components: ShellExtension32bit\r
+Filename: {sys}\regsvr32.exe; Parameters: "/s ""{app}\ShellExtensionX64.dll"""; Flags: waituntilterminated; Check: IsAdminInstallMode and not IsWindows11OrLater\r
+Filename: {sys}\regsvr32.exe; Parameters: "/s /n /i:user ""{app}\ShellExtensionX64.dll"""; Flags: waituntilterminated; Check: not IsAdminInstallMode and not IsWindows11OrLater\r
 Filename: {app}\WinMerge32BitPluginProxy.exe; Parameters: "/RegServer"; Flags: waituntilidle; Check: IsAdminInstallMode\r
 Filename: {app}\WinMerge32BitPluginProxy.exe; Parameters: "/RegServerPerUser"; Flags: waituntilidle; Check: not IsAdminInstallMode\r
 Filename: {app}\WinMerge32BitPluginProxy.exe; Parameters: "/RegServer"; Flags: waituntilidle; Check: IsAdminInstallMode\r
 Filename: {app}\WinMerge32BitPluginProxy.exe; Parameters: "/RegServerPerUser"; Flags: waituntilidle; Check: not IsAdminInstallMode\r
+Filename: powershell.exe; Parameters: "-c ""$host.ui.RawUI.WindowTitle = 'Registering WinMergeContextMenu package...'; if ((Get-AppxPackage -name WinMerge) -eq $null) {{ Add-AppxPackage '{app}\WinMergeContextMenuPackage.msix' -ExternalLocation '{app}'}"""; Flags: waituntilterminated; Check: IsWindows11OrLater\r
 \r
 [UninstallRun]\r
 \r
 [UninstallRun]\r
-Filename: {syswow64}\regsvr32.exe; Parameters: "/s /u ""{app}\ShellExtensionU.dll"""; Flags: waituntilidle; Check: IsAdminInstallMode; Components: ShellExtension32bit\r
-Filename: {syswow64}\regsvr32.exe; Parameters: "/s /u /n /i:user ""{app}\ShellExtensionU.dll"""; Flags: waituntilidle; Check: not IsAdminInstallMode; Components: ShellExtension32bit\r
-Filename: {sys}\regsvr32.exe; Parameters: "/s /u ""{app}\ShellExtensionX64.dll"""; Flags: waituntilidle; Check: IsAdminInstallMode\r
-Filename: {sys}\regsvr32.exe; Parameters: "/s /u /n /i:user ""{app}\ShellExtensionX64.dll"""; Flags: waituntilidle; Check: not IsAdminInstallMode\r
+Filename: {syswow64}\regsvr32.exe; Parameters: "/s /u ""{app}\ShellExtensionU.dll"""; Flags: waituntilterminated; Check: IsAdminInstallMode; Components: ShellExtension32bit\r
+Filename: {syswow64}\regsvr32.exe; Parameters: "/s /u /n /i:user ""{app}\ShellExtensionU.dll"""; Flags: waituntilterminated; Check: not IsAdminInstallMode; Components: ShellExtension32bit\r
+Filename: {sys}\regsvr32.exe; Parameters: "/s /u ""{app}\ShellExtensionX64.dll"""; Flags: waituntilterminated; Check: IsAdminInstallMode\r
+Filename: {sys}\regsvr32.exe; Parameters: "/s /u /n /i:user ""{app}\ShellExtensionX64.dll"""; Flags: waituntilterminated; Check: not IsAdminInstallMode\r
 Filename: {app}\WinMerge32BitPluginProxy.exe; Parameters: "/UnregServer"; Flags: waituntilidle; Check: IsAdminInstallMode\r
 Filename: {app}\WinMerge32BitPluginProxy.exe; Parameters: "/UnregServerPerUser"; Flags: waituntilidle; Check: not IsAdminInstallMode\r
 Filename: {app}\WinMerge32BitPluginProxy.exe; Parameters: "/UnregServer"; Flags: waituntilidle; Check: IsAdminInstallMode\r
 Filename: {app}\WinMerge32BitPluginProxy.exe; Parameters: "/UnregServerPerUser"; Flags: waituntilidle; Check: not IsAdminInstallMode\r
-\r
+Filename: powershell.exe; Parameters: "-c ""$host.ui.RawUI.WindowTitle = 'Unregistering WinMergeContextMenu package...'; Get-AppxPackage -name WinMerge | Remove-AppxPackage"""; Flags: waituntilterminated\r
 \r
 [UninstallDelete]\r
 ;Remove 7-zip integration dlls possibly installed (by hand or using separate installer)\r
 \r
 [UninstallDelete]\r
 ;Remove 7-zip integration dlls possibly installed (by hand or using separate installer)\r
@@ -976,6 +980,18 @@ begin
     Result := false;\r
 end;\r
 \r
     Result := false;\r
 end;\r
 \r
+function AreSourceAndDestinationOfWinMergeContextMenuSame(Filename: String) : Boolean;\r
+var\r
+  ver: String;\r
+begin\r
+  ver := ''\r
+  GetVersionNumbersString(Filename, ver);\r
+  if ver = ExpandConstant('{#WinMergeContextMenuVersion}') then\r
+    Result := true\r
+  else\r
+    Result := false;\r
+end;\r
+\r
 procedure RegisterPreviousData(PreviousDataKey: Integer);\r
 begin\r
   SetPreviousData(PreviousDataKey, 'UseAs3WayMergeTool', BooleanToString(g_CheckListBox.Checked[0]));\r
 procedure RegisterPreviousData(PreviousDataKey: Integer);\r
 begin\r
   SetPreviousData(PreviousDataKey, 'UseAs3WayMergeTool', BooleanToString(g_CheckListBox.Checked[0]));\r
@@ -1005,3 +1021,26 @@ begin
   g_CheckListBox.AddRadioButton(ExpandConstant('{cm:MergeAtLeftPane}'), '', 1, StringToBoolean(GetPreviousData('MergeAtLeftPane', 'false')), True, nil);\r
   g_CheckListBox.AddCheckBox(ExpandConstant('{cm:AutoMergeAtStartup}'), '', 1, StringToBoolean(GetPreviousData('AutoMergeAtStartup', 'true')), True, False, True, nil);\r
 end;\r
   g_CheckListBox.AddRadioButton(ExpandConstant('{cm:MergeAtLeftPane}'), '', 1, StringToBoolean(GetPreviousData('MergeAtLeftPane', 'false')), True, nil);\r
   g_CheckListBox.AddCheckBox(ExpandConstant('{cm:AutoMergeAtStartup}'), '', 1, StringToBoolean(GetPreviousData('AutoMergeAtStartup', 'true')), True, False, True, nil);\r
 end;\r
+\r
+Function IsWindows11OrLater(): Boolean;\r
+Var\r
+  OSVersion: TWindowsVersion;\r
+Begin\r
+  GetWindowsVersionEx(OSVersion);\r
+  if OSVersion.Major > 10 then\r
+    Result := true\r
+  else if (OSVersion.Major = 10) and (OSVersion.Minor > 0) then\r
+    Result := true\r
+  else if (OSVersion.Major = 10) and (OSVersion.Build >= 22000) then\r
+    Result := true\r
+  else\r
+    Result := false;\r
+End;\r
+\r
+Function UnregisterWinMergeContextMenuPackage: Boolean;\r
+var\r
+  ResultCode: Integer;\r
+Begin;\r
+  Exec('powershell.exe', '-c "$host.ui.RawUI.WindowTitle = ""Unregistering WinMergeContextMenu package...""; Get-AppxPackage -name WinMerge | Remove-AppxPackage"', '', SW_SHOW, ewWaitUntilTerminated, ResultCode);  \r
+  Result := true;\r
+End;
\ No newline at end of file
index 36f6212..5e078d8 100644 (file)
@@ -49,6 +49,7 @@
 \r
 #define AppVersion GetFileVersion(SourcePath + "\..\..\Build\X64\Release\WinMergeU.exe")\r
 #define ShellExtensionVersion GetFileVersion(SourcePath + "..\..\Build\ShellExtension\ShellExtensionX64.dll")\r
 \r
 #define AppVersion GetFileVersion(SourcePath + "\..\..\Build\X64\Release\WinMergeU.exe")\r
 #define ShellExtensionVersion GetFileVersion(SourcePath + "..\..\Build\ShellExtension\ShellExtensionX64.dll")\r
+#define WinMergeContextMenuVersion GetFileVersion(SourcePath + "..\..\Build\ShellExtension\x64\WinMergeContextMenu.dll")\r
 \r
 [Setup]\r
 AppName=WinMerge\r
 \r
 [Setup]\r
 AppName=WinMerge\r
@@ -412,7 +413,9 @@ Source: ..\..\Plugins\WinMerge32BitPluginProxy\Release\WinMerge32BitPluginProxy.
 ; Shell extension\r
 Source: ..\..\Build\ShellExtension\ShellExtensionU.dll; DestDir: {app}; Flags: regserver uninsrestartdelete restartreplace promptifolder 32bit; MinVersion: 0, 4; Components: ShellExtension32bit; Check: not AreSourceAndDestinationOfShellExtensionSame(ExpandConstant('{app}\ShellExtensionU.dll'))\r
 ; 64-bit version of ShellExtension\r
 ; Shell extension\r
 Source: ..\..\Build\ShellExtension\ShellExtensionU.dll; DestDir: {app}; Flags: regserver uninsrestartdelete restartreplace promptifolder 32bit; MinVersion: 0, 4; Components: ShellExtension32bit; Check: not AreSourceAndDestinationOfShellExtensionSame(ExpandConstant('{app}\ShellExtensionU.dll'))\r
 ; 64-bit version of ShellExtension\r
-Source: ..\..\Build\ShellExtension\ShellExtensionX64.dll; DestDir: {app}; Flags: regserver uninsrestartdelete restartreplace promptifolder 64bit; MinVersion: 0,5.01.2600; Check: IsWin64 and not AreSourceAndDestinationOfShellExtensionSame(ExpandConstant('{app}\ShellExtensionX64.dll'))\r
+Source: ..\..\Build\ShellExtension\ShellExtensionX64.dll; DestDir: {app}; Flags: uninsrestartdelete restartreplace promptifolder 64bit; MinVersion: 0,5.01.2600; Check: IsWin64 and not AreSourceAndDestinationOfShellExtensionSame(ExpandConstant('{app}\ShellExtensionX64.dll'))\r
+Source: ..\..\Build\ShellExtension\x64\WinMergeContextMenu.dll; DestDir: {app}; Flags: uninsrestartdelete restartreplace promptifolder 64bit; MinVersion: 0,5.01.2600; Check: IsWin64 and not AreSourceAndDestinationOfWinMergeContextMenuSame(ExpandConstant('{app}\WinMergeContextMenu.dll')) and UnregisterWinMergeContextMenuPackage\r
+Source: ..\..\Build\ShellExtension\WinMergeContextMenuPackage.msix; DestDir: {app}; Flags: uninsrestartdelete restartreplace promptifolder 64bit; MinVersion: 0,5.01.2600; Check: IsWin64 and not AreSourceAndDestinationOfWinMergeContextMenuSame(ExpandConstant('{app}\WinMergeContextMenuPackage.msix'))\r
 \r
 ; ArchiveSupport\r
 ;Please do not reorder the 7z Dlls by version they compress better ordered by platform and then by version\r
 \r
 ; ArchiveSupport\r
 ;Please do not reorder the 7z Dlls by version they compress better ordered by platform and then by version\r
@@ -720,11 +723,14 @@ Filename: {win}\Explorer.exe; Description: {cm:ViewStartMenuFolder}; Parameters:
 \r
 Filename: {app}\WinMergeU.exe; Description: {cm:LaunchProgram,WinMerge}; Flags: nowait postinstall skipifsilent runmaximized\r
 \r
 \r
 Filename: {app}\WinMergeU.exe; Description: {cm:LaunchProgram,WinMerge}; Flags: nowait postinstall skipifsilent runmaximized\r
 \r
+Filename: {sys}\regsvr32.exe; Parameters: "/s ""{app}\ShellExtensionX64.dll"""; Flags: waituntilterminated; Check: not IsWindows11OrLater\r
 Filename: {app}\WinMerge32BitPluginProxy.exe; Parameters: "/RegServer"; Flags: waituntilidle\r
 Filename: {app}\WinMerge32BitPluginProxy.exe; Parameters: "/RegServer"; Flags: waituntilidle\r
+Filename: powershell.exe; Parameters: "-c ""$host.ui.RawUI.WindowTitle = 'Registering WinMergeContextMenu package...'; if ((Get-AppxPackage -name WinMerge) -eq $null) {{ Add-AppxPackage '{app}\WinMergeContextMenuPackage.msix' -ExternalLocation '{app}'}"""; Flags: waituntilterminated; Check: IsWindows11OrLater\r
 \r
 [UninstallRun]\r
 \r
 [UninstallRun]\r
+Filename: {sys}\regsvr32.exe; Parameters: "/s /u ""{app}\ShellExtensionX64.dll"""; Flags: waituntilterminated\r
 Filename: {app}\WinMerge32BitPluginProxy.exe; Parameters: "/UnregServer"; Flags: waituntilidle\r
 Filename: {app}\WinMerge32BitPluginProxy.exe; Parameters: "/UnregServer"; Flags: waituntilidle\r
-\r
+Filename: powershell.exe; Parameters: "-c ""$host.ui.RawUI.WindowTitle = 'Unregistering WinMergeContextMenu package...'; Get-AppxPackage -name WinMerge | Remove-AppxPackage"""; Flags: waituntilterminated\r
 \r
 [UninstallDelete]\r
 ;Remove 7-zip integration dlls possibly installed (by hand or using separate installer)\r
 \r
 [UninstallDelete]\r
 ;Remove 7-zip integration dlls possibly installed (by hand or using separate installer)\r
@@ -955,6 +961,18 @@ begin
     Result := false;\r
 end;\r
 \r
     Result := false;\r
 end;\r
 \r
+function AreSourceAndDestinationOfWinMergeContextMenuSame(Filename: String) : Boolean;\r
+var\r
+  ver: String;\r
+begin\r
+  ver := ''\r
+  GetVersionNumbersString(Filename, ver);\r
+  if ver = ExpandConstant('{#WinMergeContextMenuVersion}') then\r
+    Result := true\r
+  else\r
+    Result := false;\r
+end;\r
+\r
 procedure RegisterPreviousData(PreviousDataKey: Integer);\r
 begin\r
   SetPreviousData(PreviousDataKey, 'UseAs3WayMergeTool', BooleanToString(g_CheckListBox.Checked[0]));\r
 procedure RegisterPreviousData(PreviousDataKey: Integer);\r
 begin\r
   SetPreviousData(PreviousDataKey, 'UseAs3WayMergeTool', BooleanToString(g_CheckListBox.Checked[0]));\r
@@ -987,3 +1005,26 @@ begin
   g_CheckListBox.AddRadioButton(ExpandConstant('{cm:MergeAtLeftPane}'), '', 1, StringToBoolean(GetPreviousData('MergeAtLeftPane', 'false')), True, nil);\r
   g_CheckListBox.AddCheckBox(ExpandConstant('{cm:AutoMergeAtStartup}'), '', 1, StringToBoolean(GetPreviousData('AutoMergeAtStartup', 'true')), True, False, True, nil);\r
 end;\r
   g_CheckListBox.AddRadioButton(ExpandConstant('{cm:MergeAtLeftPane}'), '', 1, StringToBoolean(GetPreviousData('MergeAtLeftPane', 'false')), True, nil);\r
   g_CheckListBox.AddCheckBox(ExpandConstant('{cm:AutoMergeAtStartup}'), '', 1, StringToBoolean(GetPreviousData('AutoMergeAtStartup', 'true')), True, False, True, nil);\r
 end;\r
+\r
+Function IsWindows11OrLater(): Boolean;\r
+Var\r
+  OSVersion: TWindowsVersion;\r
+Begin\r
+  GetWindowsVersionEx(OSVersion);\r
+  if OSVersion.Major > 10 then\r
+    Result := true\r
+  else if (OSVersion.Major = 10) and (OSVersion.Minor > 0) then\r
+    Result := true\r
+  else if (OSVersion.Major = 10) and (OSVersion.Build >= 22000) then\r
+    Result := true\r
+  else\r
+    Result := false;\r
+End;\r
+\r
+Function UnregisterWinMergeContextMenuPackage: Boolean;\r
+var\r
+  ResultCode: Integer;\r
+Begin;\r
+  Exec('powershell.exe', '-c "$host.ui.RawUI.WindowTitle = ""Unregistering WinMergeContextMenu package...""; Get-AppxPackage -name WinMerge | Remove-AppxPackage"', '', SW_SHOW, ewWaitUntilTerminated, ResultCode);  \r
+  Result := true;\r
+End;
\ No newline at end of file
index 26a185e..212a316 100644 (file)
@@ -49,6 +49,7 @@
 
 #define AppVersion GetFileVersion(SourcePath + "\..\..\Build\X64\Release\WinMergeU.exe")
 #define ShellExtensionVersion GetFileVersion(SourcePath + "..\..\Build\ShellExtension\ShellExtensionX64.dll")
 
 #define AppVersion GetFileVersion(SourcePath + "\..\..\Build\X64\Release\WinMergeU.exe")
 #define ShellExtensionVersion GetFileVersion(SourcePath + "..\..\Build\ShellExtension\ShellExtensionX64.dll")
+#define WinMergeContextMenuVersion GetFileVersion(SourcePath + "..\..\Build\ShellExtension\x64\WinMergeContextMenu.dll")
 
 [Setup]
 AppName=WinMerge
 
 [Setup]
 AppName=WinMerge
@@ -412,6 +413,8 @@ Source: ..\..\Plugins\WinMerge32BitPluginProxy\Release\WinMerge32BitPluginProxy.
 Source: ..\..\Build\ShellExtension\ShellExtensionU.dll; DestDir: {app}; Flags: uninsrestartdelete restartreplace promptifolder; MinVersion: 0, 4; Components: ShellExtension32bit; Check: not AreSourceAndDestinationOfShellExtensionSame(ExpandConstant('{app}\ShellExtensionU.dll'))
 ; 64-bit version of ShellExtension
 Source: ..\..\Build\ShellExtension\ShellExtensionX64.dll; DestDir: {app}; Flags: uninsrestartdelete restartreplace promptifolder 64bit; MinVersion: 0,5.01.2600; Check: IsWin64 and not AreSourceAndDestinationOfShellExtensionSame(ExpandConstant('{app}\ShellExtensionX64.dll'))
 Source: ..\..\Build\ShellExtension\ShellExtensionU.dll; DestDir: {app}; Flags: uninsrestartdelete restartreplace promptifolder; MinVersion: 0, 4; Components: ShellExtension32bit; Check: not AreSourceAndDestinationOfShellExtensionSame(ExpandConstant('{app}\ShellExtensionU.dll'))
 ; 64-bit version of ShellExtension
 Source: ..\..\Build\ShellExtension\ShellExtensionX64.dll; DestDir: {app}; Flags: uninsrestartdelete restartreplace promptifolder 64bit; MinVersion: 0,5.01.2600; Check: IsWin64 and not AreSourceAndDestinationOfShellExtensionSame(ExpandConstant('{app}\ShellExtensionX64.dll'))
+Source: ..\..\Build\ShellExtension\x64\WinMergeContextMenu.dll; DestDir: {app}; Flags: uninsrestartdelete restartreplace promptifolder 64bit; MinVersion: 0,5.01.2600; Check: IsWin64 and not AreSourceAndDestinationOfWinMergeContextMenuSame(ExpandConstant('{app}\WinMergeContextMenu.dll')) and UnregisterWinMergeContextMenuPackage
+Source: ..\..\Build\ShellExtension\WinMergeContextMenuPackage.msix; DestDir: {app}; Flags: uninsrestartdelete restartreplace promptifolder 64bit; MinVersion: 0,5.01.2600; Check: IsWin64 and not AreSourceAndDestinationOfWinMergeContextMenuSame(ExpandConstant('{app}\WinMergeContextMenuPackage.msix'))
 
 ; ArchiveSupport
 ;Please do not reorder the 7z Dlls by version they compress better ordered by platform and then by version
 
 ; ArchiveSupport
 ;Please do not reorder the 7z Dlls by version they compress better ordered by platform and then by version
@@ -716,15 +719,16 @@ Filename: {win}\Explorer.exe; Description: {cm:ViewStartMenuFolder}; Parameters:
 
 Filename: {app}\WinMergeU.exe; Description: {cm:LaunchProgram,WinMerge}; Flags: nowait postinstall skipifsilent runmaximized
 
 
 Filename: {app}\WinMergeU.exe; Description: {cm:LaunchProgram,WinMerge}; Flags: nowait postinstall skipifsilent runmaximized
 
-Filename: {syswow64}\regsvr32.exe; Parameters: "/s /n /i:user ""{app}\ShellExtensionU.dll"""; Flags: waituntilidle; Components: ShellExtension32bit
-Filename: {sys}\regsvr32.exe; Parameters: "/s /n /i:user ""{app}\ShellExtensionX64.dll"""; Flags: waituntilidle
+Filename: {syswow64}\regsvr32.exe; Parameters: "/s /n /i:user ""{app}\ShellExtensionU.dll"""; Flags: waituntilterminated; Components: ShellExtension32bit
+Filename: {sys}\regsvr32.exe; Parameters: "/s /n /i:user ""{app}\ShellExtensionX64.dll"""; Flags: waituntilterminated; Check: not IsWindows11OrLater
 Filename: {app}\WinMerge32BitPluginProxy.exe; Parameters: "/RegServerPerUser"; Flags: waituntilidle
 Filename: {app}\WinMerge32BitPluginProxy.exe; Parameters: "/RegServerPerUser"; Flags: waituntilidle
+Filename: powershell.exe; Parameters: "-c ""$host.ui.RawUI.WindowTitle = 'Registering WinMergeContextMenu package...'; if ((Get-AppxPackage -name WinMerge) -eq $null) {{ Add-AppxPackage '{app}\WinMergeContextMenuPackage.msix' -ExternalLocation '{app}'}"""; Flags: waituntilterminated; Check: IsWindows11OrLater
 
 [UninstallRun]
 
 [UninstallRun]
-Filename: {syswow64}\regsvr32.exe; Parameters: "/s /u /n /i:user ""{app}\ShellExtensionU.dll"""; Flags: waituntilidle; Components: ShellExtension32bit
-Filename: {sys}\regsvr32.exe; Parameters: "/s /u /n /i:user ""{app}\ShellExtensionX64.dll"""; Flags: waituntilidle
+Filename: {syswow64}\regsvr32.exe; Parameters: "/s /u /n /i:user ""{app}\ShellExtensionU.dll"""; Flags: waituntilterminated; Components: ShellExtension32bit
+Filename: {sys}\regsvr32.exe; Parameters: "/s /u /n /i:user ""{app}\ShellExtensionX64.dll"""; Flags: waituntilterminated
 Filename: {app}\WinMerge32BitPluginProxy.exe; Parameters: "/UnregServerPerUser"; Flags: waituntilidle
 Filename: {app}\WinMerge32BitPluginProxy.exe; Parameters: "/UnregServerPerUser"; Flags: waituntilidle
-
+Filename: powershell.exe; Parameters: "-c ""$host.ui.RawUI.WindowTitle = 'Unregistering WinMergeContextMenu package...'; Get-AppxPackage -name WinMerge | Remove-AppxPackage"""; Flags: waituntilterminated
 
 [UninstallDelete]
 ;Remove 7-zip integration dlls possibly installed (by hand or using separate installer)
 
 [UninstallDelete]
 ;Remove 7-zip integration dlls possibly installed (by hand or using separate installer)
@@ -955,6 +959,18 @@ begin
     Result := false;
 end;
 
     Result := false;
 end;
 
+function AreSourceAndDestinationOfWinMergeContextMenuSame(Filename: String) : Boolean;
+var
+  ver: String;
+begin
+  ver := ''
+  GetVersionNumbersString(Filename, ver);
+  if ver = ExpandConstant('{#WinMergeContextMenuVersion}') then
+    Result := true
+  else
+    Result := false;
+end;
+
 procedure RegisterPreviousData(PreviousDataKey: Integer);
 begin
   SetPreviousData(PreviousDataKey, 'UseAs3WayMergeTool', BooleanToString(g_CheckListBox.Checked[0]));
 procedure RegisterPreviousData(PreviousDataKey: Integer);
 begin
   SetPreviousData(PreviousDataKey, 'UseAs3WayMergeTool', BooleanToString(g_CheckListBox.Checked[0]));
@@ -987,3 +1003,26 @@ begin
   g_CheckListBox.AddRadioButton(ExpandConstant('{cm:MergeAtLeftPane}'), '', 1, StringToBoolean(GetPreviousData('MergeAtLeftPane', 'false')), True, nil);
   g_CheckListBox.AddCheckBox(ExpandConstant('{cm:AutoMergeAtStartup}'), '', 1, StringToBoolean(GetPreviousData('AutoMergeAtStartup', 'true')), True, False, True, nil);
 end;
   g_CheckListBox.AddRadioButton(ExpandConstant('{cm:MergeAtLeftPane}'), '', 1, StringToBoolean(GetPreviousData('MergeAtLeftPane', 'false')), True, nil);
   g_CheckListBox.AddCheckBox(ExpandConstant('{cm:AutoMergeAtStartup}'), '', 1, StringToBoolean(GetPreviousData('AutoMergeAtStartup', 'true')), True, False, True, nil);
 end;
+
+Function IsWindows11OrLater(): Boolean;
+Var
+  OSVersion: TWindowsVersion;
+Begin
+  GetWindowsVersionEx(OSVersion);
+  if OSVersion.Major > 10 then
+    Result := true
+  else if (OSVersion.Major = 10) and (OSVersion.Minor > 0) then
+    Result := true
+  else if (OSVersion.Major = 10) and (OSVersion.Build >= 22000) then
+    Result := true
+  else
+    Result := false;
+End;
+
+Function UnregisterWinMergeContextMenuPackage: Boolean;
+var
+  ResultCode: Integer;
+Begin;
+  Exec('powershell.exe', '-c "$host.ui.RawUI.WindowTitle = ""Unregistering WinMergeContextMenu package...""; Get-AppxPackage -name WinMerge | Remove-AppxPackage"', '', SW_SHOW, ewWaitUntilTerminated, ResultCode);  
+  Result := true;
+End;
\ No newline at end of file
index 7189464..6ffb358 100644 (file)
@@ -5,10 +5,15 @@ set PATH="%ProgramFiles%\7-zip";"%ProgramFiles(x86)%\7-zip";%PATH%
 set DISTDIR=..\Build\Releases
 
 mkdir ..\Build\ShellExtension 2> NUL
 set DISTDIR=..\Build\Releases
 
 mkdir ..\Build\ShellExtension 2> NUL
+mkdir ..\Build\ShellExtension\x64 2> NUL
+mkdir ..\Build\ShellExtension\ARM64 2> NUL
 
 copy /y "..\Build\Release\ShellExtensionU.dll" ..\Build\ShellExtension\
 copy /y "..\Build\x64\Release\ShellExtensionX64.dll" ..\Build\ShellExtension\
 
 copy /y "..\Build\Release\ShellExtensionU.dll" ..\Build\ShellExtension\
 copy /y "..\Build\x64\Release\ShellExtensionX64.dll" ..\Build\ShellExtension\
+copy /y "..\Build\x64\Release\WinMergeContextMenu.dll" ..\Build\ShellExtension\x64
 copy /y "..\Build\ARM64\Release\ShellExtensionARM64.dll" ..\Build\ShellExtension\
 copy /y "..\Build\ARM64\Release\ShellExtensionARM64.dll" ..\Build\ShellExtension\
+copy /y "..\Build\ARM64\Release\WinMergeContextMenu.dll" ..\Build\ShellExtension\ARM64
+copy /y "..\Build\x64\Release\WinMergeContextMenuPackage.msix" ..\Build\ShellExtension\
 
 WMIC Path CIM_DataFile WHERE Name='%CD:\=\\%\\..\\Build\\ShellExtension\\ShellExtensionX64.dll' Get Version | findstr /v Version > _tmp_.txt
 set /P DLLVERSIONTMP=<_tmp_.txt
 
 WMIC Path CIM_DataFile WHERE Name='%CD:\=\\%\\..\\Build\\ShellExtension\\ShellExtensionX64.dll' Get Version | findstr /v Version > _tmp_.txt
 set /P DLLVERSIONTMP=<_tmp_.txt
index bfc8361..6f27aa3 100644 (file)
@@ -31,7 +31,8 @@ MSBuild ShellExtension.vs2017.sln /t:Rebuild /p:Configuration="Release" /p:Platf
 endlocal
 
 if exist "%SIGNBAT_PATH%" (
 endlocal
 
 if exist "%SIGNBAT_PATH%" (
-  call "%SIGNBAT_PATH%" "Build\%PLATFORM%\Release\%DLLFILENAME%"
+  call "%SIGNBAT_PATH%" "..\Build\%PLATFORM%\Release\%DLLFILENAME%"
+  call "%SIGNBAT_PATH%" "..\Build\%PLATFORM%\Release\WinMergeContextMenu.dll
 )
 
 goto :eof
 )
 
 goto :eof
index 9109378..0ed953e 100644 (file)
@@ -32,6 +32,7 @@ endlocal
 
 if exist "%SIGNBAT_PATH%" (
   call "%SIGNBAT_PATH%" "Build\%PLATFORM%\Release\%DLLFILENAME%"
 
 if exist "%SIGNBAT_PATH%" (
   call "%SIGNBAT_PATH%" "Build\%PLATFORM%\Release\%DLLFILENAME%"
+  call "%SIGNBAT_PATH%" "Build\%PLATFORM%\Release\WinMergeContextMenu.dll
 )
 
 goto :eof
 )
 
 goto :eof
diff --git a/ShellExtension/CreateWinMergeContextMenuPackage.bat b/ShellExtension/CreateWinMergeContextMenuPackage.bat
new file mode 100644 (file)
index 0000000..df37f85
--- /dev/null
@@ -0,0 +1 @@
+powershell -executionpolicy remotesigned %~dp0CreateWinMergeContextMenuPackage.ps1
\ No newline at end of file
diff --git a/ShellExtension/CreateWinMergeContextMenuPackage.ps1 b/ShellExtension/CreateWinMergeContextMenuPackage.ps1
new file mode 100644 (file)
index 0000000..ed71bd2
--- /dev/null
@@ -0,0 +1,44 @@
+$vspath = & "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" -latest -property installationPath
+$instid = & "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" -latest -property instanceId
+Import-Module "$vspath\Common7\Tools\Microsoft.VisualStudio.DevShell.dll"
+Enter-VsDevShell $instid -DevCmdArguments -arch=x64
+
+cd $(Split-Path $MyInvocation.MyCommand.Path -Parent)
+
+if (($env:SIGNBAT_PATH -eq "") -or !(Test-Path publisher.txt) -or (($args[0] -ne $null) -and ($args[0].ToLower() -eq "selfsignedpackage"))) {
+  $publisher = "CN=winmergedev"
+} else {
+  $publisher = Get-Content publisher.txt
+  $certList = dir Cert:\CurrentUser\My | where { $_.Subject -eq $publisher }
+  if ($certList.Length -eq 0) {
+    $publisher = "CN=winmergedev"
+  }
+}
+
+Get-Content WinMergePkg\AppxManifest.xml.in | % { $_ -replace '\${Publisher}',$publisher } | Set-Content WinMergePkg\AppxManifest.xml
+if (Test-Path WinMergeContextMenuPackage.msix) { del WinMergeContextMenuPackage.msix }
+MakeAppx.exe pack /d WinMergePkg /p WinMergeContextMenuPackage.msix /nv
+
+if ($publisher -eq "CN=winmergedev") {
+  $certList = dir Cert:\CurrentUser\My | where { $_.Subject -eq $publisher  }
+  if ($certList.Length -eq 0)  {
+    $cert = New-SelfSignedCertificate -Type Custom -Subject $publisher -KeyUsage DigitalSignature -FriendlyName "Your friendly name goes here" -CertStoreLocation "Cert:\CurrentUser\My" -TextExtension @("2.5.29.37={text}1.3.6.1.5.5.7.3.3", "2.5.29.19={text}")
+  } else {
+    $cert = $certList[0]
+  }
+
+  $certPassword = ConvertTo-SecureString -String "test" -Force -AsPlainText
+  Export-PfxCertificate -Cert $cert -FilePath selfsigncert.pfx -Password $certPassword
+  Export-Certificate -Type CERT -Cert $cert -FilePath selfsigncert.cer
+
+  SignTool.exe sign /fd SHA256 /a /f selfsigncert.pfx /p test /v WinMergeContextMenuPackage.msix
+} else {
+  & $env:SIGNBAT_PATH WinMergeContextMenuPackage.msix
+}
+
+foreach($i in @("", "X64\", "ARM64\")) {
+  foreach($j in @("Debug", "Release")) {
+    if (!(Test-Path ..\Build\$i$j)) { mkdir ..\Build\$i$j }
+    copy WinMergeContextMenuPackage.msix ..\Build\$i$j
+  }
+}
diff --git a/ShellExtension/CreateWinMergeContextMenuSelfSignedPackage.bat b/ShellExtension/CreateWinMergeContextMenuSelfSignedPackage.bat
new file mode 100644 (file)
index 0000000..c1138b7
--- /dev/null
@@ -0,0 +1,2 @@
+powershell -executionpolicy remotesigned %~dp0CreateWinMergeContextMenuPackage.ps1 SelfSignedPackage
+pause
\ No newline at end of file
diff --git a/ShellExtension/RegisterWinMergeContextMenuPackage.bat b/ShellExtension/RegisterWinMergeContextMenuPackage.bat
new file mode 100644 (file)
index 0000000..ba49343
--- /dev/null
@@ -0,0 +1 @@
+powershell -c Add-AppxPackage "%~dp0WinMergeContextMenuPackage.msix" -ExternalLocation "%~dp0"
diff --git a/ShellExtension/RegisterWinMergeContextMenuX64DebugPackage.bat b/ShellExtension/RegisterWinMergeContextMenuX64DebugPackage.bat
new file mode 100644 (file)
index 0000000..29d75a1
--- /dev/null
@@ -0,0 +1,3 @@
+cd %~dp0..
+powershell -c Add-AppxPackage %~dp0WinMergeContextMenuPackage.msix -ExternalLocation %CD%\Build\x64\Debug
+pause
index 2c9b794..643e86f 100644 (file)
@@ -4,6 +4,31 @@ VisualStudioVersion = 15.0.27130.0
 MinimumVisualStudioVersion = 10.0.40219.1\r
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ShellExtension", "ShellExtension\ShellExtension.vcxproj", "{76A538A1-9D2C-49CB-AE9F-72548CE37F88}"\r
 EndProject\r
 MinimumVisualStudioVersion = 10.0.40219.1\r
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ShellExtension", "ShellExtension\ShellExtension.vcxproj", "{76A538A1-9D2C-49CB-AE9F-72548CE37F88}"\r
 EndProject\r
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "WinMergePkg", "WinMergePkg", "{AD7D9F86-6CF2-43BB-B3E4-0FC222AECBFE}"\r
+       ProjectSection(SolutionItems) = preProject\r
+               WinMergePkg\AppxManifest.xml.in = WinMergePkg\AppxManifest.xml.in\r
+       EndProjectSection\r
+EndProject\r
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WinMergeContextMenu", "WinMergeContextMenu\WinMergeContextMenu.vcxproj", "{16746B0C-5840-4ED4-AEDF-1ABB617827FD}"\r
+EndProject\r
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Scripts", "Scripts", "{8C870F7A-C681-4D1A-9B4A-B0B7D4A5AE35}"\r
+       ProjectSection(SolutionItems) = preProject\r
+               BuildArc.cmd = BuildArc.cmd\r
+               BuildBin.vs2017.cmd = BuildBin.vs2017.cmd\r
+               BuildBin.vs2019.cmd = BuildBin.vs2019.cmd\r
+               CreateWinMergeContextMenuPackage.bat = CreateWinMergeContextMenuPackage.bat\r
+               CreateWinMergeContextMenuPackage.ps1 = CreateWinMergeContextMenuPackage.ps1\r
+               CreateWinMergeContextMenuSelfSignedPackage.bat = CreateWinMergeContextMenuSelfSignedPackage.bat\r
+               Register.bat = Register.bat\r
+               RegisterPerUser.bat = RegisterPerUser.bat\r
+               RegisterWinMergeContextMenuPackage.bat = RegisterWinMergeContextMenuPackage.bat\r
+               RegisterWinMergeContextMenuX64DebugPackage.bat = RegisterWinMergeContextMenuX64DebugPackage.bat\r
+               SignShellExtension.bat = SignShellExtension.bat\r
+               UnRegister.bat = UnRegister.bat\r
+               UnRegisterPerUser.bat = UnRegisterPerUser.bat\r
+               UnregisterWinMergeContextMenuPackage.bat = UnregisterWinMergeContextMenuPackage.bat\r
+       EndProjectSection\r
+EndProject\r
 Global\r
        GlobalSection(SolutionConfigurationPlatforms) = preSolution\r
                Debug|ARM64 = Debug|ARM64\r
 Global\r
        GlobalSection(SolutionConfigurationPlatforms) = preSolution\r
                Debug|ARM64 = Debug|ARM64\r
@@ -26,6 +51,16 @@ Global
                {76A538A1-9D2C-49CB-AE9F-72548CE37F88}.Release|Win32.Build.0 = Release|Win32\r
                {76A538A1-9D2C-49CB-AE9F-72548CE37F88}.Release|x64.ActiveCfg = Release|x64\r
                {76A538A1-9D2C-49CB-AE9F-72548CE37F88}.Release|x64.Build.0 = Release|x64\r
                {76A538A1-9D2C-49CB-AE9F-72548CE37F88}.Release|Win32.Build.0 = Release|Win32\r
                {76A538A1-9D2C-49CB-AE9F-72548CE37F88}.Release|x64.ActiveCfg = Release|x64\r
                {76A538A1-9D2C-49CB-AE9F-72548CE37F88}.Release|x64.Build.0 = Release|x64\r
+               {16746B0C-5840-4ED4-AEDF-1ABB617827FD}.Debug|ARM64.ActiveCfg = Debug|ARM64\r
+               {16746B0C-5840-4ED4-AEDF-1ABB617827FD}.Debug|ARM64.Build.0 = Debug|ARM64\r
+               {16746B0C-5840-4ED4-AEDF-1ABB617827FD}.Debug|Win32.ActiveCfg = Debug|x64\r
+               {16746B0C-5840-4ED4-AEDF-1ABB617827FD}.Debug|x64.ActiveCfg = Debug|x64\r
+               {16746B0C-5840-4ED4-AEDF-1ABB617827FD}.Debug|x64.Build.0 = Debug|x64\r
+               {16746B0C-5840-4ED4-AEDF-1ABB617827FD}.Release|ARM64.ActiveCfg = Release|ARM64\r
+               {16746B0C-5840-4ED4-AEDF-1ABB617827FD}.Release|ARM64.Build.0 = Release|ARM64\r
+               {16746B0C-5840-4ED4-AEDF-1ABB617827FD}.Release|Win32.ActiveCfg = Release|x64\r
+               {16746B0C-5840-4ED4-AEDF-1ABB617827FD}.Release|x64.ActiveCfg = Release|x64\r
+               {16746B0C-5840-4ED4-AEDF-1ABB617827FD}.Release|x64.Build.0 = Release|x64\r
        EndGlobalSection\r
        GlobalSection(SolutionProperties) = preSolution\r
                HideSolutionNode = FALSE\r
        EndGlobalSection\r
        GlobalSection(SolutionProperties) = preSolution\r
                HideSolutionNode = FALSE\r
index 4ed8eb4..f64af80 100644 (file)
@@ -4,6 +4,31 @@ VisualStudioVersion = 16.0.28407.52
 MinimumVisualStudioVersion = 10.0.40219.1
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ShellExtension", "ShellExtension\ShellExtension.vcxproj", "{76A538A1-9D2C-49CB-AE9F-72548CE37F88}"
 EndProject
 MinimumVisualStudioVersion = 10.0.40219.1
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ShellExtension", "ShellExtension\ShellExtension.vcxproj", "{76A538A1-9D2C-49CB-AE9F-72548CE37F88}"
 EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "WinMergePkg", "WinMergePkg", "{AD7D9F86-6CF2-43BB-B3E4-0FC222AECBFE}"
+       ProjectSection(SolutionItems) = preProject
+               WinMergePkg\AppxManifest.xml.in = WinMergePkg\AppxManifest.xml.in
+       EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WinMergeContextMenu", "WinMergeContextMenu\WinMergeContextMenu.vcxproj", "{16746B0C-5840-4ED4-AEDF-1ABB617827FD}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Scripts", "Scripts", "{8C870F7A-C681-4D1A-9B4A-B0B7D4A5AE35}"
+       ProjectSection(SolutionItems) = preProject
+               BuildArc.cmd = BuildArc.cmd
+               BuildBin.vs2017.cmd = BuildBin.vs2017.cmd
+               BuildBin.vs2019.cmd = BuildBin.vs2019.cmd
+               CreateWinMergeContextMenuPackage.bat = CreateWinMergeContextMenuPackage.bat
+               CreateWinMergeContextMenuPackage.ps1 = CreateWinMergeContextMenuPackage.ps1
+               CreateWinMergeContextMenuSelfSignedPackage.bat = CreateWinMergeContextMenuSelfSignedPackage.bat
+               Register.bat = Register.bat
+               RegisterPerUser.bat = RegisterPerUser.bat
+               RegisterWinMergeContextMenuPackage.bat = RegisterWinMergeContextMenuPackage.bat
+               RegisterWinMergeContextMenuX64DebugPackage.bat = RegisterWinMergeContextMenuX64DebugPackage.bat
+               SignShellExtension.bat = SignShellExtension.bat
+               UnRegister.bat = UnRegister.bat
+               UnRegisterPerUser.bat = UnRegisterPerUser.bat
+               UnregisterWinMergeContextMenuPackage.bat = UnregisterWinMergeContextMenuPackage.bat
+       EndProjectSection
+EndProject
 Global
        GlobalSection(SolutionConfigurationPlatforms) = preSolution
                Debug|ARM64 = Debug|ARM64
 Global
        GlobalSection(SolutionConfigurationPlatforms) = preSolution
                Debug|ARM64 = Debug|ARM64
@@ -26,6 +51,16 @@ Global
                {76A538A1-9D2C-49CB-AE9F-72548CE37F88}.Release|Win32.Build.0 = Release|Win32
                {76A538A1-9D2C-49CB-AE9F-72548CE37F88}.Release|x64.ActiveCfg = Release|x64
                {76A538A1-9D2C-49CB-AE9F-72548CE37F88}.Release|x64.Build.0 = Release|x64
                {76A538A1-9D2C-49CB-AE9F-72548CE37F88}.Release|Win32.Build.0 = Release|Win32
                {76A538A1-9D2C-49CB-AE9F-72548CE37F88}.Release|x64.ActiveCfg = Release|x64
                {76A538A1-9D2C-49CB-AE9F-72548CE37F88}.Release|x64.Build.0 = Release|x64
+               {16746B0C-5840-4ED4-AEDF-1ABB617827FD}.Debug|ARM64.ActiveCfg = Debug|ARM64
+               {16746B0C-5840-4ED4-AEDF-1ABB617827FD}.Debug|ARM64.Build.0 = Debug|ARM64
+               {16746B0C-5840-4ED4-AEDF-1ABB617827FD}.Debug|Win32.ActiveCfg = Debug|x64
+               {16746B0C-5840-4ED4-AEDF-1ABB617827FD}.Debug|x64.ActiveCfg = Debug|x64
+               {16746B0C-5840-4ED4-AEDF-1ABB617827FD}.Debug|x64.Build.0 = Debug|x64
+               {16746B0C-5840-4ED4-AEDF-1ABB617827FD}.Release|ARM64.ActiveCfg = Release|ARM64
+               {16746B0C-5840-4ED4-AEDF-1ABB617827FD}.Release|ARM64.Build.0 = Release|ARM64
+               {16746B0C-5840-4ED4-AEDF-1ABB617827FD}.Release|Win32.ActiveCfg = Release|x64
+               {16746B0C-5840-4ED4-AEDF-1ABB617827FD}.Release|x64.ActiveCfg = Release|x64
+               {16746B0C-5840-4ED4-AEDF-1ABB617827FD}.Release|x64.Build.0 = Release|x64
        EndGlobalSection
        GlobalSection(SolutionProperties) = preSolution
                HideSolutionNode = FALSE
        EndGlobalSection
        GlobalSection(SolutionProperties) = preSolution
                HideSolutionNode = FALSE
diff --git a/ShellExtension/UnregisterWinMergeContextMenuPackage.bat b/ShellExtension/UnregisterWinMergeContextMenuPackage.bat
new file mode 100644 (file)
index 0000000..da4115c
--- /dev/null
@@ -0,0 +1 @@
+powershell -c "Get-AppxPackage -name WinMerge | Remove-AppxPackage"
diff --git a/ShellExtension/WinMergeContextMenu/Source.def b/ShellExtension/WinMergeContextMenu/Source.def
new file mode 100644 (file)
index 0000000..1ffdadd
--- /dev/null
@@ -0,0 +1,5 @@
+LIBRARY
+EXPORTS             
+DllCanUnloadNow           PRIVATE
+DllGetClassObject         PRIVATE
+DllGetActivationFactory   PRIVATE
\ No newline at end of file
diff --git a/ShellExtension/WinMergeContextMenu/WinMergeContextMenu.rc b/ShellExtension/WinMergeContextMenu/WinMergeContextMenu.rc
new file mode 100644 (file)
index 0000000..f69809c
--- /dev/null
@@ -0,0 +1,112 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (United States) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE 
+BEGIN
+    "resource.h\0"
+END
+
+2 TEXTINCLUDE 
+BEGIN
+    "#include ""afxres.h""\r\n"
+    "\0"
+END
+
+#endif    // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,0,0,0
+ PRODUCTVERSION 1,0,0,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+    BLOCK "StringFileInfo"
+    BEGIN
+        BLOCK "040904b0"
+        BEGIN
+            VALUE "CompanyName", "https://winmerge.org"
+            VALUE "FileDescription", "WinMerge Shell Integration library"
+            VALUE "FileVersion", "1.0.0.0"
+            VALUE "InternalName", "WinMergeContextMenu"
+            VALUE "LegalCopyright", "Copyright 2021"
+            VALUE "OriginalFilename", "WinMergeContextMenu.dll"
+            VALUE "ProductName", "WinMerge Shell Integration library"
+            VALUE "ProductVersion", "1.0.0.0"
+        END
+    END
+    BLOCK "VarFileInfo"
+    BEGIN
+        VALUE "Translation", 0x409, 1200
+    END
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_WINMERGE            ICON                    "..\\Resources\\WinMerge.ico"
+
+IDI_WINMERGEDIR         ICON                    "..\\Resources\\WinMergeDir.ico"
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE
+BEGIN
+    IDS_PROJNAME            "ShellExtension"
+    IDS_CONTEXT_MENU        "&WinMerge"
+    IDS_COMPARE             "&Compare"
+    IDS_COMPARE_ELLIPSIS    "Compare&..."
+    IDS_SELECT_LEFT         "Select &Left"
+    IDS_SELECT_MIDDLE       "Select &Middle"
+    IDS_RESELECT_LEFT       "Re-select &Left"
+END
+
+#endif    // English (United States) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
diff --git a/ShellExtension/WinMergeContextMenu/WinMergeContextMenu.vcxproj b/ShellExtension/WinMergeContextMenu/WinMergeContextMenu.vcxproj
new file mode 100644 (file)
index 0000000..713b09a
--- /dev/null
@@ -0,0 +1,222 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|ARM64">
+      <Configuration>Debug</Configuration>
+      <Platform>ARM64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|ARM64">
+      <Configuration>Release</Configuration>
+      <Platform>ARM64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <VCProjectVersion>16.0</VCProjectVersion>
+    <Keyword>Win32Proj</Keyword>
+    <ProjectGuid>{16746b0c-5840-4ed4-aedf-1abb617827fd}</ProjectGuid>
+    <RootNamespace>WinMergeContextMenu</RootNamespace>
+    <WindowsTargetPlatformVersion Condition="'$(VisualStudioVersion)' == '15'">10.0.17763.0</WindowsTargetPlatformVersion>
+    <WindowsTargetPlatformVersion Condition="'$(VisualStudioVersion)' == '16'">10.0</WindowsTargetPlatformVersion>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset Condition="'$(VisualStudioVersion)' == '15'">v141</PlatformToolset>
+    <PlatformToolset Condition="'$(VisualStudioVersion)' == '16'">v142</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset Condition="'$(VisualStudioVersion)' == '15'">v141</PlatformToolset>
+    <PlatformToolset Condition="'$(VisualStudioVersion)' == '16'">v142</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset Condition="'$(VisualStudioVersion)' == '15'">v141</PlatformToolset>
+    <PlatformToolset Condition="'$(VisualStudioVersion)' == '16'">v142</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset Condition="'$(VisualStudioVersion)' == '15'">v141</PlatformToolset>
+    <PlatformToolset Condition="'$(VisualStudioVersion)' == '16'">v142</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="Shared">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <LinkIncremental>true</LinkIncremental>
+    <OutDir>..\..\Build\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>..\..\BuildTmp\WinMergeContextMenu\$(Platform)\$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
+    <LinkIncremental>true</LinkIncremental>
+    <OutDir>..\..\Build\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>..\..\BuildTmp\WinMergeContextMenu\$(Platform)\$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <LinkIncremental>false</LinkIncremental>
+    <OutDir>..\..\Build\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>..\..\BuildTmp\WinMergeContextMenu\$(Platform)\$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
+    <LinkIncremental>false</LinkIncremental>
+    <OutDir>..\..\Build\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>..\..\BuildTmp\WinMergeContextMenu\$(Platform)\$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <SDLCheck>true</SDLCheck>
+      <PreprocessorDefinitions>_DEBUG;PHOTOSTORECONTEXTMENU_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ConformanceMode>true</ConformanceMode>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
+      <LanguageStandard>stdcpp17</LanguageStandard>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableUAC>false</EnableUAC>
+      <ModuleDefinitionFile>Source.def</ModuleDefinitionFile>
+      <AdditionalDependencies>runtimeobject.lib;%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <SDLCheck>true</SDLCheck>
+      <PreprocessorDefinitions>_DEBUG;PHOTOSTORECONTEXTMENU_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ConformanceMode>true</ConformanceMode>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
+      <LanguageStandard>stdcpp17</LanguageStandard>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableUAC>false</EnableUAC>
+      <AdditionalDependencies>runtimeobject.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <ModuleDefinitionFile>Source.def</ModuleDefinitionFile>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <SDLCheck>true</SDLCheck>
+      <PreprocessorDefinitions>NDEBUG;PHOTOSTORECONTEXTMENU_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ConformanceMode>true</ConformanceMode>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
+      <LanguageStandard>stdcpp17</LanguageStandard>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableUAC>false</EnableUAC>
+      <AdditionalDependencies>runtimeobject.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <ModuleDefinitionFile>Source.def</ModuleDefinitionFile>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <SDLCheck>true</SDLCheck>
+      <PreprocessorDefinitions>NDEBUG;PHOTOSTORECONTEXTMENU_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ConformanceMode>true</ConformanceMode>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
+      <LanguageStandard>stdcpp17</LanguageStandard>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableUAC>false</EnableUAC>
+      <AdditionalDependencies>runtimeobject.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <ModuleDefinitionFile>Source.def</ModuleDefinitionFile>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClInclude Include="..\Common\LanguageSelect.h" />
+    <ClInclude Include="..\Common\RegKey.h" />
+    <ClInclude Include="..\Common\UnicodeString.h" />
+    <ClInclude Include="..\Common\WinMergeContextMenu.h" />
+    <ClInclude Include="framework.h" />
+    <ClInclude Include="pch.h" />
+    <ClInclude Include="resource.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\Common\LanguageSelect.cpp">
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+    </ClCompile>
+    <ClCompile Include="..\Common\RegKey.cpp">
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+    </ClCompile>
+    <ClCompile Include="..\Common\UnicodeString.cpp">
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+    </ClCompile>
+    <ClCompile Include="..\Common\WinMergeContextMenu.cpp">
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+    </ClCompile>
+    <ClCompile Include="dllmain.cpp" />
+    <ClCompile Include="pch.cpp">
+      <PrecompiledHeader>Create</PrecompiledHeader>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <Image Include="..\Resources\WinMerge.ico" />
+    <Image Include="..\Resources\WinMergeDir.ico" />
+  </ItemGroup>
+  <ItemGroup>
+    <ResourceCompile Include="WinMergeContextMenu.rc" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+    <Import Project="..\packages\Microsoft.Windows.ImplementationLibrary.1.0.201120.3\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('..\packages\Microsoft.Windows.ImplementationLibrary.1.0.201120.3\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
+  </ImportGroup>
+  <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
+    <PropertyGroup>
+      <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
+    </PropertyGroup>
+    <Error Condition="!Exists('..\packages\Microsoft.Windows.ImplementationLibrary.1.0.201120.3\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Windows.ImplementationLibrary.1.0.201120.3\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
+  </Target>
+</Project>
\ No newline at end of file
diff --git a/ShellExtension/WinMergeContextMenu/WinMergeContextMenu.vcxproj.filters b/ShellExtension/WinMergeContextMenu/WinMergeContextMenu.vcxproj.filters
new file mode 100644 (file)
index 0000000..c802a9a
--- /dev/null
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <ClCompile Include="dllmain.cpp" />
+    <ClCompile Include="pch.cpp" />
+    <ClCompile Include="..\Common\LanguageSelect.cpp">
+      <Filter>Common</Filter>
+    </ClCompile>
+    <ClCompile Include="..\Common\RegKey.cpp">
+      <Filter>Common</Filter>
+    </ClCompile>
+    <ClCompile Include="..\Common\UnicodeString.cpp">
+      <Filter>Common</Filter>
+    </ClCompile>
+    <ClCompile Include="..\Common\WinMergeContextMenu.cpp">
+      <Filter>Common</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="framework.h" />
+    <ClInclude Include="pch.h" />
+    <ClInclude Include="..\Common\LanguageSelect.h">
+      <Filter>Common</Filter>
+    </ClInclude>
+    <ClInclude Include="..\Common\RegKey.h">
+      <Filter>Common</Filter>
+    </ClInclude>
+    <ClInclude Include="..\Common\UnicodeString.h">
+      <Filter>Common</Filter>
+    </ClInclude>
+    <ClInclude Include="..\Common\WinMergeContextMenu.h">
+      <Filter>Common</Filter>
+    </ClInclude>
+    <ClInclude Include="resource.h">
+      <Filter>Resource Files</Filter>
+    </ClInclude>
+  </ItemGroup>
+  <ItemGroup>
+    <Filter Include="Resource Files">
+      <UniqueIdentifier>{de172a05-f54c-451d-853e-14a7a6cb7cd5}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Common">
+      <UniqueIdentifier>{b0354d5d-0c3b-4ffd-9a24-593c908d947a}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <Image Include="..\Resources\WinMerge.ico">
+      <Filter>Resource Files</Filter>
+    </Image>
+    <Image Include="..\Resources\WinMergeDir.ico">
+      <Filter>Resource Files</Filter>
+    </Image>
+  </ItemGroup>
+  <ItemGroup>
+    <ResourceCompile Include="WinMergeContextMenu.rc">
+      <Filter>Resource Files</Filter>
+    </ResourceCompile>
+  </ItemGroup>
+</Project>
\ No newline at end of file
diff --git a/ShellExtension/WinMergeContextMenu/dllmain.cpp b/ShellExtension/WinMergeContextMenu/dllmain.cpp
new file mode 100644 (file)
index 0000000..fbf69fa
--- /dev/null
@@ -0,0 +1,359 @@
+// SPDX-License-Identifier: MIT
+// Based on code from https://github.com/microsoft/AppModelSamples/tree/master/Samples/SparsePackages
+// dllmain.cpp : Defines the entry point for the DLL application.
+#include "pch.h"
+#include <wrl/module.h>
+#include <wrl/implements.h>
+#include <wrl/client.h>
+#include <shobjidl_core.h>
+#include <wil/resource.h>
+#include <wil/win32_helpers.h>
+#include <string>
+#include <vector>
+#include <sstream>
+#include <memory>
+#include <Shlwapi.h>
+#include <ExDisp.h>
+#include <ShlObj.h>
+#include "../Common/WinMergeContextMenu.h"
+#include "resource.h"
+
+#pragma comment(lib, "shlwapi.lib")
+
+using namespace Microsoft::WRL;
+
+BOOL APIENTRY DllMain( HMODULE hModule,
+                       DWORD  ul_reason_for_call,
+                       LPVOID lpReserved
+                     )
+{
+    switch (ul_reason_for_call)
+    {
+    case DLL_PROCESS_ATTACH:
+    case DLL_THREAD_ATTACH:
+    case DLL_THREAD_DETACH:
+    case DLL_PROCESS_DETACH:
+        break;
+    }
+    return TRUE;
+}
+
+class WinMergeExplorerCommandBase : public RuntimeClass<RuntimeClassFlags<ClassicCom>, IExplorerCommand>
+{
+public:
+    WinMergeExplorerCommandBase(WinMergeContextMenu* pContextMenu) : m_pContextMenu(pContextMenu) {}
+    virtual const wchar_t* Title() = 0;
+    virtual const EXPCMDFLAGS Flags() { return ECF_DEFAULT; }
+    virtual const EXPCMDSTATE State(_In_opt_ IShellItemArray* selection) { return ECS_ENABLED; }
+    virtual const int IconId(_In_opt_ IShellItemArray* selection) { return 0; }
+    virtual const int Verb() { return 0; }
+
+    // IExplorerCommand
+    IFACEMETHODIMP GetTitle(_In_opt_ IShellItemArray* items, _Outptr_result_nullonfailure_ PWSTR* name)
+    {
+        *name = nullptr;
+        auto title = wil::make_cotaskmem_string_nothrow(Title());
+        RETURN_IF_NULL_ALLOC(title);
+        *name = title.release();
+        return S_OK;
+    }
+    IFACEMETHODIMP GetIcon(_In_opt_ IShellItemArray* items, _Outptr_result_nullonfailure_ PWSTR* icon)
+    {
+        const int id = IconId(items);
+        if (id == 0)
+        {
+            *icon = nullptr;
+            return E_NOTIMPL;
+        }
+        auto modulefilename = wil::GetModuleFileNameW(wil::GetModuleInstanceHandle());
+        std::wstring path = modulefilename.get() + std::wstring(L",-") + std::to_wstring(id);
+        SHStrDupW(path.c_str(), icon);
+        return S_OK;
+    }
+    IFACEMETHODIMP GetToolTip(_In_opt_ IShellItemArray*, _Outptr_result_nullonfailure_ PWSTR* infoTip)
+    {
+        *infoTip = nullptr;
+        return E_NOTIMPL;
+    }
+    IFACEMETHODIMP GetCanonicalName(_Out_ GUID* guidCommandName)
+    {
+        *guidCommandName = GUID_NULL;
+        return S_OK;
+    }
+    IFACEMETHODIMP GetState(_In_opt_ IShellItemArray* selection, _In_ BOOL okToBeSlow, _Out_ EXPCMDSTATE* cmdState)
+    {
+        *cmdState = State(selection);
+        return S_OK;
+    }
+    IFACEMETHODIMP Invoke(_In_opt_ IShellItemArray* selection, _In_opt_ IBindCtx*) noexcept try
+    {
+        m_pContextMenu->InvokeCommand(Verb());
+        return S_OK;
+    }
+    CATCH_RETURN();
+
+    IFACEMETHODIMP GetFlags(_Out_ EXPCMDFLAGS* flags)
+    {
+        *flags = Flags();
+        return S_OK;
+    }
+    IFACEMETHODIMP EnumSubCommands(_COM_Outptr_ IEnumExplorerCommand** enumCommands)
+    {
+        *enumCommands = nullptr;
+        return E_NOTIMPL;
+    }
+
+protected:
+
+    // code from https://github.com/microsoft/terminal/blob/main/src/cascadia/ShellExtension/OpenTerminalHere.cpp
+    std::wstring _GetPathFromExplorer() const
+    {
+        std::wstring path;
+        HRESULT hr = NOERROR;
+
+        auto hwnd = ::GetForegroundWindow();
+        if (hwnd == nullptr)
+        {
+            return path;
+        }
+
+        TCHAR szName[MAX_PATH] = { 0 };
+        ::GetClassName(hwnd, szName, MAX_PATH);
+        if (0 == StrCmp(szName, L"WorkerW") ||
+            0 == StrCmp(szName, L"Progman"))
+        {
+            //special folder: desktop
+            hr = ::SHGetFolderPath(NULL, CSIDL_DESKTOP, NULL, SHGFP_TYPE_CURRENT, szName);
+            if (FAILED(hr))
+            {
+                return path;
+            }
+
+            path = szName;
+            return path;
+        }
+
+        if (0 != StrCmp(szName, L"CabinetWClass"))
+        {
+            return path;
+        }
+
+        ComPtr<IShellWindows> shell;
+        hr = CoCreateInstance(CLSID_ShellWindows, nullptr, CLSCTX_ALL, IID_IShellWindows, &shell);
+        if (FAILED(hr) || shell == nullptr)
+        {
+            return path;
+        }
+
+        ComPtr<IDispatch> disp;
+        wil::unique_variant variant;
+        variant.vt = VT_I4;
+
+        ComPtr<IWebBrowserApp> browser;
+        // look for correct explorer window
+        for (variant.intVal = 0;
+            shell->Item(variant, &disp) == S_OK;
+            variant.intVal++)
+        {
+            ComPtr<IWebBrowserApp> tmp;
+            if (FAILED(disp->QueryInterface<IWebBrowserApp>(&tmp)))
+            {
+                disp = nullptr; // get rid of DEBUG non-nullptr warning
+                continue;
+            }
+
+            HWND tmpHWND = NULL;
+            hr = tmp->get_HWND(reinterpret_cast<SHANDLE_PTR*>(&tmpHWND));
+            if (hwnd == tmpHWND)
+            {
+                browser = tmp;
+                disp = nullptr; // get rid of DEBUG non-nullptr warning
+                break; //found
+            }
+
+            disp = nullptr; // get rid of DEBUG non-nullptr warning
+        }
+
+        if (browser != nullptr)
+        {
+            wil::unique_bstr url;
+            hr = browser->get_LocationURL(&url);
+            if (FAILED(hr))
+            {
+                return path;
+            }
+
+            std::wstring sUrl(url.get(), SysStringLen(url.get()));
+            DWORD size = MAX_PATH;
+            hr = ::PathCreateFromUrl(sUrl.c_str(), szName, &size, NULL);
+            if (SUCCEEDED(hr))
+            {
+                path = szName;
+            }
+        }
+
+        return path;
+    }
+
+    std::vector<std::wstring> GetPaths(_In_opt_ IShellItemArray* selection)
+    {
+        std::vector<std::wstring> paths;
+        DWORD dwNumItems = 0;
+        if (!selection)
+        {
+            std::wstring path = _GetPathFromExplorer();
+            if (!path.empty())
+                paths.push_back(path);
+        }
+        else
+        {
+            selection->GetCount(&dwNumItems);
+            for (DWORD i = 0; i < dwNumItems; ++i)
+            {
+                ComPtr<IShellItem> psi;
+                wil::unique_cotaskmem_string pszFilePath;
+                if (SUCCEEDED(selection->GetItemAt(i, &psi)) &&
+                    SUCCEEDED(psi->GetDisplayName(SIGDN_FILESYSPATH, &pszFilePath)))
+                {
+                    paths.push_back(pszFilePath.get());
+                }
+            }
+        }
+        return paths;
+    }
+    WinMergeContextMenu* m_pContextMenu;
+};
+
+class SubExplorerCommandHandler final : public WinMergeExplorerCommandBase
+{
+public:
+    SubExplorerCommandHandler(WinMergeContextMenu *pContextMenu, const MenuItem& menuItem)
+        : WinMergeExplorerCommandBase(pContextMenu)
+        , m_menuItem(menuItem)
+    {
+    }
+    const wchar_t* Title() override
+    {
+        return m_menuItem.text.c_str();
+    }
+    const int IconId(_In_opt_ IShellItemArray* selection) override
+    {
+        return m_menuItem.icon;
+    }
+    const int Verb() override
+    {
+        return m_menuItem.verb;
+    }
+    const EXPCMDSTATE State(_In_opt_ IShellItemArray* selection) override
+    {
+        return m_menuItem.enabled ? ECS_ENABLED : ECS_DISABLED;
+    }
+private:
+    MenuItem m_menuItem;
+};
+
+class EnumCommands : public RuntimeClass<RuntimeClassFlags<ClassicCom>, IEnumExplorerCommand>
+{
+public:
+    explicit EnumCommands(WinMergeContextMenu* pContextMenu)
+    {
+        for (auto& menuItem : pContextMenu->GetMenuItemList())
+            m_commands.push_back(Make<SubExplorerCommandHandler>(pContextMenu, menuItem));
+        m_current = m_commands.cbegin();
+    }
+
+    // IEnumExplorerCommand
+    IFACEMETHODIMP Next(ULONG celt, __out_ecount_part(celt, *pceltFetched) IExplorerCommand** apUICommand, __out_opt ULONG* pceltFetched)
+    {
+        ULONG fetched{ 0 };
+        wil::assign_to_opt_param(pceltFetched, 0ul);
+
+        for (ULONG i = 0; (i < celt) && (m_current != m_commands.cend()); i++)
+        {
+            m_current->CopyTo(&apUICommand[0]);
+            m_current++;
+            fetched++;
+        }
+
+        wil::assign_to_opt_param(pceltFetched, fetched);
+        return (fetched == celt) ? S_OK : S_FALSE;
+    }
+
+    IFACEMETHODIMP Skip(ULONG /*celt*/) { return E_NOTIMPL; }
+    IFACEMETHODIMP Reset()
+    {
+        m_current = m_commands.cbegin();
+        return S_OK;
+    }
+    IFACEMETHODIMP Clone(__deref_out IEnumExplorerCommand** ppenum) { *ppenum = nullptr; return E_NOTIMPL; }
+
+private:
+    std::vector<ComPtr<IExplorerCommand>> m_commands;
+    std::vector<ComPtr<IExplorerCommand>>::const_iterator m_current;
+};
+
+class __declspec(uuid("90340779-F37E-468E-9728-A2593498ED32")) WinMergeFileDirExplorerCommandHandler : public WinMergeExplorerCommandBase
+{
+public:
+    WinMergeFileDirExplorerCommandHandler()
+        : m_contextMenu(wil::GetModuleInstanceHandle())
+        , WinMergeExplorerCommandBase(&m_contextMenu)
+    {
+    }
+    const wchar_t* Title() override { return L"WinMerge"; }
+    const int IconId(_In_opt_ IShellItemArray* selection) override
+    {
+        auto paths = GetPaths(selection);
+        if (paths.size() > 0 && PathIsDirectory(paths[0].c_str()))
+            return IDI_WINMERGEDIR;
+        return IDI_WINMERGE;
+    }
+    const int Verb() override { return WinMergeContextMenu::CMD_COMPARE; }
+    const EXPCMDFLAGS Flags() override
+    {
+        if ((m_contextMenu.GetContextMenuEnabled() & (WinMergeContextMenu::EXT_ENABLED | WinMergeContextMenu::EXT_ADVANCED)) == (WinMergeContextMenu::EXT_ENABLED | WinMergeContextMenu::EXT_ADVANCED))
+            return ECF_HASSUBCOMMANDS;
+        else
+            return ECF_DEFAULT;
+    }
+    const EXPCMDSTATE State(_In_opt_ IShellItemArray* selection) override
+    {
+        auto paths = GetPaths(selection);
+        if (paths.size() > 3)
+            return ECS_DISABLED;
+        m_contextMenu.UpdateMenuState(paths);
+        if (m_contextMenu.GetMenuState() == WinMergeContextMenu::MENU_HIDDEN)
+        {
+            return ECS_HIDDEN;
+        }
+        return ECS_ENABLED;
+    }
+    IFACEMETHODIMP EnumSubCommands(_COM_Outptr_ IEnumExplorerCommand** enumCommands)
+    {
+        *enumCommands = nullptr;
+        auto e = Make<EnumCommands>(&m_contextMenu);
+        return e->QueryInterface(IID_PPV_ARGS(enumCommands));
+    }
+private:
+    WinMergeContextMenu m_contextMenu;
+};
+
+CoCreatableClass(WinMergeFileDirExplorerCommandHandler)
+
+CoCreatableClassWrlCreatorMapInclude(WinMergeFileDirExplorerCommandHandler)
+
+
+STDAPI DllGetActivationFactory(_In_ HSTRING activatableClassId, _COM_Outptr_ IActivationFactory** factory)
+{
+    return Module<ModuleType::InProc>::GetModule().GetActivationFactory(activatableClassId, factory);
+}
+
+STDAPI DllCanUnloadNow()
+{
+    return Module<InProc>::GetModule().GetObjectCount() == 0 ? S_OK : S_FALSE;
+}
+
+STDAPI DllGetClassObject(_In_ REFCLSID rclsid, _In_ REFIID riid, _COM_Outptr_ void** instance)
+{
+    return Module<InProc>::GetModule().GetClassObject(rclsid, riid, instance);
+}
\ No newline at end of file
diff --git a/ShellExtension/WinMergeContextMenu/framework.h b/ShellExtension/WinMergeContextMenu/framework.h
new file mode 100644 (file)
index 0000000..54b83e9
--- /dev/null
@@ -0,0 +1,5 @@
+#pragma once
+
+#define WIN32_LEAN_AND_MEAN             // Exclude rarely-used stuff from Windows headers
+// Windows Header Files
+#include <windows.h>
diff --git a/ShellExtension/WinMergeContextMenu/packages.config b/ShellExtension/WinMergeContextMenu/packages.config
new file mode 100644 (file)
index 0000000..50c8ee2
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+  <package id="Microsoft.Windows.ImplementationLibrary" version="1.0.201120.3" targetFramework="native" />
+</packages>
\ No newline at end of file
diff --git a/ShellExtension/WinMergeContextMenu/pch.cpp b/ShellExtension/WinMergeContextMenu/pch.cpp
new file mode 100644 (file)
index 0000000..64b7eef
--- /dev/null
@@ -0,0 +1,5 @@
+// pch.cpp: source file corresponding to the pre-compiled header
+
+#include "pch.h"
+
+// When you are using pre-compiled headers, this source file is necessary for compilation to succeed.
diff --git a/ShellExtension/WinMergeContextMenu/pch.h b/ShellExtension/WinMergeContextMenu/pch.h
new file mode 100644 (file)
index 0000000..885d5d6
--- /dev/null
@@ -0,0 +1,13 @@
+// pch.h: This is a precompiled header file.
+// Files listed below are compiled only once, improving build performance for future builds.
+// This also affects IntelliSense performance, including code completion and many code browsing features.
+// However, files listed here are ALL re-compiled if any one of them is updated between builds.
+// Do not add files here that you will be updating frequently as this negates the performance advantage.
+
+#ifndef PCH_H
+#define PCH_H
+
+// add headers that you want to pre-compile here
+#include "framework.h"
+
+#endif //PCH_H
diff --git a/ShellExtension/WinMergeContextMenu/resource.h b/ShellExtension/WinMergeContextMenu/resource.h
new file mode 100644 (file)
index 0000000..9caaad6
--- /dev/null
@@ -0,0 +1,25 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by WinMergeContextMenu.rc
+//
+#define IDS_PROJNAME                    100
+#define IDS_CONTEXT_MENU                101
+#define IDR_WINMERGESHELL               102
+#define IDS_COMPARE                     104
+#define IDS_COMPARE_ELLIPSIS            105
+#define IDS_SELECT_LEFT                 106
+#define IDS_SELECT_MIDDLE               107
+#define IDS_RESELECT_LEFT               108
+#define IDI_WINMERGE                    208
+#define IDI_WINMERGEDIR                 209
+
+// Next default values for new objects
+// 
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE        210
+#define _APS_NEXT_COMMAND_VALUE         32768
+#define _APS_NEXT_CONTROL_VALUE         201
+#define _APS_NEXT_SYMED_VALUE           111
+#endif
+#endif
diff --git a/ShellExtension/WinMergePkg/AppxManifest.xml.in b/ShellExtension/WinMergePkg/AppxManifest.xml.in
new file mode 100644 (file)
index 0000000..4f8dc16
--- /dev/null
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Package
+  xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
+  xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
+  xmlns:uap2="http://schemas.microsoft.com/appx/manifest/uap/windows10/2"
+  xmlns:uap3="http://schemas.microsoft.com/appx/manifest/uap/windows10/3"
+  xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
+  xmlns:desktop="http://schemas.microsoft.com/appx/manifest/desktop/windows10"
+  xmlns:desktop4="http://schemas.microsoft.com/appx/manifest/desktop/windows10/4"
+  xmlns:desktop5="http://schemas.microsoft.com/appx/manifest/desktop/windows10/5"
+  xmlns:uap10="http://schemas.microsoft.com/appx/manifest/uap/windows10/10"
+  xmlns:com="http://schemas.microsoft.com/appx/manifest/com/windows10"
+  IgnorableNamespaces="uap uap2 uap3 rescap desktop desktop4 desktop5 uap10 com">
+  <Identity Name="WinMerge" ProcessorArchitecture="neutral" Publisher="${Publisher}" Version="1.0.0.0" />
+  <Properties>
+    <DisplayName>WinMerge</DisplayName>
+    <PublisherDisplayName>winmerge.org</PublisherDisplayName>
+    <Logo>Assets\storelogo.png</Logo>
+    <uap10:AllowExternalContent>true</uap10:AllowExternalContent>
+  </Properties>
+  <Resources>
+    <Resource Language="en-us" />
+  </Resources>
+  <Dependencies>
+    <TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.18950.0" MaxVersionTested="10.0.22000.160" />
+  </Dependencies>
+  <Capabilities>
+    <rescap:Capability Name="runFullTrust" />
+    <rescap:Capability Name="unvirtualizedResources"/>
+  </Capabilities>
+  <Applications>
+    <Application Id="WinMerge" Executable="WinMergeU.exe" uap10:TrustLevel="mediumIL" uap10:RuntimeBehavior="win32App">
+      <uap:VisualElements AppListEntry="none" DisplayName="WinMerge" Description="WinMerge" BackgroundColor="transparent" Square150x150Logo="Assets\Square150x150Logo.png" Square44x44Logo="Assets\Square44x44Logo.png">
+        <uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png" Square310x310Logo="Assets\LargeTile.png" Square71x71Logo="Assets\SmallTile.png"></uap:DefaultTile>
+      </uap:VisualElements>
+      <Extensions>
+        <desktop4:Extension Category="windows.fileExplorerContextMenus">
+          <desktop4:FileExplorerContextMenus>
+            <desktop5:ItemType Type="Directory">
+              <desktop5:Verb Id="WinMergeDir" Clsid="90340779-F37E-468E-9728-A2593498ED32" />
+            </desktop5:ItemType>
+            <desktop5:ItemType Type="Directory\Background">
+              <desktop5:Verb Id="WinMergeDir" Clsid="90340779-F37E-468E-9728-A2593498ED32" />
+            </desktop5:ItemType>
+            <desktop5:ItemType Type="*">
+              <desktop5:Verb Id="WinMerge" Clsid="90340779-F37E-468E-9728-A2593498ED32" />
+            </desktop5:ItemType>
+          </desktop4:FileExplorerContextMenus>
+        </desktop4:Extension>
+        <com:Extension Category="windows.comServer">
+          <com:ComServer>
+            <com:SurrogateServer  DisplayName="WinMerge context menu verb handler">
+              <com:Class Id="90340779-F37E-468E-9728-A2593498ED32" Path="WinMergeContextMenu.dll" ThreadingModel="STA"/>
+            </com:SurrogateServer>
+          </com:ComServer>
+        </com:Extension>
+      </Extensions>
+    </Application>
+  </Applications>
+</Package>
index df3db7a..4aa1e11 100644 (file)
@@ -377,6 +377,7 @@ bool CConfigLog::DoFile(String &sError)
        WriteVersionOf1(2, _T(".\\ShellExtensionU.dll"));
        WriteVersionOf1(2, _T(".\\ShellExtensionX64.dll"));
        WriteVersionOf1(2, _T(".\\ShellExtensionARM64.dll"));
        WriteVersionOf1(2, _T(".\\ShellExtensionU.dll"));
        WriteVersionOf1(2, _T(".\\ShellExtensionX64.dll"));
        WriteVersionOf1(2, _T(".\\ShellExtensionARM64.dll"));
+       WriteVersionOf1(2, _T(".\\WinMergeContextMenu.dll"));
        WriteVersionOf1(2, _T(".\\Frhed\\hekseditU.dll"));
        WriteVersionOf1(2, _T(".\\WinIMerge\\WinIMergeLib.dll"));
        WriteVersionOf1(2, _T(".\\Merge7z\\7z.dll"));
        WriteVersionOf1(2, _T(".\\Frhed\\hekseditU.dll"));
        WriteVersionOf1(2, _T(".\\WinIMerge\\WinIMergeLib.dll"));
        WriteVersionOf1(2, _T(".\\Merge7z\\7z.dll"));
index 101df14..cd524f6 100644 (file)
@@ -2018,13 +2018,15 @@ STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_CAPTION
 CAPTION "Shell Integration"\r
 FONT 8, "MS Shell Dlg", 0, 0, 0x1\r
 BEGIN\r
 CAPTION "Shell Integration"\r
 FONT 8, "MS Shell Dlg", 0, 0, 0x1\r
 BEGIN\r
-    GROUPBOX        "Explorer",IDC_STATIC,7,6,238,112\r
+    GROUPBOX        "Explorer",IDC_STATIC,7,6,238,144\r
     CONTROL         "E&nable advanced menu",IDC_EXPLORER_ADVANCED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,27,30,210,10\r
     CONTROL         "&Add to context menu",IDC_EXPLORER_CONTEXT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,18,220,10\r
     PUSHBUTTON      "&Register shell extension",IDC_REGISTER_SHELLEXTENSION,17,48,220,14\r
     PUSHBUTTON      "&Unregister shell extension",IDC_UNREGISTER_SHELLEXTENSION,17,64,220,14\r
     PUSHBUTTON      "Register shell extension for current user &only",IDC_REGISTER_SHELLEXTENSION_PERUSER,17,80,220,14\r
     PUSHBUTTON      "Unregister shell extension for current user on&ly",IDC_UNREGISTER_SHELLEXTENSION_PERUSER,17,96,220,14\r
     CONTROL         "E&nable advanced menu",IDC_EXPLORER_ADVANCED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,27,30,210,10\r
     CONTROL         "&Add to context menu",IDC_EXPLORER_CONTEXT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,18,220,10\r
     PUSHBUTTON      "&Register shell extension",IDC_REGISTER_SHELLEXTENSION,17,48,220,14\r
     PUSHBUTTON      "&Unregister shell extension",IDC_UNREGISTER_SHELLEXTENSION,17,64,220,14\r
     PUSHBUTTON      "Register shell extension for current user &only",IDC_REGISTER_SHELLEXTENSION_PERUSER,17,80,220,14\r
     PUSHBUTTON      "Unregister shell extension for current user on&ly",IDC_UNREGISTER_SHELLEXTENSION_PERUSER,17,96,220,14\r
+    PUSHBUTTON      "Register shell extension for &Windows 11 or later",IDC_REGISTER_WINMERGECONTEXTMENU,17,112,220,14\r
+    PUSHBUTTON      "Unregister shell extension for W&indows 11 or later",IDC_UNREGISTER_WINMERGECONTEXTMENU,17,128,220,14\r
 END\r
 \r
 IDD_PROPPAGE_COMPARE_FOLDER DIALOGEX 0, 0, 255, 242\r
 END\r
 \r
 IDD_PROPPAGE_COMPARE_FOLDER DIALOGEX 0, 0, 255, 242\r
index dece7e4..d15d697 100644 (file)
@@ -43,6 +43,23 @@ static bool IsShellExtensionRegistered(bool peruser)
        return false;
 }
 
        return false;
 }
 
+static bool IsWinMergeContextMenuRegistered()
+{
+       HKEY hKey;
+#ifdef _WIN64
+       DWORD ulOptions = KEY_QUERY_VALUE;
+#else
+       auto Is64BitWindows = []() { BOOL f64 = FALSE; return IsWow64Process(GetCurrentProcess(), &f64) && f64; };
+       DWORD ulOptions = KEY_QUERY_VALUE | (Is64BitWindows() ? KEY_WOW64_64KEY : 0);
+#endif
+       if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Classes\\PackagedCom\\ClassIndex\\{90340779-F37E-468E-9728-A2593498ED32}"), 0, ulOptions, &hKey))
+       {
+               RegCloseKey(hKey);
+               return true;
+       }
+       return false;
+}
+
 static bool RegisterShellExtension(bool unregister, bool peruser)
 {
        TCHAR szSystem32[260] = { 0 };
 static bool RegisterShellExtension(bool unregister, bool peruser)
 {
        TCHAR szSystem32[260] = { 0 };
@@ -96,6 +113,30 @@ PropShell::PropShell(COptionsMgr *optionsMgr)
 {
 }
 
 {
 }
 
+static bool RegisterWinMergeContextMenu(bool unregister)
+{
+       String cmd;
+       String progpath = env::GetProgPath();
+       String packagepath = paths::ConcatPath(progpath, _T("WinMergeContextMenuPackage.msix"));
+       if (!unregister)
+               cmd = strutils::format(_T("powershell -c \"Add-AppxPackage '%s' -ExternalLocation '%s'\""), packagepath, progpath);
+       else
+               cmd = _T("powershell -c \"Get-AppxPackage -name WinMerge | Remove-AppxPackage\"");
+
+       STARTUPINFO stInfo = { sizeof(STARTUPINFO) };
+       stInfo.dwFlags = STARTF_USESHOWWINDOW;
+       stInfo.wShowWindow = SW_SHOW;
+       PROCESS_INFORMATION processInfo;
+       bool retVal = !!CreateProcess(nullptr, (LPTSTR)cmd.c_str(),
+               nullptr, nullptr, FALSE, CREATE_DEFAULT_ERROR_MODE, nullptr, nullptr,
+               &stInfo, &processInfo);
+       if (!retVal)
+               return false;
+       CloseHandle(processInfo.hThread);
+       CloseHandle(processInfo.hProcess);
+       return true;
+}
+
 BOOL PropShell::OnInitDialog()
 {
        OptionsPanel::OnInitDialog();
 BOOL PropShell::OnInitDialog()
 {
        OptionsPanel::OnInitDialog();
@@ -134,6 +175,8 @@ BEGIN_MESSAGE_MAP(PropShell, OptionsPanel)
        ON_BN_CLICKED(IDC_UNREGISTER_SHELLEXTENSION, OnUnregisterShellExtension)
        ON_BN_CLICKED(IDC_REGISTER_SHELLEXTENSION_PERUSER, OnRegisterShellExtensionPerUser)
        ON_BN_CLICKED(IDC_UNREGISTER_SHELLEXTENSION_PERUSER, OnUnregisterShellExtensionPerUser)
        ON_BN_CLICKED(IDC_UNREGISTER_SHELLEXTENSION, OnUnregisterShellExtension)
        ON_BN_CLICKED(IDC_REGISTER_SHELLEXTENSION_PERUSER, OnRegisterShellExtensionPerUser)
        ON_BN_CLICKED(IDC_UNREGISTER_SHELLEXTENSION_PERUSER, OnUnregisterShellExtensionPerUser)
+       ON_BN_CLICKED(IDC_REGISTER_WINMERGECONTEXTMENU, OnRegisterWinMergeContextMenu)
+       ON_BN_CLICKED(IDC_UNREGISTER_WINMERGECONTEXTMENU, OnUnregisterWinMergeContextMenu)
        ON_WM_TIMER()
        //}}AFX_MSG_MAP
 END_MESSAGE_MAP()
        ON_WM_TIMER()
        //}}AFX_MSG_MAP
 END_MESSAGE_MAP()
@@ -153,7 +196,8 @@ void PropShell::WriteOptions()
 {
        bool registered = IsShellExtensionRegistered(false);
        bool registeredPerUser = IsShellExtensionRegistered(true);
 {
        bool registered = IsShellExtensionRegistered(false);
        bool registeredPerUser = IsShellExtensionRegistered(true);
-       if (registered || registeredPerUser)
+       bool registeredWinMergeContextMenu = IsWinMergeContextMenuRegistered();
+       if (registered || registeredPerUser || registeredWinMergeContextMenu)
                SaveMergePath(); // saves context menu settings as well
 }
 
                SaveMergePath(); // saves context menu settings as well
 }
 
@@ -249,13 +293,16 @@ void PropShell::UpdateButtons()
 {
        bool registered = IsShellExtensionRegistered(false);
        bool registeredPerUser = IsShellExtensionRegistered(true);
 {
        bool registered = IsShellExtensionRegistered(false);
        bool registeredPerUser = IsShellExtensionRegistered(true);
-       EnableDlgItem(IDC_EXPLORER_CONTEXT, registered || registeredPerUser);
+       bool registerdWinMergeContextMenu = IsWinMergeContextMenuRegistered();
+       EnableDlgItem(IDC_EXPLORER_CONTEXT, registered || registeredPerUser || registerdWinMergeContextMenu);
        EnableDlgItem(IDC_REGISTER_SHELLEXTENSION, !registered);
        EnableDlgItem(IDC_UNREGISTER_SHELLEXTENSION, registered);
        EnableDlgItem(IDC_REGISTER_SHELLEXTENSION_PERUSER, !registeredPerUser);
        EnableDlgItem(IDC_UNREGISTER_SHELLEXTENSION_PERUSER, registeredPerUser);
        EnableDlgItem(IDC_REGISTER_SHELLEXTENSION, !registered);
        EnableDlgItem(IDC_UNREGISTER_SHELLEXTENSION, registered);
        EnableDlgItem(IDC_REGISTER_SHELLEXTENSION_PERUSER, !registeredPerUser);
        EnableDlgItem(IDC_UNREGISTER_SHELLEXTENSION_PERUSER, registeredPerUser);
+       EnableDlgItem(IDC_REGISTER_WINMERGECONTEXTMENU, !registerdWinMergeContextMenu);
+       EnableDlgItem(IDC_UNREGISTER_WINMERGECONTEXTMENU, registerdWinMergeContextMenu);
        EnableDlgItem(IDC_EXPLORER_ADVANCED, 
        EnableDlgItem(IDC_EXPLORER_ADVANCED, 
-               (registered || registeredPerUser) && IsDlgButtonChecked(IDC_EXPLORER_CONTEXT));
+               (registered || registeredPerUser || registerdWinMergeContextMenu) && IsDlgButtonChecked(IDC_EXPLORER_CONTEXT));
 }
 
 void PropShell::OnRegisterShellExtension()
 }
 
 void PropShell::OnRegisterShellExtension()
@@ -278,6 +325,16 @@ void PropShell::OnUnregisterShellExtensionPerUser()
        RegisterShellExtension(true, true);
 }
 
        RegisterShellExtension(true, true);
 }
 
+void PropShell::OnRegisterWinMergeContextMenu()
+{
+       RegisterWinMergeContextMenu(false);
+}
+
+void PropShell::OnUnregisterWinMergeContextMenu()
+{
+       RegisterWinMergeContextMenu(true);
+}
+
 void PropShell::OnTimer(UINT_PTR nIDEvent)
 {
        UpdateButtons();
 void PropShell::OnTimer(UINT_PTR nIDEvent)
 {
        UpdateButtons();
index 65fdca1..702027c 100644 (file)
@@ -38,6 +38,8 @@ protected:
        afx_msg void OnUnregisterShellExtension();
        afx_msg void OnRegisterShellExtensionPerUser();
        afx_msg void OnUnregisterShellExtensionPerUser();
        afx_msg void OnUnregisterShellExtension();
        afx_msg void OnRegisterShellExtensionPerUser();
        afx_msg void OnUnregisterShellExtensionPerUser();
+       afx_msg void OnRegisterWinMergeContextMenu();
+       afx_msg void OnUnregisterWinMergeContextMenu();
        afx_msg void OnTimer(UINT_PTR nIDEvent);
 
        void GetContextRegValues();
        afx_msg void OnTimer(UINT_PTR nIDEvent);
 
        void GetContextRegValues();
index 0c51392..e930ba8 100644 (file)
 #define IDC_PLUGIN_DEFAULTS             1366\r
 #define IDC_PLUGIN_AUTOMATIC            1367\r
 #define IDC_RENDERING_MODE              1368\r
 #define IDC_PLUGIN_DEFAULTS             1366\r
 #define IDC_PLUGIN_AUTOMATIC            1367\r
 #define IDC_RENDERING_MODE              1368\r
+#define IDC_REGISTER_WINMERGECONTEXTMENU 1369\r
+#define IDC_UNREGISTER_WINMERGECONTEXTMENU 1370\r
 #define IDC_DIFF_IGNORECP               1377\r
 #define IDC_RESET                       1378\r
 #define IDC_LEFT1                       1379\r
 #define IDC_DIFF_IGNORECP               1377\r
 #define IDC_RESET                       1378\r
 #define IDC_LEFT1                       1379\r
index 818036c..c9b8233 100644 (file)
   </tr>
   <tr>
     <td class="left">Arabic</td>
   </tr>
   <tr>
     <td class="left">Arabic</td>
-    <td class="right">1100</td>
+    <td class="right">1102</td>
     <td class="right translated">905</td>
     <td class="right fuzzy">0</td>
     <td class="right translated">905</td>
     <td class="right fuzzy">0</td>
-    <td class="right untranslated">195</td>
+    <td class="right untranslated">197</td>
     <td class="right">82 %</td>
     <td class="center">2019-12-30</td>
   </tr>
   <tr>
     <td class="left">Basque</td>
     <td class="right">82 %</td>
     <td class="center">2019-12-30</td>
   </tr>
   <tr>
     <td class="left">Basque</td>
-    <td class="right">1100</td>
+    <td class="right">1102</td>
     <td class="right translated">642</td>
     <td class="right fuzzy">0</td>
     <td class="right translated">642</td>
     <td class="right fuzzy">0</td>
-    <td class="right untranslated">458</td>
+    <td class="right untranslated">460</td>
     <td class="right">58 %</td>
     <td class="center">2013-02-03</td>
   </tr>
   <tr>
     <td class="left">Brazilian</td>
     <td class="right">58 %</td>
     <td class="center">2013-02-03</td>
   </tr>
   <tr>
     <td class="left">Brazilian</td>
-    <td class="right">1100</td>
+    <td class="right">1102</td>
     <td class="right translated">1089</td>
     <td class="right fuzzy">0</td>
     <td class="right translated">1089</td>
     <td class="right fuzzy">0</td>
-    <td class="right untranslated">11</td>
+    <td class="right untranslated">13</td>
     <td class="right">99 %</td>
     <td class="center">2021-08-09</td>
   </tr>
   <tr>
     <td class="left">Bulgarian</td>
     <td class="right">99 %</td>
     <td class="center">2021-08-09</td>
   </tr>
   <tr>
     <td class="left">Bulgarian</td>
-    <td class="right">1100</td>
+    <td class="right">1102</td>
     <td class="right translated">970</td>
     <td class="right fuzzy">0</td>
     <td class="right translated">970</td>
     <td class="right fuzzy">0</td>
-    <td class="right untranslated">130</td>
+    <td class="right untranslated">132</td>
     <td class="right">88 %</td>
     <td class="center">2021-06-28</td>
   </tr>
   <tr>
     <td class="left">Catalan</td>
     <td class="right">88 %</td>
     <td class="center">2021-06-28</td>
   </tr>
   <tr>
     <td class="left">Catalan</td>
-    <td class="right">1100</td>
+    <td class="right">1102</td>
     <td class="right translated">568</td>
     <td class="right fuzzy">0</td>
     <td class="right translated">568</td>
     <td class="right fuzzy">0</td>
-    <td class="right untranslated">532</td>
+    <td class="right untranslated">534</td>
     <td class="right">52 %</td>
     <td class="center"></td>
   </tr>
   <tr>
     <td class="left">ChineseSimplified</td>
     <td class="right">52 %</td>
     <td class="center"></td>
   </tr>
   <tr>
     <td class="left">ChineseSimplified</td>
-    <td class="right">1100</td>
+    <td class="right">1102</td>
     <td class="right translated">978</td>
     <td class="right fuzzy">0</td>
     <td class="right translated">978</td>
     <td class="right fuzzy">0</td>
-    <td class="right untranslated">122</td>
+    <td class="right untranslated">124</td>
     <td class="right">89 %</td>
     <td class="center"></td>
   </tr>
   <tr>
     <td class="left">ChineseTraditional</td>
     <td class="right">89 %</td>
     <td class="center"></td>
   </tr>
   <tr>
     <td class="left">ChineseTraditional</td>
-    <td class="right">1100</td>
+    <td class="right">1102</td>
     <td class="right translated">858</td>
     <td class="right fuzzy">0</td>
     <td class="right translated">858</td>
     <td class="right fuzzy">0</td>
-    <td class="right untranslated">242</td>
+    <td class="right untranslated">244</td>
     <td class="right">78 %</td>
     <td class="center">2010-02-19</td>
   </tr>
   <tr>
     <td class="left">Croatian</td>
     <td class="right">78 %</td>
     <td class="center">2010-02-19</td>
   </tr>
   <tr>
     <td class="left">Croatian</td>
-    <td class="right">1100</td>
+    <td class="right">1102</td>
     <td class="right translated">633</td>
     <td class="right fuzzy">1</td>
     <td class="right translated">633</td>
     <td class="right fuzzy">1</td>
-    <td class="right untranslated">466</td>
+    <td class="right untranslated">468</td>
     <td class="right">58 %</td>
     <td class="center">2009-02-13</td>
   </tr>
   <tr>
     <td class="left">Czech</td>
     <td class="right">58 %</td>
     <td class="center">2009-02-13</td>
   </tr>
   <tr>
     <td class="left">Czech</td>
-    <td class="right">1100</td>
+    <td class="right">1102</td>
     <td class="right translated">608</td>
     <td class="right fuzzy">0</td>
     <td class="right translated">608</td>
     <td class="right fuzzy">0</td>
-    <td class="right untranslated">492</td>
+    <td class="right untranslated">494</td>
     <td class="right">55 %</td>
     <td class="center"></td>
   </tr>
   <tr>
     <td class="left">Danish</td>
     <td class="right">55 %</td>
     <td class="center"></td>
   </tr>
   <tr>
     <td class="left">Danish</td>
-    <td class="right">1100</td>
+    <td class="right">1102</td>
     <td class="right translated">642</td>
     <td class="right fuzzy">0</td>
     <td class="right translated">642</td>
     <td class="right fuzzy">0</td>
-    <td class="right untranslated">458</td>
+    <td class="right untranslated">460</td>
     <td class="right">58 %</td>
     <td class="center">2013-01-13</td>
   </tr>
   <tr>
     <td class="left">Dutch</td>
     <td class="right">58 %</td>
     <td class="center">2013-01-13</td>
   </tr>
   <tr>
     <td class="left">Dutch</td>
-    <td class="right">1100</td>
+    <td class="right">1102</td>
     <td class="right translated">1089</td>
     <td class="right fuzzy">0</td>
     <td class="right translated">1089</td>
     <td class="right fuzzy">0</td>
-    <td class="right untranslated">11</td>
+    <td class="right untranslated">13</td>
     <td class="right">99 %</td>
     <td class="center">2018-09-06</td>
   </tr>
   <tr>
     <td class="left">English</td>
     <td class="right">99 %</td>
     <td class="center">2018-09-06</td>
   </tr>
   <tr>
     <td class="left">English</td>
-    <td class="right">1101</td>
-    <td class="right translated">1101</td>
+    <td class="right">1103</td>
+    <td class="right translated">1103</td>
     <td class="right fuzzy">0</td>
     <td class="right untranslated">0</td>
     <td class="right">100 %</td>
     <td class="right fuzzy">0</td>
     <td class="right untranslated">0</td>
     <td class="right">100 %</td>
-    <td class="center">2021-08-29</td>
+    <td class="center">2021-09-12</td>
   </tr>
   <tr>
     <td class="left">Finnish</td>
   </tr>
   <tr>
     <td class="left">Finnish</td>
-    <td class="right">1100</td>
+    <td class="right">1102</td>
     <td class="right translated">905</td>
     <td class="right fuzzy">0</td>
     <td class="right translated">905</td>
     <td class="right fuzzy">0</td>
-    <td class="right untranslated">195</td>
+    <td class="right untranslated">197</td>
     <td class="right">82 %</td>
     <td class="center"></td>
   </tr>
   <tr>
     <td class="left">French</td>
     <td class="right">82 %</td>
     <td class="center"></td>
   </tr>
   <tr>
     <td class="left">French</td>
-    <td class="right">1100</td>
+    <td class="right">1102</td>
     <td class="right translated">1022</td>
     <td class="right fuzzy">0</td>
     <td class="right translated">1022</td>
     <td class="right fuzzy">0</td>
-    <td class="right untranslated">78</td>
+    <td class="right untranslated">80</td>
     <td class="right">93 %</td>
     <td class="center">2021-04-29</td>
   </tr>
   <tr>
     <td class="left">Galician</td>
     <td class="right">93 %</td>
     <td class="center">2021-04-29</td>
   </tr>
   <tr>
     <td class="left">Galician</td>
-    <td class="right">1100</td>
+    <td class="right">1102</td>
     <td class="right translated">1084</td>
     <td class="right fuzzy">0</td>
     <td class="right translated">1084</td>
     <td class="right fuzzy">0</td>
-    <td class="right untranslated">16</td>
-    <td class="right">99 %</td>
+    <td class="right untranslated">18</td>
+    <td class="right">98 %</td>
     <td class="center">2021-07-11</td>
   </tr>
   <tr>
     <td class="left">German</td>
     <td class="center">2021-07-11</td>
   </tr>
   <tr>
     <td class="left">German</td>
-    <td class="right">1100</td>
+    <td class="right">1102</td>
     <td class="right translated">1100</td>
     <td class="right fuzzy">0</td>
     <td class="right translated">1100</td>
     <td class="right fuzzy">0</td>
-    <td class="right untranslated">0</td>
+    <td class="right untranslated">2</td>
     <td class="right">100 %</td>
     <td class="center">2021-09-11</td>
   </tr>
   <tr>
     <td class="left">Greek</td>
     <td class="right">100 %</td>
     <td class="center">2021-09-11</td>
   </tr>
   <tr>
     <td class="left">Greek</td>
-    <td class="right">1100</td>
+    <td class="right">1102</td>
     <td class="right translated">606</td>
     <td class="right fuzzy">0</td>
     <td class="right translated">606</td>
     <td class="right fuzzy">0</td>
-    <td class="right untranslated">494</td>
+    <td class="right untranslated">496</td>
     <td class="right">55 %</td>
     <td class="center"></td>
   </tr>
   <tr>
     <td class="left">Hungarian</td>
     <td class="right">55 %</td>
     <td class="center"></td>
   </tr>
   <tr>
     <td class="left">Hungarian</td>
-    <td class="right">1100</td>
+    <td class="right">1102</td>
     <td class="right translated">1100</td>
     <td class="right fuzzy">0</td>
     <td class="right translated">1100</td>
     <td class="right fuzzy">0</td>
-    <td class="right untranslated">0</td>
+    <td class="right untranslated">2</td>
     <td class="right">100 %</td>
     <td class="center">2021-03-15</td>
   </tr>
   <tr>
     <td class="left">Italian</td>
     <td class="right">100 %</td>
     <td class="center">2021-03-15</td>
   </tr>
   <tr>
     <td class="left">Italian</td>
-    <td class="right">1100</td>
+    <td class="right">1102</td>
     <td class="right translated">995</td>
     <td class="right fuzzy">0</td>
     <td class="right translated">995</td>
     <td class="right fuzzy">0</td>
-    <td class="right untranslated">105</td>
+    <td class="right untranslated">107</td>
     <td class="right">90 %</td>
     <td class="center">2021-08-09</td>
   </tr>
   <tr>
     <td class="left">Japanese</td>
     <td class="right">90 %</td>
     <td class="center">2021-08-09</td>
   </tr>
   <tr>
     <td class="left">Japanese</td>
-    <td class="right">1100</td>
+    <td class="right">1102</td>
     <td class="right translated">1100</td>
     <td class="right fuzzy">0</td>
     <td class="right translated">1100</td>
     <td class="right fuzzy">0</td>
-    <td class="right untranslated">0</td>
+    <td class="right untranslated">2</td>
     <td class="right">100 %</td>
     <td class="center">2021-07-11</td>
   </tr>
   <tr>
     <td class="left">Korean</td>
     <td class="right">100 %</td>
     <td class="center">2021-07-11</td>
   </tr>
   <tr>
     <td class="left">Korean</td>
-    <td class="right">1100</td>
+    <td class="right">1102</td>
     <td class="right translated">1038</td>
     <td class="right fuzzy">0</td>
     <td class="right translated">1038</td>
     <td class="right fuzzy">0</td>
-    <td class="right untranslated">62</td>
+    <td class="right untranslated">64</td>
     <td class="right">94 %</td>
     <td class="center">2021-08-23</td>
   </tr>
   <tr>
     <td class="left">Lithuanian</td>
     <td class="right">94 %</td>
     <td class="center">2021-08-23</td>
   </tr>
   <tr>
     <td class="left">Lithuanian</td>
-    <td class="right">1100</td>
+    <td class="right">1102</td>
     <td class="right translated">1088</td>
     <td class="right fuzzy">0</td>
     <td class="right translated">1088</td>
     <td class="right fuzzy">0</td>
-    <td class="right untranslated">12</td>
+    <td class="right untranslated">14</td>
     <td class="right">99 %</td>
     <td class="center">2021-07-22</td>
   </tr>
   <tr>
     <td class="left">Norwegian</td>
     <td class="right">99 %</td>
     <td class="center">2021-07-22</td>
   </tr>
   <tr>
     <td class="left">Norwegian</td>
-    <td class="right">1100</td>
+    <td class="right">1102</td>
     <td class="right translated">634</td>
     <td class="right fuzzy">0</td>
     <td class="right translated">634</td>
     <td class="right fuzzy">0</td>
-    <td class="right untranslated">466</td>
+    <td class="right untranslated">468</td>
     <td class="right">58 %</td>
     <td class="center"></td>
   </tr>
   <tr>
     <td class="left">Persian</td>
     <td class="right">58 %</td>
     <td class="center"></td>
   </tr>
   <tr>
     <td class="left">Persian</td>
-    <td class="right">1100</td>
+    <td class="right">1102</td>
     <td class="right translated">645</td>
     <td class="right fuzzy">0</td>
     <td class="right translated">645</td>
     <td class="right fuzzy">0</td>
-    <td class="right untranslated">455</td>
+    <td class="right untranslated">457</td>
     <td class="right">59 %</td>
     <td class="center">2013-08-15</td>
   </tr>
   <tr>
     <td class="left">Polish</td>
     <td class="right">59 %</td>
     <td class="center">2013-08-15</td>
   </tr>
   <tr>
     <td class="left">Polish</td>
-    <td class="right">1100</td>
+    <td class="right">1102</td>
     <td class="right translated">1012</td>
     <td class="right fuzzy">0</td>
     <td class="right translated">1012</td>
     <td class="right fuzzy">0</td>
-    <td class="right untranslated">88</td>
+    <td class="right untranslated">90</td>
     <td class="right">92 %</td>
     <td class="center"></td>
   </tr>
   <tr>
     <td class="left">Portuguese</td>
     <td class="right">92 %</td>
     <td class="center"></td>
   </tr>
   <tr>
     <td class="left">Portuguese</td>
-    <td class="right">1100</td>
+    <td class="right">1102</td>
     <td class="right translated">1100</td>
     <td class="right fuzzy">0</td>
     <td class="right translated">1100</td>
     <td class="right fuzzy">0</td>
-    <td class="right untranslated">0</td>
+    <td class="right untranslated">2</td>
     <td class="right">100 %</td>
     <td class="center">2021-09-08</td>
   </tr>
   <tr>
     <td class="left">Romanian</td>
     <td class="right">100 %</td>
     <td class="center">2021-09-08</td>
   </tr>
   <tr>
     <td class="left">Romanian</td>
-    <td class="right">1100</td>
+    <td class="right">1102</td>
     <td class="right translated">563</td>
     <td class="right fuzzy">44</td>
     <td class="right translated">563</td>
     <td class="right fuzzy">44</td>
-    <td class="right untranslated">493</td>
+    <td class="right untranslated">495</td>
     <td class="right">55 %</td>
     <td class="center"></td>
   </tr>
   <tr>
     <td class="left">Russian</td>
     <td class="right">55 %</td>
     <td class="center"></td>
   </tr>
   <tr>
     <td class="left">Russian</td>
-    <td class="right">1100</td>
+    <td class="right">1102</td>
     <td class="right translated">1081</td>
     <td class="right fuzzy">0</td>
     <td class="right translated">1081</td>
     <td class="right fuzzy">0</td>
-    <td class="right untranslated">19</td>
+    <td class="right untranslated">21</td>
     <td class="right">98 %</td>
     <td class="center">2021-09-11</td>
   </tr>
   <tr>
     <td class="left">Serbian</td>
     <td class="right">98 %</td>
     <td class="center">2021-09-11</td>
   </tr>
   <tr>
     <td class="left">Serbian</td>
-    <td class="right">1100</td>
+    <td class="right">1102</td>
     <td class="right translated">634</td>
     <td class="right fuzzy">0</td>
     <td class="right translated">634</td>
     <td class="right fuzzy">0</td>
-    <td class="right untranslated">466</td>
+    <td class="right untranslated">468</td>
     <td class="right">58 %</td>
     <td class="center"></td>
   </tr>
   <tr>
     <td class="left">Sinhala</td>
     <td class="right">58 %</td>
     <td class="center"></td>
   </tr>
   <tr>
     <td class="left">Sinhala</td>
-    <td class="right">1100</td>
+    <td class="right">1102</td>
     <td class="right translated">568</td>
     <td class="right fuzzy">59</td>
     <td class="right translated">568</td>
     <td class="right fuzzy">59</td>
-    <td class="right untranslated">473</td>
+    <td class="right untranslated">475</td>
     <td class="right">57 %</td>
     <td class="center">2010-12-12</td>
   </tr>
   <tr>
     <td class="left">Slovak</td>
     <td class="right">57 %</td>
     <td class="center">2010-12-12</td>
   </tr>
   <tr>
     <td class="left">Slovak</td>
-    <td class="right">1100</td>
+    <td class="right">1102</td>
     <td class="right translated">978</td>
     <td class="right fuzzy">0</td>
     <td class="right translated">978</td>
     <td class="right fuzzy">0</td>
-    <td class="right untranslated">122</td>
+    <td class="right untranslated">124</td>
     <td class="right">89 %</td>
     <td class="center">2020-11-02</td>
   </tr>
   <tr>
     <td class="left">Slovenian</td>
     <td class="right">89 %</td>
     <td class="center">2020-11-02</td>
   </tr>
   <tr>
     <td class="left">Slovenian</td>
-    <td class="right">1100</td>
+    <td class="right">1102</td>
     <td class="right translated">1089</td>
     <td class="right fuzzy">0</td>
     <td class="right translated">1089</td>
     <td class="right fuzzy">0</td>
-    <td class="right untranslated">11</td>
+    <td class="right untranslated">13</td>
     <td class="right">99 %</td>
     <td class="center">2021-07-25</td>
   </tr>
   <tr>
     <td class="left">Spanish</td>
     <td class="right">99 %</td>
     <td class="center">2021-07-25</td>
   </tr>
   <tr>
     <td class="left">Spanish</td>
-    <td class="right">1100</td>
+    <td class="right">1102</td>
     <td class="right translated">874</td>
     <td class="right fuzzy">0</td>
     <td class="right translated">874</td>
     <td class="right fuzzy">0</td>
-    <td class="right untranslated">226</td>
+    <td class="right untranslated">228</td>
     <td class="right">79 %</td>
     <td class="center">2020-04-03</td>
   </tr>
   <tr>
     <td class="left">Swedish</td>
     <td class="right">79 %</td>
     <td class="center">2020-04-03</td>
   </tr>
   <tr>
     <td class="left">Swedish</td>
-    <td class="right">1100</td>
+    <td class="right">1102</td>
     <td class="right translated">1021</td>
     <td class="right fuzzy">0</td>
     <td class="right translated">1021</td>
     <td class="right fuzzy">0</td>
-    <td class="right untranslated">79</td>
+    <td class="right untranslated">81</td>
     <td class="right">93 %</td>
     <td class="center">2021-04-10</td>
   </tr>
   <tr>
     <td class="left">Turkish</td>
     <td class="right">93 %</td>
     <td class="center">2021-04-10</td>
   </tr>
   <tr>
     <td class="left">Turkish</td>
-    <td class="right">1100</td>
+    <td class="right">1102</td>
     <td class="right translated">1089</td>
     <td class="right fuzzy">0</td>
     <td class="right translated">1089</td>
     <td class="right fuzzy">0</td>
-    <td class="right untranslated">11</td>
+    <td class="right untranslated">13</td>
     <td class="right">99 %</td>
     <td class="center">2021-07-25</td>
   </tr>
   <tr>
     <td class="left">Ukrainian</td>
     <td class="right">99 %</td>
     <td class="center">2021-07-25</td>
   </tr>
   <tr>
     <td class="left">Ukrainian</td>
-    <td class="right">1100</td>
+    <td class="right">1102</td>
     <td class="right translated">639</td>
     <td class="right fuzzy">0</td>
     <td class="right translated">639</td>
     <td class="right fuzzy">0</td>
-    <td class="right untranslated">461</td>
+    <td class="right untranslated">463</td>
     <td class="right">58 %</td>
     <td class="center">2009-06-13</td>
   </tr>
     <td class="right">58 %</td>
     <td class="center">2009-06-13</td>
   </tr>
index 60b6ca4..b940918 100644 (file)
@@ -6,42 +6,42 @@ Status from **2021-09-12**:
 
 | Language             | Total | Translated | Fuzzy | Untranslated | Complete | Last Update |
 |:---------------------|------:|-----------:|------:|-------------:|---------:|:-----------:|
 
 | Language             | Total | Translated | Fuzzy | Untranslated | Complete | Last Update |
 |:---------------------|------:|-----------:|------:|-------------:|---------:|:-----------:|
-| Arabic               |  1100 |        905 |     0 |          195 |     82 % |  2019-12-30 |
-| Basque               |  1100 |        642 |     0 |          458 |     58 % |  2013-02-03 |
-| Brazilian            |  1100 |       1089 |     0 |           11 |     99 % |  2021-08-09 |
-| Bulgarian            |  1100 |        970 |     0 |          130 |     88 % |  2021-06-28 |
-| Catalan              |  1100 |        568 |     0 |          532 |     52 % |             |
-| ChineseSimplified    |  1100 |        978 |     0 |          122 |     89 % |             |
-| ChineseTraditional   |  1100 |        858 |     0 |          242 |     78 % |  2010-02-19 |
-| Croatian             |  1100 |        633 |     1 |          466 |     58 % |  2009-02-13 |
-| Czech                |  1100 |        608 |     0 |          492 |     55 % |             |
-| Danish               |  1100 |        642 |     0 |          458 |     58 % |  2013-01-13 |
-| Dutch                |  1100 |       1089 |     0 |           11 |     99 % |  2018-09-06 |
-| English              |  1101 |       1101 |     0 |            0 |    100 % |  2021-08-29 |
-| Finnish              |  1100 |        905 |     0 |          195 |     82 % |             |
-| French               |  1100 |       1022 |     0 |           78 |     93 % |  2021-04-29 |
-| Galician             |  1100 |       1084 |     0 |           16 |     99 % |  2021-07-11 |
-| German               |  1100 |       1100 |     0 |            0 |    100 % |  2021-09-11 |
-| Greek                |  1100 |        606 |     0 |          494 |     55 % |             |
-| Hungarian            |  1100 |       1100 |     0 |            0 |    100 % |  2021-03-15 |
-| Italian              |  1100 |        995 |     0 |          105 |     90 % |  2021-08-09 |
-| Japanese             |  1100 |       1100 |     0 |            0 |    100 % |  2021-07-11 |
-| Korean               |  1100 |       1038 |     0 |           62 |     94 % |  2021-08-23 |
-| Lithuanian           |  1100 |       1088 |     0 |           12 |     99 % |  2021-07-22 |
-| Norwegian            |  1100 |        634 |     0 |          466 |     58 % |             |
-| Persian              |  1100 |        645 |     0 |          455 |     59 % |  2013-08-15 |
-| Polish               |  1100 |       1012 |     0 |           88 |     92 % |             |
-| Portuguese           |  1100 |       1100 |     0 |            0 |    100 % |  2021-09-08 |
-| Romanian             |  1100 |        563 |    44 |          493 |     55 % |             |
-| Russian              |  1100 |       1081 |     0 |           19 |     98 % |  2021-09-11 |
-| Serbian              |  1100 |        634 |     0 |          466 |     58 % |             |
-| Sinhala              |  1100 |        568 |    59 |          473 |     57 % |  2010-12-12 |
-| Slovak               |  1100 |        978 |     0 |          122 |     89 % |  2020-11-02 |
-| Slovenian            |  1100 |       1089 |     0 |           11 |     99 % |  2021-07-25 |
-| Spanish              |  1100 |        874 |     0 |          226 |     79 % |  2020-04-03 |
-| Swedish              |  1100 |       1021 |     0 |           79 |     93 % |  2021-04-10 |
-| Turkish              |  1100 |       1089 |     0 |           11 |     99 % |  2021-07-25 |
-| Ukrainian            |  1100 |        639 |     0 |          461 |     58 % |  2009-06-13 |
+| Arabic               |  1102 |        905 |     0 |          197 |     82 % |  2019-12-30 |
+| Basque               |  1102 |        642 |     0 |          460 |     58 % |  2013-02-03 |
+| Brazilian            |  1102 |       1089 |     0 |           13 |     99 % |  2021-08-09 |
+| Bulgarian            |  1102 |        970 |     0 |          132 |     88 % |  2021-06-28 |
+| Catalan              |  1102 |        568 |     0 |          534 |     52 % |             |
+| ChineseSimplified    |  1102 |        978 |     0 |          124 |     89 % |             |
+| ChineseTraditional   |  1102 |        858 |     0 |          244 |     78 % |  2010-02-19 |
+| Croatian             |  1102 |        633 |     1 |          468 |     58 % |  2009-02-13 |
+| Czech                |  1102 |        608 |     0 |          494 |     55 % |             |
+| Danish               |  1102 |        642 |     0 |          460 |     58 % |  2013-01-13 |
+| Dutch                |  1102 |       1089 |     0 |           13 |     99 % |  2018-09-06 |
+| English              |  1103 |       1103 |     0 |            0 |    100 % |  2021-09-12 |
+| Finnish              |  1102 |        905 |     0 |          197 |     82 % |             |
+| French               |  1102 |       1022 |     0 |           80 |     93 % |  2021-04-29 |
+| Galician             |  1102 |       1084 |     0 |           18 |     98 % |  2021-07-11 |
+| German               |  1102 |       1100 |     0 |            2 |    100 % |  2021-09-11 |
+| Greek                |  1102 |        606 |     0 |          496 |     55 % |             |
+| Hungarian            |  1102 |       1100 |     0 |            2 |    100 % |  2021-03-15 |
+| Italian              |  1102 |        995 |     0 |          107 |     90 % |  2021-08-09 |
+| Japanese             |  1102 |       1100 |     0 |            2 |    100 % |  2021-07-11 |
+| Korean               |  1102 |       1038 |     0 |           64 |     94 % |  2021-08-23 |
+| Lithuanian           |  1102 |       1088 |     0 |           14 |     99 % |  2021-07-22 |
+| Norwegian            |  1102 |        634 |     0 |          468 |     58 % |             |
+| Persian              |  1102 |        645 |     0 |          457 |     59 % |  2013-08-15 |
+| Polish               |  1102 |       1012 |     0 |           90 |     92 % |             |
+| Portuguese           |  1102 |       1100 |     0 |            2 |    100 % |  2021-09-08 |
+| Romanian             |  1102 |        563 |    44 |          495 |     55 % |             |
+| Russian              |  1102 |       1081 |     0 |           21 |     98 % |  2021-09-11 |
+| Serbian              |  1102 |        634 |     0 |          468 |     58 % |             |
+| Sinhala              |  1102 |        568 |    59 |          475 |     57 % |  2010-12-12 |
+| Slovak               |  1102 |        978 |     0 |          124 |     89 % |  2020-11-02 |
+| Slovenian            |  1102 |       1089 |     0 |           13 |     99 % |  2021-07-25 |
+| Spanish              |  1102 |        874 |     0 |          228 |     79 % |  2020-04-03 |
+| Swedish              |  1102 |       1021 |     0 |           81 |     93 % |  2021-04-10 |
+| Turkish              |  1102 |       1089 |     0 |           13 |     99 % |  2021-07-25 |
+| Ukrainian            |  1102 |        639 |     0 |          463 |     58 % |  2009-06-13 |
 
 ## ShellExtension
 
 
 ## ShellExtension
 
index d15d109..693a5d4 100644 (file)
@@ -7,10 +7,10 @@
       <file>Arabic.po</file>
       <update>2019-12-30</update>
       <strings>
       <file>Arabic.po</file>
       <update>2019-12-30</update>
       <strings>
-        <count>1100</count>
+        <count>1102</count>
         <translated>905</translated>
         <fuzzy>0</fuzzy>
         <translated>905</translated>
         <fuzzy>0</fuzzy>
-        <untranslated>195</untranslated>
+        <untranslated>197</untranslated>
       </strings>
     </translation>
     <translation>
       </strings>
     </translation>
     <translation>
       <file>Basque.po</file>
       <update>2013-02-03</update>
       <strings>
       <file>Basque.po</file>
       <update>2013-02-03</update>
       <strings>
-        <count>1100</count>
+        <count>1102</count>
         <translated>642</translated>
         <fuzzy>0</fuzzy>
         <translated>642</translated>
         <fuzzy>0</fuzzy>
-        <untranslated>458</untranslated>
+        <untranslated>460</untranslated>
       </strings>
       <translators>
         <translator>
       </strings>
       <translators>
         <translator>
       <file>Brazilian.po</file>
       <update>2021-08-09</update>
       <strings>
       <file>Brazilian.po</file>
       <update>2021-08-09</update>
       <strings>
-        <count>1100</count>
+        <count>1102</count>
         <translated>1089</translated>
         <fuzzy>0</fuzzy>
         <translated>1089</translated>
         <fuzzy>0</fuzzy>
-        <untranslated>11</untranslated>
+        <untranslated>13</untranslated>
       </strings>
       <translators>
         <translator>
       </strings>
       <translators>
         <translator>
       <file>Bulgarian.po</file>
       <update>2021-06-28</update>
       <strings>
       <file>Bulgarian.po</file>
       <update>2021-06-28</update>
       <strings>
-        <count>1100</count>
+        <count>1102</count>
         <translated>970</translated>
         <fuzzy>0</fuzzy>
         <translated>970</translated>
         <fuzzy>0</fuzzy>
-        <untranslated>130</untranslated>
+        <untranslated>132</untranslated>
       </strings>
       <translators>
         <translator>
       </strings>
       <translators>
         <translator>
       <file>Catalan.po</file>
       <update></update>
       <strings>
       <file>Catalan.po</file>
       <update></update>
       <strings>
-        <count>1100</count>
+        <count>1102</count>
         <translated>568</translated>
         <fuzzy>0</fuzzy>
         <translated>568</translated>
         <fuzzy>0</fuzzy>
-        <untranslated>532</untranslated>
+        <untranslated>534</untranslated>
       </strings>
       <translators>
         <translator>
       </strings>
       <translators>
         <translator>
       <file>ChineseSimplified.po</file>
       <update></update>
       <strings>
       <file>ChineseSimplified.po</file>
       <update></update>
       <strings>
-        <count>1100</count>
+        <count>1102</count>
         <translated>978</translated>
         <fuzzy>0</fuzzy>
         <translated>978</translated>
         <fuzzy>0</fuzzy>
-        <untranslated>122</untranslated>
+        <untranslated>124</untranslated>
       </strings>
       <translators>
         <translator>
       </strings>
       <translators>
         <translator>
       <file>ChineseTraditional.po</file>
       <update>2010-02-19</update>
       <strings>
       <file>ChineseTraditional.po</file>
       <update>2010-02-19</update>
       <strings>
-        <count>1100</count>
+        <count>1102</count>
         <translated>858</translated>
         <fuzzy>0</fuzzy>
         <translated>858</translated>
         <fuzzy>0</fuzzy>
-        <untranslated>242</untranslated>
+        <untranslated>244</untranslated>
       </strings>
       <translators>
         <translator>
       </strings>
       <translators>
         <translator>
       <file>Croatian.po</file>
       <update>2009-02-13</update>
       <strings>
       <file>Croatian.po</file>
       <update>2009-02-13</update>
       <strings>
-        <count>1100</count>
+        <count>1102</count>
         <translated>633</translated>
         <fuzzy>1</fuzzy>
         <translated>633</translated>
         <fuzzy>1</fuzzy>
-        <untranslated>466</untranslated>
+        <untranslated>468</untranslated>
       </strings>
       <translators>
         <translator>
       </strings>
       <translators>
         <translator>
       <file>Czech.po</file>
       <update></update>
       <strings>
       <file>Czech.po</file>
       <update></update>
       <strings>
-        <count>1100</count>
+        <count>1102</count>
         <translated>608</translated>
         <fuzzy>0</fuzzy>
         <translated>608</translated>
         <fuzzy>0</fuzzy>
-        <untranslated>492</untranslated>
+        <untranslated>494</untranslated>
       </strings>
       <translators>
         <translator>
       </strings>
       <translators>
         <translator>
       <file>Danish.po</file>
       <update>2013-01-13</update>
       <strings>
       <file>Danish.po</file>
       <update>2013-01-13</update>
       <strings>
-        <count>1100</count>
+        <count>1102</count>
         <translated>642</translated>
         <fuzzy>0</fuzzy>
         <translated>642</translated>
         <fuzzy>0</fuzzy>
-        <untranslated>458</untranslated>
+        <untranslated>460</untranslated>
       </strings>
       <translators>
         <translator>
       </strings>
       <translators>
         <translator>
       <file>Dutch.po</file>
       <update>2018-09-06</update>
       <strings>
       <file>Dutch.po</file>
       <update>2018-09-06</update>
       <strings>
-        <count>1100</count>
+        <count>1102</count>
         <translated>1089</translated>
         <fuzzy>0</fuzzy>
         <translated>1089</translated>
         <fuzzy>0</fuzzy>
-        <untranslated>11</untranslated>
+        <untranslated>13</untranslated>
       </strings>
       <translators>
         <translator>
       </strings>
       <translators>
         <translator>
     <translation template="1">
       <language>English</language>
       <file>English.pot</file>
     <translation template="1">
       <language>English</language>
       <file>English.pot</file>
-      <update>2021-08-29</update>
+      <update>2021-09-12</update>
       <strings>
       <strings>
-        <count>1101</count>
-        <translated>1101</translated>
+        <count>1103</count>
+        <translated>1103</translated>
         <fuzzy>0</fuzzy>
         <untranslated>0</untranslated>
       </strings>
         <fuzzy>0</fuzzy>
         <untranslated>0</untranslated>
       </strings>
       <file>Finnish.po</file>
       <update></update>
       <strings>
       <file>Finnish.po</file>
       <update></update>
       <strings>
-        <count>1100</count>
+        <count>1102</count>
         <translated>905</translated>
         <fuzzy>0</fuzzy>
         <translated>905</translated>
         <fuzzy>0</fuzzy>
-        <untranslated>195</untranslated>
+        <untranslated>197</untranslated>
       </strings>
     </translation>
     <translation>
       </strings>
     </translation>
     <translation>
       <file>French.po</file>
       <update>2021-04-29</update>
       <strings>
       <file>French.po</file>
       <update>2021-04-29</update>
       <strings>
-        <count>1100</count>
+        <count>1102</count>
         <translated>1022</translated>
         <fuzzy>0</fuzzy>
         <translated>1022</translated>
         <fuzzy>0</fuzzy>
-        <untranslated>78</untranslated>
+        <untranslated>80</untranslated>
       </strings>
       <translators>
         <translator maintainer="1">
       </strings>
       <translators>
         <translator maintainer="1">
       <file>Galician.po</file>
       <update>2021-07-11</update>
       <strings>
       <file>Galician.po</file>
       <update>2021-07-11</update>
       <strings>
-        <count>1100</count>
+        <count>1102</count>
         <translated>1084</translated>
         <fuzzy>0</fuzzy>
         <translated>1084</translated>
         <fuzzy>0</fuzzy>
-        <untranslated>16</untranslated>
+        <untranslated>18</untranslated>
       </strings>
       <translators>
         <translator>
       </strings>
       <translators>
         <translator>
       <file>German.po</file>
       <update>2021-09-11</update>
       <strings>
       <file>German.po</file>
       <update>2021-09-11</update>
       <strings>
-        <count>1100</count>
+        <count>1102</count>
         <translated>1100</translated>
         <fuzzy>0</fuzzy>
         <translated>1100</translated>
         <fuzzy>0</fuzzy>
-        <untranslated>0</untranslated>
+        <untranslated>2</untranslated>
       </strings>
       <translators>
         <translator maintainer="1">
       </strings>
       <translators>
         <translator maintainer="1">
       <file>Greek.po</file>
       <update></update>
       <strings>
       <file>Greek.po</file>
       <update></update>
       <strings>
-        <count>1100</count>
+        <count>1102</count>
         <translated>606</translated>
         <fuzzy>0</fuzzy>
         <translated>606</translated>
         <fuzzy>0</fuzzy>
-        <untranslated>494</untranslated>
+        <untranslated>496</untranslated>
       </strings>
       <translators>
         <translator>
       </strings>
       <translators>
         <translator>
       <file>Hungarian.po</file>
       <update>2021-03-15</update>
       <strings>
       <file>Hungarian.po</file>
       <update>2021-03-15</update>
       <strings>
-        <count>1100</count>
+        <count>1102</count>
         <translated>1100</translated>
         <fuzzy>0</fuzzy>
         <translated>1100</translated>
         <fuzzy>0</fuzzy>
-        <untranslated>0</untranslated>
+        <untranslated>2</untranslated>
       </strings>
       <translators>
         <translator>
       </strings>
       <translators>
         <translator>
       <file>Italian.po</file>
       <update>2021-08-09</update>
       <strings>
       <file>Italian.po</file>
       <update>2021-08-09</update>
       <strings>
-        <count>1100</count>
+        <count>1102</count>
         <translated>995</translated>
         <fuzzy>0</fuzzy>
         <translated>995</translated>
         <fuzzy>0</fuzzy>
-        <untranslated>105</untranslated>
+        <untranslated>107</untranslated>
       </strings>
       <translators>
         <translator>
       </strings>
       <translators>
         <translator>
       <file>Japanese.po</file>
       <update>2021-07-11</update>
       <strings>
       <file>Japanese.po</file>
       <update>2021-07-11</update>
       <strings>
-        <count>1100</count>
+        <count>1102</count>
         <translated>1100</translated>
         <fuzzy>0</fuzzy>
         <translated>1100</translated>
         <fuzzy>0</fuzzy>
-        <untranslated>0</untranslated>
+        <untranslated>2</untranslated>
       </strings>
       <translators>
         <translator>
       </strings>
       <translators>
         <translator>
       <file>Korean.po</file>
       <update>2021-08-23</update>
       <strings>
       <file>Korean.po</file>
       <update>2021-08-23</update>
       <strings>
-        <count>1100</count>
+        <count>1102</count>
         <translated>1038</translated>
         <fuzzy>0</fuzzy>
         <translated>1038</translated>
         <fuzzy>0</fuzzy>
-        <untranslated>62</untranslated>
+        <untranslated>64</untranslated>
       </strings>
       <translators>
         <translator>
       </strings>
       <translators>
         <translator>
       <file>Lithuanian.po</file>
       <update>2021-07-22</update>
       <strings>
       <file>Lithuanian.po</file>
       <update>2021-07-22</update>
       <strings>
-        <count>1100</count>
+        <count>1102</count>
         <translated>1088</translated>
         <fuzzy>0</fuzzy>
         <translated>1088</translated>
         <fuzzy>0</fuzzy>
-        <untranslated>12</untranslated>
+        <untranslated>14</untranslated>
       </strings>
       <translators>
         <translator>
       </strings>
       <translators>
         <translator>
       <file>Norwegian.po</file>
       <update></update>
       <strings>
       <file>Norwegian.po</file>
       <update></update>
       <strings>
-        <count>1100</count>
+        <count>1102</count>
         <translated>634</translated>
         <fuzzy>0</fuzzy>
         <translated>634</translated>
         <fuzzy>0</fuzzy>
-        <untranslated>466</untranslated>
+        <untranslated>468</untranslated>
       </strings>
       <translators>
         <translator>
       </strings>
       <translators>
         <translator>
       <file>Persian.po</file>
       <update>2013-08-15</update>
       <strings>
       <file>Persian.po</file>
       <update>2013-08-15</update>
       <strings>
-        <count>1100</count>
+        <count>1102</count>
         <translated>645</translated>
         <fuzzy>0</fuzzy>
         <translated>645</translated>
         <fuzzy>0</fuzzy>
-        <untranslated>455</untranslated>
+        <untranslated>457</untranslated>
       </strings>
       <translators>
         <translator>
       </strings>
       <translators>
         <translator>
       <file>Polish.po</file>
       <update></update>
       <strings>
       <file>Polish.po</file>
       <update></update>
       <strings>
-        <count>1100</count>
+        <count>1102</count>
         <translated>1012</translated>
         <fuzzy>0</fuzzy>
         <translated>1012</translated>
         <fuzzy>0</fuzzy>
-        <untranslated>88</untranslated>
+        <untranslated>90</untranslated>
       </strings>
       <translators>
         <translator>
       </strings>
       <translators>
         <translator>
       <file>Portuguese.po</file>
       <update>2021-09-08</update>
       <strings>
       <file>Portuguese.po</file>
       <update>2021-09-08</update>
       <strings>
-        <count>1100</count>
+        <count>1102</count>
         <translated>1100</translated>
         <fuzzy>0</fuzzy>
         <translated>1100</translated>
         <fuzzy>0</fuzzy>
-        <untranslated>0</untranslated>
+        <untranslated>2</untranslated>
       </strings>
       <translators>
         <translator>
       </strings>
       <translators>
         <translator>
       <file>Romanian.po</file>
       <update></update>
       <strings>
       <file>Romanian.po</file>
       <update></update>
       <strings>
-        <count>1100</count>
+        <count>1102</count>
         <translated>563</translated>
         <fuzzy>44</fuzzy>
         <translated>563</translated>
         <fuzzy>44</fuzzy>
-        <untranslated>493</untranslated>
+        <untranslated>495</untranslated>
       </strings>
       <translators>
         <translator>
       </strings>
       <translators>
         <translator>
       <file>Russian.po</file>
       <update>2021-09-11</update>
       <strings>
       <file>Russian.po</file>
       <update>2021-09-11</update>
       <strings>
-        <count>1100</count>
+        <count>1102</count>
         <translated>1081</translated>
         <fuzzy>0</fuzzy>
         <translated>1081</translated>
         <fuzzy>0</fuzzy>
-        <untranslated>19</untranslated>
+        <untranslated>21</untranslated>
       </strings>
       <translators>
         <translator>
       </strings>
       <translators>
         <translator>
       <file>Serbian.po</file>
       <update></update>
       <strings>
       <file>Serbian.po</file>
       <update></update>
       <strings>
-        <count>1100</count>
+        <count>1102</count>
         <translated>634</translated>
         <fuzzy>0</fuzzy>
         <translated>634</translated>
         <fuzzy>0</fuzzy>
-        <untranslated>466</untranslated>
+        <untranslated>468</untranslated>
       </strings>
       <translators>
         <translator>
       </strings>
       <translators>
         <translator>
       <file>Sinhala.po</file>
       <update>2010-12-12</update>
       <strings>
       <file>Sinhala.po</file>
       <update>2010-12-12</update>
       <strings>
-        <count>1100</count>
+        <count>1102</count>
         <translated>568</translated>
         <fuzzy>59</fuzzy>
         <translated>568</translated>
         <fuzzy>59</fuzzy>
-        <untranslated>473</untranslated>
+        <untranslated>475</untranslated>
       </strings>
       <translators>
         <translator>
       </strings>
       <translators>
         <translator>
       <file>Slovak.po</file>
       <update>2020-11-02</update>
       <strings>
       <file>Slovak.po</file>
       <update>2020-11-02</update>
       <strings>
-        <count>1100</count>
+        <count>1102</count>
         <translated>978</translated>
         <fuzzy>0</fuzzy>
         <translated>978</translated>
         <fuzzy>0</fuzzy>
-        <untranslated>122</untranslated>
+        <untranslated>124</untranslated>
       </strings>
       <translators>
         <translator>
       </strings>
       <translators>
         <translator>
       <file>Slovenian.po</file>
       <update>2021-07-25</update>
       <strings>
       <file>Slovenian.po</file>
       <update>2021-07-25</update>
       <strings>
-        <count>1100</count>
+        <count>1102</count>
         <translated>1089</translated>
         <fuzzy>0</fuzzy>
         <translated>1089</translated>
         <fuzzy>0</fuzzy>
-        <untranslated>11</untranslated>
+        <untranslated>13</untranslated>
       </strings>
       <translators>
         <translator>
       </strings>
       <translators>
         <translator>
       <file>Spanish.po</file>
       <update>2020-04-03</update>
       <strings>
       <file>Spanish.po</file>
       <update>2020-04-03</update>
       <strings>
-        <count>1100</count>
+        <count>1102</count>
         <translated>874</translated>
         <fuzzy>0</fuzzy>
         <translated>874</translated>
         <fuzzy>0</fuzzy>
-        <untranslated>226</untranslated>
+        <untranslated>228</untranslated>
       </strings>
       <translators>
         <translator>
       </strings>
       <translators>
         <translator>
       <file>Swedish.po</file>
       <update>2021-04-10</update>
       <strings>
       <file>Swedish.po</file>
       <update>2021-04-10</update>
       <strings>
-        <count>1100</count>
+        <count>1102</count>
         <translated>1021</translated>
         <fuzzy>0</fuzzy>
         <translated>1021</translated>
         <fuzzy>0</fuzzy>
-        <untranslated>79</untranslated>
+        <untranslated>81</untranslated>
       </strings>
       <translators>
         <translator>
       </strings>
       <translators>
         <translator>
       <file>Turkish.po</file>
       <update>2021-07-25</update>
       <strings>
       <file>Turkish.po</file>
       <update>2021-07-25</update>
       <strings>
-        <count>1100</count>
+        <count>1102</count>
         <translated>1089</translated>
         <fuzzy>0</fuzzy>
         <translated>1089</translated>
         <fuzzy>0</fuzzy>
-        <untranslated>11</untranslated>
+        <untranslated>13</untranslated>
       </strings>
       <translators>
         <translator>
       </strings>
       <translators>
         <translator>
       <file>Ukrainian.po</file>
       <update>2009-06-13</update>
       <strings>
       <file>Ukrainian.po</file>
       <update>2009-06-13</update>
       <strings>
-        <count>1100</count>
+        <count>1102</count>
         <translated>639</translated>
         <fuzzy>0</fuzzy>
         <translated>639</translated>
         <fuzzy>0</fuzzy>
-        <untranslated>461</untranslated>
+        <untranslated>463</untranslated>
       </strings>
       <translators>
         <translator>
       </strings>
       <translators>
         <translator>
index e0518fe..e60f627 100644 (file)
@@ -1839,6 +1839,12 @@ msgstr "تسجيل امتداد الطرفية للمست&خدم الحالي ف
 msgid "Unregister shell extension for current user on&ly"
 msgstr "عدم تسجيل امتداد الطرفية للمستخدم الحالي &فقط"
 
 msgid "Unregister shell extension for current user on&ly"
 msgstr "عدم تسجيل امتداد الطرفية للمستخدم الحالي &فقط"
 
+msgid "Register shell extension for &Windows 11 or later"
+msgstr ""
+
+msgid "Unregister shell extension for W&indows 11 or later"
+msgstr ""
+
 msgctxt "Options dialog|Categories"
 msgid "Folder"
 msgstr "المجلد"
 msgctxt "Options dialog|Categories"
 msgid "Folder"
 msgstr "المجلد"
index 2bb7aac..e39f8ad 100644 (file)
@@ -2307,6 +2307,12 @@ msgstr ""
 msgid "Unregister shell extension for current user on&ly"
 msgstr ""
 
 msgid "Unregister shell extension for current user on&ly"
 msgstr ""
 
+msgid "Register shell extension for &Windows 11 or later"
+msgstr ""
+
+msgid "Unregister shell extension for W&indows 11 or later"
+msgstr ""
+
 msgctxt "Options dialog|Categories"
 msgid "Folder"
 msgstr "Agiritegia"
 msgctxt "Options dialog|Categories"
 msgid "Folder"
 msgstr "Agiritegia"
index 9d4ee93..24cbcdf 100644 (file)
@@ -1854,6 +1854,12 @@ msgstr "Registrar a extensão do shell só pro usual &atual"
 msgid "Unregister shell extension for current user on&ly"
 msgstr "Remover a registro da extensão do shell só pra usual atu&al"
 
 msgid "Unregister shell extension for current user on&ly"
 msgstr "Remover a registro da extensão do shell só pra usual atu&al"
 
+msgid "Register shell extension for &Windows 11 or later"
+msgstr ""
+
+msgid "Unregister shell extension for W&indows 11 or later"
+msgstr ""
+
 msgctxt "Options dialog|Categories"
 msgid "Folder"
 msgstr "Pasta"
 msgctxt "Options dialog|Categories"
 msgid "Folder"
 msgstr "Pasta"
index 88b26ba..7825fe5 100644 (file)
@@ -1841,6 +1841,12 @@ msgstr "Р&егистриране на разширение на обвивка
 msgid "Unregister shell extension for current user on&ly"
 msgstr "Пр&емахване на разширение на обвивката (текущ потребител)"
 
 msgid "Unregister shell extension for current user on&ly"
 msgstr "Пр&емахване на разширение на обвивката (текущ потребител)"
 
+msgid "Register shell extension for &Windows 11 or later"
+msgstr ""
+
+msgid "Unregister shell extension for W&indows 11 or later"
+msgstr ""
+
 msgctxt "Options dialog|Categories"
 msgid "Folder"
 msgstr "Папки"
 msgctxt "Options dialog|Categories"
 msgid "Folder"
 msgstr "Папки"
index 0f8db24..1352b29 100644 (file)
@@ -2303,6 +2303,12 @@ msgstr ""
 msgid "Unregister shell extension for current user on&ly"
 msgstr ""
 
 msgid "Unregister shell extension for current user on&ly"
 msgstr ""
 
+msgid "Register shell extension for &Windows 11 or later"
+msgstr ""
+
+msgid "Unregister shell extension for W&indows 11 or later"
+msgstr ""
+
 msgctxt "Options dialog|Categories"
 msgid "Folder"
 msgstr "Directori"
 msgctxt "Options dialog|Categories"
 msgid "Folder"
 msgstr "Directori"
index 5a2d788..609896f 100644 (file)
@@ -1844,6 +1844,12 @@ msgstr "为当前用户注册 shell 扩展(&O)"
 msgid "Unregister shell extension for current user on&ly"
 msgstr "为当前用户反注册 shell 扩展(&L)"
 
 msgid "Unregister shell extension for current user on&ly"
 msgstr "为当前用户反注册 shell 扩展(&L)"
 
+msgid "Register shell extension for &Windows 11 or later"
+msgstr ""
+
+msgid "Unregister shell extension for W&indows 11 or later"
+msgstr ""
+
 msgctxt "Options dialog|Categories"
 msgid "Folder"
 msgstr "文件夹"
 msgctxt "Options dialog|Categories"
 msgid "Folder"
 msgstr "文件夹"
index 863acc5..4dc839b 100644 (file)
@@ -2317,6 +2317,12 @@ msgstr ""
 msgid "Unregister shell extension for current user on&ly"
 msgstr ""
 
 msgid "Unregister shell extension for current user on&ly"
 msgstr ""
 
+msgid "Register shell extension for &Windows 11 or later"
+msgstr ""
+
+msgid "Unregister shell extension for W&indows 11 or later"
+msgstr ""
+
 msgctxt "Options dialog|Categories"
 msgid "Folder"
 msgstr "資料夾"
 msgctxt "Options dialog|Categories"
 msgid "Folder"
 msgstr "資料夾"
index 8ae9599..00bd312 100644 (file)
@@ -2306,6 +2306,12 @@ msgstr ""
 msgid "Unregister shell extension for current user on&ly"
 msgstr ""
 
 msgid "Unregister shell extension for current user on&ly"
 msgstr ""
 
+msgid "Register shell extension for &Windows 11 or later"
+msgstr ""
+
+msgid "Unregister shell extension for W&indows 11 or later"
+msgstr ""
+
 msgctxt "Options dialog|Categories"
 msgid "Folder"
 msgstr "Mapa"
 msgctxt "Options dialog|Categories"
 msgid "Folder"
 msgstr "Mapa"
index b2e5126..8c0fa18 100644 (file)
@@ -2306,6 +2306,12 @@ msgstr ""
 msgid "Unregister shell extension for current user on&ly"
 msgstr ""
 
 msgid "Unregister shell extension for current user on&ly"
 msgstr ""
 
+msgid "Register shell extension for &Windows 11 or later"
+msgstr ""
+
+msgid "Unregister shell extension for W&indows 11 or later"
+msgstr ""
+
 msgctxt "Options dialog|Categories"
 msgid "Folder"
 msgstr "Složky"
 msgctxt "Options dialog|Categories"
 msgid "Folder"
 msgstr "Složky"
index c695e41..0f267f9 100644 (file)
@@ -2311,6 +2311,12 @@ msgstr ""
 msgid "Unregister shell extension for current user on&ly"
 msgstr ""
 
 msgid "Unregister shell extension for current user on&ly"
 msgstr ""
 
+msgid "Register shell extension for &Windows 11 or later"
+msgstr ""
+
+msgid "Unregister shell extension for W&indows 11 or later"
+msgstr ""
+
 msgctxt "Options dialog|Categories"
 msgid "Folder"
 msgstr "Mappe"
 msgctxt "Options dialog|Categories"
 msgid "Folder"
 msgstr "Mappe"
index 4e6fa37..222c4f4 100644 (file)
@@ -1851,6 +1851,12 @@ msgstr "Shell-extensie alleen voor huidige gebruiker registreren"
 msgid "Unregister shell extension for current user on&ly"
 msgstr "Shell-extensie alleen voor huidige gebruiker de-registreren"
 
 msgid "Unregister shell extension for current user on&ly"
 msgstr "Shell-extensie alleen voor huidige gebruiker de-registreren"
 
+msgid "Register shell extension for &Windows 11 or later"
+msgstr ""
+
+msgid "Unregister shell extension for W&indows 11 or later"
+msgstr ""
+
 msgctxt "Options dialog|Categories"
 msgid "Folder"
 msgstr "Map"
 msgctxt "Options dialog|Categories"
 msgid "Folder"
 msgstr "Map"
index 19556df..c59853e 100644 (file)
@@ -5,7 +5,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: WinMerge\n"
 "Report-Msgid-Bugs-To: https://bugs.winmerge.org/\n"
 msgstr ""
 "Project-Id-Version: WinMerge\n"
 "Report-Msgid-Bugs-To: https://bugs.winmerge.org/\n"
-"POT-Creation-Date: 2021-08-29 20:11+0000\n"
+"POT-Creation-Date: 2021-09-12 22:35+0000\n"
 "PO-Revision-Date: \n"
 "Last-Translator: \n"
 "Language-Team: English <winmerge-translate@lists.sourceforge.net>\n"
 "PO-Revision-Date: \n"
 "Last-Translator: \n"
 "Language-Team: English <winmerge-translate@lists.sourceforge.net>\n"
@@ -1824,6 +1824,12 @@ msgstr ""
 msgid "Unregister shell extension for current user on&ly"
 msgstr ""
 
 msgid "Unregister shell extension for current user on&ly"
 msgstr ""
 
+msgid "Register shell extension for &Windows 11 or later"
+msgstr ""
+
+msgid "Unregister shell extension for W&indows 11 or later"
+msgstr ""
+
 msgctxt "Options dialog|Categories"
 msgid "Folder"
 msgstr ""
 msgctxt "Options dialog|Categories"
 msgid "Folder"
 msgstr ""
index 812c311..3a5b735 100644 (file)
@@ -2310,6 +2310,12 @@ msgstr "Rekisteröi liittymälaajennus &vain nykyiselle käyttäjälle"
 msgid "Unregister shell extension for current user on&ly"
 msgstr "Poista &liittymälaajennuksen rekisteröinti vain nykyiseltä käyttäjältä"
 
 msgid "Unregister shell extension for current user on&ly"
 msgstr "Poista &liittymälaajennuksen rekisteröinti vain nykyiseltä käyttäjältä"
 
+msgid "Register shell extension for &Windows 11 or later"
+msgstr ""
+
+msgid "Unregister shell extension for W&indows 11 or later"
+msgstr ""
+
 msgctxt "Options dialog|Categories"
 msgid "Folder"
 msgstr "Kansio"
 msgctxt "Options dialog|Categories"
 msgid "Folder"
 msgstr "Kansio"
index 103fffb..cf72e1a 100644 (file)
@@ -2319,6 +2319,12 @@ msgstr "Enregistrer l'extension du menu de l'explorateur pour l'utilisateur en c
 msgid "Unregister shell extension for current user on&ly"
 msgstr "Désinscrire l'extension du menu de l'explorateur pour &l'utilisateur en cours"
 
 msgid "Unregister shell extension for current user on&ly"
 msgstr "Désinscrire l'extension du menu de l'explorateur pour &l'utilisateur en cours"
 
+msgid "Register shell extension for &Windows 11 or later"
+msgstr ""
+
+msgid "Unregister shell extension for W&indows 11 or later"
+msgstr ""
+
 msgctxt "Options dialog|Categories"
 msgid "Folder"
 msgstr "Dossier"
 msgctxt "Options dialog|Categories"
 msgid "Folder"
 msgstr "Dossier"
index 17b126d..6429b71 100644 (file)
@@ -2313,6 +2313,12 @@ msgstr "Rexistrar a integración de shell só para o &usuario actual"
 msgid "Unregister shell extension for current user on&ly"
 msgstr "Desrexistrar a integración de shell só para o &usuario actual"
 
 msgid "Unregister shell extension for current user on&ly"
 msgstr "Desrexistrar a integración de shell só para o &usuario actual"
 
+msgid "Register shell extension for &Windows 11 or later"
+msgstr ""
+
+msgid "Unregister shell extension for W&indows 11 or later"
+msgstr ""
+
 msgctxt "Options dialog|Categories"
 msgid "Folder"
 msgstr "Cartafol"
 msgctxt "Options dialog|Categories"
 msgid "Folder"
 msgstr "Cartafol"
index 203165c..85145a0 100644 (file)
@@ -2304,6 +2304,12 @@ msgstr "Shell-Erweiterung nur für aktuellen Nutzer registrieren"
 msgid "Unregister shell extension for current user on&ly"
 msgstr "Shell-Erweiterung nur für aktuellen Nutzer nicht registrieren"
 
 msgid "Unregister shell extension for current user on&ly"
 msgstr "Shell-Erweiterung nur für aktuellen Nutzer nicht registrieren"
 
+msgid "Register shell extension for &Windows 11 or later"
+msgstr ""
+
+msgid "Unregister shell extension for W&indows 11 or later"
+msgstr ""
+
 msgctxt "Options dialog|Categories"
 msgid "Folder"
 msgstr "Ordner"
 msgctxt "Options dialog|Categories"
 msgid "Folder"
 msgstr "Ordner"
index 3a7b844..8ff7756 100644 (file)
@@ -2303,6 +2303,12 @@ msgstr ""
 msgid "Unregister shell extension for current user on&ly"
 msgstr ""
 
 msgid "Unregister shell extension for current user on&ly"
 msgstr ""
 
+msgid "Register shell extension for &Windows 11 or later"
+msgstr ""
+
+msgid "Unregister shell extension for W&indows 11 or later"
+msgstr ""
+
 msgctxt "Options dialog|Categories"
 msgid "Folder"
 msgstr "Φάκελος"
 msgctxt "Options dialog|Categories"
 msgid "Folder"
 msgstr "Φάκελος"
index 7f76f4a..3d9c837 100644 (file)
@@ -2314,6 +2314,12 @@ msgstr "Regisztrálás a helyi menübe (csak ez a felhasználó)"
 msgid "Unregister shell extension for current user on&ly"
 msgstr "Eltávolítás a helyi menüből (csak ez a felhasználó)"
 
 msgid "Unregister shell extension for current user on&ly"
 msgstr "Eltávolítás a helyi menüből (csak ez a felhasználó)"
 
+msgid "Register shell extension for &Windows 11 or later"
+msgstr ""
+
+msgid "Unregister shell extension for W&indows 11 or later"
+msgstr ""
+
 msgctxt "Options dialog|Categories"
 msgid "Folder"
 msgstr "Könyvtár"
 msgctxt "Options dialog|Categories"
 msgid "Folder"
 msgstr "Könyvtár"
index 2bf2212..c98a6db 100644 (file)
@@ -1838,6 +1838,12 @@ msgstr "Registra estensione shell solo per l'&utente attuale"
 msgid "Unregister shell extension for current user on&ly"
 msgstr "De-registra estensione shell solo per &l'utente attuale"
 
 msgid "Unregister shell extension for current user on&ly"
 msgstr "De-registra estensione shell solo per &l'utente attuale"
 
+msgid "Register shell extension for &Windows 11 or later"
+msgstr ""
+
+msgid "Unregister shell extension for W&indows 11 or later"
+msgstr ""
+
 msgctxt "Options dialog|Categories"
 msgid "Folder"
 msgstr "Cartella"
 msgctxt "Options dialog|Categories"
 msgid "Folder"
 msgstr "Cartella"
index f2c09e4..5ed995d 100644 (file)
@@ -1843,6 +1843,12 @@ msgstr "現在のユーザーのみシェル拡張を登録(&O)"
 msgid "Unregister shell extension for current user on&ly"
 msgstr "現在のユーザーのみシェル拡張の登録を解除(&L)"
 
 msgid "Unregister shell extension for current user on&ly"
 msgstr "現在のユーザーのみシェル拡張の登録を解除(&L)"
 
+msgid "Register shell extension for &Windows 11 or later"
+msgstr "Windows 11 以降用シェル拡張を登録(&W)"
+
+msgid "Unregister shell extension for W&indows 11 or later"
+msgstr "Windows 11 以降用シェル拡張の登録を解除(&I)"
+
 msgctxt "Options dialog|Categories"
 msgid "Folder"
 msgstr "フォルダー"
 msgctxt "Options dialog|Categories"
 msgid "Folder"
 msgstr "フォルダー"
index c89539b..a88aec7 100644 (file)
@@ -2318,6 +2318,12 @@ msgstr "현재 사용자만 쉘 확장자 등록(&O)"
 msgid "Unregister shell extension for current user on&ly"
 msgstr "현재 사용자만 쉘 확장자 등록 해제(&L)"
 
 msgid "Unregister shell extension for current user on&ly"
 msgstr "현재 사용자만 쉘 확장자 등록 해제(&L)"
 
+msgid "Register shell extension for &Windows 11 or later"
+msgstr ""
+
+msgid "Unregister shell extension for W&indows 11 or later"
+msgstr ""
+
 msgctxt "Options dialog|Categories"
 msgid "Folder"
 msgstr "폴더"
 msgctxt "Options dialog|Categories"
 msgid "Folder"
 msgstr "폴더"
index 342a78f..def7d8e 100644 (file)
@@ -1833,6 +1833,12 @@ msgstr "Registruoti aplinkos plėtinį tik šiam naud&otojui"
 msgid "Unregister shell extension for current user on&ly"
 msgstr "Išregistruoti aplinkos p&lėtinį tik šiam naudotojui"
 
 msgid "Unregister shell extension for current user on&ly"
 msgstr "Išregistruoti aplinkos p&lėtinį tik šiam naudotojui"
 
+msgid "Register shell extension for &Windows 11 or later"
+msgstr ""
+
+msgid "Unregister shell extension for W&indows 11 or later"
+msgstr ""
+
 msgctxt "Options dialog|Categories"
 msgid "Folder"
 msgstr "Katalogų"
 msgctxt "Options dialog|Categories"
 msgid "Folder"
 msgstr "Katalogų"
index fcfdce1..78a1d41 100644 (file)
@@ -2306,6 +2306,12 @@ msgstr ""
 msgid "Unregister shell extension for current user on&ly"
 msgstr ""
 
 msgid "Unregister shell extension for current user on&ly"
 msgstr ""
 
+msgid "Register shell extension for &Windows 11 or later"
+msgstr ""
+
+msgid "Unregister shell extension for W&indows 11 or later"
+msgstr ""
+
 msgctxt "Options dialog|Categories"
 msgid "Folder"
 msgstr "Mappe"
 msgctxt "Options dialog|Categories"
 msgid "Folder"
 msgstr "Mappe"
index d062ae3..73ecf96 100644 (file)
@@ -2313,6 +2313,12 @@ msgstr ""
 msgid "Unregister shell extension for current user on&ly"
 msgstr ""
 
 msgid "Unregister shell extension for current user on&ly"
 msgstr ""
 
+msgid "Register shell extension for &Windows 11 or later"
+msgstr ""
+
+msgid "Unregister shell extension for W&indows 11 or later"
+msgstr ""
+
 msgctxt "Options dialog|Categories"
 msgid "Folder"
 msgstr " پوشه "
 msgctxt "Options dialog|Categories"
 msgid "Folder"
 msgstr " پوشه "
index cfda0d9..e3044da 100644 (file)
@@ -1830,6 +1830,12 @@ msgstr "Zarejestruj rozszerzenie powłoki dla bieżącego użytkownika"
 msgid "Unregister shell extension for current user on&ly"
 msgstr "Wyrejestruj rozszerzenie powłoki z bieżącego użytkownika"
 
 msgid "Unregister shell extension for current user on&ly"
 msgstr "Wyrejestruj rozszerzenie powłoki z bieżącego użytkownika"
 
+msgid "Register shell extension for &Windows 11 or later"
+msgstr ""
+
+msgid "Unregister shell extension for W&indows 11 or later"
+msgstr ""
+
 msgctxt "Options dialog|Categories"
 msgid "Folder"
 msgstr "Folder"
 msgctxt "Options dialog|Categories"
 msgid "Folder"
 msgstr "Folder"
index 12c9e65..f9f8585 100644 (file)
@@ -1854,6 +1854,12 @@ msgstr "Extensão da shell de registo para o utilizador atual &apenas"
 msgid "Unregister shell extension for current user on&ly"
 msgstr "Anular o registo da extensão da shell para o utilizador actual ap&enas"
 
 msgid "Unregister shell extension for current user on&ly"
 msgstr "Anular o registo da extensão da shell para o utilizador actual ap&enas"
 
+msgid "Register shell extension for &Windows 11 or later"
+msgstr ""
+
+msgid "Unregister shell extension for W&indows 11 or later"
+msgstr ""
+
 msgctxt "Options dialog|Categories"
 msgid "Folder"
 msgstr "Pasta"
 msgctxt "Options dialog|Categories"
 msgid "Folder"
 msgstr "Pasta"
index 2e4e248..d58ecbc 100644 (file)
@@ -2304,6 +2304,12 @@ msgstr ""
 msgid "Unregister shell extension for current user on&ly"
 msgstr ""
 
 msgid "Unregister shell extension for current user on&ly"
 msgstr ""
 
+msgid "Register shell extension for &Windows 11 or later"
+msgstr ""
+
+msgid "Unregister shell extension for W&indows 11 or later"
+msgstr ""
+
 msgctxt "Options dialog|Categories"
 msgid "Folder"
 msgstr "Director"
 msgctxt "Options dialog|Categories"
 msgid "Folder"
 msgstr "Director"
index cf900ca..39a9fe9 100644 (file)
@@ -1832,6 +1832,12 @@ msgstr "Зарегистрировать shell для текущего поль
 msgid "Unregister shell extension for current user on&ly"
 msgstr "Удалить shell для текущего пользователя"
 
 msgid "Unregister shell extension for current user on&ly"
 msgstr "Удалить shell для текущего пользователя"
 
+msgid "Register shell extension for &Windows 11 or later"
+msgstr ""
+
+msgid "Unregister shell extension for W&indows 11 or later"
+msgstr ""
+
 msgctxt "Options dialog|Categories"
 msgid "Folder"
 msgstr "Папка"
 msgctxt "Options dialog|Categories"
 msgid "Folder"
 msgstr "Папка"
index 8ce9641..ae661e4 100644 (file)
@@ -2289,6 +2289,12 @@ msgstr ""
 msgid "Unregister shell extension for current user on&ly"
 msgstr ""
 
 msgid "Unregister shell extension for current user on&ly"
 msgstr ""
 
+msgid "Register shell extension for &Windows 11 or later"
+msgstr ""
+
+msgid "Unregister shell extension for W&indows 11 or later"
+msgstr ""
+
 msgctxt "Options dialog|Categories"
 msgid "Folder"
 msgstr "Фасцикла"
 msgctxt "Options dialog|Categories"
 msgid "Folder"
 msgstr "Фасцикла"
index 78cded6..807b3c4 100644 (file)
@@ -2301,6 +2301,12 @@ msgstr ""
 msgid "Unregister shell extension for current user on&ly"
 msgstr ""
 
 msgid "Unregister shell extension for current user on&ly"
 msgstr ""
 
+msgid "Register shell extension for &Windows 11 or later"
+msgstr ""
+
+msgid "Unregister shell extension for W&indows 11 or later"
+msgstr ""
+
 msgctxt "Options dialog|Categories"
 msgid "Folder"
 msgstr "ෆෝල්ඩර"
 msgctxt "Options dialog|Categories"
 msgid "Folder"
 msgstr "ෆෝල්ඩර"
index 5d9bedf..3790a5c 100644 (file)
@@ -1843,6 +1843,12 @@ msgstr "Zaregistruje rozšírenie prostredia iba pre aktuálneho používateľa"
 msgid "Unregister shell extension for current user on&ly"
 msgstr "Zruší registráciu rozšírenia prostredia pre súčasného používateľa"
 
 msgid "Unregister shell extension for current user on&ly"
 msgstr "Zruší registráciu rozšírenia prostredia pre súčasného používateľa"
 
+msgid "Register shell extension for &Windows 11 or later"
+msgstr ""
+
+msgid "Unregister shell extension for W&indows 11 or later"
+msgstr ""
+
 msgctxt "Options dialog|Categories"
 msgid "Folder"
 msgstr "Priečinok"
 msgctxt "Options dialog|Categories"
 msgid "Folder"
 msgstr "Priečinok"
index 339ee29..c8281f5 100644 (file)
@@ -2308,6 +2308,12 @@ msgstr "Registriraj končnico lupine le za &trenutnega uporabnika"
 msgid "Unregister shell extension for current user on&ly"
 msgstr "Odstrani registracijo končnice lupine &le za trenut. uporabnika"
 
 msgid "Unregister shell extension for current user on&ly"
 msgstr "Odstrani registracijo končnice lupine &le za trenut. uporabnika"
 
+msgid "Register shell extension for &Windows 11 or later"
+msgstr ""
+
+msgid "Unregister shell extension for W&indows 11 or later"
+msgstr ""
+
 msgctxt "Options dialog|Categories"
 msgid "Folder"
 msgstr "Mapa"
 msgctxt "Options dialog|Categories"
 msgid "Folder"
 msgstr "Mapa"
index 30e90b4..48c917d 100644 (file)
@@ -1842,6 +1842,12 @@ msgstr "Registrar extensión de Shell sólo para usuari&o actual"
 msgid "Unregister shell extension for current user on&ly"
 msgstr "Quitar extensión de Shell só&lo para usuario actual"
 
 msgid "Unregister shell extension for current user on&ly"
 msgstr "Quitar extensión de Shell só&lo para usuario actual"
 
+msgid "Register shell extension for &Windows 11 or later"
+msgstr ""
+
+msgid "Unregister shell extension for W&indows 11 or later"
+msgstr ""
+
 msgctxt "Options dialog|Categories"
 msgid "Folder"
 msgstr "Carpeta"
 msgctxt "Options dialog|Categories"
 msgid "Folder"
 msgstr "Carpeta"
index 90c8212..5642691 100644 (file)
@@ -2314,6 +2314,12 @@ msgstr "Registrera GränssnittsIntegration för endast nuvarande användare"
 msgid "Unregister shell extension for current user on&ly"
 msgstr "Avregistrera GränssnittsIntegration för endast nuvarande användare"
 
 msgid "Unregister shell extension for current user on&ly"
 msgstr "Avregistrera GränssnittsIntegration för endast nuvarande användare"
 
+msgid "Register shell extension for &Windows 11 or later"
+msgstr ""
+
+msgid "Unregister shell extension for W&indows 11 or later"
+msgstr ""
+
 msgctxt "Options dialog|Categories"
 msgid "Folder"
 msgstr "Mapp"
 msgctxt "Options dialog|Categories"
 msgid "Folder"
 msgstr "Mapp"
index 5d32898..b5f74d8 100644 (file)
@@ -1846,6 +1846,12 @@ msgstr "&Yalnız geçerli kullanıcı için kabuk eklentisi kaydını ekle"
 msgid "Unregister shell extension for current user on&ly"
 msgstr "Yalnız geçerli kullanıcı için kabuk ek&lentisi kaydını sil"
 
 msgid "Unregister shell extension for current user on&ly"
 msgstr "Yalnız geçerli kullanıcı için kabuk ek&lentisi kaydını sil"
 
+msgid "Register shell extension for &Windows 11 or later"
+msgstr ""
+
+msgid "Unregister shell extension for W&indows 11 or later"
+msgstr ""
+
 msgctxt "Options dialog|Categories"
 msgid "Folder"
 msgstr "Klasör"
 msgctxt "Options dialog|Categories"
 msgid "Folder"
 msgstr "Klasör"
index 4e95551..ff81431 100644 (file)
@@ -2307,6 +2307,12 @@ msgstr ""
 msgid "Unregister shell extension for current user on&ly"
 msgstr ""
 
 msgid "Unregister shell extension for current user on&ly"
 msgstr ""
 
+msgid "Register shell extension for &Windows 11 or later"
+msgstr ""
+
+msgid "Unregister shell extension for W&indows 11 or later"
+msgstr ""
+
 msgctxt "Options dialog|Categories"
 msgid "Folder"
 msgstr "Тека"
 msgctxt "Options dialog|Categories"
 msgid "Folder"
 msgstr "Тека"