Compare commits

..

1 Commits

Author SHA1 Message Date
Kai Tao
d030088bb9 Update build-installer.ps1 2025-07-23 16:44:27 +08:00
152 changed files with 417 additions and 3933 deletions

View File

@@ -282,9 +282,3 @@ xef
xes
PACKAGEVERSIONNUMBER
APPXMANIFESTVERSION
# MRU lists
CACHEWRITE
MRUCMPPROC
MRUINFO
REGSTR

View File

@@ -38,7 +38,6 @@ ALLAPPS
ALLCHILDREN
ALLINPUT
Allman
Allmodule
ALLOWUNDO
ALLVIEW
ALPHATYPE
@@ -247,7 +246,6 @@ CONTEXTMENUHANDLER
contractversion
CONTROLPARENT
copiedcolorrepresentation
coppied
copyable
COPYPEN
COREWINDOW
@@ -446,7 +444,6 @@ ERRORIMAGE
ERRORTITLE
ESettings
esrp
etd
ETDT
etl
etw
@@ -531,8 +528,8 @@ frm
FROMTOUCH
fsanitize
fsmgmt
fuzzingtesting
fxf
fuzzingtesting
FZE
gacutil
Gaeilge
@@ -737,7 +734,6 @@ INSTALLSTARTMENUSHORTCUT
INSTALLSTATE
Inste
Interlop
intput
INTRESOURCE
INVALIDARG
invalidoperatioexception
@@ -820,7 +816,6 @@ LMEM
LMENU
LOADFROMFILE
LOBYTE
localappdata
localpackage
LOCALSYSTEM
LOCATIONCHANGE
@@ -1123,7 +1118,6 @@ oldtheme
oleaut
OLECHAR
onebranch
OOBEUI
openas
opencode
OPENFILENAME
@@ -1389,8 +1383,8 @@ RIDEV
RIGHTSCROLLBAR
riid
RKey
Rns
RNumber
Rns
rop
ROUNDSMALL
ROWSETEXT
@@ -1401,7 +1395,6 @@ Rsp
rstringalnum
rstringalpha
rstringdigit
rtb
RTB
RTLREADING
rtm
@@ -1536,7 +1529,6 @@ SLGP
sln
SMALLICON
smartphone
smileys
SMTO
SNAPPROCESS
snk
@@ -1764,8 +1756,8 @@ Uptool
urld
Usb
USEDEFAULT
USEFILEATTRIBUTES
USEINSTALLERFORTEST
USEFILEATTRIBUTES
USESHOWWINDOW
USESTDHANDLES
USRDLL

View File

@@ -4,7 +4,7 @@
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
- [ ] Closes: #xxx
- [ ] **Closes:** #xxx
- [ ] **Communication:** I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected
- [ ] **Tests:** Added/updated and all pass
- [ ] **Localization:** All end-user-facing strings can be localized

View File

@@ -70,7 +70,6 @@
<PackageVersion Include="NLog.Schema" Version="5.2.8" />
<PackageVersion Include="OpenAI" Version="2.0.0" />
<PackageVersion Include="ReverseMarkdown" Version="4.1.0" />
<PackageVersion Include="RtfPipe" Version="2.0.7677.4303" />
<PackageVersion Include="ScipBe.Common.Office.OneNote" Version="3.0.1" />
<PackageVersion Include="SharpCompress" Version="0.37.2" />
<!-- Don't update SkiaSharp.Views.WinUI to version 3.* branch as this brakes the HexBox control in Registry Preview. -->

View File

@@ -39,14 +39,14 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "fancyzones", "fancyzones",
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FancyZonesLib", "src\modules\fancyzones\FancyZonesLib\FancyZonesLib.vcxproj", "{F9C68EDF-AC74-4B77-9AF1-005D9C9F6A99}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FancyZones.UnitTests", "src\modules\fancyzones\FancyZonesTests\UnitTests\UnitTests.vcxproj", "{9C6A7905-72D4-4BF5-B256-ABFDAEF68AE9}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UnitTests-FancyZones", "src\modules\fancyzones\FancyZonesTests\UnitTests\UnitTests.vcxproj", "{9C6A7905-72D4-4BF5-B256-ABFDAEF68AE9}"
ProjectSection(ProjectDependencies) = postProject
{F9C68EDF-AC74-4B77-9AF1-005D9C9F6A99} = {F9C68EDF-AC74-4B77-9AF1-005D9C9F6A99}
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "common", "common", "{1AFB6476-670D-4E80-A464-657E01DFF482}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Common.Lib.UnitTests", "src\common\UnitTests-CommonLib\UnitTests-CommonLib.vcxproj", "{1A066C63-64B3-45F8-92FE-664E1CCE8077}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UnitTests-CommonLib", "src\common\UnitTests-CommonLib\UnitTests-CommonLib.vcxproj", "{1A066C63-64B3-45F8-92FE-664E1CCE8077}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FancyZonesEditor", "src\modules\fancyzones\editor\FancyZonesEditor\FancyZonesEditor.csproj", "{5CCC8468-DEC8-4D36-99D4-5C891BEBD481}"
EndProject
@@ -61,7 +61,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PowerRenameLib", "src\modul
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PowerRenameTest", "src\modules\powerrename\testapp\PowerRenameTest.vcxproj", "{A3935CF4-46C5-4A88-84D3-6B12E16E6BA2}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PowerRename.UnitTests", "src\modules\powerrename\unittests\PowerRenameLibUnitTests.vcxproj", "{2151F984-E006-4A9F-92EF-C6DDE3DC8413}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PowerRenameUnitTests", "src\modules\powerrename\unittests\PowerRenameLibUnitTests.vcxproj", "{2151F984-E006-4A9F-92EF-C6DDE3DC8413}"
ProjectSection(ProjectDependencies) = postProject
{51920F1F-C28C-4ADF-8660-4238766796C2} = {51920F1F-C28C-4ADF-8660-4238766796C2}
{B25AC7A5-FB9F-4789-B392-D5C85E948670} = {B25AC7A5-FB9F-4789-B392-D5C85E948670}
@@ -77,7 +77,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ImageResizerUI", "src\modul
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ImageResizerExt", "src\modules\imageresizer\dll\ImageResizerExt.vcxproj", "{0B43679E-EDFA-4DA0-AD30-F4628B308B1B}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ImageResizer.UnitTests", "src\modules\imageresizer\tests\ImageResizer.UnitTests.csproj", "{E0CC7526-D85E-43AC-844F-D5DF0D2F5AB8}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ImageResizerUITest", "src\modules\imageresizer\tests\ImageResizerUITest.csproj", "{E0CC7526-D85E-43AC-844F-D5DF0D2F5AB8}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PowerToys.ActionRunner", "src\ActionRunner\ActionRunner.vcxproj", "{D29DDD63-E2CF-4657-9FD5-2AEDE4257E5D}"
ProjectSection(ProjectDependencies) = postProject
@@ -149,13 +149,13 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PreviewHandlerCommon", "src
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MarkdownPreviewHandler", "src\modules\previewpane\MarkdownPreviewHandler\MarkdownPreviewHandler.csproj", "{6A71162E-FC4C-4A2C-B90F-3CF94F59A9BB}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Preview.MarkdownPreviewHandler.UnitTests", "src\modules\previewpane\UnitTests-MarkdownPreviewHandler\Preview.MarkdownPreviewHandler.UnitTests.csproj", "{A2B51B8B-8F90-424E-BC97-F9AB7D76CA1A}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTests-MarkdownPreviewHandler", "src\modules\previewpane\UnitTests-MarkdownPreviewHandler\UnitTests-MarkdownPreviewHandler.csproj", "{A2B51B8B-8F90-424E-BC97-F9AB7D76CA1A}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SvgPreviewHandler", "src\modules\previewpane\SvgPreviewHandler\SvgPreviewHandler.csproj", "{DA425894-6E13-404F-8DCB-78584EC0557A}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Preview.SvgPreviewHandler.UnitTests", "src\modules\previewpane\UnitTests-SvgPreviewHandler\Preview.SvgPreviewHandler.UnitTests.csproj", "{060D75DA-2D1C-48E6-A4A1-6F0718B64661}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTests-SvgPreviewHandler", "src\modules\previewpane\UnitTests-SvgPreviewHandler\UnitTests-SvgPreviewHandler.csproj", "{060D75DA-2D1C-48E6-A4A1-6F0718B64661}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Preview.PreviewHandlerCommon.UnitTests", "src\modules\previewpane\UnitTests-PreviewHandlerCommon\Preview.PreviewHandlerCommon.UnitTests.csproj", "{748417CA-F17E-487F-9411-CAFB6D3F4877}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTests-PreviewHandlerCommon", "src\modules\previewpane\UnitTests-PreviewHandlerCommon\UnitTests-PreviewHandlerCommon.csproj", "{748417CA-F17E-487F-9411-CAFB6D3F4877}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "powerpreview", "src\modules\previewpane\powerpreview\powerpreview.vcxproj", "{217DF501-135C-4E38-BFC8-99D4821032EA}"
ProjectSection(ProjectDependencies) = postProject
@@ -192,7 +192,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ManagedCommon", "src\common
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Plugin.Program.UnitTests", "src\modules\launcher\Plugins\Microsoft.Plugin.Program.UnitTests\Microsoft.Plugin.Program.UnitTests.csproj", "{42851751-CBC8-45A6-97F5-7A0753F7B4D1}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Preview.SvgThumbnailProvider.UnitTests", "src\modules\previewpane\UnitTests-SvgThumbnailProvider\Preview.SvgThumbnailProvider.UnitTests.csproj", "{1EF1EEF0-10F0-4F2E-8550-39B6D8044D3E}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTests-SvgThumbnailProvider", "src\modules\previewpane\UnitTests-SvgThumbnailProvider\UnitTests-SvgThumbnailProvider.csproj", "{1EF1EEF0-10F0-4F2E-8550-39B6D8044D3E}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SvgThumbnailProvider", "src\modules\previewpane\SvgThumbnailProvider\SvgThumbnailProvider.csproj", "{8FFE09DA-FA4F-4EE1-B3A2-AD5497FBD1AD}"
EndProject
@@ -213,6 +213,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Settings.UI.UnitTests", "sr
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.PowerToys.Run.Plugin.Calculator.UnitTest", "src\modules\launcher\Plugins\Microsoft.PowerToys.Run.Plugin.Calculator.UnitTest\Microsoft.PowerToys.Run.Plugin.Calculator.UnitTest.csproj", "{632BBE62-5421-49EA-835A-7FFA4F499BD6}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Plugin.Folder.UnitTests", "src\modules\launcher\Plugins\Microsoft.Plugin.Folder.UnitTests\Microsoft.Plugin.Folder.UnitTests.csproj", "{4FA206A5-F69F-4193-BF8F-F6EEB496734C}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTest-ColorPickerUI", "src\modules\colorPicker\UnitTest-ColorPickerUI\UnitTest-ColorPickerUI.csproj", "{090CD7B7-3B0C-4D1D-BC98-83EB5D799BC1}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "spdlog", "src\logging\logging.vcxproj", "{7E1E3F13-2BD6-3F75-A6A7-873A2B55C60F}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.PowerToys.Run.Plugin.System", "src\modules\launcher\Plugins\Microsoft.PowerToys.Run.Plugin.System\Microsoft.PowerToys.Run.Plugin.System.csproj", "{FD8EB419-FF9C-4D88-BB6F-BF6CED37747B}"
@@ -228,7 +232,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "logger", "src\common\logger
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SettingsAPI", "src\common\SettingsAPI\SettingsAPI.vcxproj", "{6955446D-23F7-4023-9BB3-8657F904AF99}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Common.Interop.UnitTests", "src\common\interop\interop-tests\Common.Interop.UnitTests.csproj", "{58736667-1027-4AD7-BFDF-7A3A6474103A}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Interop.Tests", "src\common\interop\interop-tests\Microsoft.Interop.Tests.csproj", "{58736667-1027-4AD7-BFDF-7A3A6474103A}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "notifications", "notifications", "{D92131D6-7610-4D60-A7DB-1C169783F83B}"
EndProject
@@ -300,7 +304,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Common.UI", "src\common\Com
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PdfPreviewHandler", "src\modules\previewpane\PdfPreviewHandler\PdfPreviewHandler.csproj", "{69E1EE8D-143A-4060-9129-4658ACF14AAF}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Preview.PdfPreviewHandler.UnitTests", "src\modules\previewpane\UnitTests-PdfPreviewHandler\Preview.PdfPreviewHandler.UnitTests.csproj", "{ECC20689-002A-4354-95A6-B58DF089C6FF}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTests-PdfPreviewHandler", "src\modules\previewpane\UnitTests-PdfPreviewHandler\UnitTests-PdfPreviewHandler.csproj", "{ECC20689-002A-4354-95A6-B58DF089C6FF}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.PowerToys.Run.Plugin.Registry", "src\modules\launcher\Plugins\Microsoft.PowerToys.Run.Plugin.Registry\Microsoft.PowerToys.Run.Plugin.Registry.csproj", "{4BABF3FE-3451-42FD-873F-3C332E18DCEF}"
EndProject
@@ -310,13 +314,13 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KeyboardManagerEngine", "sr
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KeyboardManagerEngineLibrary", "src\modules\keyboardmanager\KeyboardManagerEngineLibrary\KeyboardManagerEngineLibrary.vcxproj", "{E496B7FC-1E99-4BAB-849B-0E8367040B02}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KeyboardManager.Engine.UnitTests", "src\modules\keyboardmanager\KeyboardManagerEngineTest\KeyboardManagerEngineTest.vcxproj", "{7F4B3A60-BC27-45A7-8000-68B0B6EA7466}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KeyboardManagerEngineTest", "src\modules\keyboardmanager\KeyboardManagerEngineTest\KeyboardManagerEngineTest.vcxproj", "{7F4B3A60-BC27-45A7-8000-68B0B6EA7466}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KeyboardManagerEditor", "src\modules\keyboardmanager\KeyboardManagerEditor\KeyboardManagerEditor.vcxproj", "{8DF78B53-200E-451F-9328-01EB907193AE}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KeyboardManagerEditorLibrary", "src\modules\keyboardmanager\KeyboardManagerEditorLibrary\KeyboardManagerEditorLibrary.vcxproj", "{23D2070D-E4AD-4ADD-85A7-083D9C76AD49}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KeyboardManager.Editor.UnitTests", "src\modules\keyboardmanager\KeyboardManagerEditorTest\KeyboardManagerEditorTest.vcxproj", "{62173D9A-6724-4C00-A1C8-FB646480A9EC}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KeyboardManagerEditorTest", "src\modules\keyboardmanager\KeyboardManagerEditorTest\KeyboardManagerEditorTest.vcxproj", "{62173D9A-6724-4C00-A1C8-FB646480A9EC}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "awake", "awake", "{127F38E0-40AA-4594-B955-5616BF206882}"
EndProject
@@ -344,7 +348,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.PowerToys.Run.Plu
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PdfThumbnailProvider", "src\modules\previewpane\PdfThumbnailProvider\PdfThumbnailProvider.csproj", "{11491FD8-F921-48BF-880C-7FEA185B80A1}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Preview.PdfThumbnailProvider.UnitTests", "src\modules\previewpane\UnitTests-PdfThumbnailProvider\Preview.PdfThumbnailProvider.UnitTests.csproj", "{F40C3397-1834-4530-B2D9-8F8B8456BCDF}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTests-PdfThumbnailProvider", "src\modules\previewpane\UnitTests-PdfThumbnailProvider\UnitTests-PdfThumbnailProvider.csproj", "{F40C3397-1834-4530-B2D9-8F8B8456BCDF}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.PowerToys.Run.Plugin.WindowsTerminal", "src\modules\launcher\Plugins\Microsoft.PowerToys.Run.Plugin.WindowsTerminal\Microsoft.PowerToys.Run.Plugin.WindowsTerminal.csproj", "{A2D583F0-B70C-4462-B1F0-8E81AFB7BA85}"
EndProject
@@ -358,11 +362,11 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MouseHighlighter", "src\mod
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GcodeThumbnailProvider", "src\modules\previewpane\GcodeThumbnailProvider\GcodeThumbnailProvider.csproj", "{809AA252-E17A-4FA2-B0A1-0450976B763F}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Preview.GcodeThumbnailProvider.UnitTests", "src\modules\previewpane\UnitTests-GcodeThumbnailProvider\Preview.GcodeThumbnailProvider.UnitTests.csproj", "{133281D8-1BCE-4D07-B31E-796612A9609E}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTests-GcodeThumbnailProvider", "src\modules\previewpane\UnitTests-GcodeThumbnailProvider\UnitTests-GcodeThumbnailProvider.csproj", "{133281D8-1BCE-4D07-B31E-796612A9609E}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GcodePreviewHandler", "src\modules\previewpane\GcodePreviewHandler\GcodePreviewHandler.csproj", "{805306FF-A562-4415-8DEF-E493BDC45918}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Preview.GcodePreviewHandler.UnitTests", "src\modules\previewpane\UnitTests-GcodePreviewHandler\Preview.GcodePreviewHandler.UnitTests.csproj", "{FCF3E52D-B80A-4FC3-98FD-6391354F0EE3}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTests-GcodePreviewHandler", "src\modules\previewpane\UnitTests-GcodePreviewHandler\UnitTests-GcodePreviewHandler.csproj", "{FCF3E52D-B80A-4FC3-98FD-6391354F0EE3}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "AlwaysOnTop", "AlwaysOnTop", "{60CD2D4F-C3B9-4897-9821-FCA5098B41CE}"
EndProject
@@ -376,7 +380,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MousePointerCrosshairs", "s
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "StlThumbnailProvider", "src\modules\previewpane\StlThumbnailProvider\StlThumbnailProvider.csproj", "{F7C8C0F1-5431-4347-89D0-8E5354F93CF2}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Preview.StlThumbnailProvider.UnitTests", "src\modules\previewpane\UnitTests-StlThumbnailProvider\Preview.StlThumbnailProvider.UnitTests.csproj", "{F1F6B6B6-9F18-4A17-8B5C-97DF552C53DC}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTests-StlThumbnailProvider", "src\modules\previewpane\UnitTests-StlThumbnailProvider\UnitTests-StlThumbnailProvider.csproj", "{F1F6B6B6-9F18-4A17-8B5C-97DF552C53DC}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MonacoPreviewHandler", "src\modules\previewpane\MonacoPreviewHandler\MonacoPreviewHandler.csproj", "{04B193D7-3E21-46B8-A958-89B63A8A69DE}"
EndProject
@@ -412,8 +416,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PowerOCR", "src\modules\Pow
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PowerOCRModuleInterface", "src\modules\PowerOCR\PowerOCRModuleInterface\PowerOCRModuleInterface.vcxproj", "{6AB6A2D6-F859-4A82-9184-0BD29C9F07D1}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{B1234567-1234-1234-1234-123456789ABC}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.PowerToys.Run.Plugin.History", "src\modules\launcher\Plugins\Microsoft.PowerToys.Run.Plugin.History\Microsoft.PowerToys.Run.Plugin.History.csproj", "{212AD910-8488-4036-BE20-326931B75FB2}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "MeasureTool", "MeasureTool", "{7AC943C9-52E8-44CF-9083-744D8049667B}"
@@ -435,7 +437,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HostsUILib", "src\modules\H
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Hosts", "Hosts", "{F05E590D-AD46-42BE-9C25-6A63ADD2E3EA}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HostsEditor.UnitTests", "src\modules\Hosts\Hosts.Tests\HostsEditor.UnitTests.csproj", "{E2D03E0F-7A75-4813-9F4B-D8763D43FD3A}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Hosts.Tests", "src\modules\Hosts\Hosts.Tests\Hosts.Tests.csproj", "{E2D03E0F-7A75-4813-9F4B-D8763D43FD3A}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "HostsModuleInterface", "src\modules\Hosts\HostsModuleInterface\HostsModuleInterface.vcxproj", "{B41B888C-7DB8-4747-B262-4062E05A230D}"
EndProject
@@ -525,6 +527,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CropAndLockModuleInterface"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "cmdNotFound", "cmdNotFound", "{4C0D0746-BE5B-49EE-BD5D-A7811628AE8B}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTests-FancyZonesEditor", "src\modules\fancyzones\UnitTests-FancyZonesEditor\UnitTests-FancyZonesEditor.csproj", "{FC8EB78F-F061-4BD9-A3F6-507BEA965E2B}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "EnvironmentVariables", "EnvironmentVariables", "{538ED0BB-B863-4B20-98CC-BCDF7FA0B68A}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EnvironmentVariablesUILib", "src\modules\EnvironmentVariables\EnvironmentVariablesUILib\EnvironmentVariablesUILib.csproj", "{51465DA1-C18B-4B99-93E1-ECF8E0FA0CBA}"
@@ -539,9 +543,9 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "QoiPreviewHandlerCpp", "src
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "QoiPreviewHandler", "src\modules\previewpane\QoiPreviewHandler\QoiPreviewHandler.csproj", "{6B04803D-B418-4833-A67E-B0FC966636A5}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Preview.QoiPreviewHandler.UnitTests", "src\modules\previewpane\UnitTests-QoiPreviewHandler\Preview.QoiPreviewHandler.UnitTests.csproj", "{3940AD4D-F748-4BE4-9083-85769CD553EF}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTests-QoiPreviewHandler", "src\modules\previewpane\UnitTests-QoiPreviewHandler\UnitTests-QoiPreviewHandler.csproj", "{3940AD4D-F748-4BE4-9083-85769CD553EF}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Preview.QoiThumbnailProvider.UnitTests", "src\modules\previewpane\UnitTests-QoiThumbnailProvider\Preview.QoiThumbnailProvider.UnitTests.csproj", "{F8FFFC12-A31A-4AFA-B3DF-14DCF42B5E38}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTests-QoiThumbnailProvider", "src\modules\previewpane\UnitTests-QoiThumbnailProvider\UnitTests-QoiThumbnailProvider.csproj", "{F8FFFC12-A31A-4AFA-B3DF-14DCF42B5E38}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CmdNotFoundModuleInterface", "src\modules\cmdNotFound\CmdNotFoundModuleInterface\CmdNotFoundModuleInterface.vcxproj", "{0014D652-901F-4456-8D65-06FC5F997FB0}"
EndProject
@@ -557,6 +561,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RegistryPreview", "src\modu
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EnvironmentVariables", "src\modules\EnvironmentVariables\EnvironmentVariables\EnvironmentVariables.csproj", "{DFF88D16-D36F-40A4-A955-CDCAA76EF7B8}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UITests-FancyZones", "src\modules\fancyzones\UITests-FancyZones\UITests-FancyZones.csproj", "{FE38FC07-1C05-4B57-ADA3-2FE2F53C6A52}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UITests-FancyZonesEditor", "src\modules\fancyzones\UITests-FancyZonesEditor\UITests-FancyZonesEditor.csproj", "{3A9A791E-94A9-49F8-8401-C11CE288D5FB}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FancyZonesEditorCommon", "src\modules\fancyzones\FancyZonesEditorCommon\FancyZonesEditorCommon.csproj", "{C0974915-8A1D-4BF0-977B-9587D3807AB7}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DSC", "DSC", "{557C4636-D7E1-4838-A504-7D19B725EE95}"
@@ -593,7 +601,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "WindowProperties", "WindowP
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WorkspacesLib", "src\modules\Workspaces\WorkspacesLib\WorkspacesLib.vcxproj", "{B31FCC55-B5A4-4EA7-B414-2DCEAE6AF332}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Workspaces.Lib.UnitTests", "src\modules\Workspaces\WorkspacesLib.UnitTests\WorkspacesLibUnitTests.vcxproj", "{A85D4D9F-9A39-4B5D-8B5A-9F2D5C9A8B4C}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WorkspacesLibUnitTests", "src\modules\Workspaces\WorkspacesLib.UnitTests\WorkspacesLibUnitTests.vcxproj", "{A85D4D9F-9A39-4B5D-8B5A-9F2D5C9A8B4C}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WorkspacesLauncherUI", "src\modules\Workspaces\WorkspacesLauncherUI\WorkspacesLauncherUI.csproj", "{9C53CC25-0623-4569-95BC-B05410675EE3}"
EndProject
@@ -669,6 +677,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.CmdPal.Ext.WebSea
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.CmdPal.Ext.WinGet", "src\modules\cmdpal\ext\Microsoft.CmdPal.Ext.WinGet\Microsoft.CmdPal.Ext.WinGet.csproj", "{E81A7D20-9862-ABDB-0AAE-9BC5B517A9F9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AdvancedPaste.UnitTests", "src\modules\AdvancedPaste\AdvancedPaste.UnitTests\AdvancedPaste.UnitTests.csproj", "{D5E5F5EA-1B6C-4A73-88BE-304F36C9E4EE}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AdvancedPaste.FuzzTests", "src\modules\AdvancedPaste\AdvancedPaste.FuzzTests\AdvancedPaste.FuzzTests.csproj", "{7F5B9557-5878-4438-A721-3E28296BA193}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ZoomIt", "ZoomIt", "{DD6E12FE-5509-4ABC-ACC2-3D6DC98A238C}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ZoomIt", "src\modules\ZoomIt\ZoomIt\ZoomIt.vcxproj", "{0A84F764-3A88-44CD-AA96-41BDBD48627B}"
@@ -685,17 +697,19 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KeyboardManagerEditorUI", "
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KeyboardManagerEditorLibraryWrapper", "src\modules\keyboardmanager\KeyboardManagerEditorLibraryWrapper\KeyboardManagerEditorLibraryWrapper.vcxproj", "{4382A954-179A-4078-92AF-715187DFFF50}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HostsEditor.FuzzTests", "src\modules\Hosts\Hosts.FuzzTests\HostsEditor.FuzzTests.csproj", "{EBED240C-8702-452D-B764-6DB9DA9179AF}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Hosts.FuzzTests", "src\modules\Hosts\Hosts.FuzzTests\Hosts.FuzzTests.csproj", "{EBED240C-8702-452D-B764-6DB9DA9179AF}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HostsEditor.UITests", "src\modules\Hosts\Hosts.UITests\HostsEditor.UITests.csproj", "{4E0AE3A4-2EE0-44D7-A2D0-8769977254A0}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Hosts.UITests", "src\modules\Hosts\Hosts.UITests\Hosts.UITests.csproj", "{4E0AE3A4-2EE0-44D7-A2D0-8769977254A0}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RegistryPreview.FuzzTests", "src\modules\registrypreview\RegistryPreview.FuzzTests\RegistryPreview.FuzzTests.csproj", "{5702B3CC-8575-48D5-83D8-15BB42269CD3}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.CmdPal.Ext.System", "src\modules\cmdpal\ext\Microsoft.CmdPal.Ext.System\Microsoft.CmdPal.Ext.System.csproj", "{64B88F02-CD88-4ED8-9624-989A800230F9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FancyZones.FuzzTests", "src\modules\fancyzones\FancyZones.FuzzTests\FancyZones.FuzzTests.csproj", "{0217E86E-3476-9946-DE8E-9D200CEBD47A}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CmdPalKeyboardService", "src\modules\cmdpal\CmdPalKeyboardService\CmdPalKeyboardService.vcxproj", "{5F63C743-F6CE-4DBA-A200-2B3F8A14E8C2}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PowerRename.FuzzTests", "src\modules\powerrename\PowerRename.FuzzingTest\PowerRename.FuzzingTest.vcxproj", "{2694E2FB-DCD5-4BFF-A418-B6C3C7CE3B8E}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PowerRename.FuzzingTest", "src\modules\powerrename\PowerRename.FuzzingTest\PowerRename.FuzzingTest.vcxproj", "{2694E2FB-DCD5-4BFF-A418-B6C3C7CE3B8E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BgcodePreviewHandler", "src\modules\previewpane\BgcodePreviewHandler\BgcodePreviewHandler.csproj", "{9E0CBC06-F29A-4810-B93C-97D53863B95E}"
EndProject
@@ -705,84 +719,37 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BgcodeThumbnailProviderCpp"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BgcodeThumbnailProvider", "src\modules\previewpane\BgcodeThumbnailProvider\BgcodeThumbnailProvider.csproj", "{9BC1C986-1E97-4D07-A7B1-CE226C239EFA}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Preview.BgcodePreviewHandler.UnitTests", "src\modules\previewpane\UnitTests-BgcodePreviewHandler\Preview.BgcodePreviewHandler.UnitTests.csproj", "{99CA1509-FB73-456E-AFAF-AB89C017BD72}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTests-BgcodePreviewHandler", "src\modules\previewpane\UnitTests-BgcodePreviewHandler\UnitTests-BgcodePreviewHandler.csproj", "{99CA1509-FB73-456E-AFAF-AB89C017BD72}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Preview.BgcodeThumbnailProvider.UnitTests", "src\modules\previewpane\UnitTests-BgcodeThumbnailProvider\Preview.BgcodeThumbnailProvider.UnitTests.csproj", "{61CBF221-9452-4934-B685-146285E080D7}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTests-BgcodeThumbnailProvider", "src\modules\previewpane\UnitTests-BgcodeThumbnailProvider\UnitTests-BgcodeThumbnailProvider.csproj", "{61CBF221-9452-4934-B685-146285E080D7}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MouseUtils.UITests", "src\modules\MouseUtils\MouseUtils.UITests\MouseUtils.UITests.csproj", "{4E0AE3A4-2EE0-44D7-A2D0-8769977254A1}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Workspaces.Editor.UITests", "src\modules\Workspaces\WorkspacesEditorUITest\Workspaces.Editor.UITests.csproj", "{43E779F3-D83C-48B1-BA8D-1912DBD76FC9}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WorkspacesEditorUITest", "src\modules\Workspaces\WorkspacesEditorUITest\WorkspacesEditorUITest.csproj", "{43E779F3-D83C-48B1-BA8D-1912DBD76FC9}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CalculatorEngineCommon", "src\common\CalculatorEngineCommon\CalculatorEngineCommon.vcxproj", "{2CF78CF7-8FEB-4BE1-9591-55FA25B48FC6}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ManagedCsWin32", "src\common\ManagedCsWin32\ManagedCsWin32.csproj", "{14AFD976-B4D2-49D0-9E6C-AA93CC061B8A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PowerRename.UITests", "src\modules\powerrename\PowerRenameUITest\PowerRename.UITests.csproj", "{9D3F3793-EFE3-4525-8782-238015DABA62}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PowerRenameUITest", "src\modules\powerrename\PowerRenameUITest\PowerRenameUITest.csproj", "{9D3F3793-EFE3-4525-8782-238015DABA62}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Peek.UITests", "src\modules\peek\Peek.UITests\Peek.UITests.csproj", "{BCDC7246-F4F8-4EED-8DE6-037AA2E7C6D1}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Core", "Core", "{02EA681E-C7D8-13C7-8484-4AC65E1B71E8}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.CmdPal.Core.ViewModels", "src\modules\cmdpal\Microsoft.CmdPal.Core.ViewModels\Microsoft.CmdPal.Core.ViewModels.csproj", "{24133F7F-C1D1-DE04-EFA8-F5D5467FE027}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{0E556541-6A45-42CB-AE49-EE5A9BE05E7C}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.CmdPal.UITests", "src\modules\cmdpal\Microsoft.CmdPal.UITests\Microsoft.CmdPal.UITests.csproj", "{840455DF-5634-51BB-D937-9D7D32F0B0C2}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{27D9CB3A-46D1-402C-9273-F88CB8AC42F7}"
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{15EA681E-C7D8-13C7-8484-4AC65E1B71E8}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{B9617A31-0F0A-4397-851D-BF2FBEE32D7F}"
ProjectSection(SolutionItems) = preProject
src\modules\launcher\Plugins\Microsoft.Plugin.Folder.UnitTests\Microsoft.Plugin.Folder.UnitTests.csproj = src\modules\launcher\Plugins\Microsoft.Plugin.Folder.UnitTests\Microsoft.Plugin.Folder.UnitTests.csproj
EndProjectSection
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.CmdPal.Ext.Registry.UnitTests", "src\modules\cmdpal\Tests\Microsoft.CmdPal.Ext.Registry.UnitTests\Microsoft.CmdPal.Ext.Registry.UnitTests.csproj", "{2CF0567E-1E00-4E3F-1561-BF85F5CE5FE7}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{1C48CD47-D610-463A-A53C-AF82DD6C47E7}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.CmdPal.Ext.System.UnitTests", "src\modules\cmdpal\Tests\Microsoft.CmdPal.Ext.System.UnitTests\Microsoft.CmdPal.Ext.System.UnitTests.csproj", "{790247CB-2B95-E139-E933-09D10137EEAF}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{D9BD324E-1D80-44AA-8E7B-73EB00944434}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.CmdPal.Ext.TimeDate.UnitTests", "src\modules\cmdpal\Tests\Microsoft.CmdPal.Ext.TimeDate.UnitTests\Microsoft.CmdPal.Ext.TimeDate.UnitTests.csproj", "{18525614-CDB2-8BBE-B1B4-3812CD990C22}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{8EF25507-2575-4ADE-BF7E-D23376903AB8}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PowerOCR.UITests", "src\modules\PowerOCR\PowerOCR-UITests\PowerOCR.UITests.csproj", "{070AC093-C9F2-20AD-0BCD-F318FC2761EA}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{2C318EC3-BA86-4372-B1BC-DB0F33C208B2}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{BFFB607F-7C78-434B-86B9-DA4C8196A1B5}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{66E1534A-1587-42B2-912F-45C994D32904}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{E885E71F-0B34-4A03-B13B-20F4E05E90BB}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{264B412F-DB8B-4CF8-A74B-96998B183045}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{3527BF37-DFC5-4309-A032-29278CA21328}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{6B01F1CF-F4DB-48B5-BFE7-0BF576C1D704}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{68328142-5B31-4715-BCBB-7B6345EE0971}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AdvancedPaste.FuzzTests", "src\modules\AdvancedPaste\AdvancedPaste.FuzzTests\AdvancedPaste.FuzzTests.csproj", "{4122388B-59E4-CDB0-0338-EA6881DF86F0}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AdvancedPaste.UnitTests", "src\modules\AdvancedPaste\AdvancedPaste.UnitTests\AdvancedPaste.UnitTests.csproj", "{988C9FAF-5AEC-EB15-578D-FED0DF52BF55}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.CmdPal.UITests", "src\modules\cmdpal\Tests\Microsoft.CmdPal.UITests\Microsoft.CmdPal.UITests.csproj", "{6748A29D-DA6A-033A-825B-752295FF6AA0}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FancyZones.FuzzTests", "src\modules\fancyzones\FancyZones.FuzzTests\FancyZones.FuzzTests.csproj", "{6EABCF9A-6526-441F-932F-658B1DC3E403}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FancyZones.UITests", "src\modules\fancyzones\FancyZones.UITests\FancyZones.UITests.csproj", "{69D76A76-6EF6-4846-94CD-EAAF0CAC9F15}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FancyZonesEditor.UITests", "src\modules\fancyzones\FancyZonesEditor.UITests\FancyZonesEditor.UITests.csproj", "{9BAFFC28-E1EF-4C14-A101-EEBFC0A50D83}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FancyZonesEditor.UnitTests", "src\modules\fancyzones\FancyZonesEditor.UnitTests\FancyZonesEditor.UnitTests.csproj", "{806BF185-8B89-5BE1-9AA1-DA5BC9487DB9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ColorPickerUI.UnitTests", "src\modules\colorPicker\ColorPickerUI.UnitTests\ColorPickerUI.UnitTests.csproj", "{F93C2817-C846-4259-84D8-B39A6B57C8DE}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Test", "Test", "{8131151D-B0E9-4E18-84A5-E5F946C4480A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.CmdPal.Ext.Calc.UnitTests", "src\modules\cmdpal\Tests\Microsoft.CmdPal.Ext.Calc.UnitTests\Microsoft.CmdPal.Ext.Calc.UnitTests.csproj", "{E816D7AC-4688-4ECB-97CC-3D8E798F3825}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.CmdPal.Ext.Registry.UnitTests", "src\modules\cmdpal\Tests\Microsoft.CmdPal.Ext.Registry.UnitTests\Microsoft.CmdPal.Ext.Registry.UnitTests.csproj", "{E816D7AD-4688-4ECB-97CC-3D8E798F3826}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.CmdPal.Ext.System.UnitTests", "src\modules\cmdpal\Tests\Microsoft.CmdPal.Ext.System.UnitTests\Microsoft.CmdPal.Ext.System.UnitTests.csproj", "{E816D7AE-4688-4ECB-97CC-3D8E798F3827}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.CmdPal.Ext.TimeDate.UnitTests", "src\modules\cmdpal\Tests\Microsoft.CmdPal.Ext.TimeDate.UnitTests\Microsoft.CmdPal.Ext.TimeDate.UnitTests.csproj", "{E816D7AF-4688-4ECB-97CC-3D8E798F3828}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.CmdPal.Ext.WindowWalker.UnitTests", "src\modules\cmdpal\Tests\Microsoft.CmdPal.Ext.WindowWalker.UnitTests\Microsoft.CmdPal.Ext.WindowWalker.UnitTests.csproj", "{E816D7B0-4688-4ECB-97CC-3D8E798F3829}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.CmdPal.Ext.WindowWalker.UnitTests", "src\modules\cmdpal\Tests\Microsoft.CmdPal.Ext.WindowWalker.UnitTests\Microsoft.CmdPal.Ext.WindowWalker.UnitTests.csproj", "{B0FE6EF3-5FB3-B8DC-7507-008BBB392FD8}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -1184,6 +1151,22 @@ Global
{632BBE62-5421-49EA-835A-7FFA4F499BD6}.Release|ARM64.Build.0 = Release|ARM64
{632BBE62-5421-49EA-835A-7FFA4F499BD6}.Release|x64.ActiveCfg = Release|x64
{632BBE62-5421-49EA-835A-7FFA4F499BD6}.Release|x64.Build.0 = Release|x64
{4FA206A5-F69F-4193-BF8F-F6EEB496734C}.Debug|ARM64.ActiveCfg = Debug|ARM64
{4FA206A5-F69F-4193-BF8F-F6EEB496734C}.Debug|ARM64.Build.0 = Debug|ARM64
{4FA206A5-F69F-4193-BF8F-F6EEB496734C}.Debug|x64.ActiveCfg = Debug|x64
{4FA206A5-F69F-4193-BF8F-F6EEB496734C}.Debug|x64.Build.0 = Debug|x64
{4FA206A5-F69F-4193-BF8F-F6EEB496734C}.Release|ARM64.ActiveCfg = Release|ARM64
{4FA206A5-F69F-4193-BF8F-F6EEB496734C}.Release|ARM64.Build.0 = Release|ARM64
{4FA206A5-F69F-4193-BF8F-F6EEB496734C}.Release|x64.ActiveCfg = Release|x64
{4FA206A5-F69F-4193-BF8F-F6EEB496734C}.Release|x64.Build.0 = Release|x64
{090CD7B7-3B0C-4D1D-BC98-83EB5D799BC1}.Debug|ARM64.ActiveCfg = Debug|ARM64
{090CD7B7-3B0C-4D1D-BC98-83EB5D799BC1}.Debug|ARM64.Build.0 = Debug|ARM64
{090CD7B7-3B0C-4D1D-BC98-83EB5D799BC1}.Debug|x64.ActiveCfg = Debug|x64
{090CD7B7-3B0C-4D1D-BC98-83EB5D799BC1}.Debug|x64.Build.0 = Debug|x64
{090CD7B7-3B0C-4D1D-BC98-83EB5D799BC1}.Release|ARM64.ActiveCfg = Release|ARM64
{090CD7B7-3B0C-4D1D-BC98-83EB5D799BC1}.Release|ARM64.Build.0 = Release|ARM64
{090CD7B7-3B0C-4D1D-BC98-83EB5D799BC1}.Release|x64.ActiveCfg = Release|x64
{090CD7B7-3B0C-4D1D-BC98-83EB5D799BC1}.Release|x64.Build.0 = Release|x64
{7E1E3F13-2BD6-3F75-A6A7-873A2B55C60F}.Debug|ARM64.ActiveCfg = Debug|ARM64
{7E1E3F13-2BD6-3F75-A6A7-873A2B55C60F}.Debug|ARM64.Build.0 = Debug|ARM64
{7E1E3F13-2BD6-3F75-A6A7-873A2B55C60F}.Debug|x64.ActiveCfg = Debug|x64
@@ -2068,6 +2051,14 @@ Global
{3157FA75-86CF-4EE2-8F62-C43F776493C6}.Release|ARM64.Build.0 = Release|ARM64
{3157FA75-86CF-4EE2-8F62-C43F776493C6}.Release|x64.ActiveCfg = Release|x64
{3157FA75-86CF-4EE2-8F62-C43F776493C6}.Release|x64.Build.0 = Release|x64
{FC8EB78F-F061-4BD9-A3F6-507BEA965E2B}.Debug|ARM64.ActiveCfg = Debug|ARM64
{FC8EB78F-F061-4BD9-A3F6-507BEA965E2B}.Debug|ARM64.Build.0 = Debug|ARM64
{FC8EB78F-F061-4BD9-A3F6-507BEA965E2B}.Debug|x64.ActiveCfg = Debug|x64
{FC8EB78F-F061-4BD9-A3F6-507BEA965E2B}.Debug|x64.Build.0 = Debug|x64
{FC8EB78F-F061-4BD9-A3F6-507BEA965E2B}.Release|ARM64.ActiveCfg = Release|ARM64
{FC8EB78F-F061-4BD9-A3F6-507BEA965E2B}.Release|ARM64.Build.0 = Release|ARM64
{FC8EB78F-F061-4BD9-A3F6-507BEA965E2B}.Release|x64.ActiveCfg = Release|x64
{FC8EB78F-F061-4BD9-A3F6-507BEA965E2B}.Release|x64.Build.0 = Release|x64
{51465DA1-C18B-4B99-93E1-ECF8E0FA0CBA}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{51465DA1-C18B-4B99-93E1-ECF8E0FA0CBA}.Debug|ARM64.Build.0 = Debug|Any CPU
{51465DA1-C18B-4B99-93E1-ECF8E0FA0CBA}.Debug|x64.ActiveCfg = Debug|Any CPU
@@ -2192,6 +2183,22 @@ Global
{DFF88D16-D36F-40A4-A955-CDCAA76EF7B8}.Release|ARM64.Build.0 = Release|ARM64
{DFF88D16-D36F-40A4-A955-CDCAA76EF7B8}.Release|x64.ActiveCfg = Release|x64
{DFF88D16-D36F-40A4-A955-CDCAA76EF7B8}.Release|x64.Build.0 = Release|x64
{FE38FC07-1C05-4B57-ADA3-2FE2F53C6A52}.Debug|ARM64.ActiveCfg = Debug|ARM64
{FE38FC07-1C05-4B57-ADA3-2FE2F53C6A52}.Debug|ARM64.Build.0 = Debug|ARM64
{FE38FC07-1C05-4B57-ADA3-2FE2F53C6A52}.Debug|x64.ActiveCfg = Debug|x64
{FE38FC07-1C05-4B57-ADA3-2FE2F53C6A52}.Debug|x64.Build.0 = Debug|x64
{FE38FC07-1C05-4B57-ADA3-2FE2F53C6A52}.Release|ARM64.ActiveCfg = Release|ARM64
{FE38FC07-1C05-4B57-ADA3-2FE2F53C6A52}.Release|ARM64.Build.0 = Release|ARM64
{FE38FC07-1C05-4B57-ADA3-2FE2F53C6A52}.Release|x64.ActiveCfg = Release|x64
{FE38FC07-1C05-4B57-ADA3-2FE2F53C6A52}.Release|x64.Build.0 = Release|x64
{3A9A791E-94A9-49F8-8401-C11CE288D5FB}.Debug|ARM64.ActiveCfg = Debug|ARM64
{3A9A791E-94A9-49F8-8401-C11CE288D5FB}.Debug|ARM64.Build.0 = Debug|ARM64
{3A9A791E-94A9-49F8-8401-C11CE288D5FB}.Debug|x64.ActiveCfg = Debug|x64
{3A9A791E-94A9-49F8-8401-C11CE288D5FB}.Debug|x64.Build.0 = Debug|x64
{3A9A791E-94A9-49F8-8401-C11CE288D5FB}.Release|ARM64.ActiveCfg = Release|ARM64
{3A9A791E-94A9-49F8-8401-C11CE288D5FB}.Release|ARM64.Build.0 = Release|ARM64
{3A9A791E-94A9-49F8-8401-C11CE288D5FB}.Release|x64.ActiveCfg = Release|x64
{3A9A791E-94A9-49F8-8401-C11CE288D5FB}.Release|x64.Build.0 = Release|x64
{C0974915-8A1D-4BF0-977B-9587D3807AB7}.Debug|ARM64.ActiveCfg = Debug|ARM64
{C0974915-8A1D-4BF0-977B-9587D3807AB7}.Debug|ARM64.Build.0 = Debug|ARM64
{C0974915-8A1D-4BF0-977B-9587D3807AB7}.Debug|x64.ActiveCfg = Debug|x64
@@ -2516,6 +2523,22 @@ Global
{E81A7D20-9862-ABDB-0AAE-9BC5B517A9F9}.Release|x64.ActiveCfg = Release|x64
{E81A7D20-9862-ABDB-0AAE-9BC5B517A9F9}.Release|x64.Build.0 = Release|x64
{E81A7D20-9862-ABDB-0AAE-9BC5B517A9F9}.Release|x64.Deploy.0 = Release|x64
{D5E5F5EA-1B6C-4A73-88BE-304F36C9E4EE}.Debug|ARM64.ActiveCfg = Debug|ARM64
{D5E5F5EA-1B6C-4A73-88BE-304F36C9E4EE}.Debug|ARM64.Build.0 = Debug|ARM64
{D5E5F5EA-1B6C-4A73-88BE-304F36C9E4EE}.Debug|x64.ActiveCfg = Debug|x64
{D5E5F5EA-1B6C-4A73-88BE-304F36C9E4EE}.Debug|x64.Build.0 = Debug|x64
{D5E5F5EA-1B6C-4A73-88BE-304F36C9E4EE}.Release|ARM64.ActiveCfg = Release|ARM64
{D5E5F5EA-1B6C-4A73-88BE-304F36C9E4EE}.Release|ARM64.Build.0 = Release|ARM64
{D5E5F5EA-1B6C-4A73-88BE-304F36C9E4EE}.Release|x64.ActiveCfg = Release|x64
{D5E5F5EA-1B6C-4A73-88BE-304F36C9E4EE}.Release|x64.Build.0 = Release|x64
{7F5B9557-5878-4438-A721-3E28296BA193}.Debug|ARM64.ActiveCfg = Debug|ARM64
{7F5B9557-5878-4438-A721-3E28296BA193}.Debug|ARM64.Build.0 = Debug|ARM64
{7F5B9557-5878-4438-A721-3E28296BA193}.Debug|x64.ActiveCfg = Debug|x64
{7F5B9557-5878-4438-A721-3E28296BA193}.Debug|x64.Build.0 = Debug|x64
{7F5B9557-5878-4438-A721-3E28296BA193}.Release|ARM64.ActiveCfg = Release|ARM64
{7F5B9557-5878-4438-A721-3E28296BA193}.Release|ARM64.Build.0 = Release|ARM64
{7F5B9557-5878-4438-A721-3E28296BA193}.Release|x64.ActiveCfg = Release|x64
{7F5B9557-5878-4438-A721-3E28296BA193}.Release|x64.Build.0 = Release|x64
{0A84F764-3A88-44CD-AA96-41BDBD48627B}.Debug|ARM64.ActiveCfg = Debug|ARM64
{0A84F764-3A88-44CD-AA96-41BDBD48627B}.Debug|ARM64.Build.0 = Debug|ARM64
{0A84F764-3A88-44CD-AA96-41BDBD48627B}.Debug|x64.ActiveCfg = Debug|x64
@@ -2608,6 +2631,14 @@ Global
{64B88F02-CD88-4ED8-9624-989A800230F9}.Release|ARM64.Build.0 = Release|ARM64
{64B88F02-CD88-4ED8-9624-989A800230F9}.Release|x64.ActiveCfg = Release|x64
{64B88F02-CD88-4ED8-9624-989A800230F9}.Release|x64.Build.0 = Release|x64
{0217E86E-3476-9946-DE8E-9D200CEBD47A}.Debug|ARM64.ActiveCfg = Debug|ARM64
{0217E86E-3476-9946-DE8E-9D200CEBD47A}.Debug|ARM64.Build.0 = Debug|ARM64
{0217E86E-3476-9946-DE8E-9D200CEBD47A}.Debug|x64.ActiveCfg = Debug|x64
{0217E86E-3476-9946-DE8E-9D200CEBD47A}.Debug|x64.Build.0 = Debug|x64
{0217E86E-3476-9946-DE8E-9D200CEBD47A}.Release|ARM64.ActiveCfg = Release|ARM64
{0217E86E-3476-9946-DE8E-9D200CEBD47A}.Release|ARM64.Build.0 = Release|ARM64
{0217E86E-3476-9946-DE8E-9D200CEBD47A}.Release|x64.ActiveCfg = Release|x64
{0217E86E-3476-9946-DE8E-9D200CEBD47A}.Release|x64.Build.0 = Release|x64
{5F63C743-F6CE-4DBA-A200-2B3F8A14E8C2}.Debug|ARM64.ActiveCfg = Debug|ARM64
{5F63C743-F6CE-4DBA-A200-2B3F8A14E8C2}.Debug|ARM64.Build.0 = Debug|ARM64
{5F63C743-F6CE-4DBA-A200-2B3F8A14E8C2}.Debug|x64.ActiveCfg = Debug|x64
@@ -2702,14 +2733,6 @@ Global
{14AFD976-B4D2-49D0-9E6C-AA93CC061B8A}.Release|ARM64.Build.0 = Release|ARM64
{14AFD976-B4D2-49D0-9E6C-AA93CC061B8A}.Release|x64.ActiveCfg = Release|x64
{14AFD976-B4D2-49D0-9E6C-AA93CC061B8A}.Release|x64.Build.0 = Release|x64
{9D3F3793-EFE3-4525-8782-238015DABA62}.Debug|ARM64.ActiveCfg = Debug|ARM64
{9D3F3793-EFE3-4525-8782-238015DABA62}.Debug|ARM64.Build.0 = Debug|ARM64
{9D3F3793-EFE3-4525-8782-238015DABA62}.Debug|x64.ActiveCfg = Debug|x64
{9D3F3793-EFE3-4525-8782-238015DABA62}.Debug|x64.Build.0 = Debug|x64
{9D3F3793-EFE3-4525-8782-238015DABA62}.Release|ARM64.ActiveCfg = Release|ARM64
{9D3F3793-EFE3-4525-8782-238015DABA62}.Release|ARM64.Build.0 = Release|ARM64
{9D3F3793-EFE3-4525-8782-238015DABA62}.Release|x64.ActiveCfg = Release|x64
{9D3F3793-EFE3-4525-8782-238015DABA62}.Release|x64.Build.0 = Release|x64
{24133F7F-C1D1-DE04-EFA8-F5D5467FE027}.Debug|ARM64.ActiveCfg = Debug|ARM64
{24133F7F-C1D1-DE04-EFA8-F5D5467FE027}.Debug|ARM64.Build.0 = Debug|ARM64
{24133F7F-C1D1-DE04-EFA8-F5D5467FE027}.Debug|x64.ActiveCfg = Debug|x64
@@ -2718,118 +2741,62 @@ Global
{24133F7F-C1D1-DE04-EFA8-F5D5467FE027}.Release|ARM64.Build.0 = Release|ARM64
{24133F7F-C1D1-DE04-EFA8-F5D5467FE027}.Release|x64.ActiveCfg = Release|x64
{24133F7F-C1D1-DE04-EFA8-F5D5467FE027}.Release|x64.Build.0 = Release|x64
{070AC093-C9F2-20AD-0BCD-F318FC2761EA}.Debug|ARM64.ActiveCfg = Debug|ARM64
{070AC093-C9F2-20AD-0BCD-F318FC2761EA}.Debug|ARM64.Build.0 = Debug|ARM64
{070AC093-C9F2-20AD-0BCD-F318FC2761EA}.Debug|x64.ActiveCfg = Debug|x64
{070AC093-C9F2-20AD-0BCD-F318FC2761EA}.Debug|x64.Build.0 = Debug|x64
{070AC093-C9F2-20AD-0BCD-F318FC2761EA}.Release|ARM64.ActiveCfg = Release|ARM64
{070AC093-C9F2-20AD-0BCD-F318FC2761EA}.Release|ARM64.Build.0 = Release|ARM64
{070AC093-C9F2-20AD-0BCD-F318FC2761EA}.Release|x64.ActiveCfg = Release|x64
{070AC093-C9F2-20AD-0BCD-F318FC2761EA}.Release|x64.Build.0 = Release|x64
{4122388B-59E4-CDB0-0338-EA6881DF86F0}.Debug|ARM64.ActiveCfg = Debug|ARM64
{4122388B-59E4-CDB0-0338-EA6881DF86F0}.Debug|ARM64.Build.0 = Debug|ARM64
{4122388B-59E4-CDB0-0338-EA6881DF86F0}.Debug|x64.ActiveCfg = Debug|x64
{4122388B-59E4-CDB0-0338-EA6881DF86F0}.Debug|x64.Build.0 = Debug|x64
{4122388B-59E4-CDB0-0338-EA6881DF86F0}.Release|ARM64.ActiveCfg = Release|ARM64
{4122388B-59E4-CDB0-0338-EA6881DF86F0}.Release|ARM64.Build.0 = Release|ARM64
{4122388B-59E4-CDB0-0338-EA6881DF86F0}.Release|x64.ActiveCfg = Release|x64
{4122388B-59E4-CDB0-0338-EA6881DF86F0}.Release|x64.Build.0 = Release|x64
{988C9FAF-5AEC-EB15-578D-FED0DF52BF55}.Debug|ARM64.ActiveCfg = Debug|ARM64
{988C9FAF-5AEC-EB15-578D-FED0DF52BF55}.Debug|ARM64.Build.0 = Debug|ARM64
{988C9FAF-5AEC-EB15-578D-FED0DF52BF55}.Debug|x64.ActiveCfg = Debug|x64
{988C9FAF-5AEC-EB15-578D-FED0DF52BF55}.Debug|x64.Build.0 = Debug|x64
{988C9FAF-5AEC-EB15-578D-FED0DF52BF55}.Release|ARM64.ActiveCfg = Release|ARM64
{988C9FAF-5AEC-EB15-578D-FED0DF52BF55}.Release|ARM64.Build.0 = Release|ARM64
{988C9FAF-5AEC-EB15-578D-FED0DF52BF55}.Release|x64.ActiveCfg = Release|x64
{988C9FAF-5AEC-EB15-578D-FED0DF52BF55}.Release|x64.Build.0 = Release|x64
{6748A29D-DA6A-033A-825B-752295FF6AA0}.Debug|ARM64.ActiveCfg = Debug|ARM64
{6748A29D-DA6A-033A-825B-752295FF6AA0}.Debug|ARM64.Build.0 = Debug|ARM64
{6748A29D-DA6A-033A-825B-752295FF6AA0}.Debug|x64.ActiveCfg = Debug|x64
{6748A29D-DA6A-033A-825B-752295FF6AA0}.Debug|x64.Build.0 = Debug|x64
{6748A29D-DA6A-033A-825B-752295FF6AA0}.Release|ARM64.ActiveCfg = Release|ARM64
{6748A29D-DA6A-033A-825B-752295FF6AA0}.Release|ARM64.Build.0 = Release|ARM64
{6748A29D-DA6A-033A-825B-752295FF6AA0}.Release|x64.ActiveCfg = Release|x64
{6748A29D-DA6A-033A-825B-752295FF6AA0}.Release|x64.Build.0 = Release|x64
{6EABCF9A-6526-441F-932F-658B1DC3E403}.Debug|ARM64.ActiveCfg = Debug|ARM64
{6EABCF9A-6526-441F-932F-658B1DC3E403}.Debug|ARM64.Build.0 = Debug|ARM64
{6EABCF9A-6526-441F-932F-658B1DC3E403}.Debug|x64.ActiveCfg = Debug|x64
{6EABCF9A-6526-441F-932F-658B1DC3E403}.Debug|x64.Build.0 = Debug|x64
{6EABCF9A-6526-441F-932F-658B1DC3E403}.Release|ARM64.ActiveCfg = Release|ARM64
{6EABCF9A-6526-441F-932F-658B1DC3E403}.Release|ARM64.Build.0 = Release|ARM64
{6EABCF9A-6526-441F-932F-658B1DC3E403}.Release|x64.ActiveCfg = Release|x64
{6EABCF9A-6526-441F-932F-658B1DC3E403}.Release|x64.Build.0 = Release|x64
{69D76A76-6EF6-4846-94CD-EAAF0CAC9F15}.Debug|ARM64.ActiveCfg = Debug|ARM64
{69D76A76-6EF6-4846-94CD-EAAF0CAC9F15}.Debug|ARM64.Build.0 = Debug|ARM64
{69D76A76-6EF6-4846-94CD-EAAF0CAC9F15}.Debug|x64.ActiveCfg = Debug|x64
{69D76A76-6EF6-4846-94CD-EAAF0CAC9F15}.Debug|x64.Build.0 = Debug|x64
{69D76A76-6EF6-4846-94CD-EAAF0CAC9F15}.Release|ARM64.ActiveCfg = Release|ARM64
{69D76A76-6EF6-4846-94CD-EAAF0CAC9F15}.Release|ARM64.Build.0 = Release|ARM64
{69D76A76-6EF6-4846-94CD-EAAF0CAC9F15}.Release|x64.ActiveCfg = Release|x64
{69D76A76-6EF6-4846-94CD-EAAF0CAC9F15}.Release|x64.Build.0 = Release|x64
{9BAFFC28-E1EF-4C14-A101-EEBFC0A50D83}.Debug|ARM64.ActiveCfg = Debug|ARM64
{9BAFFC28-E1EF-4C14-A101-EEBFC0A50D83}.Debug|ARM64.Build.0 = Debug|ARM64
{9BAFFC28-E1EF-4C14-A101-EEBFC0A50D83}.Debug|x64.ActiveCfg = Debug|x64
{9BAFFC28-E1EF-4C14-A101-EEBFC0A50D83}.Debug|x64.Build.0 = Debug|x64
{9BAFFC28-E1EF-4C14-A101-EEBFC0A50D83}.Release|ARM64.ActiveCfg = Release|ARM64
{9BAFFC28-E1EF-4C14-A101-EEBFC0A50D83}.Release|ARM64.Build.0 = Release|ARM64
{9BAFFC28-E1EF-4C14-A101-EEBFC0A50D83}.Release|x64.ActiveCfg = Release|x64
{9BAFFC28-E1EF-4C14-A101-EEBFC0A50D83}.Release|x64.Build.0 = Release|x64
{806BF185-8B89-5BE1-9AA1-DA5BC9487DB9}.Debug|ARM64.ActiveCfg = Debug|ARM64
{806BF185-8B89-5BE1-9AA1-DA5BC9487DB9}.Debug|ARM64.Build.0 = Debug|ARM64
{806BF185-8B89-5BE1-9AA1-DA5BC9487DB9}.Debug|x64.ActiveCfg = Debug|x64
{806BF185-8B89-5BE1-9AA1-DA5BC9487DB9}.Debug|x64.Build.0 = Debug|x64
{806BF185-8B89-5BE1-9AA1-DA5BC9487DB9}.Release|ARM64.ActiveCfg = Release|ARM64
{806BF185-8B89-5BE1-9AA1-DA5BC9487DB9}.Release|ARM64.Build.0 = Release|ARM64
{806BF185-8B89-5BE1-9AA1-DA5BC9487DB9}.Release|x64.ActiveCfg = Release|x64
{806BF185-8B89-5BE1-9AA1-DA5BC9487DB9}.Release|x64.Build.0 = Release|x64
{F93C2817-C846-4259-84D8-B39A6B57C8DE}.Debug|ARM64.ActiveCfg = Debug|ARM64
{F93C2817-C846-4259-84D8-B39A6B57C8DE}.Debug|ARM64.Build.0 = Debug|ARM64
{F93C2817-C846-4259-84D8-B39A6B57C8DE}.Debug|x64.ActiveCfg = Debug|x64
{F93C2817-C846-4259-84D8-B39A6B57C8DE}.Debug|x64.Build.0 = Debug|x64
{F93C2817-C846-4259-84D8-B39A6B57C8DE}.Release|ARM64.ActiveCfg = Release|ARM64
{F93C2817-C846-4259-84D8-B39A6B57C8DE}.Release|ARM64.Build.0 = Release|ARM64
{F93C2817-C846-4259-84D8-B39A6B57C8DE}.Release|x64.ActiveCfg = Release|x64
{F93C2817-C846-4259-84D8-B39A6B57C8DE}.Release|x64.Build.0 = Release|x64
{E816D7AC-4688-4ECB-97CC-3D8E798F3825}.Debug|ARM64.ActiveCfg = Debug|ARM64
{E816D7AC-4688-4ECB-97CC-3D8E798F3825}.Debug|ARM64.Build.0 = Debug|ARM64
{E816D7AC-4688-4ECB-97CC-3D8E798F3825}.Debug|x64.ActiveCfg = Debug|x64
{E816D7AC-4688-4ECB-97CC-3D8E798F3825}.Debug|x64.Build.0 = Debug|x64
{E816D7AC-4688-4ECB-97CC-3D8E798F3825}.Release|ARM64.ActiveCfg = Release|ARM64
{E816D7AC-4688-4ECB-97CC-3D8E798F3825}.Release|ARM64.Build.0 = Release|ARM64
{E816D7AC-4688-4ECB-97CC-3D8E798F3825}.Release|x64.ActiveCfg = Release|x64
{E816D7AC-4688-4ECB-97CC-3D8E798F3825}.Release|x64.Build.0 = Release|x64
{E816D7AD-4688-4ECB-97CC-3D8E798F3826}.Debug|ARM64.ActiveCfg = Debug|ARM64
{E816D7AD-4688-4ECB-97CC-3D8E798F3826}.Debug|ARM64.Build.0 = Debug|ARM64
{E816D7AD-4688-4ECB-97CC-3D8E798F3826}.Debug|x64.ActiveCfg = Debug|x64
{E816D7AD-4688-4ECB-97CC-3D8E798F3826}.Debug|x64.Build.0 = Debug|x64
{E816D7AD-4688-4ECB-97CC-3D8E798F3826}.Release|ARM64.ActiveCfg = Release|ARM64
{E816D7AD-4688-4ECB-97CC-3D8E798F3826}.Release|ARM64.Build.0 = Release|ARM64
{E816D7AD-4688-4ECB-97CC-3D8E798F3826}.Release|x64.ActiveCfg = Release|x64
{E816D7AD-4688-4ECB-97CC-3D8E798F3826}.Release|x64.Build.0 = Release|x64
{E816D7AE-4688-4ECB-97CC-3D8E798F3827}.Debug|ARM64.ActiveCfg = Debug|ARM64
{E816D7AE-4688-4ECB-97CC-3D8E798F3827}.Debug|ARM64.Build.0 = Debug|ARM64
{E816D7AE-4688-4ECB-97CC-3D8E798F3827}.Debug|x64.ActiveCfg = Debug|x64
{E816D7AE-4688-4ECB-97CC-3D8E798F3827}.Debug|x64.Build.0 = Debug|x64
{E816D7AE-4688-4ECB-97CC-3D8E798F3827}.Release|ARM64.ActiveCfg = Release|ARM64
{E816D7AE-4688-4ECB-97CC-3D8E798F3827}.Release|ARM64.Build.0 = Release|ARM64
{E816D7AE-4688-4ECB-97CC-3D8E798F3827}.Release|x64.ActiveCfg = Release|x64
{E816D7AE-4688-4ECB-97CC-3D8E798F3827}.Release|x64.Build.0 = Release|x64
{E816D7AF-4688-4ECB-97CC-3D8E798F3828}.Debug|ARM64.ActiveCfg = Debug|ARM64
{E816D7AF-4688-4ECB-97CC-3D8E798F3828}.Debug|ARM64.Build.0 = Debug|ARM64
{E816D7AF-4688-4ECB-97CC-3D8E798F3828}.Debug|x64.ActiveCfg = Debug|x64
{E816D7AF-4688-4ECB-97CC-3D8E798F3828}.Debug|x64.Build.0 = Debug|x64
{E816D7AF-4688-4ECB-97CC-3D8E798F3828}.Release|ARM64.ActiveCfg = Release|ARM64
{E816D7AF-4688-4ECB-97CC-3D8E798F3828}.Release|ARM64.Build.0 = Release|ARM64
{E816D7AF-4688-4ECB-97CC-3D8E798F3828}.Release|x64.ActiveCfg = Release|x64
{E816D7AF-4688-4ECB-97CC-3D8E798F3828}.Release|x64.Build.0 = Release|x64
{E816D7B0-4688-4ECB-97CC-3D8E798F3829}.Debug|ARM64.ActiveCfg = Debug|ARM64
{E816D7B0-4688-4ECB-97CC-3D8E798F3829}.Debug|ARM64.Build.0 = Debug|ARM64
{E816D7B0-4688-4ECB-97CC-3D8E798F3829}.Debug|x64.ActiveCfg = Debug|x64
{E816D7B0-4688-4ECB-97CC-3D8E798F3829}.Debug|x64.Build.0 = Debug|x64
{E816D7B0-4688-4ECB-97CC-3D8E798F3829}.Release|ARM64.ActiveCfg = Release|ARM64
{E816D7B0-4688-4ECB-97CC-3D8E798F3829}.Release|ARM64.Build.0 = Release|ARM64
{E816D7B0-4688-4ECB-97CC-3D8E798F3829}.Release|x64.ActiveCfg = Release|x64
{E816D7B0-4688-4ECB-97CC-3D8E798F3829}.Release|x64.Build.0 = Release|x64
{9D3F3793-EFE3-4525-8782-238015DABA62}.Debug|ARM64.ActiveCfg = Debug|ARM64
{9D3F3793-EFE3-4525-8782-238015DABA62}.Debug|ARM64.Build.0 = Debug|ARM64
{9D3F3793-EFE3-4525-8782-238015DABA62}.Debug|x64.ActiveCfg = Debug|x64
{9D3F3793-EFE3-4525-8782-238015DABA62}.Debug|x64.Build.0 = Debug|x64
{9D3F3793-EFE3-4525-8782-238015DABA62}.Release|ARM64.ActiveCfg = Release|ARM64
{9D3F3793-EFE3-4525-8782-238015DABA62}.Release|ARM64.Build.0 = Release|ARM64
{9D3F3793-EFE3-4525-8782-238015DABA62}.Release|x64.ActiveCfg = Release|x64
{9D3F3793-EFE3-4525-8782-238015DABA62}.Release|x64.Build.0 = Release|x64
{BCDC7246-F4F8-4EED-8DE6-037AA2E7C6D1}.Debug|ARM64.ActiveCfg = Debug|ARM64
{BCDC7246-F4F8-4EED-8DE6-037AA2E7C6D1}.Debug|ARM64.Build.0 = Debug|ARM64
{BCDC7246-F4F8-4EED-8DE6-037AA2E7C6D1}.Debug|x64.ActiveCfg = Debug|x64
{BCDC7246-F4F8-4EED-8DE6-037AA2E7C6D1}.Debug|x64.Build.0 = Debug|x64
{BCDC7246-F4F8-4EED-8DE6-037AA2E7C6D1}.Release|ARM64.ActiveCfg = Release|ARM64
{BCDC7246-F4F8-4EED-8DE6-037AA2E7C6D1}.Release|ARM64.Build.0 = Release|ARM64
{BCDC7246-F4F8-4EED-8DE6-037AA2E7C6D1}.Release|x64.ActiveCfg = Release|x64
{BCDC7246-F4F8-4EED-8DE6-037AA2E7C6D1}.Release|x64.Build.0 = Release|x64
{840455DF-5634-51BB-D937-9D7D32F0B0C2}.Debug|ARM64.ActiveCfg = Debug|ARM64
{840455DF-5634-51BB-D937-9D7D32F0B0C2}.Debug|ARM64.Build.0 = Debug|ARM64
{840455DF-5634-51BB-D937-9D7D32F0B0C2}.Debug|x64.ActiveCfg = Debug|x64
{840455DF-5634-51BB-D937-9D7D32F0B0C2}.Debug|x64.Build.0 = Debug|x64
{840455DF-5634-51BB-D937-9D7D32F0B0C2}.Release|ARM64.ActiveCfg = Release|ARM64
{840455DF-5634-51BB-D937-9D7D32F0B0C2}.Release|ARM64.Build.0 = Release|ARM64
{840455DF-5634-51BB-D937-9D7D32F0B0C2}.Release|x64.ActiveCfg = Release|x64
{840455DF-5634-51BB-D937-9D7D32F0B0C2}.Release|x64.Build.0 = Release|x64
{2CF0567E-1E00-4E3F-1561-BF85F5CE5FE7}.Debug|ARM64.ActiveCfg = Debug|ARM64
{2CF0567E-1E00-4E3F-1561-BF85F5CE5FE7}.Debug|ARM64.Build.0 = Debug|ARM64
{2CF0567E-1E00-4E3F-1561-BF85F5CE5FE7}.Debug|x64.ActiveCfg = Debug|x64
{2CF0567E-1E00-4E3F-1561-BF85F5CE5FE7}.Debug|x64.Build.0 = Debug|x64
{2CF0567E-1E00-4E3F-1561-BF85F5CE5FE7}.Release|ARM64.ActiveCfg = Release|ARM64
{2CF0567E-1E00-4E3F-1561-BF85F5CE5FE7}.Release|ARM64.Build.0 = Release|ARM64
{2CF0567E-1E00-4E3F-1561-BF85F5CE5FE7}.Release|x64.ActiveCfg = Release|x64
{2CF0567E-1E00-4E3F-1561-BF85F5CE5FE7}.Release|x64.Build.0 = Release|x64
{790247CB-2B95-E139-E933-09D10137EEAF}.Debug|ARM64.ActiveCfg = Debug|ARM64
{790247CB-2B95-E139-E933-09D10137EEAF}.Debug|ARM64.Build.0 = Debug|ARM64
{790247CB-2B95-E139-E933-09D10137EEAF}.Debug|x64.ActiveCfg = Debug|x64
{790247CB-2B95-E139-E933-09D10137EEAF}.Debug|x64.Build.0 = Debug|x64
{790247CB-2B95-E139-E933-09D10137EEAF}.Release|ARM64.ActiveCfg = Release|ARM64
{790247CB-2B95-E139-E933-09D10137EEAF}.Release|ARM64.Build.0 = Release|ARM64
{790247CB-2B95-E139-E933-09D10137EEAF}.Release|x64.ActiveCfg = Release|x64
{790247CB-2B95-E139-E933-09D10137EEAF}.Release|x64.Build.0 = Release|x64
{18525614-CDB2-8BBE-B1B4-3812CD990C22}.Debug|ARM64.ActiveCfg = Debug|ARM64
{18525614-CDB2-8BBE-B1B4-3812CD990C22}.Debug|ARM64.Build.0 = Debug|ARM64
{18525614-CDB2-8BBE-B1B4-3812CD990C22}.Debug|x64.ActiveCfg = Debug|x64
{18525614-CDB2-8BBE-B1B4-3812CD990C22}.Debug|x64.Build.0 = Debug|x64
{18525614-CDB2-8BBE-B1B4-3812CD990C22}.Release|ARM64.ActiveCfg = Release|ARM64
{18525614-CDB2-8BBE-B1B4-3812CD990C22}.Release|ARM64.Build.0 = Release|ARM64
{18525614-CDB2-8BBE-B1B4-3812CD990C22}.Release|x64.ActiveCfg = Release|x64
{18525614-CDB2-8BBE-B1B4-3812CD990C22}.Release|x64.Build.0 = Release|x64
{B0FE6EF3-5FB3-B8DC-7507-008BBB392FD8}.Debug|ARM64.ActiveCfg = Debug|ARM64
{B0FE6EF3-5FB3-B8DC-7507-008BBB392FD8}.Debug|ARM64.Build.0 = Debug|ARM64
{B0FE6EF3-5FB3-B8DC-7507-008BBB392FD8}.Debug|x64.ActiveCfg = Debug|x64
{B0FE6EF3-5FB3-B8DC-7507-008BBB392FD8}.Debug|x64.Build.0 = Debug|x64
{B0FE6EF3-5FB3-B8DC-7507-008BBB392FD8}.Release|ARM64.ActiveCfg = Release|ARM64
{B0FE6EF3-5FB3-B8DC-7507-008BBB392FD8}.Release|ARM64.Build.0 = Release|ARM64
{B0FE6EF3-5FB3-B8DC-7507-008BBB392FD8}.Release|x64.ActiveCfg = Release|x64
{B0FE6EF3-5FB3-B8DC-7507-008BBB392FD8}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -2838,26 +2805,26 @@ Global
{3BB8493E-D18E-4485-A320-CB40F90F55AE} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
{D1D6BC88-09AE-4FB4-AD24-5DED46A791DD} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
{F9C68EDF-AC74-4B77-9AF1-005D9C9F6A99} = {D1D6BC88-09AE-4FB4-AD24-5DED46A791DD}
{9C6A7905-72D4-4BF5-B256-ABFDAEF68AE9} = {264B412F-DB8B-4CF8-A74B-96998B183045}
{9C6A7905-72D4-4BF5-B256-ABFDAEF68AE9} = {D1D6BC88-09AE-4FB4-AD24-5DED46A791DD}
{1A066C63-64B3-45F8-92FE-664E1CCE8077} = {1AFB6476-670D-4E80-A464-657E01DFF482}
{5CCC8468-DEC8-4D36-99D4-5C891BEBD481} = {D1D6BC88-09AE-4FB4-AD24-5DED46A791DD}
{89E20BCE-EB9C-46C8-8B50-E01A82E6FDC3} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
{B25AC7A5-FB9F-4789-B392-D5C85E948670} = {89E20BCE-EB9C-46C8-8B50-E01A82E6FDC3}
{51920F1F-C28C-4ADF-8660-4238766796C2} = {89E20BCE-EB9C-46C8-8B50-E01A82E6FDC3}
{A3935CF4-46C5-4A88-84D3-6B12E16E6BA2} = {89E20BCE-EB9C-46C8-8B50-E01A82E6FDC3}
{2151F984-E006-4A9F-92EF-C6DDE3DC8413} = {66E1534A-1587-42B2-912F-45C994D32904}
{2151F984-E006-4A9F-92EF-C6DDE3DC8413} = {89E20BCE-EB9C-46C8-8B50-E01A82E6FDC3}
{89F34AF7-1C34-4A72-AA6E-534BCF972BD9} = {38BDB927-829B-4C65-9CD9-93FB05D66D65}
{6C7F47CC-2151-44A3-A546-41C70025132C} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
{2BE46397-4DFA-414C-9BD4-41E4BBF8CB34} = {6C7F47CC-2151-44A3-A546-41C70025132C}
{0B43679E-EDFA-4DA0-AD30-F4628B308B1B} = {6C7F47CC-2151-44A3-A546-41C70025132C}
{E0CC7526-D85E-43AC-844F-D5DF0D2F5AB8} = {0E556541-6A45-42CB-AE49-EE5A9BE05E7C}
{E0CC7526-D85E-43AC-844F-D5DF0D2F5AB8} = {6C7F47CC-2151-44A3-A546-41C70025132C}
{17DA04DF-E393-4397-9CF0-84DABE11032E} = {1AFB6476-670D-4E80-A464-657E01DFF482}
{38BDB927-829B-4C65-9CD9-93FB05D66D65} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
{8AFFA899-0B73-49EC-8C50-0FADDA57B2FC} = {38BDB927-829B-4C65-9CD9-93FB05D66D65}
{C140A3EF-6DBF-4084-9D4C-4EB5A99FEE68} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
{4FD29318-A8AB-4D8F-AA47-60BC241B8DA3} = {C140A3EF-6DBF-4084-9D4C-4EB5A99FEE68}
{8451ECDD-2EA4-4966-BB0A-7BBC40138E80} = {C140A3EF-6DBF-4084-9D4C-4EB5A99FEE68}
{FF742965-9A80-41A5-B042-D6C7D3A21708} = {B9617A31-0F0A-4397-851D-BF2FBEE32D7F}
{FF742965-9A80-41A5-B042-D6C7D3A21708} = {C140A3EF-6DBF-4084-9D4C-4EB5A99FEE68}
{4AFC9975-2456-4C70-94A4-84073C1CED93} = {C140A3EF-6DBF-4084-9D4C-4EB5A99FEE68}
{59BD9891-3837-438A-958D-ADC7F91F6F7E} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
{4D971245-7A70-41D5-BAA0-DDB5684CAF51} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
@@ -2870,29 +2837,31 @@ Global
{2F305555-C296-497E-AC20-5FA1B237996A} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
{AF2349B8-E5B6-4004-9502-687C1C7730B1} = {2F305555-C296-497E-AC20-5FA1B237996A}
{6A71162E-FC4C-4A2C-B90F-3CF94F59A9BB} = {2F305555-C296-497E-AC20-5FA1B237996A}
{A2B51B8B-8F90-424E-BC97-F9AB7D76CA1A} = {6B01F1CF-F4DB-48B5-BFE7-0BF576C1D704}
{A2B51B8B-8F90-424E-BC97-F9AB7D76CA1A} = {2F305555-C296-497E-AC20-5FA1B237996A}
{DA425894-6E13-404F-8DCB-78584EC0557A} = {2F305555-C296-497E-AC20-5FA1B237996A}
{060D75DA-2D1C-48E6-A4A1-6F0718B64661} = {6B01F1CF-F4DB-48B5-BFE7-0BF576C1D704}
{748417CA-F17E-487F-9411-CAFB6D3F4877} = {6B01F1CF-F4DB-48B5-BFE7-0BF576C1D704}
{060D75DA-2D1C-48E6-A4A1-6F0718B64661} = {2F305555-C296-497E-AC20-5FA1B237996A}
{748417CA-F17E-487F-9411-CAFB6D3F4877} = {2F305555-C296-497E-AC20-5FA1B237996A}
{217DF501-135C-4E38-BFC8-99D4821032EA} = {2F305555-C296-497E-AC20-5FA1B237996A}
{B1BCC8C6-46B5-4BFA-8F22-20F32D99EC6A} = {C3081D9A-1586-441A-B5F4-ED815B3719C1}
{787B8AA6-CA93-4C84-96FE-DF31110AD1C4} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
{08C8C05F-0362-41BC-818C-724572DF8B06} = {C140A3EF-6DBF-4084-9D4C-4EB5A99FEE68}
{5D00D290-4016-4CFE-9E41-1E7C724509BA} = {1AFB6476-670D-4E80-A464-657E01DFF482}
{4AED67B6-55FD-486F-B917-E543DEE2CB3C} = {1AFB6476-670D-4E80-A464-657E01DFF482}
{42851751-CBC8-45A6-97F5-7A0753F7B4D1} = {B9617A31-0F0A-4397-851D-BF2FBEE32D7F}
{1EF1EEF0-10F0-4F2E-8550-39B6D8044D3E} = {6B01F1CF-F4DB-48B5-BFE7-0BF576C1D704}
{42851751-CBC8-45A6-97F5-7A0753F7B4D1} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
{1EF1EEF0-10F0-4F2E-8550-39B6D8044D3E} = {2F305555-C296-497E-AC20-5FA1B237996A}
{8FFE09DA-FA4F-4EE1-B3A2-AD5497FBD1AD} = {2F305555-C296-497E-AC20-5FA1B237996A}
{655C9AF2-18D3-4DA6-80E4-85504A7722BA} = {1D78B84B-CA39-406C-98F4-71F7EC266CC0}
{BA58206B-1493-4C75-BFEA-A85768A1E156} = {1D78B84B-CA39-406C-98F4-71F7EC266CC0}
{1D78B84B-CA39-406C-98F4-71F7EC266CC0} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
{03276A39-D4E9-417C-8FFD-200B0EE5E871} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
{B81FB7B6-D30E-428F-908A-41422EFC1172} = {B9617A31-0F0A-4397-851D-BF2FBEE32D7F}
{0F85E674-34AE-443D-954C-8321EB8B93B1} = {E885E71F-0B34-4A03-B13B-20F4E05E90BB}
{632BBE62-5421-49EA-835A-7FFA4F499BD6} = {B9617A31-0F0A-4397-851D-BF2FBEE32D7F}
{B81FB7B6-D30E-428F-908A-41422EFC1172} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
{0F85E674-34AE-443D-954C-8321EB8B93B1} = {C3081D9A-1586-441A-B5F4-ED815B3719C1}
{632BBE62-5421-49EA-835A-7FFA4F499BD6} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
{4FA206A5-F69F-4193-BF8F-F6EEB496734C} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
{090CD7B7-3B0C-4D1D-BC98-83EB5D799BC1} = {1D78B84B-CA39-406C-98F4-71F7EC266CC0}
{7E1E3F13-2BD6-3F75-A6A7-873A2B55C60F} = {E4E03FE0-94FD-47C7-88C5-F17D0AA549D3}
{FD8EB419-FF9C-4D88-BB6F-BF6CED37747B} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
{DA5A6FE9-0040-40CC-83CC-764AE5306590} = {B9617A31-0F0A-4397-851D-BF2FBEE32D7F}
{DA5A6FE9-0040-40CC-83CC-764AE5306590} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
{0351ADA4-0C32-4652-9BA0-41F7B602372B} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
{D9B8FC84-322A-4F9F-BBB9-20915C47DDFD} = {E4E03FE0-94FD-47C7-88C5-F17D0AA549D3}
{6955446D-23F7-4023-9BB3-8657F904AF99} = {1AFB6476-670D-4E80-A464-657E01DFF482}
@@ -2911,20 +2880,20 @@ Global
{8F62026A-294B-41C6-8839-87463613F216} = {1AFB6476-670D-4E80-A464-657E01DFF482}
{C3A17DCA-217B-462C-BB0C-BE086AF80081} = {1AFB6476-670D-4E80-A464-657E01DFF482}
{69E1EE8D-143A-4060-9129-4658ACF14AAF} = {2F305555-C296-497E-AC20-5FA1B237996A}
{ECC20689-002A-4354-95A6-B58DF089C6FF} = {6B01F1CF-F4DB-48B5-BFE7-0BF576C1D704}
{ECC20689-002A-4354-95A6-B58DF089C6FF} = {2F305555-C296-497E-AC20-5FA1B237996A}
{4BABF3FE-3451-42FD-873F-3C332E18DCEF} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
{0648DF05-5DDA-4BE1-B5F2-584926EBDB65} = {B9617A31-0F0A-4397-851D-BF2FBEE32D7F}
{0648DF05-5DDA-4BE1-B5F2-584926EBDB65} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
{BA661F5B-1D5A-4FFC-9BF1-FC39DF280BDD} = {38BDB927-829B-4C65-9CD9-93FB05D66D65}
{E496B7FC-1E99-4BAB-849B-0E8367040B02} = {38BDB927-829B-4C65-9CD9-93FB05D66D65}
{7F4B3A60-BC27-45A7-8000-68B0B6EA7466} = {D9BD324E-1D80-44AA-8E7B-73EB00944434}
{7F4B3A60-BC27-45A7-8000-68B0B6EA7466} = {38BDB927-829B-4C65-9CD9-93FB05D66D65}
{8DF78B53-200E-451F-9328-01EB907193AE} = {38BDB927-829B-4C65-9CD9-93FB05D66D65}
{23D2070D-E4AD-4ADD-85A7-083D9C76AD49} = {38BDB927-829B-4C65-9CD9-93FB05D66D65}
{62173D9A-6724-4C00-A1C8-FB646480A9EC} = {D9BD324E-1D80-44AA-8E7B-73EB00944434}
{62173D9A-6724-4C00-A1C8-FB646480A9EC} = {38BDB927-829B-4C65-9CD9-93FB05D66D65}
{127F38E0-40AA-4594-B955-5616BF206882} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
{5E7360A8-D048-4ED3-8F09-0BFD64C5529A} = {127F38E0-40AA-4594-B955-5616BF206882}
{D940E07F-532C-4FF3-883F-790DA014F19A} = {127F38E0-40AA-4594-B955-5616BF206882}
{BB23A474-5058-4F75-8FA3-5FE3DE53CDF4} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
{3E424AD2-19E5-4AE6-B833-F53963EB5FC1} = {B9617A31-0F0A-4397-851D-BF2FBEE32D7F}
{3E424AD2-19E5-4AE6-B833-F53963EB5FC1} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
{106CBECA-0701-4FC3-838C-9DF816A19AE2} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
{2D604C07-51FC-46BB-9EB7-75AECC7F5E81} = {106CBECA-0701-4FC3-838C-9DF816A19AE2}
{2EDB3EB4-FA92-4BFF-B2D8-566584837231} = {106CBECA-0701-4FC3-838C-9DF816A19AE2}
@@ -2932,27 +2901,27 @@ Global
{FF1D7936-842A-4BBB-8BEA-E9FE796DE700} = {D1D6BC88-09AE-4FB4-AD24-5DED46A791DD}
{5043CECE-E6A7-4867-9CBE-02D27D83747A} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
{11491FD8-F921-48BF-880C-7FEA185B80A1} = {2F305555-C296-497E-AC20-5FA1B237996A}
{F40C3397-1834-4530-B2D9-8F8B8456BCDF} = {6B01F1CF-F4DB-48B5-BFE7-0BF576C1D704}
{F40C3397-1834-4530-B2D9-8F8B8456BCDF} = {2F305555-C296-497E-AC20-5FA1B237996A}
{A2D583F0-B70C-4462-B1F0-8E81AFB7BA85} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
{4ED320BC-BA04-4D42-8D15-CBE62151F08B} = {B9617A31-0F0A-4397-851D-BF2FBEE32D7F}
{4ED320BC-BA04-4D42-8D15-CBE62151F08B} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
{322566EF-20DC-43A6-B9F8-616AF942579A} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
{E94FD11C-0591-456F-899F-EFC0CA548336} = {322566EF-20DC-43A6-B9F8-616AF942579A}
{782A61BE-9D85-4081-B35C-1CCC9DCC1E88} = {322566EF-20DC-43A6-B9F8-616AF942579A}
{809AA252-E17A-4FA2-B0A1-0450976B763F} = {2F305555-C296-497E-AC20-5FA1B237996A}
{133281D8-1BCE-4D07-B31E-796612A9609E} = {6B01F1CF-F4DB-48B5-BFE7-0BF576C1D704}
{133281D8-1BCE-4D07-B31E-796612A9609E} = {2F305555-C296-497E-AC20-5FA1B237996A}
{805306FF-A562-4415-8DEF-E493BDC45918} = {2F305555-C296-497E-AC20-5FA1B237996A}
{FCF3E52D-B80A-4FC3-98FD-6391354F0EE3} = {6B01F1CF-F4DB-48B5-BFE7-0BF576C1D704}
{FCF3E52D-B80A-4FC3-98FD-6391354F0EE3} = {2F305555-C296-497E-AC20-5FA1B237996A}
{60CD2D4F-C3B9-4897-9821-FCA5098B41CE} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
{1DC3BE92-CE89-43FB-8110-9C043A2FE7A2} = {60CD2D4F-C3B9-4897-9821-FCA5098B41CE}
{48A0A19E-A0BE-4256-ACF8-CC3B80291AF9} = {60CD2D4F-C3B9-4897-9821-FCA5098B41CE}
{9F94B303-5E21-4364-9362-64426F8DB932} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
{EAE14C0E-7A6B-45DA-9080-A7D8C077BA6E} = {322566EF-20DC-43A6-B9F8-616AF942579A}
{F7C8C0F1-5431-4347-89D0-8E5354F93CF2} = {2F305555-C296-497E-AC20-5FA1B237996A}
{F1F6B6B6-9F18-4A17-8B5C-97DF552C53DC} = {6B01F1CF-F4DB-48B5-BFE7-0BF576C1D704}
{F1F6B6B6-9F18-4A17-8B5C-97DF552C53DC} = {2F305555-C296-497E-AC20-5FA1B237996A}
{04B193D7-3E21-46B8-A958-89B63A8A69DE} = {2F305555-C296-497E-AC20-5FA1B237996A}
{5BDBD6C9-A31F-4CEB-871A-5E9E709197EF} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
{FD464B4C-2F68-4D06-91E7-4208146C41F5} = {B9617A31-0F0A-4397-851D-BF2FBEE32D7F}
{8FE5A5EE-1B59-401C-9FB3-B04ECD3E29C1} = {B9617A31-0F0A-4397-851D-BF2FBEE32D7F}
{FD464B4C-2F68-4D06-91E7-4208146C41F5} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
{8FE5A5EE-1B59-401C-9FB3-B04ECD3E29C1} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
{020A7474-3601-4160-A159-D7B70B77B15F} = {C3081D9A-1586-441A-B5F4-ED815B3719C1}
{27718999-C175-450A-861C-89F911E16A88} = {89E20BCE-EB9C-46C8-8B50-E01A82E6FDC3}
{1DBBB112-4BB1-444B-8EBB-E66555C76BA6} = {89E20BCE-EB9C-46C8-8B50-E01A82E6FDC3}
@@ -2966,7 +2935,6 @@ Global
{A50C70A6-2DA0-4027-B90E-B1A40755A8A5} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
{25C91A4E-BA4E-467A-85CD-8B62545BF674} = {A50C70A6-2DA0-4027-B90E-B1A40755A8A5}
{6AB6A2D6-F859-4A82-9184-0BD29C9F07D1} = {A50C70A6-2DA0-4027-B90E-B1A40755A8A5}
{B1234567-1234-1234-1234-123456789ABC} = {A50C70A6-2DA0-4027-B90E-B1A40755A8A5}
{212AD910-8488-4036-BE20-326931B75FB2} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
{7AC943C9-52E8-44CF-9083-744D8049667B} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
{54A93AF7-60C7-4F6C-99D2-FBB1F75F853A} = {7AC943C9-52E8-44CF-9083-744D8049667B}
@@ -2975,7 +2943,7 @@ Global
{C97D9A5D-206C-454E-997E-009E227D7F02} = {0F14491C-6369-4C45-AAA8-135814E66E6B}
{31D1C81D-765F-4446-AA62-E743F6325049} = {F05E590D-AD46-42BE-9C25-6A63ADD2E3EA}
{F05E590D-AD46-42BE-9C25-6A63ADD2E3EA} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
{E2D03E0F-7A75-4813-9F4B-D8763D43FD3A} = {1C48CD47-D610-463A-A53C-AF82DD6C47E7}
{E2D03E0F-7A75-4813-9F4B-D8763D43FD3A} = {F05E590D-AD46-42BE-9C25-6A63ADD2E3EA}
{B41B888C-7DB8-4747-B262-4062E05A230D} = {F05E590D-AD46-42BE-9C25-6A63ADD2E3EA}
{AB82E5DD-C32D-4F28-9746-2C780846188E} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
{57175EC7-92A5-4C1E-8244-E3FBCA2A81DE} = {AB82E5DD-C32D-4F28-9746-2C780846188E}
@@ -3004,7 +2972,7 @@ Global
{A663E672-B26D-4EC0-BEAB-FE2E424AC46F} = {B6C42F16-73EB-477E-8B0D-4E6CF6C20AAC}
{8A08D663-4995-40E3-B42C-3F910625F284} = {322566EF-20DC-43A6-B9F8-616AF942579A}
{923DF87C-CA99-4D1C-B1D2-959174E95BFA} = {322566EF-20DC-43A6-B9F8-616AF942579A}
{D5E42C63-57C5-4EF6-AECE-1E2FCA725B77} = {2C318EC3-BA86-4372-B1BC-DB0F33C208B2}
{D5E42C63-57C5-4EF6-AECE-1E2FCA725B77} = {322566EF-20DC-43A6-B9F8-616AF942579A}
{D962A009-834F-4EEC-AABB-430DF8F98E39} = {322566EF-20DC-43A6-B9F8-616AF942579A}
{9873BA05-4C41-4819-9283-CF45D795431B} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
{FC373B24-3293-453C-AAF5-CF2909DCEE6A} = {9873BA05-4C41-4819-9283-CF45D795431B}
@@ -3015,11 +2983,12 @@ Global
{9EBAA524-0EDA-470B-95D4-39383285CBB2} = {1AFB6476-670D-4E80-A464-657E01DFF482}
{500DED3E-CFB5-4ED5-ACC6-02B3D6DC336D} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
{D095BE44-1F2E-463E-A494-121892A75EA2} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
{90F9FA90-2C20-4004-96E6-F3B78151F5A5} = {B9617A31-0F0A-4397-851D-BF2FBEE32D7F}
{90F9FA90-2C20-4004-96E6-F3B78151F5A5} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
{3B227528-4BA6-4CAF-B44A-A10C78A64849} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
{F5E1146E-B7B3-4E11-85FD-270A500BD78C} = {3B227528-4BA6-4CAF-B44A-A10C78A64849}
{3157FA75-86CF-4EE2-8F62-C43F776493C6} = {3B227528-4BA6-4CAF-B44A-A10C78A64849}
{4C0D0746-BE5B-49EE-BD5D-A7811628AE8B} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
{FC8EB78F-F061-4BD9-A3F6-507BEA965E2B} = {D1D6BC88-09AE-4FB4-AD24-5DED46A791DD}
{538ED0BB-B863-4B20-98CC-BCDF7FA0B68A} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
{51465DA1-C18B-4B99-93E1-ECF8E0FA0CBA} = {538ED0BB-B863-4B20-98CC-BCDF7FA0B68A}
{B9420661-B0E4-4241-ABD4-4A27A1F64250} = {538ED0BB-B863-4B20-98CC-BCDF7FA0B68A}
@@ -3027,8 +2996,8 @@ Global
{D949EC7D-48A9-4279-95D5-078E7FD1F048} = {2F305555-C296-497E-AC20-5FA1B237996A}
{3BAF9C81-A194-4925-A035-5E24A5D1E542} = {2F305555-C296-497E-AC20-5FA1B237996A}
{6B04803D-B418-4833-A67E-B0FC966636A5} = {2F305555-C296-497E-AC20-5FA1B237996A}
{3940AD4D-F748-4BE4-9083-85769CD553EF} = {6B01F1CF-F4DB-48B5-BFE7-0BF576C1D704}
{F8FFFC12-A31A-4AFA-B3DF-14DCF42B5E38} = {6B01F1CF-F4DB-48B5-BFE7-0BF576C1D704}
{3940AD4D-F748-4BE4-9083-85769CD553EF} = {2F305555-C296-497E-AC20-5FA1B237996A}
{F8FFFC12-A31A-4AFA-B3DF-14DCF42B5E38} = {2F305555-C296-497E-AC20-5FA1B237996A}
{0014D652-901F-4456-8D65-06FC5F997FB0} = {4C0D0746-BE5B-49EE-BD5D-A7811628AE8B}
{799A50D8-DE89-4ED1-8FF8-AD5A9ED8C0CA} = {AB82E5DD-C32D-4F28-9746-2C780846188E}
{9D52FD25-EF90-4F9A-A015-91EFC5DAF54F} = {AB82E5DD-C32D-4F28-9746-2C780846188E}
@@ -3036,6 +3005,8 @@ Global
{02DD46D3-F761-47D9-8894-2D6DA0124650} = {F05E590D-AD46-42BE-9C25-6A63ADD2E3EA}
{8E23E173-7127-4A5F-9F93-3049F2B68047} = {929C1324-22E8-4412-A9A8-80E85F3985A5}
{DFF88D16-D36F-40A4-A955-CDCAA76EF7B8} = {538ED0BB-B863-4B20-98CC-BCDF7FA0B68A}
{FE38FC07-1C05-4B57-ADA3-2FE2F53C6A52} = {D1D6BC88-09AE-4FB4-AD24-5DED46A791DD}
{3A9A791E-94A9-49F8-8401-C11CE288D5FB} = {D1D6BC88-09AE-4FB4-AD24-5DED46A791DD}
{C0974915-8A1D-4BF0-977B-9587D3807AB7} = {D1D6BC88-09AE-4FB4-AD24-5DED46A791DD}
{1D6893CB-BC0C-46A8-A76C-9728706CA51A} = {557C4636-D7E1-4838-A504-7D19B725EE95}
{8ACB33D9-C95B-47D4-8363-9731EE0930A0} = {CA716AE6-FE5C-40AC-BB8F-2C87912687AC}
@@ -3045,7 +3016,7 @@ Global
{BE126CBB-AE12-406A-9837-A05ACFCA57A7} = {A2221D7E-55E7-4BEA-90D1-4F162D670BBF}
{14CB58B7-D280-4A7A-95DE-4B2DF14EA000} = {A2221D7E-55E7-4BEA-90D1-4F162D670BBF}
{B31FCC55-B5A4-4EA7-B414-2DCEAE6AF332} = {A2221D7E-55E7-4BEA-90D1-4F162D670BBF}
{A85D4D9F-9A39-4B5D-8B5A-9F2D5C9A8B4C} = {68328142-5B31-4715-BCBB-7B6345EE0971}
{A85D4D9F-9A39-4B5D-8B5A-9F2D5C9A8B4C} = {A2221D7E-55E7-4BEA-90D1-4F162D670BBF}
{9C53CC25-0623-4569-95BC-B05410675EE3} = {A2221D7E-55E7-4BEA-90D1-4F162D670BBF}
{45285DF2-9742-4ECA-9AC9-58951FC26489} = {A2221D7E-55E7-4BEA-90D1-4F162D670BBF}
{3D63307B-9D27-44FD-B033-B26F39245B85} = {A2221D7E-55E7-4BEA-90D1-4F162D670BBF}
@@ -3053,7 +3024,7 @@ Global
{2CAC093E-5FCF-4102-9C2C-AC7DD5D9EB96} = {A2221D7E-55E7-4BEA-90D1-4F162D670BBF}
{37D07516-4185-43A4-924F-3C7A5D95ECF6} = {A2221D7E-55E7-4BEA-90D1-4F162D670BBF}
{8F021B46-362B-485C-BFBA-CCF83E820CBD} = {8F62026A-294B-41C6-8839-87463613F216}
{66614C26-314C-4B91-9071-76133422CFEF} = {BFFB607F-7C78-434B-86B9-DA4C8196A1B5}
{66614C26-314C-4B91-9071-76133422CFEF} = {B6C42F16-73EB-477E-8B0D-4E6CF6C20AAC}
{3846508C-77EB-4034-A702-F8BB263C4F79} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
{ECB8E0D1-7603-4E5C-AB10-D1E545E6F8E2} = {3846508C-77EB-4034-A702-F8BB263C4F79}
{6CE438DF-C245-4997-A360-0A0939E4BA34} = {ECB8E0D1-7603-4E5C-AB10-D1E545E6F8E2}
@@ -3083,6 +3054,8 @@ Global
{3A9A7297-92C4-4F16-B6F9-8D4AB652C86C} = {ECB8E0D1-7603-4E5C-AB10-D1E545E6F8E2}
{605E914B-7232-4789-AF46-BF5D3DDFC14E} = {ECB8E0D1-7603-4E5C-AB10-D1E545E6F8E2}
{E81A7D20-9862-ABDB-0AAE-9BC5B517A9F9} = {ECB8E0D1-7603-4E5C-AB10-D1E545E6F8E2}
{D5E5F5EA-1B6C-4A73-88BE-304F36C9E4EE} = {9873BA05-4C41-4819-9283-CF45D795431B}
{7F5B9557-5878-4438-A721-3E28296BA193} = {9873BA05-4C41-4819-9283-CF45D795431B}
{DD6E12FE-5509-4ABC-ACC2-3D6DC98A238C} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
{0A84F764-3A88-44CD-AA96-41BDBD48627B} = {DD6E12FE-5509-4ABC-ACC2-3D6DC98A238C}
{E4585179-2AC1-4D5F-A3FF-CFC5392F694C} = {DD6E12FE-5509-4ABC-ACC2-3D6DC98A238C}
@@ -3091,54 +3064,33 @@ Global
{A558C25D-2007-498E-8B6F-43405AFAE9E2} = {1AFB6476-670D-4E80-A464-657E01DFF482}
{08F9155D-B6DC-46E5-9C83-AF60B655898B} = {38BDB927-829B-4C65-9CD9-93FB05D66D65}
{4382A954-179A-4078-92AF-715187DFFF50} = {38BDB927-829B-4C65-9CD9-93FB05D66D65}
{EBED240C-8702-452D-B764-6DB9DA9179AF} = {1C48CD47-D610-463A-A53C-AF82DD6C47E7}
{4E0AE3A4-2EE0-44D7-A2D0-8769977254A0} = {1C48CD47-D610-463A-A53C-AF82DD6C47E7}
{5702B3CC-8575-48D5-83D8-15BB42269CD3} = {8131151D-B0E9-4E18-84A5-E5F946C4480A}
{EBED240C-8702-452D-B764-6DB9DA9179AF} = {F05E590D-AD46-42BE-9C25-6A63ADD2E3EA}
{4E0AE3A4-2EE0-44D7-A2D0-8769977254A0} = {F05E590D-AD46-42BE-9C25-6A63ADD2E3EA}
{5702B3CC-8575-48D5-83D8-15BB42269CD3} = {929C1324-22E8-4412-A9A8-80E85F3985A5}
{64B88F02-CD88-4ED8-9624-989A800230F9} = {ECB8E0D1-7603-4E5C-AB10-D1E545E6F8E2}
{0217E86E-3476-9946-DE8E-9D200CEBD47A} = {D1D6BC88-09AE-4FB4-AD24-5DED46A791DD}
{5F63C743-F6CE-4DBA-A200-2B3F8A14E8C2} = {3846508C-77EB-4034-A702-F8BB263C4F79}
{2694E2FB-DCD5-4BFF-A418-B6C3C7CE3B8E} = {66E1534A-1587-42B2-912F-45C994D32904}
{2694E2FB-DCD5-4BFF-A418-B6C3C7CE3B8E} = {89E20BCE-EB9C-46C8-8B50-E01A82E6FDC3}
{9E0CBC06-F29A-4810-B93C-97D53863B95E} = {2F305555-C296-497E-AC20-5FA1B237996A}
{F6088A11-1C9E-4420-AA90-CF7E78DD7F1C} = {2F305555-C296-497E-AC20-5FA1B237996A}
{47B0678C-806B-4FE1-9F50-46BA88989532} = {2F305555-C296-497E-AC20-5FA1B237996A}
{9BC1C986-1E97-4D07-A7B1-CE226C239EFA} = {2F305555-C296-497E-AC20-5FA1B237996A}
{99CA1509-FB73-456E-AFAF-AB89C017BD72} = {6B01F1CF-F4DB-48B5-BFE7-0BF576C1D704}
{61CBF221-9452-4934-B685-146285E080D7} = {6B01F1CF-F4DB-48B5-BFE7-0BF576C1D704}
{4E0AE3A4-2EE0-44D7-A2D0-8769977254A1} = {2C318EC3-BA86-4372-B1BC-DB0F33C208B2}
{43E779F3-D83C-48B1-BA8D-1912DBD76FC9} = {68328142-5B31-4715-BCBB-7B6345EE0971}
{99CA1509-FB73-456E-AFAF-AB89C017BD72} = {2F305555-C296-497E-AC20-5FA1B237996A}
{61CBF221-9452-4934-B685-146285E080D7} = {2F305555-C296-497E-AC20-5FA1B237996A}
{4E0AE3A4-2EE0-44D7-A2D0-8769977254A1} = {322566EF-20DC-43A6-B9F8-616AF942579A}
{43E779F3-D83C-48B1-BA8D-1912DBD76FC9} = {A2221D7E-55E7-4BEA-90D1-4F162D670BBF}
{2CF78CF7-8FEB-4BE1-9591-55FA25B48FC6} = {1AFB6476-670D-4E80-A464-657E01DFF482}
{14AFD976-B4D2-49D0-9E6C-AA93CC061B8A} = {1AFB6476-670D-4E80-A464-657E01DFF482}
{9D3F3793-EFE3-4525-8782-238015DABA62} = {66E1534A-1587-42B2-912F-45C994D32904}
{02EA681E-C7D8-13C7-8484-4AC65E1B71E8} = {3846508C-77EB-4034-A702-F8BB263C4F79}
{24133F7F-C1D1-DE04-EFA8-F5D5467FE027} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
{0E556541-6A45-42CB-AE49-EE5A9BE05E7C} = {6C7F47CC-2151-44A3-A546-41C70025132C}
{27D9CB3A-46D1-402C-9273-F88CB8AC42F7} = {9873BA05-4C41-4819-9283-CF45D795431B}
{B9617A31-0F0A-4397-851D-BF2FBEE32D7F} = {C140A3EF-6DBF-4084-9D4C-4EB5A99FEE68}
{1C48CD47-D610-463A-A53C-AF82DD6C47E7} = {F05E590D-AD46-42BE-9C25-6A63ADD2E3EA}
{D9BD324E-1D80-44AA-8E7B-73EB00944434} = {38BDB927-829B-4C65-9CD9-93FB05D66D65}
{8EF25507-2575-4ADE-BF7E-D23376903AB8} = {3846508C-77EB-4034-A702-F8BB263C4F79}
{070AC093-C9F2-20AD-0BCD-F318FC2761EA} = {B1234567-1234-1234-1234-123456789ABC}
{E816D7AC-4688-4ECB-97CC-3D8E798F3825} = {8EF25507-2575-4ADE-BF7E-D23376903AB8}
{E816D7AD-4688-4ECB-97CC-3D8E798F3826} = {8EF25507-2575-4ADE-BF7E-D23376903AB8}
{E816D7AE-4688-4ECB-97CC-3D8E798F3827} = {8EF25507-2575-4ADE-BF7E-D23376903AB8}
{E816D7AF-4688-4ECB-97CC-3D8E798F3828} = {8EF25507-2575-4ADE-BF7E-D23376903AB8}
{E816D7B0-4688-4ECB-97CC-3D8E798F3829} = {8EF25507-2575-4ADE-BF7E-D23376903AB8}
{2C318EC3-BA86-4372-B1BC-DB0F33C208B2} = {322566EF-20DC-43A6-B9F8-616AF942579A}
{BFFB607F-7C78-434B-86B9-DA4C8196A1B5} = {B6C42F16-73EB-477E-8B0D-4E6CF6C20AAC}
{66E1534A-1587-42B2-912F-45C994D32904} = {89E20BCE-EB9C-46C8-8B50-E01A82E6FDC3}
{E885E71F-0B34-4A03-B13B-20F4E05E90BB} = {C3081D9A-1586-441A-B5F4-ED815B3719C1}
{264B412F-DB8B-4CF8-A74B-96998B183045} = {D1D6BC88-09AE-4FB4-AD24-5DED46A791DD}
{3527BF37-DFC5-4309-A032-29278CA21328} = {1D78B84B-CA39-406C-98F4-71F7EC266CC0}
{6B01F1CF-F4DB-48B5-BFE7-0BF576C1D704} = {2F305555-C296-497E-AC20-5FA1B237996A}
{68328142-5B31-4715-BCBB-7B6345EE0971} = {A2221D7E-55E7-4BEA-90D1-4F162D670BBF}
{4122388B-59E4-CDB0-0338-EA6881DF86F0} = {27D9CB3A-46D1-402C-9273-F88CB8AC42F7}
{988C9FAF-5AEC-EB15-578D-FED0DF52BF55} = {27D9CB3A-46D1-402C-9273-F88CB8AC42F7}
{6748A29D-DA6A-033A-825B-752295FF6AA0} = {8EF25507-2575-4ADE-BF7E-D23376903AB8}
{6EABCF9A-6526-441F-932F-658B1DC3E403} = {264B412F-DB8B-4CF8-A74B-96998B183045}
{69D76A76-6EF6-4846-94CD-EAAF0CAC9F15} = {264B412F-DB8B-4CF8-A74B-96998B183045}
{9BAFFC28-E1EF-4C14-A101-EEBFC0A50D83} = {264B412F-DB8B-4CF8-A74B-96998B183045}
{806BF185-8B89-5BE1-9AA1-DA5BC9487DB9} = {264B412F-DB8B-4CF8-A74B-96998B183045}
{F93C2817-C846-4259-84D8-B39A6B57C8DE} = {3527BF37-DFC5-4309-A032-29278CA21328}
{8131151D-B0E9-4E18-84A5-E5F946C4480A} = {929C1324-22E8-4412-A9A8-80E85F3985A5}
{9D3F3793-EFE3-4525-8782-238015DABA62} = {89E20BCE-EB9C-46C8-8B50-E01A82E6FDC3}
{BCDC7246-F4F8-4EED-8DE6-037AA2E7C6D1} = {17B4FA70-001E-4D33-BBBB-0D142DBC2E20}
{840455DF-5634-51BB-D937-9D7D32F0B0C2} = {7520A2FE-00A2-49B8-83ED-DB216E874C04}
{15EA681E-C7D8-13C7-8484-4AC65E1B71E8} = {3846508C-77EB-4034-A702-F8BB263C4F79}
{2CF0567E-1E00-4E3F-1561-BF85F5CE5FE7} = {15EA681E-C7D8-13C7-8484-4AC65E1B71E8}
{790247CB-2B95-E139-E933-09D10137EEAF} = {15EA681E-C7D8-13C7-8484-4AC65E1B71E8}
{18525614-CDB2-8BBE-B1B4-3812CD990C22} = {15EA681E-C7D8-13C7-8484-4AC65E1B71E8}
{B0FE6EF3-5FB3-B8DC-7507-008BBB392FD8} = {15EA681E-C7D8-13C7-8484-4AC65E1B71E8}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {C3A2F9D1-7930-4EF4-A6FC-7EE0A99821D0}

View File

@@ -68,7 +68,7 @@ The PowerToys UI test pipeline provides flexible options for building and testin
- Pipeline: https://microsoft.visualstudio.com/Dart/_build?definitionId=161438&_a=summary
## How to add the first UI tests for your modules
- Follow the naming convention: ![{ModuleFolder}/Tests/{ModuleName}-{TestType(Fuzz/UI/Unit)}Tests](images/uitests/naming.png)
- Create a new project and add the following references to the project file. Change the OutputPath to your own module's path.
```
<Project Sdk="Microsoft.NET.Sdk">

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

View File

@@ -67,7 +67,10 @@ Once you've discussed your proposed feature/fix/etc. with a team member, and an
- When you'd like the team to take a look (even if the work is not yet fully complete) mark the PR as 'Ready For Review' so that the team can review your work and provide comments, suggestions, and request changes. It may take several cycles, but the end result will be solid, testable, conformant code that is safe for us to merge.
- When the PR is approved, let the owner of the PR merge it. For community contributions, the reviewer who approved the PR can also merge it.
- Use the `Squash and merge` option to merge a PR. If you don't want to squash it because there are logically different commits, use `Rebase and merge`.
- Close issues automatically when referenced in a PR. You can use [closing keywords](https://docs.github.com/en/issues/tracking-your-work-with-issues/using-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword) in the body of the PR to have GitHub automatically link your PR to the issue.
- We don't close issues automatically when referenced in a PR, so after the PR is merged:
- mark the issue(s) that the PR solved with the `Resolution-Fix-Committed` label, remove the `In progress` label and if the issue is assigned to a project, move the item to the `Done` status.
- don't close the issue if it's a bug in the current released version; since users tend to not search for closed issues, we will close the resolved issues when a new version is released.
- if it's not a code fix that effects the end user, the issue can be closed (for example a fix in the build or a code refactoring and so on).
## Compiling PowerToys

View File

@@ -24,16 +24,5 @@ namespace Microsoft.PowerToys.UITest
{
this.Find<NavigationViewItem>(value).Click();
}
/// <summary>
/// Select a text item from the ComboBox.
/// </summary>
/// <param name="value">The text to select from the ComboBox.</param>
public void SelectTxt(string value)
{
this.Click(); // First click to expand the ComboBox
Thread.Sleep(100); // Wait for the dropdown to appear
this.Find<Element>(value).Click(); // Find and click the text item using basic Element type
}
}
}

View File

@@ -1,38 +0,0 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace Microsoft.PowerToys.UITest
{
/// <summary>
/// Represents a radio button UI element in the application.
/// </summary>
public class RadioButton : Element
{
private static readonly string ExpectedControlType = "ControlType.RadioButton";
/// <summary>
/// Initializes a new instance of the <see cref="RadioButton"/> class.
/// </summary>
public RadioButton()
{
this.TargetControlType = RadioButton.ExpectedControlType;
}
/// <summary>
/// Gets a value indicating whether the RadioButton is selected.
/// </summary>
public bool IsSelected => this.Selected;
/// <summary>
/// Select the RadioButton.
/// </summary>
public void Select()
{
if (!this.IsSelected)
{
this.Click();
}
}
}
}

View File

@@ -7,7 +7,6 @@
<Keyword>Win32Proj</Keyword>
<RootNamespace>UnitTestsCommonLib</RootNamespace>
<ProjectSubType>NativeUnitTestProject</ProjectSubType>
<ProjectName>Common.Lib.UnitTests</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Label="Configuration">

View File

@@ -1,38 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<!-- Look at Directory.Build.props in root for common stuff as well -->
<Import Project="..\..\..\Common.Dotnet.CsWinRT.props" />
<PropertyGroup>
<ProjectGuid>{2B1505FA-132A-460B-B22B-7CC3FFAB0C5D}</ProjectGuid>
<RootNamespace>Microsoft.AdvancedPaste.UITests</RootNamespace>
<IsPackable>false</IsPackable>
<Nullable>enable</Nullable>
<OutputType>Library</OutputType>
<!-- This is a UI test, so don't run as part of MSBuild -->
<RunVSTest>false</RunVSTest>
</PropertyGroup>
<PropertyGroup>
<OutputPath>..\..\..\..\$(Platform)\$(Configuration)\tests\UITests-AdvancedPaste\</OutputPath>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Appium.WebDriver" />
<PackageReference Include="MSTest" />
<PackageReference Include="System.Net.Http" />
<PackageReference Include="System.Private.Uri" />
<PackageReference Include="System.Text.RegularExpressions" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\common\UITestAutomation\UITestAutomation.csproj" />
</ItemGroup>
<ItemGroup>
<Content Include="TestFiles\**\*.*">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
</Project>

View File

@@ -1,791 +0,0 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Diagnostics;
using System.Drawing;
using System.Globalization;
using System.IO;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;
using Microsoft.AdvancedPaste.UITests.Helper;
using Microsoft.CodeCoverage.Core.Reports.Coverage;
using Microsoft.PowerToys.UITest;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using Windows.ApplicationModel.DataTransfer;
using static System.Net.Mime.MediaTypeNames;
using static System.Resources.ResXFileRef;
using static System.Runtime.InteropServices.JavaScript.JSType;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.ToolTip;
namespace Microsoft.AdvancedPaste.UITests
{
[TestClass]
public class AdvancedPasteUITest : UITestBase
{
private readonly string testFilesFolderPath;
private readonly string tempRTFFileName = "TempFile.rtf";
private readonly string pasteAsPlainTextRawFileName = "PasteAsPlainTextFileRaw.rtf";
private readonly string pasteAsPlainTextPlainFileName = "PasteAsPlainTextFilePlain.rtf";
private readonly string pasteAsPlainTextPlainNoRepeatFileName = "PasteAsPlainTextFilePlainNoRepeat.rtf";
private readonly string wordpadPath = @"C:\Program Files\wordpad\wordpad.exe";
private readonly string tempTxtFileName = "TempFile.txt";
private readonly string pasteAsMarkdownSrcFile = "PasteAsMarkdownFile.html";
private readonly string pasteAsMarkdownResultFile = "PasteAsMarkdownResultFile.txt";
private readonly string pasteAsJsonFileName = "PasteAsJsonFile.xml";
private readonly string pasteAsJsonResultFile = "PasteAsJsonResultFile.txt";
private bool _notepadSettingsChanged;
// Static constructor - runs before any instance is created
static AdvancedPasteUITest()
{
// Using the predefined settings.
// paste as plain text: win + ctrl + alt + o
// paste as markdown text: win + ctrl + alt + m
// paste as json text: win + ctrl + alt + j
CopySettingsFileBeforeTests();
}
public AdvancedPasteUITest()
: base(PowerToysModule.PowerToysSettings, size: WindowSize.Small)
{
Type currentTestType = typeof(AdvancedPasteUITest);
string? dirName = Path.GetDirectoryName(currentTestType.Assembly.Location);
Assert.IsNotNull(dirName, "Failed to get directory name of the current test assembly.");
string testFilesFolder = Path.Combine(dirName, "TestFiles");
Assert.IsTrue(Directory.Exists(testFilesFolder), $"Test files directory not found at: {testFilesFolder}");
testFilesFolderPath = testFilesFolder;
// ignore the notepad settings in pipeline
_notepadSettingsChanged = true;
}
[TestInitialize]
public void TestInitialize()
{
Session.CloseMainWindow();
SendKeys(Key.Win, Key.M);
}
[TestMethod]
[TestCategory("AdvancedPasteUITest")]
[TestCategory("PasteAsPlainText")]
[Ignore("Temporarily disabled due to wordpad.exe is missing in pipeline.")]
public void TestCasePasteAsPlainText()
{
// Copy some rich text(e.g word of the text is different color, another work is bold, underlined, etd.).
// Paste the text using standard Windows Ctrl + V shortcut and ensure that rich text is pasted(with all colors, formatting, etc.)
DeleteAndCopyFile(pasteAsPlainTextRawFileName, tempRTFFileName);
ContentCopyAndPasteDirectly(tempRTFFileName, isRTF: true);
var resultWithFormatting = FileReader.CompareRtfFiles(
Path.Combine(testFilesFolderPath, tempRTFFileName),
Path.Combine(testFilesFolderPath, pasteAsPlainTextRawFileName),
compareFormatting: true);
Assert.IsTrue(resultWithFormatting.IsConsistent, "RTF files should be identical including formatting");
// Paste the text using Paste As Plain Text activation shortcut and ensure that plain text without any formatting is pasted.
// Paste again the text using standard Windows Ctrl + V shortcut and ensure the text is now pasted plain without formatting as well.
DeleteAndCopyFile(pasteAsPlainTextRawFileName, tempRTFFileName);
ContentCopyAndPasteWithShortcutThenPasteAgain(tempRTFFileName, isRTF: true);
resultWithFormatting = FileReader.CompareRtfFiles(
Path.Combine(testFilesFolderPath, tempRTFFileName),
Path.Combine(testFilesFolderPath, pasteAsPlainTextPlainFileName),
compareFormatting: true);
Assert.IsTrue(resultWithFormatting.IsConsistent, "RTF files should be identical without formatting");
// Copy some rich text again.
// Open Advanced Paste window using hotkey, click Paste as Plain Text button and confirm that plain text without any formatting is pasted.
DeleteAndCopyFile(pasteAsPlainTextRawFileName, tempRTFFileName);
ContentCopyAndPasteCase3(tempRTFFileName, isRTF: true);
resultWithFormatting = FileReader.CompareRtfFiles(
Path.Combine(testFilesFolderPath, tempRTFFileName),
Path.Combine(testFilesFolderPath, pasteAsPlainTextPlainNoRepeatFileName),
compareFormatting: true);
Assert.IsTrue(resultWithFormatting.IsConsistent, "RTF files should be identical without formatting");
// Copy some rich text again.
// Open Advanced Paste window using hotkey, press Ctrl + 1 and confirm that plain text without any formatting is pasted.
DeleteAndCopyFile(pasteAsPlainTextRawFileName, tempRTFFileName);
ContentCopyAndPasteCase4(tempRTFFileName, isRTF: true);
resultWithFormatting = FileReader.CompareRtfFiles(
Path.Combine(testFilesFolderPath, tempRTFFileName),
Path.Combine(testFilesFolderPath, pasteAsPlainTextPlainNoRepeatFileName),
compareFormatting: true);
Assert.IsTrue(resultWithFormatting.IsConsistent, "RTF files should be identical without formatting");
}
[TestMethod]
[TestCategory("AdvancedPasteUITest")]
[TestCategory("PasteAsMarkdownCase1")]
public void TestCasePasteAsMarkdownCase1()
{
if (_notepadSettingsChanged == false)
{
ChangeNotePadSettings();
}
// Copy some text(e.g.some HTML text - convertible to Markdown)
// Paste the text using set hotkey and confirm that pasted text is converted to markdown
DeleteAndCopyFile(pasteAsMarkdownSrcFile, tempTxtFileName);
ContentCopyAndPasteAsMarkdownCase1(tempTxtFileName);
var result = FileReader.CompareRtfFiles(
Path.Combine(testFilesFolderPath, tempTxtFileName),
Path.Combine(testFilesFolderPath, pasteAsMarkdownResultFile),
compareFormatting: true);
Assert.IsTrue(result.IsConsistent, "Paste as markdown using shortcut failed.");
}
[TestMethod]
[TestCategory("AdvancedPasteUITest")]
[TestCategory("PasteAsMarkdownCase2")]
public void TestCasePasteAsMarkdownCase2()
{
if (_notepadSettingsChanged == false)
{
ChangeNotePadSettings();
}
// Copy some text(same as in the previous step or different.If nothing is coppied between steps, previously pasted Markdown text will be picked up from clipboard and converted again to nested Markdown).
// Open Advanced Paste window using hotkey, click Paste as markdown button and confirm that pasted text is converted to markdown
DeleteAndCopyFile(pasteAsMarkdownSrcFile, tempTxtFileName);
ContentCopyAndPasteAsMarkdownCase2(tempTxtFileName);
var result = FileReader.CompareRtfFiles(
Path.Combine(testFilesFolderPath, tempTxtFileName),
Path.Combine(testFilesFolderPath, pasteAsMarkdownResultFile),
compareFormatting: true);
Assert.IsTrue(result.IsConsistent, "Paste as markdown using shortcut failed.");
}
[TestMethod]
[TestCategory("AdvancedPasteUITest")]
[TestCategory("PasteAsMarkdownCase3")]
public void TestCasePasteAsMarkdownCase3()
{
if (_notepadSettingsChanged == false)
{
ChangeNotePadSettings();
}
// Copy some text(same as in the previous step or different.If nothing is coppied between steps, previously pasted Markdown text will be picked up from clipboard and converted again to nested Markdown).
// Open Advanced Paste window using hotkey, press Ctrl + 2 and confirm that pasted text is converted to markdown
DeleteAndCopyFile(pasteAsMarkdownSrcFile, tempTxtFileName);
ContentCopyAndPasteAsMarkdownCase3(tempTxtFileName);
var result = FileReader.CompareRtfFiles(
Path.Combine(testFilesFolderPath, tempTxtFileName),
Path.Combine(testFilesFolderPath, pasteAsMarkdownResultFile),
compareFormatting: true);
Assert.IsTrue(result.IsConsistent, "Paste as markdown using shortcut failed.");
}
[TestMethod]
[TestCategory("AdvancedPasteUITest")]
[TestCategory("PasteAsJSONCase1")]
public void TestCasePasteAsJSONCase1()
{
if (_notepadSettingsChanged == false)
{
ChangeNotePadSettings();
}
// Copy some XML or CSV text(or any other text, it will be converted to simple JSON object)
// Paste the text using set hotkey and confirm that pasted text is converted to JSON
DeleteAndCopyFile(pasteAsJsonFileName, tempTxtFileName);
ContentCopyAndPasteAsJsonCase1(tempTxtFileName);
var result = FileReader.CompareRtfFiles(
Path.Combine(testFilesFolderPath, tempTxtFileName),
Path.Combine(testFilesFolderPath, pasteAsJsonResultFile),
compareFormatting: true);
Assert.IsTrue(result.IsConsistent, "Paste as Json using shortcut failed.");
}
[TestMethod]
[TestCategory("AdvancedPasteUITest")]
[TestCategory("PasteAsJSONCase2")]
public void TestCasePasteAsJSONCase2()
{
if (_notepadSettingsChanged == false)
{
ChangeNotePadSettings();
}
// Copy some text(same as in the previous step or different.If nothing is coppied between steps, previously pasted JSON text will be picked up from clipboard and converted again to nested JSON).
// Open Advanced Paste window using hotkey, click Paste as markdown button and confirm that pasted text is converted to markdown
DeleteAndCopyFile(pasteAsJsonFileName, tempTxtFileName);
ContentCopyAndPasteAsJsonCase2(tempTxtFileName);
var result = FileReader.CompareRtfFiles(
Path.Combine(testFilesFolderPath, tempTxtFileName),
Path.Combine(testFilesFolderPath, pasteAsJsonResultFile),
compareFormatting: true);
Assert.IsTrue(result.IsConsistent, "Paste as Json using shortcut failed.");
}
[TestMethod]
[TestCategory("AdvancedPasteUITest")]
[TestCategory("PasteAsJSONCase3")]
public void TestCasePasteAsJSONCase3()
{
if (_notepadSettingsChanged == false)
{
ChangeNotePadSettings();
}
// Copy some text(same as in the previous step or different.If nothing is coppied between steps, previously pasted JSON text will be picked up from clipboard and converted again to nested JSON).
// Open Advanced Paste window using hotkey, press Ctrl + 3 and confirm that pasted text is converted to markdown
DeleteAndCopyFile(pasteAsJsonFileName, tempTxtFileName);
ContentCopyAndPasteAsJsonCase3(tempTxtFileName);
var result = FileReader.CompareRtfFiles(
Path.Combine(testFilesFolderPath, tempTxtFileName),
Path.Combine(testFilesFolderPath, pasteAsJsonResultFile),
compareFormatting: true);
Assert.IsTrue(result.IsConsistent, "Paste as Json using shortcut failed.");
}
/*
* Clipboard History
- [] Open Settings and Enable clipboard history (if not enabled already). Open Advanced Paste window with hotkey, click Clipboard history and try deleting some entry. Check OS clipboard history (Win+V), and confirm that the same entry no longer exist.
- [] Open Advanced Paste window with hotkey, click Clipboard history, and click any entry (but first). Observe that entry is put on top of clipboard history. Check OS clipboard history (Win+V), and confirm that the same entry is on top of the clipboard.
- [] Open Settings and Disable clipboard history. Open Advanced Paste window with hotkey and observe that Clipboard history button is disabled.
* Disable Advanced Paste, try different Advanced Paste hotkeys and confirm that it's disabled and nothing happens.
*/
private void TestCaseClipboardHistory()
{
}
private void ContentCopyAndPasteDirectly(string fileName, bool isRTF = false)
{
string tempFile = Path.Combine(testFilesFolderPath, fileName);
Process process = Process.Start(isRTF ? wordpadPath : "notepad.exe", tempFile);
if (process == null)
{
throw new InvalidOperationException($"Failed to start {(isRTF ? "WordPad" : "Notepad")}.");
}
Thread.Sleep(15000);
var window = FindWindowWithFlexibleTitle(Path.GetFileName(tempFile), isRTF);
window.Click();
Thread.Sleep(1000);
this.SendKeys(Key.LCtrl, Key.A);
Thread.Sleep(1000);
this.SendKeys(Key.LCtrl, Key.C);
Thread.Sleep(1000);
this.SendKeys(Key.Delete);
Thread.Sleep(1000);
this.SendKeys(Key.LCtrl, Key.V);
Thread.Sleep(1000);
this.SendKeys(Key.Backspace);
Thread.Sleep(1000);
this.SendKeys(Key.LCtrl, Key.S);
Thread.Sleep(1000);
process.Kill(true);
}
private void ContentCopyAndPasteWithShortcutThenPasteAgain(string fileName, bool isRTF = false)
{
string tempFile = Path.Combine(testFilesFolderPath, fileName);
Process process = Process.Start(isRTF ? wordpadPath : "notepad.exe", tempFile);
if (process == null)
{
throw new InvalidOperationException($"Failed to start {(isRTF ? "WordPad" : "Notepad")}.");
}
Thread.Sleep(15000);
var window = FindWindowWithFlexibleTitle(Path.GetFileName(tempFile), isRTF);
window.Click();
Thread.Sleep(1000);
this.SendKeys(Key.LCtrl, Key.A);
Thread.Sleep(1000);
this.SendKeys(Key.LCtrl, Key.C);
Thread.Sleep(1000);
this.SendKeys(Key.Delete);
Thread.Sleep(1000);
this.SendKeys(Key.Win, Key.LCtrl, Key.Alt, Key.O);
Thread.Sleep(1000);
this.SendKeys(Key.LCtrl, Key.V);
Thread.Sleep(1000);
this.SendKeys(Key.LCtrl, Key.S);
Thread.Sleep(1000);
process.Kill(true);
}
private void ContentCopyAndPasteCase3(string fileName, bool isRTF = false)
{
// Copy some rich text again.
// Open Advanced Paste window using hotkey, click Paste as Plain Text button and confirm that plain text without any formatting is pasted.
string tempFile = Path.Combine(testFilesFolderPath, fileName);
Process process = Process.Start(isRTF ? wordpadPath : "notepad.exe", tempFile);
if (process == null)
{
throw new InvalidOperationException($"Failed to start {(isRTF ? "WordPad" : "Notepad")}.");
}
Thread.Sleep(15000);
var window = FindWindowWithFlexibleTitle(Path.GetFileName(tempFile), isRTF);
window.Click();
Thread.Sleep(1000);
this.SendKeys(Key.LCtrl, Key.A);
Thread.Sleep(1000);
this.SendKeys(Key.LCtrl, Key.C);
Thread.Sleep(1000);
this.SendKeys(Key.Delete);
Thread.Sleep(1000);
// Open Advanced Paste window using hotkey
this.SendKeys(Key.Win, Key.Shift, Key.V);
Thread.Sleep(15000);
// Click Paste as Plain Text button and confirm that plain text without any formatting is pasted.
var apWind = this.Find<Window>("Advanced Paste", global: true);
apWind.Find<TextBlock>("Paste as plain text").Click();
this.SendKeys(Key.LCtrl, Key.S);
Thread.Sleep(1000);
process.Kill(true);
}
private void ContentCopyAndPasteCase4(string fileName, bool isRTF = false)
{
// Copy some rich text again.
// Open Advanced Paste window using hotkey, press Ctrl + 1 and confirm that plain text without any formatting is pasted.
string tempFile = Path.Combine(testFilesFolderPath, fileName);
Process process = Process.Start(isRTF ? wordpadPath : "notepad.exe", tempFile);
if (process == null)
{
throw new InvalidOperationException($"Failed to start {(isRTF ? "WordPad" : "Notepad")}.");
}
Thread.Sleep(15000);
var window = FindWindowWithFlexibleTitle(Path.GetFileName(tempFile), isRTF);
window.Click();
Thread.Sleep(1000);
this.SendKeys(Key.LCtrl, Key.A);
Thread.Sleep(1000);
this.SendKeys(Key.LCtrl, Key.C);
Thread.Sleep(1000);
this.SendKeys(Key.Delete);
Thread.Sleep(1000);
// Open Advanced Paste window using hotkey
this.SendKeys(Key.Win, Key.Shift, Key.V);
Thread.Sleep(1000);
// press Ctrl + 1 and confirm that plain text without any formatting is pasted.
this.SendKeys(Key.LCtrl, Key.Num1);
Thread.Sleep(1000);
this.SendKeys(Key.LCtrl, Key.S);
Thread.Sleep(1000);
process.Kill(true);
}
private void ContentCopyAndPasteAsMarkdownCase1(string fileName, bool isRTF = false)
{
// Copy some rich text again.
// Open Advanced Paste window using hotkey, press Ctrl + 1 and confirm that plain text without any formatting is pasted.
string tempFile = Path.Combine(testFilesFolderPath, fileName);
Process process = Process.Start(isRTF ? wordpadPath : "notepad.exe", tempFile);
if (process == null)
{
throw new InvalidOperationException($"Failed to start {(isRTF ? "WordPad" : "Notepad")}.");
}
Thread.Sleep(15000);
var window = FindWindowWithFlexibleTitle(Path.GetFileName(tempFile), isRTF);
window.Click();
Thread.Sleep(1000);
this.SendKeys(Key.LCtrl, Key.A);
Thread.Sleep(1000);
this.SendKeys(Key.LCtrl, Key.C);
Thread.Sleep(1000);
this.SendKeys(Key.Delete);
Thread.Sleep(1000);
this.SendKeys(Key.Win, Key.LCtrl, Key.Alt, Key.M);
Thread.Sleep(1000);
this.SendKeys(Key.LCtrl, Key.S);
Thread.Sleep(1000);
window.Close();
}
private void ContentCopyAndPasteAsMarkdownCase2(string fileName, bool isRTF = false)
{
string tempFile = Path.Combine(testFilesFolderPath, fileName);
Process process = Process.Start(isRTF ? wordpadPath : "notepad.exe", tempFile);
if (process == null)
{
throw new InvalidOperationException($"Failed to start {(isRTF ? "WordPad" : "Notepad")}.");
}
Thread.Sleep(15000);
var window = FindWindowWithFlexibleTitle(Path.GetFileName(tempFile), isRTF);
window.Click();
Thread.Sleep(1000);
this.SendKeys(Key.LCtrl, Key.A);
Thread.Sleep(1000);
this.SendKeys(Key.LCtrl, Key.C);
Thread.Sleep(1000);
this.SendKeys(Key.Delete);
Thread.Sleep(1000);
// Open Advanced Paste window using hotkey
this.SendKeys(Key.Win, Key.Shift, Key.V);
Thread.Sleep(15000);
// click Paste as markdown button and confirm that pasted text is converted to markdown
var apWind = this.Find<Window>("Advanced Paste", global: true);
apWind.Find<TextBlock>("Paste as markdown").Click();
this.SendKeys(Key.LCtrl, Key.S);
Thread.Sleep(1000);
window.Close();
}
private void ContentCopyAndPasteAsMarkdownCase3(string fileName, bool isRTF = false)
{
string tempFile = Path.Combine(testFilesFolderPath, fileName);
Process process = Process.Start(isRTF ? wordpadPath : "notepad.exe", tempFile);
if (process == null)
{
throw new InvalidOperationException($"Failed to start {(isRTF ? "WordPad" : "Notepad")}.");
}
Thread.Sleep(15000);
var window = FindWindowWithFlexibleTitle(Path.GetFileName(tempFile), isRTF);
window.Click();
Thread.Sleep(1000);
this.SendKeys(Key.LCtrl, Key.A);
Thread.Sleep(1000);
this.SendKeys(Key.LCtrl, Key.C);
Thread.Sleep(1000);
this.SendKeys(Key.Delete);
Thread.Sleep(1000);
// Open Advanced Paste window using hotkey
this.SendKeys(Key.Win, Key.Shift, Key.V);
Thread.Sleep(15000);
this.SendKeys(Key.LCtrl, Key.Num2);
Thread.Sleep(1000);
this.SendKeys(Key.LCtrl, Key.S);
Thread.Sleep(1000);
window.Close();
}
private void ContentCopyAndPasteAsJsonCase1(string fileName, bool isRTF = false)
{
// Copy some rich text again.
// Open Advanced Paste window using hotkey, press Ctrl + 1 and confirm that plain text without any formatting is pasted.
string tempFile = Path.Combine(testFilesFolderPath, fileName);
Process process = Process.Start(isRTF ? wordpadPath : "notepad.exe", tempFile);
if (process == null)
{
throw new InvalidOperationException($"Failed to start {(isRTF ? "WordPad" : "Notepad")}.");
}
Thread.Sleep(15000);
var window = FindWindowWithFlexibleTitle(Path.GetFileName(tempFile), isRTF);
window.Click();
Thread.Sleep(1000);
this.SendKeys(Key.LCtrl, Key.A);
Thread.Sleep(1000);
this.SendKeys(Key.LCtrl, Key.C);
Thread.Sleep(1000);
this.SendKeys(Key.Delete);
Thread.Sleep(1000);
this.SendKeys(Key.Win, Key.LCtrl, Key.Alt, Key.J);
Thread.Sleep(1000);
this.SendKeys(Key.LCtrl, Key.S);
Thread.Sleep(1000);
window.Close();
}
private void ContentCopyAndPasteAsJsonCase2(string fileName, bool isRTF = false)
{
string tempFile = Path.Combine(testFilesFolderPath, fileName);
Process process = Process.Start(isRTF ? wordpadPath : "notepad.exe", tempFile);
if (process == null)
{
throw new InvalidOperationException($"Failed to start {(isRTF ? "WordPad" : "Notepad")}.");
}
Thread.Sleep(15000);
var window = FindWindowWithFlexibleTitle(Path.GetFileName(tempFile), isRTF);
window.Click();
Thread.Sleep(1000);
this.SendKeys(Key.LCtrl, Key.A);
Thread.Sleep(1000);
this.SendKeys(Key.LCtrl, Key.C);
Thread.Sleep(1000);
this.SendKeys(Key.Delete);
Thread.Sleep(1000);
// Open Advanced Paste window using hotkey
this.SendKeys(Key.Win, Key.Shift, Key.V);
Thread.Sleep(15000);
// click Paste as markdown button and confirm that pasted text is converted to markdown
var apWind = this.Find<Window>("Advanced Paste", global: true);
apWind.Find<TextBlock>("Paste as JSON").Click();
this.SendKeys(Key.LCtrl, Key.S);
Thread.Sleep(1000);
window.Close();
}
private void ContentCopyAndPasteAsJsonCase3(string fileName, bool isRTF = false)
{
string tempFile = Path.Combine(testFilesFolderPath, fileName);
Process process = Process.Start(isRTF ? wordpadPath : "notepad.exe", tempFile);
if (process == null)
{
throw new InvalidOperationException($"Failed to start {(isRTF ? "WordPad" : "Notepad")}.");
}
Thread.Sleep(15000);
var window = FindWindowWithFlexibleTitle(Path.GetFileName(tempFile), isRTF);
window.Click();
Thread.Sleep(1000);
this.SendKeys(Key.LCtrl, Key.A);
Thread.Sleep(1000);
this.SendKeys(Key.LCtrl, Key.C);
Thread.Sleep(1000);
this.SendKeys(Key.Delete);
Thread.Sleep(1000);
// Open Advanced Paste window using hotkey
this.SendKeys(Key.Win, Key.Shift, Key.V);
Thread.Sleep(15000);
this.SendKeys(Key.LCtrl, Key.Num3);
Thread.Sleep(1000);
this.SendKeys(Key.LCtrl, Key.S);
Thread.Sleep(1000);
window.Close();
}
private string DeleteAndCopyFile(string sourceFileName, string destinationFileName)
{
string sourcePath = Path.Combine(testFilesFolderPath, sourceFileName);
string destinationPath = Path.Combine(testFilesFolderPath, destinationFileName);
// Check if source file exists
if (!File.Exists(sourcePath))
{
throw new FileNotFoundException($"Source file not found: {sourcePath}");
}
// Delete destination file if it exists
if (File.Exists(destinationPath))
{
try
{
File.Delete(destinationPath);
}
catch (IOException ex)
{
throw new IOException($"Failed to delete file {destinationPath}. The file may be in use: {ex.Message}", ex);
}
}
// Copy the source file to the destination
try
{
File.Copy(sourcePath, destinationPath);
}
catch (IOException ex)
{
throw new IOException($"Failed to copy file from {sourcePath} to {destinationPath}: {ex.Message}", ex);
}
return destinationPath;
}
private void ChangeNotePadSettings()
{
Process process = Process.Start("notepad.exe");
if (process == null)
{
throw new InvalidOperationException($"Failed to start Notepad.exe");
}
Thread.Sleep(15000);
var window = FindWindowWithFlexibleTitle("Untitled", false);
window.Find<PowerToys.UITest.Button>("Settings").Click();
var combobox = window.Find<PowerToys.UITest.ComboBox>("Opening files");
combobox.SelectTxt("Open in a new window");
window.Find<Group>("When Notepad starts").Click();
window.Find<PowerToys.UITest.RadioButton>("Open a new window").Select();
_notepadSettingsChanged = true;
window.Close();
}
/// <summary>
/// Finds a window with flexible title matching, trying multiple title variations
/// </summary>
/// <param name="baseTitle">The base title to search for</param>
/// <param name="isRTF">Whether the window is a WordPad window</param>
/// <returns>The found Window element or throws an exception if not found</returns>
private Window FindWindowWithFlexibleTitle(string baseTitle, bool isRTF)
{
Window? window = null;
string appType = isRTF ? "WordPad" : "Notepad";
// Try different title variations
string[] titleVariations = new string[]
{
baseTitle + (isRTF ? " - WordPad" : " - Notepad"), // With suffix
baseTitle, // Without suffix
Path.GetFileNameWithoutExtension(baseTitle) + (isRTF ? " - WordPad" : " - Notepad"), // Without extension, with suffix
Path.GetFileNameWithoutExtension(baseTitle), // Without extension, without suffix
};
Exception? lastException = null;
foreach (string title in titleVariations)
{
try
{
window = this.Find<Window>(title, global: true);
if (window != null)
{
return window;
}
}
catch (Exception ex)
{
// Save the exception, but continue trying other variations
lastException = ex;
}
}
// If we couldn't find the window with any variation, throw an exception with details
throw new InvalidOperationException(
$"Failed to find {appType} window with title containing '{baseTitle}'. ");
}
private static void CopySettingsFileBeforeTests()
{
try
{
// Determine the assembly location and test files path
string? assemblyLocation = Path.GetDirectoryName(typeof(AdvancedPasteUITest).Assembly.Location);
if (assemblyLocation == null)
{
Debug.WriteLine("ERROR: Failed to get assembly location");
return;
}
string testFilesFolder = Path.Combine(assemblyLocation, "TestFiles");
if (!Directory.Exists(testFilesFolder))
{
Debug.WriteLine($"ERROR: Test files directory not found at: {testFilesFolder}");
return;
}
// Settings file source path
string settingsFileName = "settings.json";
string sourceSettingsPath = Path.Combine(testFilesFolder, settingsFileName);
// Make sure the source file exists
if (!File.Exists(sourceSettingsPath))
{
Debug.WriteLine($"ERROR: Settings file not found at: {sourceSettingsPath}");
return;
}
// Determine the target directory in %LOCALAPPDATA%
string targetDirectory = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
"Microsoft",
"PowerToys",
"AdvancedPaste");
// Create the directory if it doesn't exist
if (!Directory.Exists(targetDirectory))
{
Directory.CreateDirectory(targetDirectory);
}
string targetSettingsPath = Path.Combine(targetDirectory, settingsFileName);
// Copy the file and overwrite if it exists
File.Copy(sourceSettingsPath, targetSettingsPath, true);
Debug.WriteLine($"Successfully copied settings file from {sourceSettingsPath} to {targetSettingsPath}");
}
catch (Exception ex)
{
Debug.WriteLine($"ERROR copying settings file: {ex.Message}");
}
}
}
}

View File

@@ -1,85 +0,0 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.IO;
using System.Text;
using System.Windows.Forms;
namespace Microsoft.AdvancedPaste.UITests.Helper;
public class FileReader
{
public static string ReadContent(string filePath)
{
try
{
return File.ReadAllText(filePath);
}
catch (Exception ex)
{
throw new InvalidOperationException($"Failed to read file: {ex.Message}", ex);
}
}
public static string ReadRTFPlainText(string filePath)
{
try
{
using (var rtb = new System.Windows.Forms.RichTextBox())
{
rtb.Rtf = File.ReadAllText(filePath);
return rtb.Text;
}
}
catch (Exception ex)
{
throw new InvalidOperationException($"Failed to read plain text from file: {ex.Message}", ex);
}
}
/// <summary>
/// Compares the contents of two RTF files to check if they are consistent.
/// </summary>
/// <param name="firstFilePath">Path to the first RTF file</param>
/// <param name="secondFilePath">Path to the second RTF file</param>
/// <param name="compareFormatting">If true, compares the raw RTF content (including formatting).
/// If false, compares only the plain text content.</param>
/// <returns>
/// A tuple containing: (bool isConsistent, string firstContent, string secondContent)
/// - isConsistent: true if the files are consistent according to the comparison method
/// - firstContent: the content of the first file
/// - secondContent: the content of the second file
/// </returns>
public static (bool IsConsistent, string FirstContent, string SecondContent) CompareRtfFiles(
string firstFilePath,
string secondFilePath,
bool compareFormatting = false)
{
try
{
string firstContent, secondContent;
if (compareFormatting)
{
// Compare raw RTF content (including formatting)
firstContent = ReadContent(firstFilePath);
secondContent = ReadContent(secondFilePath);
}
else
{
// Compare only the plain text content
firstContent = ReadRTFPlainText(firstFilePath);
secondContent = ReadRTFPlainText(secondFilePath);
}
bool isConsistent = string.Equals(firstContent, secondContent, StringComparison.Ordinal);
return (isConsistent, firstContent, secondContent);
}
catch (Exception ex)
{
throw new InvalidOperationException($"Failed to compare RTF files: {ex.Message}", ex);
}
}
}

View File

@@ -1,6 +0,0 @@
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>

View File

@@ -1,8 +0,0 @@
{
"note": {
"to": "Tove",
"from": "Jani",
"heading": "Reminder",
"body": "Don't forget me this weekend!"
}
}

View File

@@ -1,12 +0,0 @@
<!DOCTYPE html>
<html>
<body>
<h2 title="I'm a header">The title Attribute</h2>
<p title="I'm a tooltip">Mouse over this paragraph, to display the title attribute as a tooltip.</p>
</body>
</html>

View File

@@ -1,3 +0,0 @@
## The title Attribute
Mouse over this paragraph, to display the title attribute as a tooltip.

View File

@@ -1 +0,0 @@
{"properties":{"IsAdvancedAIEnabled":{"value":false},"ShowCustomPreview":{"value":true},"CloseAfterLosingFocus":{"value":false},"advanced-paste-ui-hotkey":{"win":true,"ctrl":false,"alt":false,"shift":true,"code":86,"key":""},"paste-as-plain-hotkey":{"win":true,"ctrl":true,"alt":true,"shift":false,"code":79,"key":""},"paste-as-markdown-hotkey":{"win":true,"ctrl":true,"alt":true,"shift":false,"code":77,"key":""},"paste-as-json-hotkey":{"win":true,"ctrl":true,"alt":true,"shift":false,"code":74,"key":""},"custom-actions":{"value":[]},"additional-actions":{"image-to-text":{"shortcut":{"win":false,"ctrl":false,"alt":false,"shift":false,"code":0,"key":""},"isShown":true},"paste-as-file":{"isShown":true,"paste-as-txt-file":{"shortcut":{"win":false,"ctrl":false,"alt":false,"shift":false,"code":0,"key":""},"isShown":true},"paste-as-png-file":{"shortcut":{"win":false,"ctrl":false,"alt":false,"shift":false,"code":0,"key":""},"isShown":true},"paste-as-html-file":{"shortcut":{"win":false,"ctrl":false,"alt":false,"shift":false,"code":0,"key":""},"isShown":true}},"transcode":{"isShown":true,"transcode-to-mp3":{"shortcut":{"win":false,"ctrl":false,"alt":false,"shift":false,"code":0,"key":""},"isShown":true},"transcode-to-mp4":{"shortcut":{"win":false,"ctrl":false,"alt":false,"shift":false,"code":0,"key":""},"isShown":true}}}},"name":"AdvancedPaste","version":"1"}

View File

@@ -1,41 +0,0 @@
## [Advanced Paste](tests-checklist-template-advanced-paste-section.md)
NOTES:
When using Advanced Paste, make sure that window focused while starting/using Advanced paste is text editor or has text input field focused (e.g. Word).
* Paste As Plain Text
- [x] Copy some rich text (e.g word of the text is different color, another work is bold, underlined, etd.).
- [x] Paste the text using standard Windows Ctrl + V shortcut and ensure that rich text is pasted (with all colors, formatting, etc.)
- [x] Paste the text using Paste As Plain Text activation shortcut and ensure that plain text without any formatting is pasted.
- [x] Paste again the text using standard Windows Ctrl + V shortcut and ensure the text is now pasted plain without formatting as well.
- [x] Copy some rich text again.
- [x] Open Advanced Paste window using hotkey, click Paste as Plain Text button and confirm that plain text without any formatting is pasted.
- [x] Copy some rich text again.
- [x] Open Advanced Paste window using hotkey, press Ctrl + 1 and confirm that plain text without any formatting is pasted.
* Paste As Markdown
- [] Open Settings and set Paste as Markdown directly hotkey
- [x] Copy some text (e.g. some HTML text - convertible to Markdown)
- [x] Paste the text using set hotkey and confirm that pasted text is converted to markdown
- [x] Copy some text (same as in the previous step or different. If nothing is coppied between steps, previously pasted Markdown text will be picked up from clipboard and converted again to nested Markdown).
- [x] Open Advanced Paste window using hotkey, click Paste as markdown button and confirm that pasted text is converted to markdown
- [x] Copy some text (same as in the previous step or different. If nothing is coppied between steps, previously pasted Markdown text will be picked up from clipboard and converted again to nested Markdown).
- [x] Open Advanced Paste window using hotkey, press Ctrl + 2 and confirm that pasted text is converted to markdown
* Paste As JSON
- [] Open Settings and set Paste as JSON directly hotkey
- [x] Copy some XML or CSV text (or any other text, it will be converted to simple JSON object)
- [x] Paste the text using set hotkey and confirm that pasted text is converted to JSON
- [x] Copy some text (same as in the previous step or different. If nothing is coppied between steps, previously pasted JSON text will be picked up from clipboard and converted again to nested JSON).
- [x] Open Advanced Paste window using hotkey, click Paste as markdown button and confirm that pasted text is converted to markdown
- [x] Copy some text (same as in the previous step or different. If nothing is coppied between steps, previously pasted JSON text will be picked up from clipboard and converted again to nested JSON).
- [x] Open Advanced Paste window using hotkey, press Ctrl + 3 and confirm that pasted text is converted to markdown
* Paste as custom format using AI
- [] Open Settings, navigate to Enable Paste with AI and set OpenAI key.
- [] Copy some text to clipboard. Any text.
- [] Open Advanced Paste window using hotkey, and confirm that Custom intput text box is now enabled. Write "Insert smiley after every word" and press Enter. Observe that result preview shows coppied text with smileys between words. Press Enter to paste the result and observe that it is pasted.
- [] Open Advanced Paste window using hotkey. Input some query (any, feel free to play around) and press Enter. When result is shown, click regenerate button, to see if new result is generated. Select one of the results and paste. Observe that correct result is pasted.
- [] Create few custom actions. Set up hotkey for custom actions and confirm they work. Enable/disable custom actions and confirm that the change is reflected in Advanced Paste UI - custom action is not listed. Try different ctrl + <num> in-app shortcuts for custom actions. Try moving custom actions up/down and confirm that the change is reflected in Advanced Paste UI.
- [] Open Settings and disable Custom format preview. Open Advanced Paste window with hotkey, enter some query and press enter. Observe that result is now pasted right away, without showing the preview first.
- [] Open Settings and Disable Enable Paste with AI. Open Advanced Paste window with hotkey and observe that Custom Input text box is now disabled.
* Clipboard History
- [] Open Settings and Enable clipboard history (if not enabled already). Open Advanced Paste window with hotkey, click Clipboard history and try deleting some entry. Check OS clipboard history (Win+V), and confirm that the same entry no longer exist.
- [] Open Advanced Paste window with hotkey, click Clipboard history, and click any entry (but first). Observe that entry is put on top of clipboard history. Check OS clipboard history (Win+V), and confirm that the same entry is on top of the clipboard.
- [] Open Settings and Disable clipboard history. Open Advanced Paste window with hotkey and observe that Clipboard history button is disabled.
* Disable Advanced Paste, try different Advanced Paste hotkeys and confirm that it's disabled and nothing happens.

View File

@@ -4,8 +4,8 @@
{
"fuzzer": {
"$type": "libfuzzerDotNet",
"dll": "HostsEditor.FuzzTests.dll",
"class": "HostsEditor.FuzzTests.FuzzTests",
"dll": "Hosts.FuzzTests.dll",
"class": "Hosts.FuzzTests.FuzzTests",
"method": "FuzzValidIPv4",
"FuzzingTargetBinaries": [
"PowerToys.Hosts.dll"
@@ -35,8 +35,8 @@
// the DLL and PDB files
// you will need to add any other files required
// (globs are supported)
"HostsEditor.FuzzTests.dll",
"HostsEditor.FuzzTests.pdb",
"Hosts.FuzzTests.dll",
"Hosts.FuzzTests.pdb",
"Microsoft.Windows.SDK.NET.dll",
"WinRT.Runtime.dll"
],
@@ -45,8 +45,8 @@
{
"fuzzer": {
"$type": "libfuzzerDotNet",
"dll": "HostsEditor.FuzzTests.dll",
"class": "HostsEditor.FuzzTests.FuzzTests",
"dll": "Hosts.FuzzTests.dll",
"class": "Hosts.FuzzTests.FuzzTests",
"method": "FuzzValidIPv6",
"FuzzingTargetBinaries": [
"PowerToys.Hosts.dll"
@@ -76,8 +76,8 @@
// the DLL and PDB files
// you will need to add any other files required
// (globs are supported)
"HostsEditor.FuzzTests.dll",
"HostsEditor.FuzzTests.pdb",
"Hosts.FuzzTests.dll",
"Hosts.FuzzTests.pdb",
"Microsoft.Windows.SDK.NET.dll",
"WinRT.Runtime.dll"
],
@@ -86,8 +86,8 @@
{
"fuzzer": {
"$type": "libfuzzerDotNet",
"dll": "HostsEditor.FuzzTests.dll",
"class": "HostsEditor.FuzzTests.FuzzTests",
"dll": "Hosts.FuzzTests.dll",
"class": "Hosts.FuzzTests.FuzzTests",
"method": "FuzzValidHosts",
"FuzzingTargetBinaries": [
"PowerToys.Hosts.dll"
@@ -117,8 +117,8 @@
// the DLL and PDB files
// you will need to add any other files required
// (globs are supported)
"HostsEditor.FuzzTests.dll",
"HostsEditor.FuzzTests.pdb",
"Hosts.FuzzTests.dll",
"Hosts.FuzzTests.pdb",
"Microsoft.Windows.SDK.NET.dll",
"WinRT.Runtime.dll"
],
@@ -127,8 +127,8 @@
{
"fuzzer": {
"$type": "libfuzzerDotNet",
"dll": "HostsEditor.FuzzTests.dll",
"class": "HostsEditor.FuzzTests.FuzzTests",
"dll": "Hosts.FuzzTests.dll",
"class": "Hosts.FuzzTests.FuzzTests",
"method": "FuzzWriteAsync",
"FuzzingTargetBinaries": [
"PowerToys.Hosts.dll"
@@ -160,8 +160,8 @@
// (globs are supported)
"Castle.Core.dll",
"CommunityToolkit.Mvvm.dll",
"HostsEditor.FuzzTests.dll",
"HostsEditor.FuzzTests.pdb",
"Hosts.FuzzTests.dll",
"Hosts.FuzzTests.pdb",
"Microsoft.Windows.SDK.NET.dll",
"Moq.dll",
"System.IO.Abstractions.dll",

View File

@@ -1,19 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\Common.Dotnet.CsWinRT.props" />
<PropertyGroup>
<RootNamespace>PowerOCR.UITests</RootNamespace>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<OutputType>Library</OutputType>
<RunVSTest>false</RunVSTest>
</PropertyGroup>
<PropertyGroup>
<OutputPath>..\..\..\..\$(Platform)\$(Configuration)\tests\PowerOCR.UITests\</OutputPath>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="MSTest" />
<ProjectReference Include="..\..\..\common\UITestAutomation\UITestAutomation.csproj" />
</ItemGroup>
</Project>

View File

@@ -1,59 +0,0 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Microsoft.PowerToys.UITest;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using static Microsoft.PowerToys.UITest.UITestBase;
namespace PowerOCR.UITests;
[TestClass]
public class PowerOCRTests : UITestBase
{
public PowerOCRTests()
: base(PowerToysModule.PowerToysSettings, WindowSize.Medium)
{
}
[TestInitialize]
public void TestInitialize()
{
if (FindAll<NavigationViewItem>("Text Extractor").Count == 0)
{
// Expand Advanced list-group if needed
Find<NavigationViewItem>("System Tools").Click();
}
Find<NavigationViewItem>("Text Extractor").Click();
Find<ToggleSwitch>("Enable Text Extractor").Toggle(true);
SendKeys(Key.Win, Key.D);
}
[TestMethod("PowerOCR.DetectTextExtractor")]
[TestCategory("PowerOCR Detection")]
public void DetectTextExtractorTest()
{
try
{
SendKeys(Key.Win, Key.Shift, Key.T);
Thread.Sleep(5000);
var textExtractorWindow = Find("TextExtractor", 10000, true);
Assert.IsNotNull(textExtractorWindow, "TextExtractor window should be found after hotkey activation");
Console.WriteLine("✓ TextExtractor window detected successfully after hotkey activation");
SendKeys(Key.Esc);
}
catch (Exception ex)
{
Console.WriteLine($"Failed to detect TextExtractor window: {ex.Message}");
Assert.Fail("TextExtractor window was not found after hotkey activation");
}
}
}

View File

@@ -5,7 +5,7 @@
<ProjectGuid>{A85D4D9F-9A39-4B5D-8B5A-9F2D5C9A8B4C}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>WorkspacesLibUnitTests</RootNamespace>
<ProjectName>Workspaces.Lib.UnitTests</ProjectName>
<ProjectName>WorkspacesLibUnitTests</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Label="Configuration">

View File

@@ -1,27 +0,0 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Collections.Generic;
namespace Microsoft.CmdPal.Common.Services;
public interface IRunHistoryService
{
/// <summary>
/// Gets the run history.
/// </summary>
/// <returns>A list of run history items.</returns>
IReadOnlyList<string> GetRunHistory();
/// <summary>
/// Clears the run history.
/// </summary>
void ClearRunHistory();
/// <summary>
/// Adds a run history item.
/// </summary>
/// <param name="item">The run history item to add.</param>
void AddRunHistoryItem(string item);
}

View File

@@ -21,12 +21,8 @@ public partial class AppStateModel : ObservableObject
///////////////////////////////////////////////////////////////////////////
// STATE HERE
// Make sure that you make the setters public (JsonSerializer.Deserialize will fail silently otherwise)!
// Make sure that any new types you add are added to JsonSerializationContext!
public RecentCommandsManager RecentCommands { get; set; } = new();
public List<string> RunHistory { get; set; } = [];
// END SETTINGS
///////////////////////////////////////////////////////////////////////////
@@ -90,7 +86,7 @@ public partial class AppStateModel : ObservableObject
{
foreach (var item in newSettings)
{
savedSettings[item.Key] = item.Value?.DeepClone();
savedSettings[item.Key] = item.Value != null ? item.Value.DeepClone() : null;
}
var serialized = savedSettings.ToJsonString(JsonSerializationContext.Default.AppStateModel.Options);
@@ -125,4 +121,20 @@ public partial class AppStateModel : ObservableObject
// now, the settings is just next to the exe
return Path.Combine(directory, "state.json");
}
// [UnconditionalSuppressMessage("AOT", "IL3050:Calling members annotated with 'RequiresDynamicCodeAttribute' may break functionality when AOT compiling.", Justification = "<Pending>")]
// private static readonly JsonSerializerOptions _serializerOptions = new()
// {
// WriteIndented = true,
// Converters = { new JsonStringEnumConverter() },
// };
// private static readonly JsonSerializerOptions _deserializerOptions = new()
// {
// PropertyNameCaseInsensitive = true,
// IncludeFields = true,
// AllowTrailingCommas = true,
// PreferredObjectCreationHandling = JsonObjectCreationHandling.Populate,
// ReadCommentHandling = JsonCommentHandling.Skip,
// };
}

View File

@@ -101,7 +101,6 @@ public partial class App : Application
var files = new IndexerCommandsProvider();
files.SuppressFallbackWhen(ShellCommandsProvider.SuppressFileFallbackIf);
services.AddSingleton<ICommandProvider>(allApps);
services.AddSingleton<ICommandProvider, ShellCommandsProvider>();
services.AddSingleton<ICommandProvider, CalculatorCommandProvider>();
services.AddSingleton<ICommandProvider>(files);
@@ -147,7 +146,6 @@ public partial class App : Application
services.AddSingleton(state);
services.AddSingleton<IExtensionService, ExtensionService>();
services.AddSingleton<TrayIconService>();
services.AddSingleton<IRunHistoryService, RunHistoryService>();
services.AddSingleton<IRootPageService, PowerToysRootPageService>();
services.AddSingleton<IAppHostService, PowerToysAppHostService>();

View File

@@ -7,8 +7,6 @@ using Microsoft.CmdPal.UI.Deferred;
using Microsoft.UI.Dispatching;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Input;
using Windows.Foundation;
namespace Microsoft.CmdPal.UI.Controls;
@@ -51,12 +49,6 @@ public partial class IconBox : ContentControl
/// </summary>
public event TypedEventHandler<IconBox, SourceRequestedEventArgs>? SourceRequested;
public IconBox()
{
TabFocusNavigation = KeyboardNavigationMode.Once;
IsTabStop = false;
}
private static void OnSourcePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is IconBox @this)

View File

@@ -336,6 +336,8 @@ public sealed partial class SearchBar : UserControl,
// ... Move the cursor to the end of the input
FilterBox.Select(FilterBox.Text.Length, 0);
}
// TODO! deal with suggestion
}
else if (property == nameof(ListViewModel.InitialSearchText))
{

View File

@@ -1,429 +0,0 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices.WindowsRuntime;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Media;
using Microsoft.UI.Xaml.Media.Imaging;
using Windows.Graphics.Imaging;
using Windows.Win32;
using Windows.Win32.Foundation;
using Windows.Win32.Graphics.Gdi;
using Windows.Win32.UI.WindowsAndMessaging;
// This is an unfortunate interaction between CsWin32 and CsWinRT.
// The warning is technically correct, but because you can't edit generated
// files, you can't really fix it. Ideally CsWin32 would generate all types as
// partial, but it doesn't do that today
[assembly: SuppressMessage("Usage", "CsWinRT1028:Class is not marked partial", Justification = "Type is not passed across the WinRT ABI", Scope = "type", Target = "Windows.Win32.DeleteObjectSafeHandle")]
[assembly: SuppressMessage("Usage", "CsWinRT1028:Class is not marked partial", Justification = "Type is not passed across the WinRT ABI", Scope = "type", Target = "Windows.Win32.DestroyIconSafeHandle")]
// Relatedly, we added a NativeMethods.json to be able to fix some
// error CA1420: Setting SetLastError to 'true' requires runtime marshalling to be enabled
// errors.
namespace Microsoft.CmdPal.UI.Helpers;
/// <summary>
/// Converts icon paths to IconSource and IconElement objects for WinUI controls.
/// This is a C# port of the C++ IconPathConverter from Microsoft.Terminal.UI.
/// </summary>
public static class IconPathConverter
{
/// <summary>
/// Creates an IconSource for the given path with default settings.
/// </summary>
/// <param name="iconPath">The path to the icon.</param>
/// <returns>An IconSource with its source set, if possible.</returns>
public static IconSource? IconSource(string iconPath, string? fontFamily = null)
{
return IconSource(iconPath, false, fontFamily, 24);
}
/// <summary>
/// Creates an IconSource for the given path.
/// </summary>
/// <param name="iconPath">The path to the icon.</param>
/// <param name="monochrome">Whether to show the icon as monochrome.</param>
/// <param name="targetSize">The target size for the icon.</param>
/// <returns>An IconSource with its source set, if possible.</returns>
public static IconSource? IconSource(string iconPath, bool monochrome, string? fontFamily = null, int targetSize = 24)
{
if (TryGetIconIndex(iconPath, out var iconPathWithoutIndex, out var index))
{
var bitmapSource = GetImageIconSourceForBinary(iconPathWithoutIndex, index, targetSize);
if (bitmapSource != null)
{
var imageIconSource = new ImageIconSource
{
ImageSource = bitmapSource
};
return imageIconSource;
}
}
return GetIconSource(iconPath, monochrome, fontFamily, targetSize);
}
/// <summary>
/// Creates an IconElement for the given path with default size.
/// </summary>
/// <param name="iconPath">The path to the icon.</param>
/// <returns>An IconElement with its IconSource set, if possible.</returns>
public static IconElement Icon(string iconPath)
{
return Icon(iconPath, 24);
}
/// <summary>
/// Creates an IconElement for the given path.
/// </summary>
/// <param name="iconPath">The path to the icon.</param>
/// <param name="targetSize">The target size for the icon.</param>
/// <returns>An IconElement with its IconSource set, if possible.</returns>
public static IconElement Icon(string iconPath, int targetSize)
{
if (TryGetIconIndex(iconPath, out var iconPathWithoutIndex, out var index))
{
var bitmapSource = GetImageIconSourceForBinary(iconPathWithoutIndex, index, targetSize);
if (bitmapSource != null)
{
var icon = new ImageIcon
{
Source = bitmapSource,
Width = targetSize,
Height = targetSize
};
return icon;
}
}
var source = IconSource(iconPath, false, targetSize);
var iconSourceElement = new IconSourceElement
{
IconSource = source
};
return iconSourceElement;
}
/// <summary>
/// Creates an IconSource for the given path.
/// </summary>
/// <param name="iconPath">The path to the icon.</param>
/// <param name="monochrome">Whether to show the icon as monochrome.</param>
/// <param name="targetSize">The target size for the icon.</param>
/// <returns>An IconSource with its source set, if possible.</returns>
private static IconSource? GetIconSource(string iconPath, bool monochrome, string? fontFamily, int targetSize)
{
IconSource? iconSource = null;
if (!string.IsNullOrEmpty(iconPath))
{
var expandedIconPath = ExpandIconPath(iconPath);
iconSource = GetColoredBitmapIcon(expandedIconPath, monochrome);
// If we fail to set the icon source using the "icon" as a path,
// let's try it as a symbol/emoji.
//
// Anything longer than 2 characters isn't an emoji or symbol, so
// don't do this if it's just an invalid path.
if (iconSource == null && iconPath.Length <= 2)
{
try
{
var icon = new FontIconSource();
var ch = iconPath[0];
// The range of MDL2 Icons isn't explicitly defined, but
// we're using this based off the table on:
// https://docs.microsoft.com/en-us/windows/uwp/design/style/segoe-ui-symbol-font
var isMDL2Icon = ch >= '\uE700' && ch <= '\uF8FF';
if (isMDL2Icon)
{
icon.FontFamily = new FontFamily("Segoe Fluent Icons, Segoe MDL2 Assets");
}
else if (fontFamily != null)
{
icon.FontFamily = new FontFamily(fontFamily);
}
else
{
// Note: you do need to manually set the font here.
icon.FontFamily = new FontFamily("Segoe UI");
}
icon.FontSize = targetSize;
icon.Glyph = iconPath;
iconSource = icon;
}
catch
{
// Ignore exceptions when creating font icons
}
}
}
if (iconSource == null)
{
// Set the default IconSource to a BitmapIconSource with a null source
// (instead of just null) because there's a really weird crash when swapping
// data bound IconSourceElements in a ListViewTemplate (i.e. CommandPalette).
// Swapping between null IconSources and non-null IconSources causes a crash
// to occur, but swapping between IconSources with a null source and non-null IconSources
// work perfectly fine.
var icon = new BitmapIconSource
{
UriSource = null
};
iconSource = icon;
}
return iconSource;
}
/// <summary>
/// Creates a colored bitmap icon source for the given path.
/// </summary>
/// <param name="path">The full, expanded path to the icon.</param>
/// <param name="monochrome">Whether to show the icon as monochrome.</param>
/// <returns>An IconSource with its source set, if possible.</returns>
private static IconSource? GetColoredBitmapIcon(string path, bool monochrome)
{
// FontIcon uses glyphs in the private use area, whereas valid URIs only contain ASCII characters.
// To skip throwing on Uri construction, we can quickly check if the first character is ASCII.
if (!string.IsNullOrEmpty(path) && path[0] < 128)
{
try
{
var iconUri = new Uri(path);
if (Path.GetExtension(path).Equals(".svg", StringComparison.OrdinalIgnoreCase))
{
var iconSource = new ImageIconSource();
var source = new SvgImageSource(iconUri);
iconSource.ImageSource = source;
return iconSource;
}
else
{
var iconSource = new BitmapIconSource
{
// Make sure to set this to false, so we keep the RGB data of the
// image. Otherwise, the icon will be white for all the
// non-transparent pixels in the image.
ShowAsMonochrome = monochrome,
UriSource = iconUri
};
return iconSource;
}
}
catch (UriFormatException)
{
// Ignore exceptions when creating URI-based icons
}
}
return null;
}
/// <summary>
/// Expands environment variables in the icon path.
/// </summary>
/// <param name="iconPath">The path that may contain environment variables.</param>
/// <returns>The expanded path.</returns>
private static string ExpandIconPath(string iconPath)
{
if (string.IsNullOrEmpty(iconPath))
{
return iconPath;
}
// Use Environment.ExpandEnvironmentVariables as the C# equivalent of wil::ExpandEnvironmentStringsW
return Environment.ExpandEnvironmentVariables(iconPath);
}
/// <summary>
/// Attempts to get the icon index from the icon path provided.
/// </summary>
/// <param name="iconPath">The full icon path, including the index if present.</param>
/// <param name="iconPathWithoutIndex">The icon path without the index.</param>
/// <param name="iconIndex">The icon index if present.</param>
/// <returns>True if the iconPath is an exe/dll/lnk file, false otherwise.</returns>
private static bool TryGetIconIndex(string iconPath, out string iconPathWithoutIndex, out int iconIndex)
{
iconPathWithoutIndex = iconPath;
iconIndex = 0;
if (string.IsNullOrEmpty(iconPath))
{
return false;
}
// Does iconPath have a comma in it? If so, split the string on the
// comma and look for the index and extension.
var commaIndex = iconPath.IndexOf(',');
// Split the path on the comma
iconPathWithoutIndex = commaIndex >= 0 ? iconPath.Substring(0, commaIndex) : iconPath;
// It's an exe, dll, or lnk, so we need to extract the icon from the file.
var extension = Path.GetExtension(iconPathWithoutIndex).ToLowerInvariant();
if (extension != ".exe" && extension != ".dll" && extension != ".lnk")
{
return false;
}
if (commaIndex >= 0)
{
// Convert the string iconIndex to a signed int to support negative numbers which represent an Icon's ID.
var indexString = iconPath.Substring(commaIndex + 1);
if (int.TryParse(indexString, out iconIndex))
{
return true;
}
// Failed to parse, return false
return false;
}
// We had a binary path, but no index. Default to 0.
iconIndex = 0;
return true;
}
/// <summary>
/// Gets an image icon source for a binary file (exe, dll, lnk).
/// </summary>
/// <param name="iconPathWithoutIndex">The path to the binary file.</param>
/// <param name="index">The icon index within the file.</param>
/// <param name="targetSize">The target size for the icon.</param>
/// <returns>A SoftwareBitmapSource if successful, null otherwise.</returns>
private static SoftwareBitmapSource? GetImageIconSourceForBinary(string iconPathWithoutIndex, int index, int targetSize)
{
try
{
using var swBitmap = GetBitmapFromIconFile(iconPathWithoutIndex, index, (uint)targetSize);
if (swBitmap == null)
{
return null;
}
var bitmapSource = new SoftwareBitmapSource();
_ = bitmapSource.SetBitmapAsync(swBitmap);
return bitmapSource;
}
catch
{
return null;
}
}
/// <summary>
/// Extracts a bitmap from an icon file using Win32 APIs.
/// This implementation uses SHDefExtractIcon to extract icons from executables, DLLs, and shortcut files.
/// </summary>
/// <param name="iconPath">The path to the icon file.</param>
/// <param name="iconIndex">The index of the icon within the file.</param>
/// <param name="iconSize">The desired icon size.</param>
/// <returns>A SoftwareBitmap if successful, null otherwise.</returns>
private static SoftwareBitmap? GetBitmapFromIconFile(string iconPath, int iconIndex, uint iconSize)
{
try
{
DestroyIconSafeHandle? hIconLarge;
DestroyIconSafeHandle? hIconSmall;
// Extract the icon using SHDefExtractIcon
var result = PInvoke.SHDefExtractIcon(
iconPath,
iconIndex,
0,
out hIconLarge,
out hIconSmall,
iconSize);
using (hIconLarge)
using (hIconSmall)
{
if (result != 0 || hIconLarge.IsInvalid)
{
return null;
}
// For simplicity, convert HICON to bitmap using a more straightforward approach
// This could be enhanced to use WIC directly for better performance
return ConvertHIconToSoftwareBitmap(hIconLarge);
}
}
catch
{
return null;
}
}
/// <summary>
/// Converts an HICON to a SoftwareBitmap using Win32 APIs.
/// </summary>
/// <param name="hIcon">The icon handle to convert.</param>
/// <returns>A SoftwareBitmap if successful, null otherwise.</returns>
private static unsafe SoftwareBitmap? ConvertHIconToSoftwareBitmap(DestroyIconSafeHandle hIcon)
{
// Get icon information
if (!PInvoke.GetIconInfo(hIcon, out var iconInfo))
{
return null;
}
// Create device contexts
var hdcScreen = PInvoke.GetDC(HWND.Null);
var hdcMem = PInvoke.CreateCompatibleDC(hdcScreen);
// Get the icon size (assuming 32x32 for now, could be enhanced to get actual size)
const int iconSize = 32;
// Create a bitmap to draw the icon onto
using var hBitmap = PInvoke.CreateCompatibleBitmap_SafeHandle(hdcScreen, iconSize, iconSize);
using var hOldBitmap = PInvoke.SelectObject(hdcMem, hBitmap);
// Draw the icon onto the bitmap
PInvoke.DrawIconEx(hdcMem, 0, 0, hIcon, iconSize, iconSize, 0, null, (DI_FLAGS)0x0003); // DI_NORMAL
// Get bitmap info
var bitmapInfo = new BITMAPINFO();
bitmapInfo.bmiHeader.biSize = (uint)sizeof(BITMAPINFOHEADER);
bitmapInfo.bmiHeader.biWidth = iconSize;
bitmapInfo.bmiHeader.biHeight = -iconSize; // Top-down DIB
bitmapInfo.bmiHeader.biPlanes = 1;
bitmapInfo.bmiHeader.biBitCount = 32;
bitmapInfo.bmiHeader.biCompression = 0; // BI_RGB
// Allocate buffer for pixel data
var pixelDataSize = iconSize * iconSize * 4; // 4 bytes per pixel (BGRA)
var pixelData = new byte[pixelDataSize];
// Get the pixel data - need to pin the byte array
fixed (byte* pixelPtr = pixelData)
{
var result = PInvoke.GetDIBits(
hdcMem,
hBitmap,
0,
iconSize,
pixelPtr,
&bitmapInfo,
0); // DIB_RGB_COLORS
if (result == 0)
{
return null;
}
}
// Create SoftwareBitmap from pixel data
var softwareBitmap = SoftwareBitmap.CreateCopyFromBuffer(
pixelData.AsBuffer(),
BitmapPixelFormat.Bgra8,
iconSize,
iconSize,
BitmapAlphaMode.Premultiplied);
return softwareBitmap;
}
}

View File

@@ -1,50 +0,0 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Microsoft.CmdPal.Common.Services;
using Microsoft.CmdPal.UI.ViewModels;
namespace Microsoft.CmdPal.UI;
internal sealed class RunHistoryService : IRunHistoryService
{
private readonly AppStateModel _appStateModel;
public RunHistoryService(AppStateModel appStateModel)
{
_appStateModel = appStateModel;
}
public IReadOnlyList<string> GetRunHistory()
{
if (_appStateModel.RunHistory.Count == 0)
{
var history = Microsoft.Terminal.UI.RunHistory.CreateRunHistory();
_appStateModel.RunHistory.AddRange(history);
}
return _appStateModel.RunHistory;
}
public void ClearRunHistory()
{
_appStateModel.RunHistory.Clear();
}
public void AddRunHistoryItem(string item)
{
// insert at the beginning of the list
if (string.IsNullOrWhiteSpace(item))
{
return; // Do not add empty or whitespace items
}
_appStateModel.RunHistory.Remove(item);
// Add the item to the front of the history
_appStateModel.RunHistory.Insert(0, item);
AppStateModel.SaveState(_appStateModel);
}
}

View File

@@ -1,5 +1,5 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\..\Common.Dotnet.CsWinRT.props" />
<Import Project="..\..\..\Common.Dotnet.CsWinRT.props" />
<PropertyGroup>
<RootNamespace>Microsoft.CmdPal.UITests</RootNamespace>
@@ -21,6 +21,6 @@
<PackageReference Include="System.Net.Http" />
<PackageReference Include="System.Private.Uri" />
<PackageReference Include="System.Text.RegularExpressions" />
<ProjectReference Include="..\..\..\..\common\UITestAutomation\UITestAutomation.csproj" />
<ProjectReference Include="..\..\..\common\UITestAutomation\UITestAutomation.csproj" />
</ItemGroup>
</Project>

View File

@@ -383,5 +383,4 @@ namespace winrt::Microsoft::Terminal::UI::implementation
icon.Height(targetSize);
return icon;
}
}

View File

@@ -13,7 +13,6 @@ namespace winrt::Microsoft::Terminal::UI::implementation
static Microsoft::UI::Xaml::Controls::IconSource IconSourceMUX(const winrt::hstring& iconPath, bool convertToGrayscale, const int targetSize=24);
static Microsoft::UI::Xaml::Controls::IconElement IconMUX(const winrt::hstring& iconPath);
static Microsoft::UI::Xaml::Controls::IconElement IconMUX(const winrt::hstring& iconPath, const int targetSize);
};
}

View File

@@ -153,9 +153,6 @@
<ClInclude Include="IconPathConverter.h">
<DependentUpon>IconPathConverter.idl</DependentUpon>
</ClInclude>
<ClInclude Include="RunHistory.h">
<DependentUpon>RunHistory.idl</DependentUpon>
</ClInclude>
<ClInclude Include="ResourceString.h">
<DependentUpon>ResourceString.idl</DependentUpon>
</ClInclude>
@@ -171,9 +168,6 @@
<ClCompile Include="IconPathConverter.cpp">
<DependentUpon>IconPathConverter.idl</DependentUpon>
</ClCompile>
<ClCompile Include="RunHistory.cpp">
<DependentUpon>RunHistory.idl</DependentUpon>
</ClCompile>
<ClCompile Include="ResourceString.cpp">
<DependentUpon>ResourceString.idl</DependentUpon>
</ClCompile>
@@ -182,7 +176,6 @@
<ItemGroup>
<Midl Include="Converters.idl" />
<Midl Include="IconPathConverter.idl" />
<Midl Include="RunHistory.idl" />
<Midl Include="IDirectKeyListener.idl" />
<Midl Include="ResourceString.idl" />
</ItemGroup>

View File

@@ -1,87 +0,0 @@
#include "pch.h"
#include "RunHistory.h"
#include "RunHistory.g.cpp"
using namespace winrt::Windows;
namespace winrt::Microsoft::Terminal::UI::implementation
{
// Run history
// Largely copied from the Run work circa 2022.
winrt::Windows::Foundation::Collections::IVector<hstring> RunHistory::CreateRunHistory()
{
// Load MRU history
std::vector<hstring> history;
wil::unique_hmodule _comctl;
HANDLE(WINAPI* _createMRUList)(MRUINFO* lpmi);
int(WINAPI* _enumMRUList)(HANDLE hMRU,int nItem,void* lpData,UINT uLen);
void(WINAPI *_freeMRUList)(HANDLE hMRU);
int(WINAPI *_addMRUString)(HANDLE hMRU, LPCWSTR szString);
// Lazy load comctl32.dll
// Theoretically, we could cache this into a magic static, but we shouldn't need to actually do this more than once in CmdPal
_comctl.reset(LoadLibraryExW(L"comctl32.dll", nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32));
_createMRUList = reinterpret_cast<decltype(_createMRUList)>(GetProcAddress(_comctl.get(), "CreateMRUListW"));
FAIL_FAST_LAST_ERROR_IF(!_createMRUList);
_enumMRUList = reinterpret_cast<decltype(_enumMRUList)>(GetProcAddress(_comctl.get(), "EnumMRUListW"));
FAIL_FAST_LAST_ERROR_IF(!_enumMRUList);
_freeMRUList = reinterpret_cast<decltype(_freeMRUList)>(GetProcAddress(_comctl.get(), "FreeMRUList"));
FAIL_FAST_LAST_ERROR_IF(!_freeMRUList);
_addMRUString = reinterpret_cast<decltype(_addMRUString)>(GetProcAddress(_comctl.get(), "AddMRUStringW"));
FAIL_FAST_LAST_ERROR_IF(!_addMRUString);
static const WCHAR c_szRunMRU[] = REGSTR_PATH_EXPLORER L"\\RunMRU";
MRUINFO mi = {
sizeof(mi),
26,
MRU_CACHEWRITE,
HKEY_CURRENT_USER,
c_szRunMRU,
NULL // NOTE: use default string compare
// since this is a GLOBAL MRU
};
if (const auto hMruList = _createMRUList(&mi))
{
auto freeMRUList = wil::scope_exit([=]() {
_freeMRUList(hMruList);
});
for (int nMax = _enumMRUList(hMruList, -1, NULL, 0), i = 0; i < nMax; ++i)
{
WCHAR szCommand[MAX_PATH + 2];
const auto length = _enumMRUList(hMruList, i, szCommand, ARRAYSIZE(szCommand));
if (length > 1)
{
// clip off the null-terminator
std::wstring_view text{ szCommand, wil::safe_cast<size_t>(length - 1) };
//#pragma disable warning(C26493)
#pragma warning( push )
#pragma warning( disable : 26493 )
if (text.back() == L'\\')
{
// old MRU format has a slash at the end with the show cmd
text = { szCommand, wil::safe_cast<size_t>(length - 2) };
#pragma warning( pop )
if (text.empty())
{
continue;
}
}
history.emplace_back(text);
}
}
}
// Update dropdown & initial value
return winrt::single_threaded_observable_vector<winrt::hstring>(std::move(history));
}
}

View File

@@ -1,21 +0,0 @@
#pragma once
#include "RunHistory.g.h"
#include "types.h"
namespace winrt::Microsoft::Terminal::UI::implementation
{
struct RunHistory
{
RunHistory() = default;
static winrt::Windows::Foundation::Collections::IVector<hstring> CreateRunHistory();
private:
winrt::Windows::Foundation::Collections::IVector<hstring> _mruHistory;
};
}
namespace winrt::Microsoft::Terminal::UI::factory_implementation
{
BASIC_FACTORY(RunHistory);
}

View File

@@ -1,11 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
namespace Microsoft.Terminal.UI
{
static runtimeclass RunHistory
{
static Windows.Foundation.Collections.IVector<String> CreateRunHistory();
};
}

View File

@@ -64,8 +64,6 @@
// WIL
#include <wil/com.h>
#include <wil/resource.h>
#include <wil/safecast.h>
#include <wil/stl.h>
#include <wil/filesystem.h>
// Due to the use of RESOURCE_SUPPRESS_STL in result.h, we need to include resource.h first, which happens
@@ -92,7 +90,6 @@
#include <winrt/Windows.ApplicationModel.Resources.h>
#include <winrt/Windows.Foundation.h>
#include <winrt/Windows.Foundation.Collections.h>
#include <winrt/Windows.Graphics.Imaging.h>
#include <Windows.Graphics.Imaging.Interop.h>

View File

@@ -1,23 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#pragma once
#define MRU_CACHEWRITE 0x0002
#define REGSTR_PATH_EXPLORER TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer")
// https://learn.microsoft.com/en-us/windows/win32/shell/mrucmpproc
typedef int(CALLBACK* MRUCMPPROC)(
LPCTSTR pString1,
LPCTSTR pString2);
// https://learn.microsoft.com/en-us/windows/win32/shell/mruinfo
struct MRUINFO
{
DWORD cbSize;
UINT uMax;
UINT fFlags;
HKEY hKey;
LPCTSTR lpszSubKey;
MRUCMPPROC lpfnCompare;
};

View File

@@ -1,51 +0,0 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Microsoft.CmdPal.Ext.Calc.Helper;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace Microsoft.CmdPal.Ext.Calc.UnitTests;
[TestClass]
public class BracketHelperTests
{
[DataTestMethod]
[DataRow(null)]
[DataRow("")]
[DataRow("\t \r\n")]
[DataRow("none")]
[DataRow("()")]
[DataRow("(())")]
[DataRow("()()")]
[DataRow("(()())")]
[DataRow("([][])")]
[DataRow("([(()[])[](([]()))])")]
public void IsBracketComplete_TestValid_WhenCalled(string input)
{
// Arrange
// Act
var result = BracketHelper.IsBracketComplete(input);
// Assert
Assert.IsTrue(result);
}
[DataTestMethod]
[DataRow("((((", "only opening brackets")]
[DataRow("]]]", "only closing brackets")]
[DataRow("([)(])", "inner bracket mismatch")]
[DataRow(")(", "opening and closing reversed")]
[DataRow("(]", "mismatch in bracket type")]
public void IsBracketComplete_TestInvalid_WhenCalled(string input, string invalidReason)
{
// Arrange
// Act
var result = BracketHelper.IsBracketComplete(input);
// Assert
Assert.IsFalse(result, invalidReason);
}
}

View File

@@ -1,389 +0,0 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
using System.Globalization;
using Microsoft.CmdPal.Ext.Calc.Helper;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace Microsoft.CmdPal.Ext.Calc.UnitTests;
[TestClass]
public class ExtendedCalculatorParserTests
{
[DataTestMethod]
[DataRow(null)]
[DataRow("")]
[DataRow(" ")]
public void InputValid_ThrowError_WhenCalledNullOrEmpty(string input)
{
// Act
Assert.IsTrue(!CalculateHelper.InputValid(input));
}
[DataTestMethod]
[DataRow("test")]
[DataRow("[10,10]")] // '[10,10]' is interpreted as array by mages engine
public void Interpret_NoResult_WhenCalled(string input)
{
var settings = new SettingsManager();
var result = CalculateEngine.Interpret(settings, input, CultureInfo.CurrentCulture, out _);
// Assert
Assert.AreEqual(default(CalculateResult), result);
}
private static IEnumerable<object[]> Interpret_NoErrors_WhenCalledWithRounding_Data =>
[
["2 * 2", 4M],
["-2 ^ 2", -4M],
["-(2 ^ 2)", -4M],
["2 * pi", 6.28318530717959M],
["round(2 * pi)", 6M],
// ["1 == 2", default(decimal)],
["pi * ( sin ( cos ( 2)))", -1.26995475603563M],
["5.6/2", 2.8M],
["123 * 4.56", 560.88M],
["1 - 9.0 / 10", 0.1M],
["0.5 * ((2*-395.2)+198.2)", -296.1M],
["2+2.11", 4.11M],
["8.43 + 4.43 - 12.86", 0M],
["8.43 + 4.43 - 12.8", 0.06M],
["exp(5)", 148.413159102577M],
["e^5", 148.413159102577M],
["e*2", 5.43656365691809M],
["ln(3)", 1.09861228866811M],
["log(3)", 0.47712125471966M],
["log2(3)", 1.58496250072116M],
["log10(3)", 0.47712125471966M],
["ln(e)", 1M],
["cosh(0)", 1M],
];
[DataTestMethod]
[DynamicData(nameof(Interpret_NoErrors_WhenCalledWithRounding_Data))]
public void Interpret_NoErrors_WhenCalledWithRounding(string input, decimal expectedResult)
{
var settings = new SettingsManager();
// Act
// Using InvariantCulture since this is internal
var result = CalculateEngine.Interpret(settings, input, CultureInfo.InvariantCulture, out _);
// Assert
Assert.IsNotNull(result);
Assert.AreEqual(CalculateEngine.FormatMax15Digits(expectedResult, new CultureInfo("en-US")), result.RoundedResult);
}
private static IEnumerable<object[]> Interpret_GreaterPrecision_WhenCalled_Data =>
[
["0.100000000000000000000", 0.1M],
["0.200000000000000000000000", 0.2M],
];
[DynamicData(nameof(Interpret_GreaterPrecision_WhenCalled_Data))]
[DataTestMethod]
public void Interpret_GreaterPrecision_WhenCalled(string input, decimal expectedResult)
{
// Arrange
var settings = new SettingsManager();
// Act
// Using InvariantCulture since this is internal
var result = CalculateEngine.Interpret(settings, input, CultureInfo.InvariantCulture, out _);
// Assert
Assert.IsNotNull(result);
Assert.AreEqual(expectedResult, result.Result);
}
private static IEnumerable<object[]> Interpret_DifferentCulture_WhenCalled_Data =>
[
["4.5/3", 1.5M, "nl-NL"],
["4.5/3", 1.5M, "en-EN"],
["4.5/3", 1.5M, "de-DE"],
];
[DataTestMethod]
[DynamicData(nameof(Interpret_DifferentCulture_WhenCalled_Data))]
public void Interpret_DifferentCulture_WhenCalled(string input, decimal expectedResult, string cultureName)
{
// Arrange
var cultureInfo = CultureInfo.GetCultureInfo(cultureName);
var settings = new SettingsManager();
// Act
var result = CalculateEngine.Interpret(settings, input, cultureInfo, out _);
// Assert
Assert.IsNotNull(result);
Assert.AreEqual(CalculateEngine.Round(expectedResult), result.RoundedResult);
}
[DataTestMethod]
[DataRow("log(3)", true)]
[DataRow("ln(3)", true)]
[DataRow("log2(3)", true)]
[DataRow("log10(3)", true)]
[DataRow("log2", false)]
[DataRow("log10", false)]
[DataRow("log", false)]
[DataRow("ln", false)]
[DataRow("ceil(2 * (pi ^ 2))", true)]
[DataRow("((1 * 2)", false)]
[DataRow("(1 * 2)))", false)]
[DataRow("abcde", false)]
[DataRow("1 + 2 +", false)]
[DataRow("1+2*", false)]
[DataRow("1+2/", false)]
[DataRow("1+2%", false)]
[DataRow("1 && 3 &&", false)]
[DataRow("sqrt( 36)", true)]
[DataRow("max 4", false)]
[DataRow("sin(0)", true)]
[DataRow("sinh(1)", true)]
[DataRow("tanh(0)", true)]
[DataRow("artanh(pi/2)", true)]
[DataRow("cosh", false)]
[DataRow("cos", false)]
[DataRow("abs", false)]
[DataRow("1+1.1e3", true)]
[DataRow("randi(8)", true)]
[DataRow("randi()", false)]
[DataRow("randi(0.5)", true)]
[DataRow("rand()", true)]
[DataRow("rand(0.5)", false)]
[DataRow("0X78AD+0o123", true)]
[DataRow("0o9", false)]
public void InputValid_TestValid_WhenCalled(string input, bool valid)
{
// Act
var result = CalculateHelper.InputValid(input);
// Assert
Assert.AreEqual(valid, result);
}
[DataTestMethod]
[DataRow("1-1")]
[DataRow("sin(0)")]
[DataRow("sinh(0)")]
public void Interpret_MustReturnResult_WhenResultIsZero(string input)
{
// Arrange
var settings = new SettingsManager();
// Act
// Using InvariantCulture since this is internal
var result = CalculateEngine.Interpret(settings, input, CultureInfo.InvariantCulture, out _);
// Assert
Assert.IsNotNull(result);
Assert.AreEqual(0.0M, result.Result);
}
private static IEnumerable<object[]> Interpret_MustReturnExpectedResult_WhenCalled_Data =>
[
// ["factorial(5)", 120M], ToDo: this don't support now
// ["sign(-2)", -1M],
// ["sign(2)", +1M],
["abs(-2)", 2M],
["abs(2)", 2M],
["0+(1*2)/(0+1)", 2M], // Validate that division by "(0+1)" is not interpret as division by zero.
["0+(1*2)/0.5", 4M], // Validate that division by number with decimal digits is not interpret as division by zero.
];
[DataTestMethod]
[DynamicData(nameof(Interpret_MustReturnExpectedResult_WhenCalled_Data))]
public void Interpret_MustReturnExpectedResult_WhenCalled(string input, decimal expectedResult)
{
// Arrange
var settings = new SettingsManager();
// Act
// Using en-us culture to have a fixed number style
var result = CalculateEngine.Interpret(settings, input, new CultureInfo("en-us", false), out _);
// Assert
Assert.IsNotNull(result);
Assert.AreEqual(expectedResult, result.Result);
}
private static IEnumerable<object[]> Interpret_TestScientificNotation_WhenCalled_Data =>
[
["0.2E1", "en-US", 2M],
["0,2E1", "pt-PT", 2M],
];
[DataTestMethod]
[DynamicData(nameof(Interpret_TestScientificNotation_WhenCalled_Data))]
public void Interpret_TestScientificNotation_WhenCalled(string input, string sourceCultureName, decimal expectedResult)
{
// Arrange
var translator = NumberTranslator.Create(new CultureInfo(sourceCultureName, false), new CultureInfo("en-US", false));
var settings = new SettingsManager();
// Act
// Using en-us culture to have a fixed number style
var translatedInput = translator.Translate(input);
var result = CalculateEngine.Interpret(settings, translatedInput, new CultureInfo("en-US", false), out _);
// Assert
Assert.IsNotNull(result);
Assert.AreEqual(expectedResult, result.Result);
}
[DataTestMethod]
[DataRow("sin(90)", "sin((pi / 180) * (90))")]
[DataRow("arcsin(0.5)", "(180 / pi) * (arcsin(0.5))")]
[DataRow("sin(sin(30))", "sin((pi / 180) * (sin((pi / 180) * (30))))")]
[DataRow("cos(tan(45))", "cos((pi / 180) * (tan((pi / 180) * (45))))")]
[DataRow("arctan(sin(30))", "(180 / pi) * (arctan(sin((pi / 180) * (30))))")]
[DataRow("sin(cos(tan(30)))", "sin((pi / 180) * (cos((pi / 180) * (tan((pi / 180) * (30))))))")]
[DataRow("sin(arcsin(0.5))", "sin((pi / 180) * ((180 / pi) * (arcsin(0.5))))")]
[DataRow("sin(30) + cos(60)", "sin((pi / 180) * (30)) + cos((pi / 180) * (60))")]
[DataRow("sin(30 + 15)", "sin((pi / 180) * (30 + 15))")]
[DataRow("sin(45) * cos(45) - tan(30)", "sin((pi / 180) * (45)) * cos((pi / 180) * (45)) - tan((pi / 180) * (30))")]
[DataRow("arcsin(arccos(0.5))", "(180 / pi) * (arcsin((180 / pi) * (arccos(0.5))))")]
[DataRow("sin(sin(sin(30)))", "sin((pi / 180) * (sin((pi / 180) * (sin((pi / 180) * (30))))))")]
[DataRow("log(10)", "log(10)")]
[DataRow("sin(30) + pi", "sin((pi / 180) * (30)) + pi")]
[DataRow("sin(-30)", "sin((pi / 180) * (-30))")]
[DataRow("sin((30))", "sin((pi / 180) * ((30)))")]
[DataRow("arcsin(1) * 2", "(180 / pi) * (arcsin(1)) * 2")]
[DataRow("cos(1/2)", "cos((pi / 180) * (1/2))")]
[DataRow("sin ( 90 )", "sin ((pi / 180) * ( 90 ))")]
[DataRow("cos(arcsin(sin(45)))", "cos((pi / 180) * ((180 / pi) * (arcsin(sin((pi / 180) * (45))))))")]
public void UpdateTrigFunctions_Degrees(string input, string expectedResult)
{
// Call UpdateTrigFunctions in degrees mode
var result = CalculateHelper.UpdateTrigFunctions(input, CalculateEngine.TrigMode.Degrees);
// Assert
Assert.IsNotNull(result);
Assert.AreEqual(expectedResult, result);
}
[DataTestMethod]
[DataRow("sin(90)", "sin((pi / 200) * (90))")]
[DataRow("arcsin(0.5)", "(200 / pi) * (arcsin(0.5))")]
[DataRow("sin(sin(30))", "sin((pi / 200) * (sin((pi / 200) * (30))))")]
[DataRow("cos(tan(45))", "cos((pi / 200) * (tan((pi / 200) * (45))))")]
[DataRow("arctan(sin(30))", "(200 / pi) * (arctan(sin((pi / 200) * (30))))")]
[DataRow("sin(cos(tan(30)))", "sin((pi / 200) * (cos((pi / 200) * (tan((pi / 200) * (30))))))")]
[DataRow("sin(arcsin(0.5))", "sin((pi / 200) * ((200 / pi) * (arcsin(0.5))))")]
[DataRow("sin(30) + cos(60)", "sin((pi / 200) * (30)) + cos((pi / 200) * (60))")]
[DataRow("sin(30 + 15)", "sin((pi / 200) * (30 + 15))")]
[DataRow("sin(45) * cos(45) - tan(30)", "sin((pi / 200) * (45)) * cos((pi / 200) * (45)) - tan((pi / 200) * (30))")]
[DataRow("arcsin(arccos(0.5))", "(200 / pi) * (arcsin((200 / pi) * (arccos(0.5))))")]
[DataRow("sin(sin(sin(30)))", "sin((pi / 200) * (sin((pi / 200) * (sin((pi / 200) * (30))))))")]
[DataRow("log(10)", "log(10)")]
[DataRow("sin(30) + pi", "sin((pi / 200) * (30)) + pi")]
[DataRow("sin(-30)", "sin((pi / 200) * (-30))")]
[DataRow("sin((30))", "sin((pi / 200) * ((30)))")]
[DataRow("arcsin(1) * 2", "(200 / pi) * (arcsin(1)) * 2")]
[DataRow("cos(1/2)", "cos((pi / 200) * (1/2))")]
[DataRow("sin ( 90 )", "sin ((pi / 200) * ( 90 ))")]
[DataRow("cos(arcsin(sin(45)))", "cos((pi / 200) * ((200 / pi) * (arcsin(sin((pi / 200) * (45))))))")]
public void UpdateTrigFunctions_Gradians(string input, string expectedResult)
{
// Call UpdateTrigFunctions in gradians mode
var result = CalculateHelper.UpdateTrigFunctions(input, CalculateEngine.TrigMode.Gradians);
// Assert
Assert.IsNotNull(result);
Assert.AreEqual(expectedResult, result);
}
[DataTestMethod]
[DataRow("rad(30)", "(180 / pi) * (30)")]
[DataRow("rad( 30 )", "(180 / pi) * ( 30 )")]
[DataRow("deg(30)", "(30)")]
[DataRow("grad(30)", "(9 / 10) * (30)")]
[DataRow("rad( 30)", "(180 / pi) * ( 30)")]
[DataRow("rad(30 )", "(180 / pi) * (30 )")]
[DataRow("rad( 30 )", "(180 / pi) * ( 30 )")]
[DataRow("rad(deg(30))", "(180 / pi) * ((30))")]
[DataRow("deg(rad(30))", "((180 / pi) * (30))")]
[DataRow("grad(rad(30))", "(9 / 10) * ((180 / pi) * (30))")]
[DataRow("rad(grad(30))", "(180 / pi) * ((9 / 10) * (30))")]
[DataRow("rad(30) + deg(45)", "(180 / pi) * (30) + (45)")]
[DataRow("sin(rad(30))", "sin((180 / pi) * (30))")]
[DataRow("cos( rad( 45 ) )", "cos( (180 / pi) * ( 45 ) )")]
[DataRow("tan(rad(grad(90)))", "tan((180 / pi) * ((9 / 10) * (90)))")]
[DataRow("rad(30) + rad(45)", "(180 / pi) * (30) + (180 / pi) * (45)")]
[DataRow("rad(30) * grad(90)", "(180 / pi) * (30) * (9 / 10) * (90)")]
[DataRow("rad(30)/rad(45)", "(180 / pi) * (30)/(180 / pi) * (45)")]
public void ExpandTrigConversions_Degrees(string input, string expectedResult)
{
// Call ExpandTrigConversions in degrees mode
var result = CalculateHelper.ExpandTrigConversions(input, CalculateEngine.TrigMode.Degrees);
// Assert
Assert.IsNotNull(result);
Assert.AreEqual(expectedResult, result);
}
[DataTestMethod]
[DataRow("rad(30)", "(30)")]
[DataRow("rad( 30 )", "( 30 )")]
[DataRow("deg(30)", "(pi / 180) * (30)")]
[DataRow("grad(30)", "(pi / 200) * (30)")]
[DataRow("rad( 30)", "( 30)")]
[DataRow("rad(30 )", "(30 )")]
[DataRow("rad( 30 )", "( 30 )")]
[DataRow("rad(deg(30))", "((pi / 180) * (30))")]
[DataRow("deg(rad(30))", "(pi / 180) * ((30))")]
[DataRow("grad(rad(30))", "(pi / 200) * ((30))")]
[DataRow("rad(grad(30))", "((pi / 200) * (30))")]
[DataRow("rad(30) + deg(45)", "(30) + (pi / 180) * (45)")]
[DataRow("sin(rad(30))", "sin((30))")]
[DataRow("cos( rad( 45 ) )", "cos( ( 45 ) )")]
[DataRow("tan(rad(grad(90)))", "tan(((pi / 200) * (90)))")]
[DataRow("rad(30) + rad(45)", "(30) + (45)")]
[DataRow("rad(30) * grad(90)", "(30) * (pi / 200) * (90)")]
[DataRow("rad(30)/rad(45)", "(30)/(45)")]
public void ExpandTrigConversions_Radians(string input, string expectedResult)
{
// Call ExpandTrigConversions in radians mode
var result = CalculateHelper.ExpandTrigConversions(input, CalculateEngine.TrigMode.Radians);
// Assert
Assert.IsNotNull(result);
Assert.AreEqual(expectedResult, result);
}
[DataTestMethod]
[DataRow("rad(30)", "(200 / pi) * (30)")]
[DataRow("rad( 30 )", "(200 / pi) * ( 30 )")]
[DataRow("deg(30)", "(10 / 9) * (30)")]
[DataRow("grad(30)", "(30)")]
[DataRow("rad( 30)", "(200 / pi) * ( 30)")]
[DataRow("rad(30 )", "(200 / pi) * (30 )")]
[DataRow("rad( 30 )", "(200 / pi) * ( 30 )")]
[DataRow("rad(deg(30))", "(200 / pi) * ((10 / 9) * (30))")]
[DataRow("deg(rad(30))", "(10 / 9) * ((200 / pi) * (30))")]
[DataRow("grad(rad(30))", "((200 / pi) * (30))")]
[DataRow("rad(grad(30))", "(200 / pi) * ((30))")]
[DataRow("rad(30) + deg(45)", "(200 / pi) * (30) + (10 / 9) * (45)")]
[DataRow("sin(rad(30))", "sin((200 / pi) * (30))")]
[DataRow("cos( rad( 45 ) )", "cos( (200 / pi) * ( 45 ) )")]
[DataRow("tan(rad(grad(90)))", "tan((200 / pi) * ((90)))")]
[DataRow("rad(30) + rad(45)", "(200 / pi) * (30) + (200 / pi) * (45)")]
[DataRow("rad(30) * grad(90)", "(200 / pi) * (30) * (90)")]
[DataRow("rad(30)/rad(45)", "(200 / pi) * (30)/(200 / pi) * (45)")]
public void ExpandTrigConversions_Gradians(string input, string expectedResult)
{
// Call ExpandTrigConversions in gradians mode
var result = CalculateHelper.ExpandTrigConversions(input, CalculateEngine.TrigMode.Gradians);
// Assert
Assert.IsNotNull(result);
Assert.AreEqual(expectedResult, result);
}
}

View File

@@ -1,18 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<!-- Look at Directory.Build.props in root for common stuff as well -->
<Import Project="..\..\..\..\Common.Dotnet.CsWinRT.props" />
<PropertyGroup>
<IsPackable>false</IsPackable>
<RootNamespace>Microsoft.CmdPal.Ext.Calc.UnitTests</RootNamespace>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Moq" />
<PackageReference Include="MSTest" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\ext\Microsoft.CmdPal.Ext.Calc\Microsoft.CmdPal.Ext.Calc.csproj" />
</ItemGroup>
</Project>

View File

@@ -1,185 +0,0 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Globalization;
using Microsoft.CmdPal.Ext.Calc.Helper;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace Microsoft.CmdPal.Ext.Calc.UnitTests;
[TestClass]
public class NumberTranslatorTests
{
[DataTestMethod]
[DataRow(null, "en-US")]
[DataRow("de-DE", null)]
public void Create_ThrowError_WhenCalledNullOrEmpty(string sourceCultureName, string targetCultureName)
{
// Arrange
CultureInfo sourceCulture = sourceCultureName != null ? new CultureInfo(sourceCultureName) : null;
CultureInfo targetCulture = targetCultureName != null ? new CultureInfo(targetCultureName) : null;
// Act
Assert.ThrowsException<ArgumentNullException>(() => NumberTranslator.Create(sourceCulture, targetCulture));
}
[DataTestMethod]
[DataRow("en-US", "en-US")]
[DataRow("en-EN", "en-US")]
[DataRow("de-DE", "en-US")]
public void Create_WhenCalled(string sourceCultureName, string targetCultureName)
{
// Arrange
CultureInfo sourceCulture = new CultureInfo(sourceCultureName);
CultureInfo targetCulture = new CultureInfo(targetCultureName);
// Act
var translator = NumberTranslator.Create(sourceCulture, targetCulture);
// Assert
Assert.IsNotNull(translator);
}
[DataTestMethod]
[DataRow(null)]
public void Translate_ThrowError_WhenCalledNull(string input)
{
// Arrange
var translator = NumberTranslator.Create(new CultureInfo("de-DE", false), new CultureInfo("en-US", false));
// Act
Assert.ThrowsException<ArgumentNullException>(() => translator.Translate(input));
}
[DataTestMethod]
[DataRow("")]
[DataRow(" ")]
public void Translate_WhenCalledEmpty(string input)
{
// Arrange
var translator = NumberTranslator.Create(new CultureInfo("de-DE", false), new CultureInfo("en-US", false));
// Act
var result = translator.Translate(input);
// Assert
Assert.AreEqual(input, result);
}
[DataTestMethod]
[DataRow("2,0 * 2", "2.0 * 2")]
[DataRow("4 * 3,6 + 9", "4 * 3.6 + 9")]
[DataRow("5,2+6", "5.2+6")]
[DataRow("round(2,5)", "round(2.5)")]
[DataRow("3,3333", "3.3333")]
[DataRow("max(2;3)", "max(2,3)")]
public void Translate_NoErrors_WhenCalled(string input, string expectedResult)
{
// Arrange
var translator = NumberTranslator.Create(new CultureInfo("de-DE", false), new CultureInfo("en-US", false));
// Act
var result = translator.Translate(input);
// Assert
Assert.IsNotNull(result);
Assert.AreEqual(expectedResult, result);
}
[DataTestMethod]
[DataRow("2.0 * 2", "2,0 * 2")]
[DataRow("4 * 3.6 + 9", "4 * 3,6 + 9")]
[DataRow("5.2+6", "5,2+6")]
[DataRow("round(2.5)", "round(2,5)")]
[DataRow("3.3333", "3,3333")]
public void TranslateBack_NoErrors_WhenCalled(string input, string expectedResult)
{
// Arrange
var translator = NumberTranslator.Create(new CultureInfo("de-DE", false), new CultureInfo("en-US", false));
// Act
var result = translator.TranslateBack(input);
// Assert
Assert.IsNotNull(result);
Assert.AreEqual(expectedResult, result);
}
[DataTestMethod]
[DataRow(".", ",", "2,000,000", "2000000")]
[DataRow(".", ",", "2,000,000.6", "2000000.6")]
[DataRow(",", ".", "2.000.000", "2000000")]
[DataRow(",", ".", "2.000.000,6", "2000000.6")]
public void Translate_RemoveNumberGroupSeparator_WhenCalled(string decimalSeparator, string groupSeparator, string input, string expectedResult)
{
// Arrange
var sourceCulture = new CultureInfo("en-US", false)
{
NumberFormat =
{
NumberDecimalSeparator = decimalSeparator,
NumberGroupSeparator = groupSeparator,
},
};
var translator = NumberTranslator.Create(sourceCulture, new CultureInfo("en-US", false));
// Act
var result = translator.Translate(input);
// Assert
Assert.IsNotNull(result);
Assert.AreEqual(expectedResult, result);
}
[DataTestMethod]
[DataRow("de-DE", "12,0004", "12.0004")]
[DataRow("de-DE", "0xF000", "61440")]
[DataRow("de-DE", "0", "0")]
[DataRow("de-DE", "00", "0")]
[DataRow("de-DE", "12.004", "12004")] // . is the group separator in de-DE
[DataRow("de-DE", "12.04", "1204")]
[DataRow("de-DE", "12.4", "124")]
[DataRow("de-DE", "3.004.044.444,05", "3004044444.05")]
[DataRow("de-DE", "123.01 + 52.30", "12301 + 5230")]
[DataRow("de-DE", "123.001 + 52.30", "123001 + 5230")]
[DataRow("fr-FR", "0", "0")]
[DataRow("fr-FR", "00", "0")]
[DataRow("fr-FR", "12.004", "12.004")] // . is not decimal or group separator in fr-FR
[DataRow("fr-FR", "12.04", "12.04")]
[DataRow("fr-FR", "12.4", "12.4")]
[DataRow("fr-FR", "12.0004", "12.0004")]
// [DataRow("fr-FR", "123.01 + 52.30", "123.01 + 52.30")]
// [DataRow("fr-FR", "123.001 + 52.30", "123.001 + 52.30")] passed locally, failed in CI
public void Translate_NoRemovalOfLeadingZeroesOnEdgeCases(string sourceCultureName, string input, string expectedResult)
{
// Arrange
var translator = NumberTranslator.Create(new CultureInfo(sourceCultureName, false), new CultureInfo("en-US", false));
// Act
var result = translator.Translate(input);
// Assert
Assert.IsNotNull(result);
Assert.AreEqual(expectedResult, result);
}
[DataTestMethod]
[DataRow("en-US", "0xF000", "61440")]
[DataRow("en-US", "0xf4572220", "4099351072")]
[DataRow("en-US", "0x12345678", "305419896")]
public void Translate_LargeHexadecimalNumbersToDecimal(string sourceCultureName, string input, string expectedResult)
{
// Arrange
var translator = NumberTranslator.Create(new CultureInfo(sourceCultureName, false), new CultureInfo("en-US", false));
// Act
var result = translator.Translate(input);
// Assert
Assert.IsNotNull(result);
Assert.AreEqual(expectedResult, result);
}
}

View File

@@ -108,7 +108,7 @@ public static class CalculateEngine
/// 100000.9999999999 → "100001"
/// 1234567890123.45 → "1234567890123.45"
/// </summary>
public static decimal FormatMax15Digits(decimal value, CultureInfo cultureInfo)
private static decimal FormatMax15Digits(decimal value, CultureInfo cultureInfo)
{
var absValue = Math.Abs(value);
var integerDigits = absValue >= 1 ? (int)Math.Floor(Math.Log10((double)absValue)) + 1 : 1;

View File

@@ -63,7 +63,7 @@ public static partial class QueryHelper
return ResultHelper.CreateResult(result.RoundedResult, inputCulture, outputCulture, query);
}
return ResultHelper.CreateResult(result.RoundedResult, inputCulture, outputCulture, query, settings, handleSave);
return ResultHelper.CreateResult(result.RoundedResult, inputCulture, outputCulture, query, handleSave);
}
catch (OverflowException)
{

View File

@@ -13,7 +13,7 @@ namespace Microsoft.CmdPal.Ext.Calc.Helper;
public static class ResultHelper
{
public static ListItem CreateResult(decimal? roundedResult, CultureInfo inputCulture, CultureInfo outputCulture, string query, SettingsManager settings, TypedEventHandler<object, object> handleSave)
public static ListItem CreateResult(decimal? roundedResult, CultureInfo inputCulture, CultureInfo outputCulture, string query, TypedEventHandler<object, object> handleSave)
{
// Return null when the expression is not a valid calculator query.
if (roundedResult == null)
@@ -32,14 +32,19 @@ public static class ResultHelper
// No TextToSuggest on the main save command item. We don't want to keep suggesting what the result is,
// as the user is typing it.
return new ListItem(settings.CloseOnEnter ? copyCommandItem.Command : saveCommand)
return new ListItem(saveCommand)
{
// Using CurrentCulture since this is user facing
Icon = Icons.ResultIcon,
Title = result,
Subtitle = query,
MoreCommands = [
new CommandContextItem(settings.CloseOnEnter ? saveCommand : copyCommandItem.Command),
new CommandContextItem(copyCommandItem.Command)
{
Icon = copyCommandItem.Icon,
Title = copyCommandItem.Title,
Subtitle = copyCommandItem.Subtitle,
},
..copyCommandItem.MoreCommands,
],
};

View File

@@ -39,12 +39,6 @@ public class SettingsManager : JsonSettingsManager
Properties.Resources.calculator_settings_out_en_format_description,
false);
private readonly ToggleSetting _closeOnEnter = new(
Namespaced(nameof(CloseOnEnter)),
Properties.Resources.calculator_settings_close_on_enter,
Properties.Resources.calculator_settings_close_on_enter_description,
true);
public CalculateEngine.TrigMode TrigUnit
{
get
@@ -79,8 +73,6 @@ public class SettingsManager : JsonSettingsManager
public bool OutputUseEnglishFormat => _outputUseEnNumberFormat.Value;
public bool CloseOnEnter => _closeOnEnter.Value;
internal static string SettingsJsonPath()
{
var directory = Utilities.BaseSettingsPath("Microsoft.CmdPal");
@@ -97,7 +89,6 @@ public class SettingsManager : JsonSettingsManager
Settings.Add(_trigUnit);
Settings.Add(_inputUseEnNumberFormat);
Settings.Add(_outputUseEnNumberFormat);
Settings.Add(_closeOnEnter);
// Load settings from file upon initialization
LoadSettings();

View File

@@ -186,24 +186,6 @@ namespace Microsoft.CmdPal.Ext.Calc.Properties {
}
}
/// <summary>
/// Looks up a localized string similar to Close on Enter.
/// </summary>
public static string calculator_settings_close_on_enter {
get {
return ResourceManager.GetString("calculator_settings_close_on_enter", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Makes Copy and close the primary command.
/// </summary>
public static string calculator_settings_close_on_enter_description {
get {
return ResourceManager.GetString("calculator_settings_close_on_enter_description", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Use English (United States) number format for input.
/// </summary>

View File

@@ -184,12 +184,6 @@
<value>Ignores your system setting and expects numbers in the format '{0}'.</value>
<comment>{0} is a placeholder and will be replaced in code.</comment>
</data>
<data name="calculator_settings_close_on_enter" xml:space="preserve">
<value>Close on Enter</value>
</data>
<data name="calculator_settings_close_on_enter_description" xml:space="preserve">
<value>Makes Copy and close the primary command</value>
</data>
<data name="calculator_settings_replace_input" xml:space="preserve">
<value>Replace input if query ends with '='</value>
</data>

View File

@@ -11,6 +11,12 @@
<ProjectPriFileName>Microsoft.CmdPal.Ext.Registry.pri</ProjectPriFileName>
</PropertyGroup>
<ItemGroup>
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo">
<_Parameter1>Microsoft.CmdPal.Ext.Registry.UnitTests</_Parameter1>
</AssemblyAttribute>
</ItemGroup>
<ItemGroup>
<PackageReference Include="System.ServiceProcess.ServiceController" />
</ItemGroup>

View File

@@ -1,7 +0,0 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo("Microsoft.CmdPal.Ext.Registry.UnitTests")]

View File

@@ -15,11 +15,10 @@ namespace Microsoft.CmdPal.Ext.Shell;
internal sealed partial class FallbackExecuteItem : FallbackCommandItem, IDisposable
{
private readonly Action<string>? _addToHistory;
private CancellationTokenSource? _cancellationTokenSource;
private Task? _currentUpdateTask;
public FallbackExecuteItem(SettingsManager settings, Action<string>? addToHistory)
public FallbackExecuteItem(SettingsManager settings)
: base(
new NoOpCommand() { Id = "com.microsoft.run.fallback" },
Resources.shell_command_display_title)
@@ -27,7 +26,6 @@ internal sealed partial class FallbackExecuteItem : FallbackCommandItem, IDispos
Title = string.Empty;
Subtitle = Properties.Resources.generic_run_command;
Icon = Icons.RunV2Icon; // Defined in Icons.cs and contains the execute command icon.
_addToHistory = addToHistory;
}
public override void UpdateQuery(string query)
@@ -144,7 +142,7 @@ internal sealed partial class FallbackExecuteItem : FallbackCommandItem, IDispos
if (exeExists)
{
// TODO we need to probably get rid of the settings for this provider entirely
var exeItem = ShellListPage.CreateExeItem(exe, args, fullExePath, _addToHistory);
var exeItem = ShellListPage.CreateExeItem(exe, args, fullExePath);
Title = exeItem.Title;
Subtitle = exeItem.Subtitle;
Icon = exeItem.Icon;
@@ -153,7 +151,7 @@ internal sealed partial class FallbackExecuteItem : FallbackCommandItem, IDispos
}
else if (pathIsDir)
{
var pathItem = new PathListItem(exe, query, _addToHistory);
var pathItem = new PathListItem(exe, query);
Title = pathItem.Title;
Subtitle = pathItem.Subtitle;
Icon = pathItem.Icon;
@@ -162,7 +160,7 @@ internal sealed partial class FallbackExecuteItem : FallbackCommandItem, IDispos
}
else if (System.Uri.TryCreate(searchText, UriKind.Absolute, out var uri))
{
Command = new OpenUrlWithHistoryCommand(searchText, _addToHistory) { Result = CommandResult.Dismiss() };
Command = new OpenUrlCommand(searchText) { Result = CommandResult.Dismiss() };
Title = searchText;
}
else

View File

@@ -7,9 +7,7 @@ using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CmdPal.Ext.Shell.Commands;
using Microsoft.CmdPal.Ext.Shell.Pages;
using Microsoft.CommandPalette.Extensions.Toolkit;
namespace Microsoft.CmdPal.Ext.Shell.Helpers;
@@ -96,80 +94,4 @@ public class ShellListPageHelpers
}
}
}
internal static ListItem? ListItemForCommandString(string query, Action<string>? addToHistory)
{
var li = new ListItem();
var searchText = query.Trim();
var expanded = Environment.ExpandEnvironmentVariables(searchText);
searchText = expanded;
if (string.IsNullOrEmpty(searchText) || string.IsNullOrWhiteSpace(searchText))
{
return null;
}
ShellListPage.ParseExecutableAndArgs(searchText, out var exe, out var args);
var exeExists = false;
var pathIsDir = false;
var fullExePath = string.Empty;
try
{
using var cts = new CancellationTokenSource(TimeSpan.FromMilliseconds(200));
// Use Task.Run with timeout - this will actually timeout even if the sync operations don't respond to cancellation
var pathResolutionTask = Task.Run(
() =>
{
// Don't check cancellation token here - let the Task timeout handle it
exeExists = ShellListPageHelpers.FileExistInPath(exe, out fullExePath);
pathIsDir = Directory.Exists(expanded);
},
CancellationToken.None); // Use None here since we're handling timeout differently
// Wait for either completion or timeout
pathResolutionTask.Wait(cts.Token);
}
catch (OperationCanceledException)
{
}
if (exeExists)
{
// TODO we need to probably get rid of the settings for this provider entirely
var exeItem = ShellListPage.CreateExeItem(exe, args, fullExePath, addToHistory);
li.Command = exeItem.Command;
li.Title = exeItem.Title;
li.Subtitle = exeItem.Subtitle;
li.Icon = exeItem.Icon;
li.MoreCommands = exeItem.MoreCommands;
}
else if (pathIsDir)
{
var pathItem = new PathListItem(exe, query, addToHistory);
li.Command = pathItem.Command;
li.Title = pathItem.Title;
li.Subtitle = pathItem.Subtitle;
li.Icon = pathItem.Icon;
li.MoreCommands = pathItem.MoreCommands;
}
else if (System.Uri.TryCreate(searchText, UriKind.Absolute, out var uri))
{
li.Command = new OpenUrlWithHistoryCommand(searchText) { Result = CommandResult.Dismiss() };
li.Title = searchText;
}
else
{
return null;
}
if (li != null)
{
li.TextToSuggest = searchText;
}
return li;
}
}

View File

@@ -14,7 +14,6 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\extensionsdk\Microsoft.CommandPalette.Extensions.Toolkit\Microsoft.CommandPalette.Extensions.Toolkit.csproj" />
<ProjectReference Include="..\..\Microsoft.CmdPal.Common\Microsoft.CmdPal.Common.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="System.CommandLine" />

View File

@@ -1,30 +0,0 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.IO;
using Microsoft.CommandPalette.Extensions;
using Microsoft.CommandPalette.Extensions.Toolkit;
namespace Microsoft.CmdPal.Ext.Shell;
internal sealed partial class OpenUrlWithHistoryCommand : OpenUrlCommand
{
private readonly Action<string>? _addToHistory;
private readonly string _url;
public OpenUrlWithHistoryCommand(string url, Action<string>? addToHistory = null)
: base(url)
{
_addToHistory = addToHistory;
_url = url;
}
public override CommandResult Invoke()
{
_addToHistory?.Invoke(_url);
var result = base.Invoke();
return result;
}
}

View File

@@ -13,7 +13,6 @@ namespace Microsoft.CmdPal.Ext.Shell.Pages;
internal sealed partial class RunExeItem : ListItem
{
private readonly Lazy<IconInfo> _icon;
private readonly Action<string>? _addToHistory;
public override IIconInfo? Icon { get => _icon.Value; set => base.Icon = value; }
@@ -23,9 +22,7 @@ internal sealed partial class RunExeItem : ListItem
private string _args = string.Empty;
private string FullString => string.IsNullOrEmpty(_args) ? Exe : $"{Exe} {_args}";
public RunExeItem(string exe, string args, string fullExePath, Action<string>? addToHistory)
public RunExeItem(string exe, string args, string fullExePath)
{
FullExePath = fullExePath;
Exe = exe;
@@ -44,8 +41,6 @@ internal sealed partial class RunExeItem : ListItem
return t.Result;
});
_addToHistory = addToHistory;
UpdateArgs(args);
MoreCommands = [
@@ -94,22 +89,16 @@ internal sealed partial class RunExeItem : ListItem
public void Run()
{
_addToHistory?.Invoke(FullString);
ShellHelpers.OpenInShell(FullExePath, _args);
}
public void RunAsAdmin()
{
_addToHistory?.Invoke(FullString);
ShellHelpers.OpenInShell(FullExePath, _args, runAs: ShellHelpers.ShellRunAsType.Administrator);
}
public void RunAsOther()
{
_addToHistory?.Invoke(FullString);
ShellHelpers.OpenInShell(FullExePath, _args, runAs: ShellHelpers.ShellRunAsType.OtherUser);
}
}

View File

@@ -8,7 +8,6 @@ using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CmdPal.Common.Services;
using Microsoft.CmdPal.Ext.Shell.Helpers;
using Microsoft.CmdPal.Ext.Shell.Properties;
using Microsoft.CommandPalette.Extensions;
@@ -21,11 +20,7 @@ internal sealed partial class ShellListPage : DynamicListPage, IDisposable
private readonly ShellListPageHelpers _helper;
private readonly List<ListItem> _topLevelItems = [];
private readonly Dictionary<string, ListItem> _historyItems = [];
private readonly List<ListItem> _currentHistoryItems = [];
private readonly IRunHistoryService _historyService;
private readonly List<ListItem> _historyItems = [];
private RunExeItem? _exeItem;
private List<ListItem> _pathItems = [];
private ListItem? _uriItem;
@@ -33,16 +28,13 @@ internal sealed partial class ShellListPage : DynamicListPage, IDisposable
private CancellationTokenSource? _cancellationTokenSource;
private Task? _currentSearchTask;
private bool _loadedInitialHistory;
public ShellListPage(SettingsManager settingsManager, IRunHistoryService runHistoryService, bool addBuiltins = false)
public ShellListPage(SettingsManager settingsManager, bool addBuiltins = false)
{
Icon = Icons.RunV2Icon;
Id = "com.microsoft.cmdpal.shell";
Name = Resources.cmd_plugin_name;
PlaceholderText = Resources.list_placeholder_text;
_helper = new(settingsManager);
_historyService = runHistoryService;
EmptyContent = new CommandItem()
{
@@ -76,6 +68,8 @@ internal sealed partial class ShellListPage : DynamicListPage, IDisposable
_cancellationTokenSource = new CancellationTokenSource();
var cancellationToken = _cancellationTokenSource.Token;
IsLoading = true;
try
{
// Save the latest search task
@@ -145,10 +139,6 @@ internal sealed partial class ShellListPage : DynamicListPage, IDisposable
_pathItems.Clear();
_exeItem = null;
_uriItem = null;
_currentHistoryItems.Clear();
_currentHistoryItems.AddRange(_historyItems.Values);
return;
}
@@ -216,7 +206,6 @@ internal sealed partial class ShellListPage : DynamicListPage, IDisposable
&& (!exeExists || pathIsDir)
&& couldResolvePath)
{
IsLoading = true;
await CreatePathItemsAsync(expanded, searchText, cancellationToken);
}
@@ -242,53 +231,18 @@ internal sealed partial class ShellListPage : DynamicListPage, IDisposable
_uriItem = null;
}
var histItemsNotInSearch =
_historyItems
.Where(kv => !kv.Key.Equals(newSearch, StringComparison.OrdinalIgnoreCase));
if (_exeItem != null)
{
// If we have an exe item, we want to remove it from the history items
histItemsNotInSearch = histItemsNotInSearch
.Where(kv => !kv.Value.Title.Equals(_exeItem.Title, StringComparison.OrdinalIgnoreCase));
}
if (_uriItem != null)
{
// If we have an uri item, we want to remove it from the history items
histItemsNotInSearch = histItemsNotInSearch
.Where(kv => !kv.Value.Title.Equals(_uriItem.Title, StringComparison.OrdinalIgnoreCase));
}
// Filter the history items based on the search text
var filterHistory = (string query, KeyValuePair<string, ListItem> pair) =>
{
// Fuzzy search on the key (command string)
var score = StringMatcher.FuzzySearch(query, pair.Key).Score;
return score;
};
var filteredHistory =
ListHelpers.FilterList<KeyValuePair<string, ListItem>>(
histItemsNotInSearch,
searchText,
filterHistory)
.Select(p => p.Value);
_currentHistoryItems.Clear();
_currentHistoryItems.AddRange(filteredHistory);
// Final cancellation check
cancellationToken.ThrowIfCancellationRequested();
}
private static ListItem PathToListItem(string path, string originalPath, string args = "", Action<string>? addToHistory = null)
private static ListItem PathToListItem(string path, string originalPath, string args = "")
{
var pathItem = new PathListItem(path, originalPath, addToHistory);
var pathItem = new PathListItem(path, originalPath);
// Is this path an executable? If so, then make a RunExeItem
if (IsExecutable(path))
{
var exeItem = new RunExeItem(Path.GetFileName(path), args, path, addToHistory);
var exeItem = new RunExeItem(Path.GetFileName(path), args, path);
exeItem.MoreCommands = [
.. exeItem.MoreCommands,
@@ -301,30 +255,24 @@ internal sealed partial class ShellListPage : DynamicListPage, IDisposable
public override IListItem[] GetItems()
{
if (!_loadedInitialHistory)
{
LoadInitialHistory();
}
var filteredTopLevel = ListHelpers.FilterList(_topLevelItems, SearchText);
List<ListItem> uriItems = _uriItem != null ? [_uriItem] : [];
List<ListItem> exeItems = _exeItem != null ? [_exeItem] : [];
return
exeItems
.Concat(filteredTopLevel)
.Concat(_currentHistoryItems)
.Concat(_historyItems)
.Concat(_pathItems)
.Concat(uriItems)
.ToArray();
}
internal static RunExeItem CreateExeItem(string exe, string args, string fullExePath, Action<string>? addToHistory)
internal static RunExeItem CreateExeItem(string exe, string args, string fullExePath)
{
// PathToListItem will return a RunExeItem if it can find a executable.
// It will ALSO add the file search commands to the RunExeItem.
return PathToListItem(fullExePath, exe, args, addToHistory) as RunExeItem ??
new RunExeItem(exe, args, fullExePath, addToHistory);
return PathToListItem(fullExePath, exe, args) as RunExeItem ??
new RunExeItem(exe, args, fullExePath);
}
private void CreateAndAddExeItems(string exe, string args, string fullExePath)
@@ -336,7 +284,7 @@ internal sealed partial class ShellListPage : DynamicListPage, IDisposable
}
else
{
_exeItem = CreateExeItem(exe, args, fullExePath, AddToHistory);
_exeItem = CreateExeItem(exe, args, fullExePath);
}
}
@@ -494,40 +442,6 @@ internal sealed partial class ShellListPage : DynamicListPage, IDisposable
};
}
private void LoadInitialHistory()
{
var hist = _historyService.GetRunHistory();
var histItems = hist
.Select(h => (h, ShellListPageHelpers.ListItemForCommandString(h, AddToHistory)))
.Where(tuple => tuple.Item2 != null)
.Select(tuple => (tuple.h, tuple.Item2!))
.ToList();
_historyItems.Clear();
// Add all the history items to the _historyItems dictionary
foreach (var (h, item) in histItems)
{
_historyItems[h] = item;
}
_currentHistoryItems.Clear();
_currentHistoryItems.AddRange(histItems.Select(tuple => tuple.Item2));
_loadedInitialHistory = true;
}
internal void AddToHistory(string commandString)
{
if (string.IsNullOrWhiteSpace(commandString))
{
return; // Do not add empty or whitespace items
}
_historyService.AddRunHistoryItem(commandString);
LoadInitialHistory();
DoUpdateSearchText(SearchText);
}
public void Dispose()
{
_cancellationTokenSource?.Cancel();

View File

@@ -16,8 +16,8 @@ internal sealed partial class PathListItem : ListItem
public override IIconInfo? Icon { get => _icon.Value; set => base.Icon = value; }
public PathListItem(string path, string originalDir, Action<string>? addToHistory)
: base(new OpenUrlWithHistoryCommand(path, addToHistory))
public PathListItem(string path, string originalDir)
: base(new OpenUrlCommand(path))
{
var fileName = Path.GetFileName(path);
_isDirectory = Directory.Exists(path);
@@ -50,7 +50,6 @@ internal sealed partial class PathListItem : ListItem
new CommandContextItem(new CopyTextCommand(path) { Name = Properties.Resources.copy_path_command_name }) { }
];
// TODO: Follow-up during 0.4. Add the indexer commands here.
// MoreCommands = [
// new CommandContextItem(new OpenWithCommand(indexerItem)),
// new CommandContextItem(new ShowFileInFolderCommand(indexerItem.FullPath) { Name = Resources.Indexer_Command_ShowInFolder }),

View File

@@ -2,7 +2,6 @@
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Microsoft.CmdPal.Common.Services;
using Microsoft.CmdPal.Ext.Shell.Helpers;
using Microsoft.CmdPal.Ext.Shell.Pages;
using Microsoft.CmdPal.Ext.Shell.Properties;
@@ -16,24 +15,18 @@ public partial class ShellCommandsProvider : CommandProvider
private readonly CommandItem _shellPageItem;
private readonly SettingsManager _settingsManager = new();
private readonly ShellListPage _shellListPage;
private readonly FallbackCommandItem _fallbackItem;
private readonly IRunHistoryService _historyService;
public ShellCommandsProvider(IRunHistoryService runHistoryService)
public ShellCommandsProvider()
{
_historyService = runHistoryService;
Id = "Run";
DisplayName = Resources.cmd_plugin_name;
Icon = Icons.RunV2Icon;
Settings = _settingsManager.Settings;
_shellListPage = new ShellListPage(_settingsManager, _historyService);
_fallbackItem = new FallbackExecuteItem(_settingsManager);
_fallbackItem = new FallbackExecuteItem(_settingsManager, _shellListPage.AddToHistory);
_shellPageItem = new CommandItem(_shellListPage)
_shellPageItem = new CommandItem(new ShellListPage(_settingsManager))
{
Icon = Icons.RunV2Icon,
Title = Resources.shell_command_name,

View File

@@ -33,4 +33,9 @@
<CustomToolNamespace>Microsoft.CmdPal.Ext.System</CustomToolNamespace>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo">
<_Parameter1>Microsoft.CmdPal.Ext.System.UnitTests</_Parameter1>
</AssemblyAttribute>
</ItemGroup>
</Project>

View File

@@ -1,7 +0,0 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo("Microsoft.CmdPal.Ext.System.UnitTests")]

View File

@@ -11,6 +11,12 @@
<ProjectPriFileName>Microsoft.CmdPal.Ext.TimeDate.pri</ProjectPriFileName>
</PropertyGroup>
<ItemGroup>
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo">
<_Parameter1>Microsoft.CmdPal.Ext.TimeDate.UnitTests</_Parameter1>
</AssemblyAttribute>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="Properties\Resources.resx">
<LastGenOutput>Resources.Designer.cs</LastGenOutput>

View File

@@ -1,7 +0,0 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo("Microsoft.CmdPal.Ext.TimeDate.UnitTests")]

View File

@@ -46,4 +46,9 @@
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo">
<_Parameter1>Microsoft.CmdPal.Ext.WindowWalker.UnitTests</_Parameter1>
</AssemblyAttribute>
</ItemGroup>
</Project>

View File

@@ -1,7 +0,0 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo("Microsoft.CmdPal.Ext.WindowWalker.UnitTests")]

View File

@@ -12,7 +12,7 @@ public sealed partial class AnonymousCommand : InvokableCommand
public AnonymousCommand(Action? action)
{
Name = Properties.Resources.AnonymousCommand_Invoke;
Name = "Invoke";
_action = action;
}

View File

@@ -8,12 +8,12 @@ public partial class CopyTextCommand : InvokableCommand
{
public virtual string Text { get; set; }
public virtual CommandResult Result { get; set; } = CommandResult.ShowToast(Properties.Resources.CopyTextCommand_CopiedToClipboard);
public virtual CommandResult Result { get; set; } = CommandResult.ShowToast("Copied to clipboard");
public CopyTextCommand(string text)
{
Text = text;
Name = Properties.Resources.CopyTextCommand_Copy;
Name = "Copy";
Icon = new IconInfo("\uE8C8");
}

View File

@@ -43,6 +43,7 @@ public partial class ListHelpers
}
public static IEnumerable<T> FilterList<T>(IEnumerable<T> items, string query, Func<string, T, int> scoreFunction)
where T : class
{
var scores = items
.Select(li => new Scored<T>() { Item = li, Score = scoreFunction(query, li) })

View File

@@ -52,21 +52,6 @@
<Content Include="$(SolutionDir)$(Platform)\$(Configuration)\Microsoft.CommandPalette.Extensions\Microsoft.CommandPalette.Extensions.winmd" Link="Microsoft.CommandPalette.Extensions.winmd" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>
<ItemGroup>
<Compile Update="Properties\Resources.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
<PropertyGroup>
<PublishTrimmed>True</PublishTrimmed>
<PublishAot>True</PublishAot>

View File

@@ -4,7 +4,7 @@
namespace Microsoft.CommandPalette.Extensions.Toolkit;
public partial class OpenUrlCommand : InvokableCommand
public sealed partial class OpenUrlCommand : InvokableCommand
{
private readonly string _target;
@@ -13,7 +13,7 @@ public partial class OpenUrlCommand : InvokableCommand
public OpenUrlCommand(string target)
{
_target = target;
Name = Properties.Resources.OpenUrlCommand_Open;
Name = "Open";
Icon = new IconInfo("\uE8A7");
}

View File

@@ -1,117 +0,0 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Microsoft.CommandPalette.Extensions.Toolkit.Properties {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.CommandPalette.Extensions.Toolkit.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// Looks up a localized string similar to Invoke.
/// </summary>
internal static string AnonymousCommand_Invoke {
get {
return ResourceManager.GetString("AnonymousCommand_Invoke", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Copied to clipboard.
/// </summary>
internal static string CopyTextCommand_CopiedToClipboard {
get {
return ResourceManager.GetString("CopyTextCommand_CopiedToClipboard", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Copy.
/// </summary>
internal static string CopyTextCommand_Copy {
get {
return ResourceManager.GetString("CopyTextCommand_Copy", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Open.
/// </summary>
internal static string OpenUrlCommand_Open {
get {
return ResourceManager.GetString("OpenUrlCommand_Open", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Settings.
/// </summary>
internal static string Settings {
get {
return ResourceManager.GetString("Settings", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Show in folder.
/// </summary>
internal static string ShowFileInFolderCommand_ShowInFolder {
get {
return ResourceManager.GetString("ShowFileInFolderCommand_ShowInFolder", resourceCulture);
}
}
}
}

View File

@@ -1,138 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="AnonymousCommand_Invoke" xml:space="preserve">
<value>Invoke</value>
</data>
<data name="CopyTextCommand_Copy" xml:space="preserve">
<value>Copy</value>
</data>
<data name="CopyTextCommand_CopiedToClipboard" xml:space="preserve">
<value>Copied to clipboard</value>
</data>
<data name="OpenUrlCommand_Open" xml:space="preserve">
<value>Open</value>
</data>
<data name="Settings" xml:space="preserve">
<value>Settings</value>
</data>
<data name="ShowFileInFolderCommand_ShowInFolder" xml:space="preserve">
<value>Show in folder</value>
</data>
</root>

View File

@@ -116,7 +116,7 @@ public sealed partial class Settings : ICommandSettings
public SettingsContentPage(Settings settings)
{
_settings = settings;
Name = Properties.Resources.Settings;
Name = "Settings";
Icon = new IconInfo("\uE713"); // Settings icon
// When our settings change, make sure to let CmdPal know to

View File

@@ -16,7 +16,7 @@ public partial class ShowFileInFolderCommand : InvokableCommand
public ShowFileInFolderCommand(string path)
{
_path = path;
Name = Properties.Resources.ShowFileInFolderCommand_ShowInFolder;
Name = "Show in folder";
Icon = Ico;
}

View File

@@ -34,7 +34,7 @@ namespace ColorPicker.Helpers
/// <param name="color">The <see cref="Color"/> for the presentation</param>
/// <param name="colorRepresentationType">The type of the representation</param>
/// <returns>A <see cref="string"/> representation of a color</returns>
public static string GetStringRepresentation(Color color, string colorRepresentationType, string colorFormat)
internal static string GetStringRepresentation(Color color, string colorRepresentationType, string colorFormat)
{
if (string.IsNullOrEmpty(colorFormat))
{

View File

@@ -1,16 +0,0 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Microsoft.PowerToys.UITest;
namespace Microsoft.ColorPicker.UITests
{
public class ColorPickerUITest : UITestBase
{
public ColorPickerUITest()
: base(PowerToysModule.Runner)
{
}
}
}

View File

@@ -1,16 +0,0 @@
## Color Picker
* Enable the Color Picker in settings and ensure that the hotkey brings up Color Picker
- [] when PowerToys is running unelevated on start-up
- [] when PowerToys is running as admin on start-up
- [] when PowerToys is restarted as admin, by clicking the restart as admin button in the settings
- [] Change `Activate Color Picker shortcut` and check the new shortcut is working
- [] Try all three `Activation behavior`s(`Color Picker with editor mode enabled`, `Editor`, `Color Picker only`)
- [] Change `Color format for clipboard` and check if the correct format is copied from the Color picker
- [] Try to copy color formats to the clipboard from the Editor
- [] Check `Show color name` and verify if color name is shown in the Color picker
- [] Enable one new format, disable one existing format, reorder enabled formats and check if settings are populated to the Editor
- [] Select a color from the history in the Editor
- [] Remove color from the history in the Editor
- [] Open the Color Picker from the Editor
- [] Open Adjust color from the Editor
- [] Check Color Picker logs for errors

View File

@@ -1,32 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<!-- Look at Directory.Build.props in root for common stuff as well -->
<Import Project="..\..\..\Common.Dotnet.CsWinRT.props" />
<PropertyGroup>
<ProjectGuid>{6880CE86-5B71-4440-9795-79A325F95747}</ProjectGuid>
<RootNamespace>Microsoft.ColorPicker.UITests</RootNamespace>
<IsPackable>false</IsPackable>
<Nullable>enable</Nullable>
<OutputType>Library</OutputType>
<!-- This is a UI test, so don't run as part of MSBuild -->
<RunVSTest>false</RunVSTest>
</PropertyGroup>
<PropertyGroup>
<OutputPath>..\..\..\..\$(Platform)\$(Configuration)\tests\UITests-ColorPicker\</OutputPath>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Appium.WebDriver" />
<PackageReference Include="MSTest" />
<PackageReference Include="System.Net.Http" />
<PackageReference Include="System.Private.Uri" />
<PackageReference Include="System.Text.RegularExpressions" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\common\UITestAutomation\UITestAutomation.csproj" />
</ItemGroup>
</Project>

View File

@@ -9,7 +9,7 @@ using System.Globalization;
using ManagedCommon;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace ColorPicker.UnitTests.Helpers
namespace Microsoft.ColorPicker.UnitTests
{
/// <summary>
/// Test class to test <see cref="ColorConverter"/>

View File

@@ -8,7 +8,7 @@ using ColorPicker.Helpers;
using ManagedCommon;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace ColorPicker.Helpers
namespace Microsoft.ColorPicker.UnitTests
{
[TestClass]
public class ColorRepresentationHelperTest

View File

@@ -3,15 +3,15 @@
<Import Project="..\..\..\Common.Dotnet.CsWinRT.props" />
<PropertyGroup>
<ProjectGuid>{F93C2817-C846-4259-84D8-B39A6B57C8DE}</ProjectGuid>
<RootNamespace>ColorPicker.UnitTests</RootNamespace>
<ProjectGuid>{090CD7B7-3B0C-4D1D-BC98-83EB5D799BC1}</ProjectGuid>
<RootNamespace>Microsoft.ColorPicker.UnitTests</RootNamespace>
<IsPackable>false</IsPackable>
<Nullable>enable</Nullable>
<OutputType>Library</OutputType>
</PropertyGroup>
<PropertyGroup>
<OutputPath>..\..\..\..\$(Platform)\$(Configuration)\tests\ColorPickerUI.UnitTest\</OutputPath>
<OutputPath>..\..\..\..\$(Platform)\$(Configuration)\tests\UnitTest-ColorPickerUI\</OutputPath>
</PropertyGroup>
<ItemGroup>

View File

@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project DefaultTargets="Build"
xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.240111.5\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('..\..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.240111.5\build\native\Microsoft.Windows.CppWinRT.props')" />
<PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion>
@@ -7,7 +8,7 @@
<Keyword>Win32Proj</Keyword>
<RootNamespace>UnitTests</RootNamespace>
<ProjectSubType>NativeUnitTestProject</ProjectSubType>
<ProjectName>FancyZones.UnitTests</ProjectName>
<ProjectName>UnitTests-FancyZones</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Label="Configuration">

View File

@@ -3,7 +3,7 @@
<Import Project="..\..\..\Common.Dotnet.CsWinRT.props" />
<PropertyGroup>
<ProjectGuid>{69D76A76-6EF6-4846-94CD-EAAF0CAC9F15}</ProjectGuid>
<ProjectGuid>{FE38FC07-1C05-4B57-ADA3-2FE2F53C6A52}</ProjectGuid>
<RootNamespace>Microsoft.FancyZones.UITests</RootNamespace>
<IsPackable>false</IsPackable>
<Nullable>enable</Nullable>
@@ -14,7 +14,7 @@
</PropertyGroup>
<PropertyGroup>
<OutputPath>..\..\..\..\$(Platform)\$(Configuration)\tests\FancyZones.UITests\</OutputPath>
<OutputPath>..\..\..\..\$(Platform)\$(Configuration)\tests\UITests-FancyZones\</OutputPath>
</PropertyGroup>
<ItemGroup>
@@ -29,12 +29,12 @@
<Folder Include="Properties\" />
<ProjectReference Include="..\editor\FancyZonesEditor\FancyZonesEditor.csproj" />
<ProjectReference Include="..\..\..\common\UITestAutomation\UITestAutomation.csproj" />
<ProjectReference Include="..\FancyZonesEditor.UITests\FancyZonesEditor.UITests.csproj" />
<ProjectReference Include="..\UITests-FancyZonesEditor\UITests-FancyZonesEditor.csproj" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\editor\FancyZonesEditor\FancyZonesEditor.csproj" />
<ProjectReference Include="..\FancyZonesEditor.UITests\FancyZonesEditor.UITests.csproj" />
<ProjectReference Include="..\UITests-FancyZonesEditor\UITests-FancyZonesEditor.csproj" />
<ProjectReference Include="..\..\..\common\UITestAutomation\UITestAutomation.csproj" />
</ItemGroup>

Some files were not shown because too many files have changed in this diff Show More