diff --git a/.github/actions/spell-check/allow/allow.txt b/.github/actions/spell-check/allow/allow.txt
deleted file mode 100644
index 20a05a495d..0000000000
--- a/.github/actions/spell-check/allow/allow.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-cloudai
-bkmeneguello
-FWest
-gdnbaselines
-github
-https
-obairka
-sdl
-ssh
-ubuntu
-unuing
-workarounds
-wil
diff --git a/.github/actions/spell-check/allow/code.txt b/.github/actions/spell-check/allow/code.txt
new file mode 100644
index 0000000000..248009b4f2
--- /dev/null
+++ b/.github/actions/spell-check/allow/code.txt
@@ -0,0 +1,134 @@
+# COLORS
+
+argb
+bgra
+BLACKONWHITE
+BLUEGRAY
+BRIGHTGREEN
+COLORONCOLOR
+DARKPURPLE
+DARKTEAL
+DARKYELLOW
+Farbraum
+ICEBLUE
+LIGHTORANGE
+LIGHTTURQUOISE
+NCol
+OLIVEGREEN
+PALEBLUE
+PArgb
+Pbgra
+WHITEONBLACK
+
+
+# FILES
+
+AYUV
+bak
+exa
+exabyte
+Gbits
+Gbps
+gcode
+Mbits
+MBs
+mkv
+msix
+nupkg
+petabyte
+resw
+resx
+Stereolithography
+terabyte
+UYVY
+xbf
+YUY
+YUYV
+YVU
+YVYU
+zipfolder
+
+
+# FONTS
+
+Consolas
+Neue
+Noto
+Roboto
+Segoe
+
+
+# IN URLs
+
+accessibilityinsights
+arik
+epicgames
+fwlink
+joefinapps
+lepo
+linkedin
+oblitum
+robmensching
+sinclairinat
+stylecop
+uipi
+yinwang
+
+
+# KEYS
+
+altdown
+BUTTONUP
+CTRLALTDEL
+Ctrls
+EXSEL
+HOLDENTER
+HOLDESC
+KBDLLHOOKSTRUCT
+keyevent
+LAlt
+LBUTTON
+LBUTTONDBLCLK
+LBUTTONDOWN
+LBUTTONUP
+LCONTROL
+LCtrl
+LEFTDOWN
+LEFTUP
+MBUTTON
+MBUTTONDBLCLK
+MBUTTONDOWN
+MBUTTONUP
+MIDDLEDOWN
+MIDDLEUP
+NCRBUTTONDBLCLK
+NCRBUTTONDOWN
+NCRBUTTONUP
+NUMLOCK
+RBUTTON
+RBUTTONDBLCLK
+RBUTTONDOWN
+RBUTTONUP
+RCONTROL
+RCtrl
+RIGHTDOWN
+RIGHTUP
+VKTAB
+winkey
+WMKEYDOWN
+WMKEYUP
+WMSYSKEYDOWN
+WMSYSKEYUP
+XBUTTON
+XBUTTONDBLCLK
+XBUTTONDOWN
+XBUTTONUP
+XDOWN
+
+
+# MATH
+
+artanh
+arsinh
+arcosh
+
diff --git a/.github/actions/spell-check/allow/names.txt b/.github/actions/spell-check/allow/names.txt
index 710e00eca9..7b3543e06f 100644
--- a/.github/actions/spell-check/allow/names.txt
+++ b/.github/actions/spell-check/allow/names.txt
@@ -1,57 +1,155 @@
-ABradley
+# POWERTOYS
+
+alwaysontop
+colorpicker
+fancyzones
+imageresizer
+kbm
+keyboardmanager
+markdownpreviewhandler
+mwb
+oobe
+pasteplain
+poweraccent
+powerlauncher
+POWEROCR
+powerpreview
+powerrename
+powertoy
+powertoys
+previewpane
+ptrun
+registrypreview
+rooler
+scoobe
+shortcutguide
+videoconference
+
+
+# USERS
+
+alekhyareddy
Aleks
+angularsen
+arjunbalgovind
Ashish
-azchohfi
Baltazar
Bao
-bdoserror
+betadele
+betsegaw
+bricelam
Chinh
+chrdavis
+Chrzan
+clayton
Coplen
crutkas
-dependabot
-Deuchert
+damienleroy
+davidegiacometti
+debian
+Delimarsky
+Deondre
ductdo
-edwinzap
Essey
+frankychen
+gabime
+Galaxi
Garside
Gershaft
Gokce
Guo
-hallatore
+hanselman
Harmath
+Heiko
Hemmerlein
+hlaueriksson
+Horvalds
+htcfreek
Huynh
Jaswal
jefflord
+jyuwono
Kamra
Kantarci
Karthick
kevinguo
Krigun
+Lambson
+Laute
+laviusmotileng
Luecking
Mahalingam
+Markovic
+martinchrzan
+martinmoene
+Melman
Mikhayelyan
-mshtang
Myrvold
-naveensrinivasan
-nVidia
+Nemeth
+nielslaute
+oldnewthing
+palenshus
+pedrolamas
+peteblois
phoboslab
Ponten
Pooja
-robmen
+Quriz
+randyrants
+ricardosantos
robmikh
+Rutkas
+ryanbodrug
+saahmedm
+sachaple
+Santossio
Schoen
-skycommand
-snickler
-sinclairinat
-streamjsonrpc
+Sekan
+Seraphima
+skttl
+somil
+Soref
+stefan
Szablewski
+Tadele
+talynone
+TBM
tilovell
-TheJoeFin
Triet
-Vidia
-WEX
-WWL
-yifan
+ycv
Yuniardi
+yuyoyuppe
Zoltan
+Zykova
+
+
+# OTHERS
+
+Controlz
+cortana
+fancymouse
+firefox
+Inkscape
+Markdig
+modernwpf
+Moq
+mozilla
+mspaint
+Newtonsoft
+onenote
+Quickime
+regedit
+roslyn
+Vanara
+WEX
+windowwalker
+winui
+winuiex
+wix
+wordpad
+WWL
+xamlstyler
+Xavalon
+Xbox
+Youdao
+
diff --git a/.github/actions/spell-check/allow/temporary.txt b/.github/actions/spell-check/allow/temporary.txt
deleted file mode 100644
index 05cd229158..0000000000
--- a/.github/actions/spell-check/allow/temporary.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-etw
-filetime
-flyouts
-lnks
-reparented
-screenshots
-SIDs
-subkeys
-TApp
-websites
-wmi
diff --git a/.github/actions/spell-check/excludes.txt b/.github/actions/spell-check/excludes.txt
index 143cedf602..79b69758a9 100644
--- a/.github/actions/spell-check/excludes.txt
+++ b/.github/actions/spell-check/excludes.txt
@@ -2,18 +2,19 @@
(?:^|/)(?i)COPYRIGHT
(?:^|/)(?i)LICEN[CS]E
(?:^|/)3rdparty/
-(?:^|/)go\.sum$
(?:^|/)FilePreviewCommon/Assets/Monaco/customLanguages/
(?:^|/)FilePreviewCommon/Assets/Monaco/generateLanguagesJson.html
(?:^|/)FilePreviewCommon/Assets/Monaco/index.html
(?:^|/)FilePreviewCommon/Assets/Monaco/monaco_languages.json
(?:^|/)FilePreviewCommon/Assets/Monaco/monacoSpecialLanguages.js
+(?:^|/)go\.sum$
(?:^|/)monacoSRC/
(?:^|/)package(?:-lock|)\.json$
(?:^|/)Pipfile$
(?:^|/)power-rename-ui-flags$
(?:^|/)pyproject.toml
(?:^|/)requirements(?:-dev|-doc|-test|)\.txt$
+(?:^|/)sample\.qoi$
(?:^|/)timezones\.json$
(?:^|/)vendor/
(?:^|/)WindowsSettings\.json$
@@ -96,30 +97,30 @@
^\.gitmodules$
^\Q.github/workflows/spelling2.yml\E$
^\Q.pipelines/ESRPSigning_core.json\E$
-^\Qinstaller/PowerToysSetup/Settings.wxs\E$
-^\Qsrc/common/ManagedCommon/ColorFormatHelper.cs\E$
^\Q.pipelines/sdl.gdnbaselines\E$
+^\Qinstaller/PowerToysSetup/Settings.wxs\E$
^\Qsrc/common/FilePreviewCommon/Assets/Monaco/monaco_languages.json\E$
+^\Qsrc/common/ManagedCommon/ColorFormatHelper.cs\E$
^\Qsrc/common/notifications/BackgroundActivatorDLL/cpp.hint\E$
^\Qsrc/modules/colorPicker/ColorPickerUI/Assets/ColorPicker/colorPicker.cur\E$
^\Qsrc/modules/colorPicker/ColorPickerUI/Shaders/GridShader.cso\E$
^\Qsrc/modules/MouseUtils/MouseJumpUI/MainForm.resx\E$
-^\Qsrc/modules/MouseWithoutBorders/App/Form/frmAbout.cs\E$
-^\Qsrc/modules/MouseWithoutBorders/ModuleInterface/generateSecurityDescriptor.h\E$
^\Qsrc/modules/MouseUtils/MouseJumpUI/NativeMethods/User32/UI/WindowsAndMessaging/User32.SYSTEM_METRICS_INDEX.cs\E$
+^\Qsrc/modules/MouseWithoutBorders/App/Form/frmAbout.cs\E$
^\Qsrc/modules/MouseWithoutBorders/App/Form/frmInputCallback.resx\E$
^\Qsrc/modules/MouseWithoutBorders/App/Form/frmLogon.resx\E$
^\Qsrc/modules/MouseWithoutBorders/App/Form/frmMatrix.resx\E$
^\Qsrc/modules/MouseWithoutBorders/App/Form/frmScreen.resx\E$
+^\Qsrc/modules/MouseWithoutBorders/ModuleInterface/generateSecurityDescriptor.h\E$
^\Qsrc/modules/peek/Peek.Common/NativeMethods.txt\E$
^\Qsrc/modules/previewpane/SvgPreviewHandler/SvgHTMLPreviewGenerator.cs\E$
^\Qsrc/modules/previewpane/UnitTests-StlThumbnailProvider/HelperFiles/sample.stl\E$
^\Qtools/project_template/ModuleTemplate/resource.h\E$
^doc/devdocs/akaLinks\.md$
-^src/modules/MouseWithoutBorders/App/Form/.*\.resx$
-^src/modules/MouseWithoutBorders/App/Form/.*\.Designer\.cs$
-^src/modules/MouseWithoutBorders/App/Helper/.*\.resx$
^src/modules/MouseWithoutBorders/App/.*/NativeMethods\.cs$
+^src/modules/MouseWithoutBorders/App/Form/.*\.Designer\.cs$
+^src/modules/MouseWithoutBorders/App/Form/.*\.resx$
+^src/modules/MouseWithoutBorders/App/Helper/.*\.resx$
^src/modules/previewpane/UnitTests-MarkdownPreviewHandler/HelperFiles/MarkdownWithHTMLImageTag.txt$
^tools/Verification scripts/Check preview handler registration\.ps1$
ignore$
diff --git a/.github/actions/spell-check/expect.txt b/.github/actions/spell-check/expect.txt
index 2965a4f3d8..40a6a085f5 100644
--- a/.github/actions/spell-check/expect.txt
+++ b/.github/actions/spell-check/expect.txt
@@ -1,7 +1,6 @@
aaaa
abcdefghjkmnpqrstuvxyz
abgr
-abi
ABlocked
ABOUTBOX
Abug
@@ -9,21 +8,14 @@ accctrl
Acceleratorkeys
ACCEPTFILES
ACCESSDENIED
-accessibilityinsights
-Acl
aclapi
AClient
AColumn
acrt
-activatable
ACTIVATEAPP
activationaction
ADDUNDORECORD
ADifferent
-adio
-adipiscing
-administra
-ADMINS
adml
admx
advapi
@@ -34,23 +26,16 @@ AFX
AGGREGATABLE
AHybrid
ALarger
-alekhyareddy
-aliquip
ALLAPPS
ALLINPUT
ALLOWUNDO
ALLVIEW
ALPHATYPE
-altdown
-alwaysontop
-amd
AModifier
AMPROPERTY
AMPROPSETID
+animatedvisuals
ANDSCANS
-anges
-angularsen
-Animatable
ansicolor
ANull
AOC
@@ -65,13 +50,11 @@ APPBARDATA
appdata
APPEXECLINK
appium
-Applets
Applicationcan
applicationframehost
appmanifest
APPNAME
appref
-apps
appsettings
appwindow
appwiz
@@ -79,27 +62,18 @@ APSTUDIO
AQS
ARandom
ARCHITEW
-arcosh
ARemapped
-argb
ari
-arik
-Arity
-arjunbalgovind
ARPINSTALLLOCATION
ARPPRODUCTICON
ARRAYSIZE
-arsinh
-artanh
arw
-asdf
asf
AShortcut
ASingle
ASSOCCHANGED
ASYNCWINDOWPLACEMENT
ASYNCWINDOWPOS
-ative
atl
atlbase
atlcom
@@ -107,12 +81,8 @@ atleast
atlfile
atlstr
ATRIOX
-Attribs
aumid
-Aut
Authenticode
-AUTHN
-AUTHZ
AUTOHIDE
AUTOMATIONPROPERTIES
Autorun
@@ -120,17 +90,11 @@ AUTOUPDATE
AValid
awakeness
AWAYMODE
-AYUV
azman
backtracer
-bak
bbwe
bck
BESTEFFORT
-betadele
-betsegaw
-BGR
-bgra
bhid
bigbar
bigobj
@@ -139,15 +103,11 @@ BITMAPFILEHEADER
bitmapimage
BITMAPINFO
BITMAPINFOHEADER
-bitmask
BITSPIXEL
bla
-BLACKONWHITE
Blockquotes
blogs
Blt
-BLUEGRAY
-Bluetooth
BLURBEHIND
BLURREGION
bmi
@@ -156,34 +116,25 @@ BNumber
BOKMAL
bootstrapper
BOOTSTRAPPERINSTALLFOLDER
-Bopomofo
bostrot
BOTTOMALIGN
BPBF
bpmf
bpp
-bricelam
-BRIGHTGREEN
Browsable
bsd
-bstr
bthprops
bti
-btn
BTNFACE
-Bto
-buf
bugreport
BUILDARCH
BUILDNUMBER
buildtask
buildtransitive
-BUTTONUP
BVal
BValue
byapp
BYPOSITION
-bytearray
CALG
callbackptr
calpwstr
@@ -197,7 +148,6 @@ CCHDEVICENAME
CCHFORMNAME
CCom
CContext
-cdecl
CDeclaration
CDEF
cdpx
@@ -209,23 +159,15 @@ certmgr
cguid
CHANGECBCHAIN
changecursor
-Changemove
-chdir
CHILDACTIVATE
CHILDWINDOW
-chrdavis
-Chrzan
-CHT
cidl
-CIELAB
-CIEXYZ
cim
CImage
cla
clangformat
CLASSDC
CLASSNOTAVAILABLE
-clayton
clickable
clickonce
CLIENTEDGE
@@ -234,15 +176,12 @@ clientside
CLIPBOARDUPDATE
CLIPCHILDREN
CLIPSIBLINGS
-Cloneable
closesocket
clrcall
-Cls
CLSCTX
-clsid
Clusion
cmder
-cmdline
+CMDNOTFOUNDMODULEINTERFACE
Cmds
CMIC
CMINVOKECOMMANDINFO
@@ -250,11 +189,8 @@ CMINVOKECOMMANDINFOEX
CMock
CMONITORS
cmpgt
-cmyk
cne
-cnt
coclass
-CODENAME
codeofconduct
codereview
Codespaces
@@ -265,11 +201,7 @@ colorformat
colorhistory
colorhistorylimit
COLORKEY
-COLORONCOLOR
-colorpicker
-COLORREF
comctl
-COMDAT
comdef
comdlg
comexp
@@ -277,7 +209,6 @@ cominterop
commandline
COMMANDTITLE
commctrl
-commodo
compmgmt
COMPOSITIONFULL
comsupp
@@ -288,10 +219,6 @@ CONFIGW
CONFLICTINGMODIFIERKEY
CONFLICTINGMODIFIERSHORTCUT
CONOUT
-consectetur
-consequat
-Consolas
-constexpr
consts
contentdialog
contentfiles
@@ -299,9 +226,7 @@ CONTEXTHELP
CONTEXTMENUHANDLER
CONTROLL
CONTROLPARENT
-Controlz
copiedcolorrepresentation
-cortana
cotaskmem
COULDNOT
countof
@@ -322,17 +247,11 @@ CRSEL
crw
CSearch
CSettings
-CSIDL
cso
CSRW
CStyle
CSY
CTest
-CTRLALTDEL
-Ctrls
-Ctx
-CUI
-cupidatat
currentculture
CURRENTDIR
CURSORINFO
@@ -343,8 +262,6 @@ CVal
cvd
CVirtual
cvtepu
-cvtsi
-cwd
cxfksword
CXSCREEN
CXSMICON
@@ -356,18 +273,10 @@ CYVIRTUALSCREEN
cziplib
Dac
dacl
-damienleroy
-DARKPURPLE
-DARKTEAL
-DARKYELLOW
datareader
datatracker
-Datavalue
dataversion
-DATAW
-davidegiacometti
Dayof
-Dbg
Dbghelp
DBLCLKS
DBLEPSILON
@@ -385,11 +294,7 @@ DDevice
ddf
DDxgi
Deact
-debian
debugbreak
-DECLAR
-declatory
-declspec
decryptor
Dedup
DEFAULTBOOTSTRAPPERINSTALLFOLDER
@@ -406,18 +311,13 @@ DELA
DELETEDKEYIMAGE
DELETESCANS
deletethis
-Delimarsky
DENORMAL
-Deondre
depersist
deprioritized
-deref
-deserunt
DESKTOPABSOLUTEEDITING
DESKTOPABSOLUTEPARSING
desktopshorcutinstalled
desktopwindowxamlsource
-DEU
devblogs
devdocs
devenum
@@ -439,11 +339,9 @@ Dlg
DLGFRAME
DLGMODALFRAME
dlib
-dllexport
dllhost
dllmain
DNLEN
-dns
DONOTROUND
DONTVALIDATEPATH
dotnet
@@ -459,7 +357,6 @@ drawingcolor
dreamsofameaningfullife
drf
drivedetectionwarning
-dsc
dshow
DSTINVERT
DUMMYUNIONNAME
@@ -493,7 +390,6 @@ dxgidebug
dxgiformat
dxguid
ecount
-ecyclebin
EData
Edid
EDITKEYBOARD
@@ -501,13 +397,8 @@ editkeyboardwindow
EDITSHORTCUTS
editshortcutswindow
EFile
-egistry
-egistrypreview
eip
ekus
-elease
-elemetry
-elit
emmintrin
Emoji
ENABLEDELAYEDEXPANSION
@@ -516,33 +407,22 @@ ENABLEDPOPUP
encodedlaunch
encryptor
endpointvolume
-endregion
ENDSESSION
-enim
ENTERSIZEMOVE
ENU
EOAC
-epicgames
epu
ERASEBKGND
EREOF
EResize
ERole
ERRORIMAGE
-ERRORLEVEL
ERRORTITLE
ESettings
esize
-esource
esrp
-estapp
-estart
-ests
-esult
etl
-etstat
ETW
-etwork
EUQ
eurochange
eventlog
@@ -555,17 +435,13 @@ EWXLOGOFF
EWXPOWEROFF
EWXREBOOT
EWXSHUTDOWN
-Exa
-exabyte
examplehandler
examplepowertoy
EXAND
-Excepteur
EXCLUDEFROMCAPTURE
exdisp
executionpolicy
exename
-exif
EXITSIZEMOVE
exlist
EXPCMDFLAGS
@@ -574,20 +450,15 @@ explr
exppowertoys
exptas
exsb
-EXSEL
exstyle
EXTENDEDKEY
EXTENDEDVERBS
EXTRINSICPROPERTIES
eyetracker
-fancymouse
-fancyzone
FANCYZONESDRAWLAYOUTTEST
FANCYZONESEDITOR
-Farbraum
FARPROC
fdw
-feimage
fff
FILEEXPLORER
FILEFLAGS
@@ -605,11 +476,9 @@ FILEVERSION
Filtergraph
Filterkeyboard
Filterx
-Finalizers
findfast
-firefox
FIXEDFILEINFO
-flyout
+flyouts
FOF
FOFX
FOLDERID
@@ -617,49 +486,36 @@ folderpath
FORCEMINIMIZE
formatetc
FRAMECHANGED
-frankychen
frm
Froml
FROMTOUCH
-FSCTL
fsmgmt
-FTYPE
Functiondiscoverykeys
-fwlink
FZE
-gabime
-GAC
gacutil
Gaeilge
Gaidhlig
-Galaxi
GBarm
-Gbits
-Gbps
-GBs
GCLP
-gcnew
-gcode
gdi
gdiplus
GDISCALED
+gdnbaselines
GEmoji
GETCLIENTAREAANIMATION
GETDESKWALLPAPER
GETDLGCODE
GETDPISCALEDSIZE
+getfilesiginforedist
GETICON
GETMINMAXINFO
GETPROPERTYSTOREFLAGS
GETSCREENSAVERRUNNING
GETSECKEY
-GETSTATE
-GETTEXT
GETTEXTLENGTH
GHND
GMEM
GNumber
-google
gpedit
gpo
GPOCA
@@ -668,7 +524,6 @@ GPT
gpu
GSM
gtm
-gui
guiddata
guiddef
guidgenerator
@@ -676,25 +531,21 @@ GUITHREADINFO
GValue
gwl
GWLP
-HACCEL
handlekeyboardhookevent
hangeul
-hanselman
Hanzi
Hardlines
hardlinks
HARDWAREINPUT
-hashcode
Hashset
-Hashtable
hashtag
HASHVAL
+HASSTRINGS
hbitmap
hbm
hbmp
hbr
HBRBACKGROUND
-HBRUSH
hcblack
HCERTSTORE
HCRYPTHASH
@@ -704,15 +555,11 @@ hcwhite
hdc
hdrop
hdwwiz
-HEB
-Heiko
Helpline
helptext
HGFE
hglobal
hhk
-HHmmss
-HHOOK
hhx
Hiber
Hiberboot
@@ -720,7 +567,6 @@ HIBYTE
hicon
HIDEWINDOW
hif
-highlighter
HIMAGELIST
himl
hinst
@@ -730,43 +576,30 @@ HKCC
HKCR
HKCU
hkey
-HKL
HKLM
HKPD
HKU
-hlaueriksson
-HLOCAL
HMD
hmenu
hmodule
hmonitor
-HOLDENTER
-HOLDESC
-HOMEPATH
homljgmgpmcbpjbnjpfijnhipfkiclkd
HOOKPROC
-Horvalds
Hostbackdropbrush
hotkeycontrol
hotkeys
hotlight
hotspot
HPAINTBUFFER
-HPALETTE
HRAWINPUT
-hread
HREDRAW
hres
hresult
hrgn
-HRSRC
hsb
HSCROLL
hsi
-hsl
hstring
-hsv
-htcfreek
HTCLIENT
hthumbnail
HTOUCHINPUT
@@ -783,10 +616,8 @@ HWNDLAST
HWNDNEXT
HWNDPREV
hyjiacan
-IBase
IBeam
ICapture
-ICEBLUE
IClass
ICONERROR
IData
@@ -797,45 +628,35 @@ idl
idlist
IDOn
IDR
-idx
IDXGI
IEnum
ietf
IExec
IEXPLORE
-Iface
IFACEMETHOD
IFACEMETHODIMP
IFile
IFilter
IGraphics
-IGT
iid
Iindex
-IIO
iiq
IJson
Ijwhost
IKs
ILogon
IMAGEHLP
-imageresizer
IMAGERESIZERCONTEXTMENU
IMAGERESIZEREXT
imageresizerinput
imageresizersettings
imagingdevices
ime
-imeutil
inetcpl
Infobar
INFOEXAMPLE
Infotip
-ingbuffer
-inheritdoc
initguid
-Inkscape
-Inlines
inorder
INPC
inproc
@@ -864,7 +685,6 @@ Interlop
INTRESOURCE
INVALIDARG
invalidoperatioexception
-ipc
ipcmanager
IPlugin
IPower
@@ -876,7 +696,6 @@ irprops
isbi
ISearch
ISettings
-isfinite
IShell
isocpp
iss
@@ -897,84 +716,52 @@ jgeosdfsdsgmkedfgdfgdfgbkmhcgcflmi
jif
jjw
jobject
-joefinapps
jpe
-JPN
jpnime
Jsons
jsonval
junja
jxr
-jyuwono
-KBDLLHOOKSTRUCT
-kbm
+Kazakhstani
kdc
keybd
KEYBDDATA
KEYBDINPUT
keyboardeventhandlers
-keyboardmanager
keyboardmanagercommon
KEYBOARDMANAGEREDITOR
keyboardmanagerstate
keyboardmanagerui
-keydown
keydropdowncontrol
-keyevent
KEYEVENTF
KEYIMAGE
keynum
keyremaps
-Keytool
-keyup
KILLFOCUS
killrunner
Knownfolders
KSPROPERTY
Kybd
-laboris
-laborum
-LAlt
-Lambson
-langword
+languagesjson
lastcodeanalysissucceeded
Lastdevice
-Laute
-laviusmotileng
+LASTEXITCODE
LAYOUTRTL
-Lbl
-LBUTTON
-LBUTTONDBLCLK
-LBUTTONDOWN
-LBUTTONUP
-Lcid
LCIDTo
lcl
Lclean
-LCONTROL
-LCtrl
Ldone
ldx
-LEFTDOWN
LEFTSCROLLBAR
-LEFTUP
lego
-len
-lepo
LError
-Lessthan
LEVELID
LExit
-lhs
lhwnd
LIBID
licate
-LIGHTORANGE
-LIGHTTURQUOISE
lindex
-linkedin
LINKOVERLAY
-linq
LINQTo
listview
lld
@@ -983,10 +770,9 @@ llkhf
lmcons
LMEM
LMENU
-lnk
+lnks
LOADFROMFILE
LOBYTE
-LOCALAPPDATA
LOCALDISPLAY
LOCALPACKAGE
localport
@@ -996,20 +782,17 @@ LOGFONT
LOGFONTW
logon
LOGPIXELSX
-LOn
longdate
LONGLONG
lowlevel
LOWORD
lparam
LPBITMAPINFOHEADER
-LPBYTE
LPCITEMIDLIST
LPCMINVOKECOMMANDINFO
LPCREATESTRUCT
LPCRECT
LPCTSTR
-LPCWSTR
lpdw
lpfn
LPINPUT
@@ -1017,12 +800,9 @@ lpmi
LPMINMAXINFO
LPMONITORINFO
LPOSVERSIONINFOEXW
-LPPOINT
LPQUERY
lprc
-LPRECT
LPSAFEARRAY
-LPSTR
lpsz
lpt
LPTHREAD
@@ -1030,13 +810,10 @@ LPTOP
lptpm
LPTR
LPTSTR
-LPVOID
LPW
lpwndpl
-LPWSTR
LReader
LRESULT
-lshift
lstrcmp
lstrcmpi
lstrlen
@@ -1049,10 +826,7 @@ LVal
LWA
lwin
LZero
-lzw
-Mainwindow
majortype
-MAJORVERSION
makecab
MAKEINTRESOURCE
MAKEINTRESOURCEA
@@ -1062,23 +836,11 @@ manifestdependency
MAPPEDTOSAMEKEY
MAPTOSAMESHORTCUT
MAPVK
-Markdig
-markdownpreviewhandler
MARKDOWNPREVIEWHANDLERCPP
-Markovic
-martinchrzan
-martinmoene
-Maximizable
MAXIMIZEBOX
MAXSHORTCUTSIZE
maxversiontested
-Mbits
MBR
-MBs
-MBUTTON
-MBUTTONDBLCLK
-MBUTTONDOWN
-MBUTTONUP
mdc
MDICHILD
MDL
@@ -1088,8 +850,6 @@ mdwn
MEDIASUBTYPE
mediatype
mef
-Mega
-Melman
MENUBREAK
MENUITEMINFO
MENUITEMINFOW
@@ -1106,13 +866,9 @@ Mfsensorgroup
mftransform
Mgmt
mic
-microsoft
-MIDDLEDOWN
-MIDDLEUP
midl
mii
MIIM
-millis
mindaro
Minimatch
Minimizable
@@ -1120,12 +876,9 @@ MINIMIZEBOX
MINIMIZEEND
MINIMIZESTART
miniz
-MINORVERSION
Miracast
mjpg
-mkd
mkdn
-mkv
mlcfg
mmc
mmcexe
@@ -1135,28 +888,19 @@ mmi
mmsys
mmsystem
mockapi
-MODECHANGE
-modernwpf
MODESPRUNED
-mollit
MONITORENUMPROC
MONITORINFO
MONITORINFOEX
MONITORINFOEXW
monitorinfof
-Monthand
-Moq
MOUSEACTIVATE
MOUSEDATA
MOUSEEVENTF
MOUSEHWHEEL
MOUSEINPUT
-MOUSELEAVE
-MOUSEMOVE
-MOUSEWHEEL
MOVESIZEEND
MOVESIZESTART
-mozilla
MOZILLAPL
MOZPL
mpmc
@@ -1164,7 +908,6 @@ MRM
MRT
mru
mrw
-msbuild
msc
msclr
mscorlib
@@ -1175,29 +918,23 @@ MSIFASTINSTALL
MSIHANDLE
msiquery
MSIRESTARTMANAGERCONTROL
-msix
+msixbundle
MSIXCA
MSLLHOOKSTRUCT
Mso
msp
-mspaint
msrc
msstore
mst
-msvc
msvcp
MTND
-Mul
MULTIPLEUSE
multizone
muxc
mvvm
-mwb
MWBEx
-myfile
MYICON
NAMECHANGE
-nameof
namespaceanddescendants
nao
NCACTIVATE
@@ -1214,37 +951,26 @@ NCMBUTTONDOWN
NCMBUTTONUP
NCMOUSELEAVE
NCMOUSEMOVE
-NCol
nconsectetur
ncpa
NCPAINT
-NCRBUTTONDBLCLK
-NCRBUTTONDOWN
-NCRBUTTONUP
NCRENDERING
ndp
NEEDDISPATCH
needinfo
-Nemeth
-NESW
netcore
netcoreapp
netcpl
netframework
-Netscape
netsetup
netsh
-Neue
newcolor
newdev
newitem
newpath
newrow
newsgroups
-Newtonsoft
-nielslaute
NIF
-nint
NLD
NLog
NLSTEXT
@@ -1256,7 +982,6 @@ NOCLOSEPROCESS
NOCOALESCE
NOCOPYBITS
nodeca
-nodiscard
nodoc
NODRAWCAPTION
NODRAWICON
@@ -1266,9 +991,7 @@ NOLINKINFO
NOMINMAX
NOMIRRORBITMAP
NOMOVE
-NONAME
nonclient
-NONCONVERT
NONELEVATED
NONINFRINGEMENT
nonstd
@@ -1286,20 +1009,16 @@ NORMALUSER
NOSEARCH
NOSENDCHANGING
NOSIZE
-nostrud
-notfound
NOTIFICATIONSDLL
NOTIFYICONDATAW
NOTIMPL
-notmatch
-Noto
NOTOPMOST
NOTRACK
NOTSRCCOPY
NOTSRCERASE
-NOUPDATE
NOZORDER
NPH
+npmjs
NResize
nrw
nsunt
@@ -1308,43 +1027,24 @@ ntdll
ntfs
NTSTATUS
nugets
-nuint
nullonfailure
numberbox
-NUMLOCK
-numpad
-nupkg
nwc
Objbase
-OBJID
objidl
-oblitum
-obmikh
-occaecat
ocr
Ocrsettings
-odbc
odbccp
-Oem
officehubintl
-officia
ofs
-oid
oldcolor
olditem
-oldnewthing
oldpath
oldtheme
oleaut
OLECHAR
-OLEDB
-OLIVEGREEN
onebranch
-onenote
-onstd
-oobe
OOBEPT
-ools
opencode
opensource
openxmlformats
@@ -1358,69 +1058,50 @@ ostr
OSVERSIONINFOEX
OSVERSIONINFOEXW
osvi
-otating
-otifications
OUTOFCONTEXT
-OUTOFMEMORY
outpin
Outptr
outputtype
-outro
outsettings
OVERLAPPEDWINDOW
overlaywindow
Oversampling
OWNDC
OWNERDRAW
-Packagemanager
PACL
PAINTSTRUCT
-PALEBLUE
-palenshus
PALETTEWINDOW
-paramref
PARENTNOTIFY
PARENTRELATIVEEDITING
PARENTRELATIVEFORADDRESSBAR
PARENTRELATIVEPARSING
-PArgb
parray
PARTIALCONFIRMATIONDIALOGTITLE
-pasteplain
PATCOPY
pathcch
-PATHEXT
Pathto
PATINVERT
PATPAINT
PAUDIO
pbc
-Pbgra
PBlob
pcb
pcch
pcelt
pch
PCIDLIST
-pcs
PCWSTR
-pdb
-pdbonly
pdisp
pdo
pdto
pdtobj
pdw
-PDWORD
-pedrolamas
pef
PElems
Pels
PERCEIVEDFLAG
perfmon
pesi
-petabyte
-peteblois
pevent
PEXCEPTION
pfn
@@ -1428,12 +1109,10 @@ pfo
pft
pgp
pguid
-PHANDLE
phbm
phbmp
phwnd
pici
-pid
pidl
PIDLIST
PINDIR
@@ -1441,28 +1120,19 @@ pinfo
pinvoke
pipename
PKBDLLHOOKSTRUCT
-pkey
plib
PLK
ploc
ploca
plocm
-plugins
pluginsmodel
PMSIHANDLE
Pnp
Popups
POPUPWINDOW
-posix
-poweraccent
-powerlauncher
-POWEROCR
-powerpreview
-powerrename
POWERRENAMECONTEXTMENU
powerrenameinput
POWERRENAMETEST
-powertoy
POWERTOYNAME
powertoyssetup
powertoysusersetup
@@ -1482,13 +1152,11 @@ ppsz
pptal
ppv
prc
-precomp
Prefixer
Preinstalled
prevhost
previewer
PREVIEWHANDLERFRAMEINFO
-previewpane
previouscamera
PREVIOUSINSTALLFOLDER
PREVIOUSVERSIONSINSTALLED
@@ -1505,8 +1173,6 @@ PRODEXT
PRODUCTVERSION
Progman
programdata
-PROGRAMFILES
-proident
projectname
PROPBAG
PROPERTYKEY
@@ -1534,13 +1200,10 @@ ptc
ptd
PTOKEN
PToy
-ptrun
ptstr
pui
-PULONG
pwa
pwcs
-pwsh
PWSTR
pwsz
pwtd
@@ -1555,37 +1218,23 @@ Quarternary
QUERYENDSESSION
QUERYOPEN
QUEUESYNC
-Quickime
QUNS
qwertyuiopasdfghjklzxcvbnm
-qword
qwrtyuiopsghjklzxvnm
raf
RAII
RAlt
-randyrants
Rasterize
-RAWINPUT
RAWINPUTDEVICE
RAWINPUTHEADER
RAWPATH
rbhid
-Rbp
-RBUTTON
-RBUTTONDBLCLK
-RBUTTONDOWN
-RBUTTONUP
rclsid
-RCONTROL
-RCtrl
READMODE
READOBJECTS
-READWRITE
recents
RECTDESTINATION
-RECTL
rectp
-rects
RECTSOURCE
recyclebin
redirectedfrom
@@ -1596,26 +1245,21 @@ reencoded
REFCLSID
REFGUID
REFIID
-Refreshable
REGCLS
-regedit
regfile
REGFILTER
REGFILTERPINS
REGISTERCLASSFAILED
REGISTRYHEADER
registrypath
-registrypreview
REGISTRYPREVIEWEXT
registryroot
regkey
REGPINTYPES
regroot
regsvr
-reinit
REINSTALLMODE
reloadable
-Remapper
remappings
REMAPSUCCESSFUL
REMAPUNSUCCESSFUL
@@ -1625,7 +1269,7 @@ Removelnk
renamable
RENAMEONCOLLISION
Renamer
-reparent
+reparented
reparenting
reparse
reportbug
@@ -1642,42 +1286,24 @@ RESTORETOMAXIMIZED
restrictedcapabilities
restrictederrorinfo
resultlist
-resw
-resx
-retval
-rfc
RGBQUAD
rgbs
rgelt
rgf
rgn
rgs
-rhs
-ricardosantos
RIDEV
-RIGHTDOWN
RIGHTSCROLLBAR
-RIGHTUP
riid
ringbuffer
RKey
-RLO
-RMENU
RNumber
roadmap
-robmensching
-Roboto
-rooler
rop
-roslyn
-roundf
ROUNDSMALL
-Rpc
rpcrt
RRF
rrr
-RSAT
-rshift
rsop
Rsp
Rstrtmgr
@@ -1689,56 +1315,42 @@ rundll
rungameid
RUNLEVEL
runsettings
+runspace
runtimeclass
runtimeobject
runtimepack
runtimes
-RUS
-Rutkas
-RValue
rvm
rwin
rwl
rwz
-ryanbodrug
-saahmedm
-sachaple
sacl
safeprojectname
SAMEKEYPREVIOUSLYMAPPED
SAMESHORTCUTPREVIOUSLYMAPPED
-Santossio
SAVEFAILED
-scancode
scanled
schedtasks
SCID
Scip
scipbe
Scode
-scoobe
-SCOPEID
-screenshot
+screenshots
scrollviewer
sddl
SDKDDK
sdns
searchterm
secpol
-Segoe
-Sekan
SENDCHANGE
sendinput
sendvirtualinput
-Seraphima
serverside
SETCONTEXT
setcursor
-setenv
SETFOCUS
SETFOREGROUND
SETICON
-setlocal
SETREDRAW
SETTEXT
SETTINGCHANGE
@@ -1750,7 +1362,6 @@ SETWORKAREA
setzero
sfgao
SFGAOF
-SFP
SHANDLE
sharpkeys
SHCNE
@@ -1768,7 +1379,6 @@ SHFILEINFO
SHGDNF
SHGFI
shinfo
-Shl
shldisp
shlobj
shlwapi
@@ -1776,7 +1386,6 @@ shmem
shobjidl
SHORTCUTATLEAST
shortcutcontrol
-shortcutguide
SHORTCUTMAXONEACTIONKEY
SHORTCUTNOREPEATEDMODIFIER
SHORTCUTONEACTIONKEY
@@ -1785,7 +1394,6 @@ Shortcuttool
shortdate
SHORTPATH
shortsplit
-should't
showcolorname
SHOWDEFAULT
SHOWELEVATIONPROMPT
@@ -1800,14 +1408,13 @@ shtypes
sia
SIATTRIBFLAGS
SICHINT
-sid
+SIDs
siex
sigdn
SIGNINGSCENARIO
Signtool
SINGLEKEY
singlekeyremapcontrol
-singletones
sipolicy
SIZEBOX
Sizename
@@ -1817,22 +1424,17 @@ SIZENWSE
sizeread
SIZEWE
SKIPOWNPROCESS
-skttl
sku
SLGP
sln
SMALLICON
smartphone
SMTO
-snd
snwprintf
softline
-somil
-Soref
SOURCECLIENTAREAONLY
SOURCEHEADER
sourcesdirectory
-spam
spdisp
spdlog
spdo
@@ -1848,7 +1450,6 @@ SRCERASE
Srch
SRCINVERT
SRCPAINT
-sre
SResize
srf
srme
@@ -1859,8 +1460,6 @@ sse
ssf
STACKFRAME
stackoverflow
-stackpanel
-standalone
STARTF
startupapps
STARTUPINFO
@@ -1872,19 +1471,17 @@ STATICEDGE
STATSTG
stdafx
STDAPI
-stdcall
stdcpp
stdcpplatest
STDMETHODCALLTYPE
STDMETHODIMP
-stefan
-Stereolithography
STGC
STGM
STGMEDIUM
sticpl
stl
storelogo
+streamjsonrpc
STRINGIZE
stringtable
stringval
@@ -1897,18 +1494,12 @@ sttngs
Stubless
STYLECHANGED
STYLECHANGING
-stylecop
-Subdir
-subfolders
-subkey
subkeys
SUBLANG
subquery
-subresource
Superbar
sut
svchost
-SVE
SVGIn
SVGIO
svgz
@@ -1932,11 +1523,7 @@ SYSKEYUP
SYSLIB
SYSMENU
SYSTEMAPPS
-systemroot
SYSTEMTIME
-sysvol
-Tadele
-talynone
tapp
TApplication
TApplied
@@ -1945,16 +1532,11 @@ TARGETAPPHEADER
TARGETDIR
targetentrypoint
TARGETHEADER
-targetnametoken
targetver
-taskbar
taskkill
-tasklist
taskschd
-TBM
tchar
Tcollab
-tcp
tcs
tcscpy
TCustom
@@ -1963,15 +1545,11 @@ TDefault
TDevice
telem
telephon
-Templated
templatenamespace
-terabyte
-testapp
-testcase
+Tenge
testhost
testprocess
TEXCOORD
-textblock
TEXTEXTRACTOR
TEXTINCLUDE
tgz
@@ -1994,7 +1572,6 @@ tlbimp
TMPVAR
TNP
toggleswitch
-tonos
toolkitcontrols
toolkitconverters
Toolset
@@ -2003,7 +1580,6 @@ TOPDOWNDIB
TOUCHEVENTF
TOUCHINPUT
touchpad
-Towindow
tracelogging
traies
transicc
@@ -2018,53 +1594,35 @@ TValue
tweakme
TWF
tymed
-typedef
-TYPEKEY
TYPEKEYBOARD
-TYPELIB
TYPEMOUSE
-typeparam
TYPESHORTCUT
UAC
UAL
uap
udit
-Udp
uefi
+uesc
UHash
UIA
-uid
UIEx
-uipi
-UIs
-ULARGE
-ullamco
ULONGLONG
ums
-unapply
-unassign
uncompilable
-Uncompress
UNCPRIORITY
UNDNAME
+unescape
UNICODETEXT
-Uninitialize
-uninstalling
uninstantiated
uniquifier
Uniquifies
unitconverter
unittests
-Unk
unknwn
UNLEN
-Unmap
-unmute
-unner
UNORM
unregistering
unremapped
-unsubscribe
unvirtualized
unwide
UOffset
@@ -2072,27 +1630,21 @@ UOI
Updatelayout
UPGRADINGPRODUCTCODE
Uptool
+urld
Usb
USEDEFAULT
USEFILEATTRIBUTES
USERDATA
-USERDOMAIN
Userenv
-userprofile
USESHOWWINDOW
USESTDHANDLES
USRDLL
-Utc
-utf
UType
-uuidof
uwp
uxtheme
-UYVY
vabdq
validmodulename
valuegenerator
-Vanara
variantassignment
vcamp
vcdl
@@ -2106,34 +1658,28 @@ vcvars
VDesktop
vdi
vdupq
-vec
VERBSONLY
VERBW
VERIFYCONTEXT
verrsrc
VERSIONINFO
-Versioning
VFT
vget
vgetq
vid
VIDCAP
-videoconference
videoconferencevirtualdriver
VIDEOINFOHEADER
-viewbox
viewmodel
vih
VIRTUALDESK
visiblecolorformats
Visibletrue
VKey
-VKTAB
vmovl
vorrq
VOS
vpaddlq
-Vpn
vqsubq
VREDRAW
vreinterpretq
@@ -2150,7 +1696,6 @@ vstemplate
VSTHRD
VSTT
vswhere
-vtable
Vtbl
WANTPALM
wbem
@@ -2165,21 +1710,15 @@ wcsnicmp
WDA
wdp
wdupenv
-weakme
+webbrowsers
webcam
webpage
-websearch
-webserver
-website
+websites
wekyb
Wevtapi
wgpocpl
-WHITEONBLACK
-whitespaces
WIC
-wifi
-wikipedia
-wildcards
+wil
winapi
winappdriver
wincodec
@@ -2201,7 +1740,6 @@ windowssettings
WINDOWSTYLES
WINDOWSTYLESICON
windowsx
-windowwalker
winerror
WINEVENT
winevt
@@ -2211,7 +1749,6 @@ winfx
winget
wingetcreate
Winhook
-winkey
WINL
winlogon
winmd
@@ -2221,19 +1758,15 @@ winres
winrt
winsdk
winsdkver
-Winsock
winspool
winsta
winternl
WINTHRESHOLD
-winui
-winuiex
WINVER
winxamlmanager
wistd
withinrafael
Withscript
-wix
wixproj
wixtoolset
WIXUI
@@ -2244,21 +1777,14 @@ Wman
WMI
WMICIM
wmimgmt
-WMKEYDOWN
-WMKEYUP
wmp
-WMSYSKEYDOWN
-WMSYSKEYUP
wnd
WNDCLASS
WNDCLASSEX
WNDCLASSEXW
WNDCLASSW
WNDPROC
-wordpad
-workaround
-workflows
-workspaces
+workarounds
wox
wparam
wpf
@@ -2270,18 +1796,13 @@ wql
wregex
WReserved
WResize
-writefile
WRITEOBJECTS
Wrk
wrl
-WSAEADDRINUSE
-WSAEADDRNOTAVAIL
-WSAECONNRESET
wscui
wsf
wsh
wsl
-wss
wstr
wsz
WTA
@@ -2292,59 +1813,42 @@ wtsapi
WTSAT
Wubi
WVC
-Wwan
Wwanpp
-xamlstyler
-Xavalon
XAxis
-xbf
-Xbox
-XBUTTON
-XBUTTONDBLCLK
-XBUTTONDOWN
-XBUTTONUP
XDocument
-XDOWN
XElement
xfd
XFile
XIncrement
XLoc
XNamespace
-XOffset
XPels
XPixel
XResource
xsi
-xstyler
XStr
+xstyler
XUP
XVIRTUALSCREEN
xxxxxx
YAxis
-ycv
Yeet
YIncrement
yinle
-yinwang
yinyue
-YOffset
-Youdao
YPels
YResolution
YStr
-YUY
-yuyoyuppe
-YUYV
YVIRTUALSCREEN
-YVU
-YVYU
ZEROINIT
-ZIndex
-zipfile
-zipfolder
zonable
zoneset
Zoneszonabletester
-Zykova
zzz
+
+# FALSE POSITIVES
+
+## NOTICE.MD > MOZILLA PUBLIC LICENSE v1.1
+declatory
+## "PackagemanagerWrapper.cs" should be "PackageManagerWrapper.cs"
+Packagemanager
diff --git a/.github/actions/spell-check/patterns.txt b/.github/actions/spell-check/patterns.txt
index daf0220efe..d48cec9abd 100644
--- a/.github/actions/spell-check/patterns.txt
+++ b/.github/actions/spell-check/patterns.txt
@@ -118,6 +118,9 @@ aka\.ms/[a-zA-Z0-9]+
# YouTube url
\b(?:(?:www\.|)youtube\.com|youtu.be)/(?:channel/|embed/|user/|playlist\?list=|watch\?v=|v/|)[-a-zA-Z0-9?&=_%]*
+# power shell gallery website
+\bpowershellgallery.com/[-_a-zA-Z0-9()=./%]*
+
# uuid: (or CompGUIDPrefix)
L?(["']|[-<({>]|\b)[0-9a-fA-F]{8}-(?:[0-9a-fA-F]{4}-){3}[0-9a-fA-F]{10,12}(?:\g{-1}|[<})>])
diff --git a/.github/workflows/spelling2.yml b/.github/workflows/spelling2.yml
index d58828a50e..b550f8986b 100644
--- a/.github/workflows/spelling2.yml
+++ b/.github/workflows/spelling2.yml
@@ -107,31 +107,36 @@ jobs:
use_sarif: ${{ (!github.event.pull_request || (github.event.pull_request.head.repo.full_name == github.repository)) && 1 }}
extra_dictionary_limit: 20
extra_dictionaries:
- cspell:software-terms/dict/softwareTerms.txt
- cspell:cpp/src/stdlib-cpp.txt
- cspell:filetypes/filetypes.txt
- cspell:cpp/src/stdlib-c.txt
- cspell:python/src/python/python-lib.txt
- cspell:lorem-ipsum/dictionary.txt
- cspell:php/dict/php.txt
- cspell:typescript/dict/typescript.txt
- cspell:swift/src/swift.txt
- cspell:fullstack/dict/fullstack.txt
- cspell:node/dict/node.txt
- cspell:dotnet/dict/dotnet.txt
- cspell:django/dict/django.txt
- cspell:python/src/python/python.txt
- cspell:csharp/csharp.txt
- cspell:python/src/common/extra.txt
- cspell:cpp/src/compiler-msvc.txt
cspell:aws/aws.txt
- cspell:golang/dict/go.txt
- cspell:java/src/java.txt
- cspell:html/dict/html.txt
+ cspell:cpp/src/compiler-clang-attributes.txt
+ cspell:cpp/src/compiler-msvc.txt
+ cspell:cpp/src/lang-keywords.txt
+ cspell:cpp/src/stdlib-c.txt
+ cspell:cpp/src/stdlib-cmath.txt
+ cspell:cpp/src/stdlib-cpp.txt
+ cspell:csharp/csharp.txt
cspell:css/dict/css.txt
- cspell:k8s/dict/k8s.txt
+ cspell:django/dict/django.txt
+ cspell:dotnet/dict/dotnet.txt
+ cspell:filetypes/filetypes.txt
+ cspell:fullstack/dict/fullstack.txt
+ cspell:golang/dict/go.txt
+ cspell:html/dict/html.txt
+ cspell:java/src/java.txt
cspell:java/src/java-terms.txt
+ cspell:k8s/dict/k8s.txt
+ cspell:lorem-ipsum/dictionary.txt
+ cspell:monkeyc/src/monkeyc_keywords.txt
+ cspell:node/dict/node.txt
+ cspell:php/dict/php.txt
cspell:powershell/dict/powershell.txt
+ cspell:python/src/common/extra.txt
+ cspell:python/src/python/python.txt
+ cspell:python/src/python/python-lib.txt
+ cspell:scala/dict/scala.txt
+ cspell:software-terms/dict/softwareTerms.txt
+ cspell:swift/src/swift.txt
+ cspell:typescript/dict/typescript.txt
comment-push:
name: Report (Push)
diff --git a/.pipelines/ESRPSigning_core.json b/.pipelines/ESRPSigning_core.json
index 73bc45ed03..a6350ec764 100644
--- a/.pipelines/ESRPSigning_core.json
+++ b/.pipelines/ESRPSigning_core.json
@@ -28,7 +28,10 @@
"PowerToys.AlwaysOnTop.exe",
"PowerToys.AlwaysOnTopModuleInterface.dll",
-
+
+ "PowerToys.CmdNotFoundModuleInterface.dll",
+ "PowerToys.CmdNotFound.dll",
+
"PowerToys.ColorPicker.dll",
"PowerToys.ColorPickerUI.dll",
"PowerToys.ColorPickerUI.exe",
@@ -251,6 +254,7 @@
"Mages.Core.dll",
"JetBrains.Annotations.dll",
"NLog.Extensions.Logging.dll",
+ "getfilesiginforedist.dll",
"concrt140_app.dll",
"msvcp140_1_app.dll",
"msvcp140_2_app.dll",
diff --git a/.pipelines/applyXamlStyling.ps1 b/.pipelines/applyXamlStyling.ps1
index 8f890d2a91..57f4ae8ee1 100644
--- a/.pipelines/applyXamlStyling.ps1
+++ b/.pipelines/applyXamlStyling.ps1
@@ -39,7 +39,7 @@ param(
Write-Output "Use 'Help .\applyXamlStyling.ps1' for more info or '-Main' to run against all files."
Write-Output ""
Write-Output "Restoring dotnet tools..."
-dotnet tool restore
+dotnet tool restore --disable-parallel --no-cache
if (-not $Passive)
{
@@ -107,7 +107,7 @@ if (-not $Passive)
else
{
Write-Output "Checking all files (passively)"
- $files = Get-ChildItem -Path "$PSScriptRoot\..\src\*.xaml" -Recurse | Select-Object -ExpandProperty FullName | Where-Object { $_ -notmatch "(\\obj\\)|(\\bin\\)|(\\x64\\)|(\\Generated Files\\PowerRenameXAML\\)|(\\launcher\\PowerLauncher\\)|(\\launcher\\Wox.Plugin\\)|(\\colorPicker\\ColorPickerUI\\)" }
+ $files = Get-ChildItem -Path "$PSScriptRoot\..\src\*.xaml" -Recurse | Select-Object -ExpandProperty FullName | Where-Object { $_ -notmatch "(\\obj\\)|(\\bin\\)|(\\x64\\)|(\\Generated Files\\PowerRenameXAML\\)|(\\colorPicker\\ColorPickerUI\\)" }
if ($files.count -gt 0)
{
diff --git a/.pipelines/ci/templates/build-powertoys-steps.yml b/.pipelines/ci/templates/build-powertoys-steps.yml
index 23cd60f191..d151a39257 100644
--- a/.pipelines/ci/templates/build-powertoys-steps.yml
+++ b/.pipelines/ci/templates/build-powertoys-steps.yml
@@ -7,6 +7,12 @@ steps:
submodules: true
clean: true
+- task: UseDotNet@2
+ displayName: 'Use .NET 6 SDK'
+ inputs:
+ packageType: sdk
+ version: '6.x'
+
- task: PowerShell@2
displayName: Verify XAML formatting
inputs:
@@ -56,11 +62,18 @@ steps:
arguments: -solution '$(build.sourcesdirectory)\installer\PowerToysSetup.sln'
pwsh: true
+- task: PowerShell@2
+ displayName: Verify and set latest VCToolsVersion usage
+ inputs:
+ filePath: '$(build.sourcesdirectory)\.pipelines\verifyAndSetLatestVCToolsVersion.ps1'
+ pwsh: true
+
- task: UseDotNet@2
- displayName: 'Use .NET 7 SDK'
+ displayName: 'Use .NET 8 SDK'
inputs:
packageType: sdk
- version: '7.x'
+ version: '8.x'
+ includePreviewVersions: true
- task: VisualStudioTestPlatformInstaller@1
displayName: Ensure VSTest Platform
diff --git a/.pipelines/release.yml b/.pipelines/release.yml
index ae62f47df7..1993c2b3ce 100644
--- a/.pipelines/release.yml
+++ b/.pipelines/release.yml
@@ -8,7 +8,7 @@ resources:
- repository: 1ESPipelineTemplates
type: git
name: 1ESPipelineTemplates/1ESPipelineTemplates
- ref: refs/tags/release
+ ref: refs/tags/release-2023-11-13-4
parameters:
- name: buildConfigurations
@@ -88,10 +88,16 @@ extends:
version: '6.x'
- task: UseDotNet@2
- displayName: 'Use .NET 7 SDK'
+ displayName: 'Use .NET 8 SDK'
inputs:
packageType: sdk
- version: '7.x'
+ version: '8.x'
+
+ - task: PowerShell@2
+ displayName: Verify and set latest VCToolsVersion usage
+ inputs:
+ filePath: '$(build.sourcesdirectory)\.pipelines\verifyAndSetLatestVCToolsVersion.ps1'
+ pwsh: true
- task: NuGetAuthenticate@1
diff --git a/.pipelines/sdl.gdnbaselines b/.pipelines/sdl.gdnbaselines
index e701628c7c..fa5950150f 100644
--- a/.pipelines/sdl.gdnbaselines
+++ b/.pipelines/sdl.gdnbaselines
@@ -9,7 +9,7 @@
"default": {
"name": "default",
"createdDate": "2023-10-03 21:03:36Z",
- "lastUpdatedDate": "2023-10-03 21:03:36Z"
+ "lastUpdatedDate": "2023-12-19 10:44:09Z"
}
},
"results": {
@@ -4073,26 +4073,6 @@
],
"createdDate": "2023-10-03 21:03:42Z"
},
- "8fff855f02ba9c7072cf59faccc3d14646b1a36c8f15363e3f1cfa25213d9634": {
- "signature": "8fff855f02ba9c7072cf59faccc3d14646b1a36c8f15363e3f1cfa25213d9634",
- "alternativeSignatures": [
- "d7e1fbefca4e33fc1113664d9d4bdbad5023a0b5dbfa237a3f9c284fc5149af5"
- ],
- "memberOf": [
- "default"
- ],
- "createdDate": "2023-10-03 21:03:42Z"
- },
- "0f106e5ef5cab492d6295ef0c086863cab9333fcc75632a71c41f374b6752186": {
- "signature": "0f106e5ef5cab492d6295ef0c086863cab9333fcc75632a71c41f374b6752186",
- "alternativeSignatures": [
- "2925182dbce19532d6f6e3eae5b16f38f81699bb5e0230d5032af21794c1e026"
- ],
- "memberOf": [
- "default"
- ],
- "createdDate": "2023-10-03 21:03:42Z"
- },
"1059cf23da551794867a86bd9403db0a040bfddedd2b21d3eac80c295250ec90": {
"signature": "1059cf23da551794867a86bd9403db0a040bfddedd2b21d3eac80c295250ec90",
"alternativeSignatures": [
@@ -4653,76 +4633,6 @@
],
"createdDate": "2023-10-03 21:03:42Z"
},
- "fb8966b1b5ffb934257b1bc520dd93b1f11d4c2b6840f8e64c36ab047136d901": {
- "signature": "fb8966b1b5ffb934257b1bc520dd93b1f11d4c2b6840f8e64c36ab047136d901",
- "alternativeSignatures": [
- "70da01abc04796dbc83d081f101e0d496bf18273f487ce9c2045710848e1ea31"
- ],
- "memberOf": [
- "default"
- ],
- "createdDate": "2023-10-03 21:03:42Z"
- },
- "52e895d56fc4c84c258af24a9f105ecd538e854312bae9a69c8b63c2d0c7e073": {
- "signature": "52e895d56fc4c84c258af24a9f105ecd538e854312bae9a69c8b63c2d0c7e073",
- "alternativeSignatures": [
- "596b117d6efc34ecc9cb3214ef1993cb8dc193ad1be369789968aea11b2e2280"
- ],
- "memberOf": [
- "default"
- ],
- "createdDate": "2023-10-03 21:03:42Z"
- },
- "a5e1e0c2930c8f288baacfe2997e3a79731202c4ec723c312f05ec25edad0b93": {
- "signature": "a5e1e0c2930c8f288baacfe2997e3a79731202c4ec723c312f05ec25edad0b93",
- "alternativeSignatures": [
- "0a7c092da3a211fc1345b18d51e74c55f06bd56650785b89e8b572d90baf7630"
- ],
- "memberOf": [
- "default"
- ],
- "createdDate": "2023-10-03 21:03:42Z"
- },
- "5da6166f715f8695139c8b2b63702f784582a22923776b5280b6640a7344f6e9": {
- "signature": "5da6166f715f8695139c8b2b63702f784582a22923776b5280b6640a7344f6e9",
- "alternativeSignatures": [
- "be6749e61fbfce75e4d437901561f9f57277ba634e3c821b7e64cc4a1c1ec3e6"
- ],
- "memberOf": [
- "default"
- ],
- "createdDate": "2023-10-03 21:03:42Z"
- },
- "d4c834d8b852ecf003acf23a42ca493252866cde300f80d89cb33c0b1f7fa50d": {
- "signature": "d4c834d8b852ecf003acf23a42ca493252866cde300f80d89cb33c0b1f7fa50d",
- "alternativeSignatures": [
- "2d56418af2e33c6071fd66a91363aa886cfeb76dc132bcd24fd7bc545b925eca"
- ],
- "memberOf": [
- "default"
- ],
- "createdDate": "2023-10-03 21:03:42Z"
- },
- "5f8939125e4811034c264d2e28090094a8136669d44e60e467b92aeb0fe9e3ca": {
- "signature": "5f8939125e4811034c264d2e28090094a8136669d44e60e467b92aeb0fe9e3ca",
- "alternativeSignatures": [
- "acfe6eaba681aa6b3b6b0cd5059361d868b5e08cbeaeff991f1c3b550e51dcf6"
- ],
- "memberOf": [
- "default"
- ],
- "createdDate": "2023-10-03 21:03:42Z"
- },
- "e6abd87ed5b6da12d2170d4c1777a3478e421d3ce2b8a6e6dd1803cfe3b7ffae": {
- "signature": "e6abd87ed5b6da12d2170d4c1777a3478e421d3ce2b8a6e6dd1803cfe3b7ffae",
- "alternativeSignatures": [
- "ab49bfc7c3aae12ecd1e98a21d0e695ecaa3b1494ef3e8b7a8326976af514050"
- ],
- "memberOf": [
- "default"
- ],
- "createdDate": "2023-10-03 21:03:42Z"
- },
"e5ee21df0c7b8dc199c5cc544d3ba1d710d223a12565bfe8b14b975967bf5070": {
"signature": "e5ee21df0c7b8dc199c5cc544d3ba1d710d223a12565bfe8b14b975967bf5070",
"alternativeSignatures": [
@@ -7452,6 +7362,1726 @@
"default"
],
"createdDate": "2023-10-03 21:03:42Z"
+ },
+ "121313e8431866f5556932da88941a0caeeb92a2979cdce9bd79a4584bf46d87": {
+ "signature": "121313e8431866f5556932da88941a0caeeb92a2979cdce9bd79a4584bf46d87",
+ "alternativeSignatures": [
+ "d1a9b882b05e5e1964df2ef3deb905875004d69bd9e52e2ca23a027e317baf89"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "072adcc944859db0f036d8a0954334c43e41b2db20668dbfdb382fc88588500b": {
+ "signature": "072adcc944859db0f036d8a0954334c43e41b2db20668dbfdb382fc88588500b",
+ "alternativeSignatures": [
+ "95498a0aa4f0de50880e1227fadb9f2ae2da1151269603dca2877c02298ce066"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "0a37408d6280c91d6765f2eb68d9d5c01e81735a6474e99dbc761aeb1a53664a": {
+ "signature": "0a37408d6280c91d6765f2eb68d9d5c01e81735a6474e99dbc761aeb1a53664a",
+ "alternativeSignatures": [
+ "2cc3fc1413022eb0ba3d14f3d847c17ddbfae531a41e3abcdca38285652bdabc"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "26bc91039ae4bd10e8aef905e95b225a2900b6986cee9f504128a0c234846204": {
+ "signature": "26bc91039ae4bd10e8aef905e95b225a2900b6986cee9f504128a0c234846204",
+ "alternativeSignatures": [
+ "146900bc636e176109b937fdb2ce0c0787d846c76ac73b418610edb840196451"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "7e5f411c782d40949b35fb68f458c3f47d46d4b5c288e578522bddfd5c018349": {
+ "signature": "7e5f411c782d40949b35fb68f458c3f47d46d4b5c288e578522bddfd5c018349",
+ "alternativeSignatures": [
+ "997d0a0a3445dd6c336707ecba3f29b9e086f1e88cd5898fea948e5c5373eaf1"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "481e6f6cb0a8a17a4a32944bd224ae78ff9c98e85310f6c41b0d3ea0445062ff": {
+ "signature": "481e6f6cb0a8a17a4a32944bd224ae78ff9c98e85310f6c41b0d3ea0445062ff",
+ "alternativeSignatures": [
+ "8fd73479260d344418f2f9fbcdfa903cbe53fec8cd960113ea7ddea9506bf281"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "72dbb91a7ef4ab32f6cf2d9bc3f9798e64e95d9aabf42fb6c98fe1ecb5f512d1": {
+ "signature": "72dbb91a7ef4ab32f6cf2d9bc3f9798e64e95d9aabf42fb6c98fe1ecb5f512d1",
+ "alternativeSignatures": [
+ "c41b56aef52b90e2593819ab75bdc0cc7db26649215f1f904fcba287d116e8c1"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "c877559f9b4378d7f16329eb741854eb1bf464df0448221090adfb8240217c03": {
+ "signature": "c877559f9b4378d7f16329eb741854eb1bf464df0448221090adfb8240217c03",
+ "alternativeSignatures": [
+ "932758601d51d1e2199491a9a7a1ad4f4360943c94d5a39a179a6d27c2d8ac54"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "f2f39815d32aa9e67c0dd73d910d7e7362e785971795503c3ccbd6103628adb0": {
+ "signature": "f2f39815d32aa9e67c0dd73d910d7e7362e785971795503c3ccbd6103628adb0",
+ "alternativeSignatures": [
+ "0bbb183dfe40a38b998933d4f16382421b0bbe433c8e099bc7c10d6525803495"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "8ed43810856e9a397f7f155ebe2d5fe59e7561d4a7e7632bf950d9da7acf3436": {
+ "signature": "8ed43810856e9a397f7f155ebe2d5fe59e7561d4a7e7632bf950d9da7acf3436",
+ "alternativeSignatures": [
+ "bf5959ca7bc7207ce2a5476d3f5857c7eb4b788375d5218dab4be3d05e8d8747"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "0b167636c3dcd9bd728fdc42e0b286463d09283956eb9210a6e5a2106c662cc9": {
+ "signature": "0b167636c3dcd9bd728fdc42e0b286463d09283956eb9210a6e5a2106c662cc9",
+ "alternativeSignatures": [
+ "41762955f66e28bc05e5e21f3fa288971d874dce0ac313a76a4c80114779c417"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "1df7dad1e36f1218c4ef34a557edb64aa2fe609d6e1f77addf01cad9e3e1cabb": {
+ "signature": "1df7dad1e36f1218c4ef34a557edb64aa2fe609d6e1f77addf01cad9e3e1cabb",
+ "alternativeSignatures": [
+ "5951af10d7bf02e61b8187fc50cf7fd952479d2bdf59bc0f562400b618b57015"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "526f5c04cc350c7367d586ef6d6efb6d63d5955f99e4950606226698de0bfce4": {
+ "signature": "526f5c04cc350c7367d586ef6d6efb6d63d5955f99e4950606226698de0bfce4",
+ "alternativeSignatures": [
+ "346fda5602d7fac4b54b3f700dd644ef51479da7ab0306115cb15a27ad621ebe"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "1b22a66c221ff36ed1995784f85ab8962c0d0cfb3436e4e49637b9ff09891097": {
+ "signature": "1b22a66c221ff36ed1995784f85ab8962c0d0cfb3436e4e49637b9ff09891097",
+ "alternativeSignatures": [
+ "45f60c3b5b7d0bfa30b1361e73cd13a9fb9b162c58894dc08033eb716d8d399c"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "7c2a6ab0e61d7d46744fc2bd5463f9e4189b8c0373d4a60fe427bb7c603ce3c2": {
+ "signature": "7c2a6ab0e61d7d46744fc2bd5463f9e4189b8c0373d4a60fe427bb7c603ce3c2",
+ "alternativeSignatures": [
+ "3020e525d815c681249c8cef8ff3b2e483929b6c730aeb68b220474b06cb6383"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "edf831f072c4b4ba155838a7575733e885bb54e575b5c15614e88703ef709344": {
+ "signature": "edf831f072c4b4ba155838a7575733e885bb54e575b5c15614e88703ef709344",
+ "alternativeSignatures": [
+ "2e536fed38a8fa3ad31d4c08a4d7b01286753ab7523b21803701c38e843eb19f"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "d89180cfb07e2a4899418ef58786fed072ac9c870a915d986e69ee383bb1f08c": {
+ "signature": "d89180cfb07e2a4899418ef58786fed072ac9c870a915d986e69ee383bb1f08c",
+ "alternativeSignatures": [
+ "da51a4342982564c98a3ace838a46cf5f13fc7dbb3468646420d16e9c7ad4316"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "59644b7825940085404799fbd28a02974a6fe1263fff32d837321da39639e4bb": {
+ "signature": "59644b7825940085404799fbd28a02974a6fe1263fff32d837321da39639e4bb",
+ "alternativeSignatures": [
+ "d682dee1a629246d4a04085b512d88c196d00109a6a7e391f0c3d8c481341cc7"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "39b13a84c1cf94d251fb643393cd7b4a1ac2c0961929cdbb330be5412d67bf4b": {
+ "signature": "39b13a84c1cf94d251fb643393cd7b4a1ac2c0961929cdbb330be5412d67bf4b",
+ "alternativeSignatures": [
+ "816f24d32a0a043a60ff72ab4dcf195d41355923be287347dc7a20b029eefd53"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "3250bd55a1b552486fc275f6c76a869a94b9309fbf6efa9a4559209d9acd8668": {
+ "signature": "3250bd55a1b552486fc275f6c76a869a94b9309fbf6efa9a4559209d9acd8668",
+ "alternativeSignatures": [
+ "20d54545caf06c54aaf334bfedac3dfcb96d65363a3517994428c15db5367813"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "7b9eae9f114b5deabf5265d6509c8d564b28e54bc6f12ebaf7d4790b81ba0fd0": {
+ "signature": "7b9eae9f114b5deabf5265d6509c8d564b28e54bc6f12ebaf7d4790b81ba0fd0",
+ "alternativeSignatures": [
+ "5e28d6173a37f209ce72e730d8339d54a709fb99d98bbb08a3af08adea4702bf"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "54abe72bbead419b8d8094ef33e0e23b322db5c5a87fd7c4ebf487df13f0b5a8": {
+ "signature": "54abe72bbead419b8d8094ef33e0e23b322db5c5a87fd7c4ebf487df13f0b5a8",
+ "alternativeSignatures": [
+ "88465f96a615231c7f6ccde3b0d86cbef0de5fa88df2c106d98942d46d610442"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "6f585bc886e45e96ef80e561df7c9478a2a211f332d1c0e6fef75ef8cbb3a610": {
+ "signature": "6f585bc886e45e96ef80e561df7c9478a2a211f332d1c0e6fef75ef8cbb3a610",
+ "alternativeSignatures": [
+ "72afb5aa9eb2372ee912d3b243e180d5df1041ec8a70a453d15faa8863bfc04f"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "3c40e56952e7ea0f6730202de9f676322a81b31db55e27e8762a7b95c2965144": {
+ "signature": "3c40e56952e7ea0f6730202de9f676322a81b31db55e27e8762a7b95c2965144",
+ "alternativeSignatures": [
+ "6b28b82635502e6a3d097cbcddc4e4d9d448eea42a76fb7391cf5b7683858851"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "eafd1f6cf18e6714f21b9e6760509c8e3b5e47209ea8e2d14c7f265c6268fe7c": {
+ "signature": "eafd1f6cf18e6714f21b9e6760509c8e3b5e47209ea8e2d14c7f265c6268fe7c",
+ "alternativeSignatures": [
+ "f3c8de56d31e8e776d521391be1d595c23b016e4ead34e02e8626d81405db6e1"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "9e6b7ab5b446aa91ad092a0ce314b0c3841beb38646be636c7bf7f2dfa171d30": {
+ "signature": "9e6b7ab5b446aa91ad092a0ce314b0c3841beb38646be636c7bf7f2dfa171d30",
+ "alternativeSignatures": [
+ "e340f9adede82191f4af68dd3b4b6691371ce1ea4d1471e3ddca1a68183f836b"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "c109329c154f283623dba68b7e92ce0d7e2f7b6835074d5e6b862f0b23090e70": {
+ "signature": "c109329c154f283623dba68b7e92ce0d7e2f7b6835074d5e6b862f0b23090e70",
+ "alternativeSignatures": [
+ "74cdde9212c384f79f69848c961b0b4d9e5c998e9940eaac7520a52a1fd28390"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "894b542ba3ccd58bf80dd6df620a284b7b0b3e5aa70ca2c5f67b74f7d65dbaa3": {
+ "signature": "894b542ba3ccd58bf80dd6df620a284b7b0b3e5aa70ca2c5f67b74f7d65dbaa3",
+ "alternativeSignatures": [
+ "cc279a7199021a5b0bea6f8b8a98622bbb514aa81cb027d2b4550ffc0cbeab80"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "a85ed08e9713634c91ce1f5ff569f31df7d43f4800aaaed78159e1496e25bcc9": {
+ "signature": "a85ed08e9713634c91ce1f5ff569f31df7d43f4800aaaed78159e1496e25bcc9",
+ "alternativeSignatures": [
+ "b471107c8ed1d5e0196d8f883c3ab3a6f398784c56d3aaf8d4ed1be07feb46e7"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "ab175e26ee5cff5d966c2a4a28315fc6a26515f0c06e6c9361377546c5e8946e": {
+ "signature": "ab175e26ee5cff5d966c2a4a28315fc6a26515f0c06e6c9361377546c5e8946e",
+ "alternativeSignatures": [
+ "c5afdab17beb9bd2221ebf0811ff9c1857d82435c51fe60bbb69e0cae441ff09"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "cec2fe8b71fa3939c2dc81c1761e49e62336dc4da027826cafc58fb4c754001f": {
+ "signature": "cec2fe8b71fa3939c2dc81c1761e49e62336dc4da027826cafc58fb4c754001f",
+ "alternativeSignatures": [
+ "16573891a6addcff7f349bc76be0af765ab76f9d9229aa60d972b6402ae6f640"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "a3123356fb65d4313d1d70ed3091f71cd3d831a02ed2961b184a3d2267ceff3e": {
+ "signature": "a3123356fb65d4313d1d70ed3091f71cd3d831a02ed2961b184a3d2267ceff3e",
+ "alternativeSignatures": [
+ "366060a980ef35012094bbf3a4995ec72dd86685bd4d42bf066b4b2ad2c6a5cf"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "1cee9cee813752f2fb34090a34ecc7e8434fe34f7176067f0ea9e63b87db1591": {
+ "signature": "1cee9cee813752f2fb34090a34ecc7e8434fe34f7176067f0ea9e63b87db1591",
+ "alternativeSignatures": [
+ "5034b3d71b2150bb5fa96b9d3d3b1bf624ff8976c9aa1f9c433351ea274a2d4e"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "4c6c600fb59e77929b82bb38691aa3f3a2a11029a02c347e897a922caec7800a": {
+ "signature": "4c6c600fb59e77929b82bb38691aa3f3a2a11029a02c347e897a922caec7800a",
+ "alternativeSignatures": [
+ "01834447f52d0e6f763d353a4b323fe18138e1b82bfc24bfff2fc282f52244a0"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "84645153dafb606e63e9bea7e49f093b0260487773799ffbdba446c62c45640a": {
+ "signature": "84645153dafb606e63e9bea7e49f093b0260487773799ffbdba446c62c45640a",
+ "alternativeSignatures": [
+ "7fece5dcd915f5d721157ba9ba3739d3da65babd53e7f39c23f20bf4394b86cb"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "293f5f36829a7b3e4c3d17ec533198dca4684cd600518ffe21e8eb3902f0e32d": {
+ "signature": "293f5f36829a7b3e4c3d17ec533198dca4684cd600518ffe21e8eb3902f0e32d",
+ "alternativeSignatures": [
+ "cbf5a264a56c1d06fe8a5bbe7345f35cbf051d9d836e3d88cab3af752f818257"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "237fad55920cdbb2dc205224ab0921801fc3ffd5dff5cd72b6bf64b1a3d44b1a": {
+ "signature": "237fad55920cdbb2dc205224ab0921801fc3ffd5dff5cd72b6bf64b1a3d44b1a",
+ "alternativeSignatures": [
+ "3594af79579d29d3b71471c0dfbde0693d1199fff01a387f702e6cca82b7e146"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "b654525f71db7d809bc307d17359e055b4b1d2d0796d22bb016fecc2250f03d4": {
+ "signature": "b654525f71db7d809bc307d17359e055b4b1d2d0796d22bb016fecc2250f03d4",
+ "alternativeSignatures": [
+ "2e613dcd0ee6f9898673cce1d9f0d7f089821f9c94b96668387081aba20e25ed"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "ae71d87bc2abe90d116d000a578312339f6db6f6581b7fcc00f5583b3cc6d2b8": {
+ "signature": "ae71d87bc2abe90d116d000a578312339f6db6f6581b7fcc00f5583b3cc6d2b8",
+ "alternativeSignatures": [
+ "133a75eec0b0ae29234bc51156120363b2bf3e3c8bd0f772f55192eca639ee37"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "686d06d5e3db9245204a219838709fe6ac2c140004bdc55b973ff1223ff03cc1": {
+ "signature": "686d06d5e3db9245204a219838709fe6ac2c140004bdc55b973ff1223ff03cc1",
+ "alternativeSignatures": [
+ "d1062dc3de292f943ac4ae330512943873f8721f56423bfa6d3f4f21d751b607"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "76b220c88f65a8d433ee59aff494efd7e5dc382047b032d785e4740e4c4b5caf": {
+ "signature": "76b220c88f65a8d433ee59aff494efd7e5dc382047b032d785e4740e4c4b5caf",
+ "alternativeSignatures": [
+ "19287944b96cf90db616003f39a8de00467ea35bdbd0f242fc8aa8299f5ed97f"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "fa89fa82cb1824e4a53d384acc741513678c417e577cfd8a56fb8c0dbb9b217f": {
+ "signature": "fa89fa82cb1824e4a53d384acc741513678c417e577cfd8a56fb8c0dbb9b217f",
+ "alternativeSignatures": [
+ "02a451ea743e03a917eaf4c9eaffa33ae8bbb69818f062c5ec9ac3d0885d3b0f"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "d4270cb1d32ac6734b0cdd3605b8a367295d51a7e20d12f640293aa288da7d91": {
+ "signature": "d4270cb1d32ac6734b0cdd3605b8a367295d51a7e20d12f640293aa288da7d91",
+ "alternativeSignatures": [
+ "2685266c2313995fe38d986137769f2db92decdd513c3ecee59c0fc45e976929"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "c46ef4c60812e38e9b307badb43f339923ae8e8d63511678f1ec5ceb3b7e4496": {
+ "signature": "c46ef4c60812e38e9b307badb43f339923ae8e8d63511678f1ec5ceb3b7e4496",
+ "alternativeSignatures": [
+ "41504381a8727c36db403f8c3ff0c8d95a12acaaef410b14ae4424d3a87b354f"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "bd4b1782033d9d0dbbba80101bd9bb764f37f20c45ef3d318841b2e2d36284f5": {
+ "signature": "bd4b1782033d9d0dbbba80101bd9bb764f37f20c45ef3d318841b2e2d36284f5",
+ "alternativeSignatures": [
+ "9e2a5bba0ee3e51ecfc826ef3df955f99a61a0b4870eda851ac70468664e5ab5"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "8e98b72b1dfdb2d8a34322c2c3d5bc23ac39c6f64762669541ec07056e80edee": {
+ "signature": "8e98b72b1dfdb2d8a34322c2c3d5bc23ac39c6f64762669541ec07056e80edee",
+ "alternativeSignatures": [
+ "8885fb9dc7597242a3a9167da0c6b64e1fd84d672b2fe4ca67224e7b055f97e8"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "a48df0829755a7f8dedb7e96b4fa7b62d187ef88400ccf802b3c3248d779e8f9": {
+ "signature": "a48df0829755a7f8dedb7e96b4fa7b62d187ef88400ccf802b3c3248d779e8f9",
+ "alternativeSignatures": [
+ "478aa5c8860e276bc2d05a2bef2c8da87d22aac76317927f9ff4fcb64daaf65f"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "a5ee21f6fcc7666c48d69c55b16f610385702a929d7fb5630abc265a964ab7dc": {
+ "signature": "a5ee21f6fcc7666c48d69c55b16f610385702a929d7fb5630abc265a964ab7dc",
+ "alternativeSignatures": [
+ "358a196042b95f24aa3a876c6064f0f6aec8bc4593a7682c9c44b50e4d64bffc"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "65b2f24e130ef0f23f956790e35ad6360899b8205d64b3c9a4a983f8bf36d223": {
+ "signature": "65b2f24e130ef0f23f956790e35ad6360899b8205d64b3c9a4a983f8bf36d223",
+ "alternativeSignatures": [
+ "9ec0e6bf5a1ebd589c4d3a33bf2f146ed64fff7aae25e9358b4eec49c6bd048b"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "2254e8de9aa66eda2cb7990502cb1a57fb40bc2f4aa0687646b77ff58326b314": {
+ "signature": "2254e8de9aa66eda2cb7990502cb1a57fb40bc2f4aa0687646b77ff58326b314",
+ "alternativeSignatures": [
+ "a20251e913bbeda843de79e8539a5ff22817a19336126243e838ed4c48d7323f"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "077c76edeba33767060e4c81a27c67214bacbf54e723358986e74ec5d53d6575": {
+ "signature": "077c76edeba33767060e4c81a27c67214bacbf54e723358986e74ec5d53d6575",
+ "alternativeSignatures": [
+ "40e69167d2e414f777f93d6422cfee9a58d6805cbae36df542b850c583ef4602"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "983ba3f13d13079187101206597481be77c6deba1b7a63e1bd53a94a0817c383": {
+ "signature": "983ba3f13d13079187101206597481be77c6deba1b7a63e1bd53a94a0817c383",
+ "alternativeSignatures": [
+ "3b8fb80eaec206339816b604e174e75eb7fe076273531bc0de1176ff42f23e90"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "7d4478e6e481335799e69c961bf2341cf34568aa643b480454f8749a2cc83a8a": {
+ "signature": "7d4478e6e481335799e69c961bf2341cf34568aa643b480454f8749a2cc83a8a",
+ "alternativeSignatures": [
+ "73b76119e28649a5c0213994803941fb799b48b60e70d270f4f3e58a8e021631"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "43a7c05409c1e943b78051d774f331aba10c4747f7eb6fc4ab972d38ffd69fd4": {
+ "signature": "43a7c05409c1e943b78051d774f331aba10c4747f7eb6fc4ab972d38ffd69fd4",
+ "alternativeSignatures": [
+ "8b3a216c7c51a2e23f69c32b51d75e8224932b8a0ef01cfdd133a7e57cce8f7a"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "37c4473c0fa972f79832a3fc956fd4bad2c0d6f2ca95273dbd40c740dd97d5c4": {
+ "signature": "37c4473c0fa972f79832a3fc956fd4bad2c0d6f2ca95273dbd40c740dd97d5c4",
+ "alternativeSignatures": [
+ "2b1cd8cc7b30615c8b9266e98f7dcd44cb0c156e2836311498f8f266488c51a1"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "3c5e71e1c3003467190391f926bb102a2ff6c89e1e41f3d625bf5fff18cf5956": {
+ "signature": "3c5e71e1c3003467190391f926bb102a2ff6c89e1e41f3d625bf5fff18cf5956",
+ "alternativeSignatures": [
+ "4f9742e521815e570e2c6027009c92099f4e556ed8d5e0d1e98809d6c238b3af"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "dbfa27a45067a471e3d6862069d8fc6d01af1628591c46aee3b395ab62428c4c": {
+ "signature": "dbfa27a45067a471e3d6862069d8fc6d01af1628591c46aee3b395ab62428c4c",
+ "alternativeSignatures": [
+ "a92f0da74c399a29fbfa1d2e6c940d58b3b300028e004df1a1c23f5931018160"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "0e039ebdb8d4984bab6e6cea54530903455a722f4e2524221e0241e4797c44ef": {
+ "signature": "0e039ebdb8d4984bab6e6cea54530903455a722f4e2524221e0241e4797c44ef",
+ "alternativeSignatures": [
+ "f8c8439fb8b1ea12eb0096ff32dd260dd57ad4ec5e1363aaf8160e59fbaac10a"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "03fbe1c7d42905bcd527e3792eef81d44a53c0c154a42bd1a905f43ced22ac9d": {
+ "signature": "03fbe1c7d42905bcd527e3792eef81d44a53c0c154a42bd1a905f43ced22ac9d",
+ "alternativeSignatures": [
+ "822559e3edcda036340577e6a13a270a9d5faff852de0b1927ac4a68518cf4b9"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "261f5866ac9607e708e038b863278c8ebcd11adfed0f348acf5486ddff761911": {
+ "signature": "261f5866ac9607e708e038b863278c8ebcd11adfed0f348acf5486ddff761911",
+ "alternativeSignatures": [
+ "9c15ccae1db547f9379807697c43b13b25fd40df0d710c7c994efae4923ea195"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "1aa8fb8cdb7dbaee75d9df1b3a5cbaa96b77598e8b870511a5c351699f78fa10": {
+ "signature": "1aa8fb8cdb7dbaee75d9df1b3a5cbaa96b77598e8b870511a5c351699f78fa10",
+ "alternativeSignatures": [
+ "c8943159b9af7086748bdc9868706fcf5ecd91a77b7b144eb39e2441edc8fc3f"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "555fdfbbe3b2f8134084dd2c1c1d93f8b1f43f8a2e5ab26cb55d1177e00b701d": {
+ "signature": "555fdfbbe3b2f8134084dd2c1c1d93f8b1f43f8a2e5ab26cb55d1177e00b701d",
+ "alternativeSignatures": [
+ "9c9168cacaafaacda07c61241cfe48ac90ea1390dc4e62498f30d0924524c76b"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "496cebb6ef8c488975d3e17d273ed75aaf360692092fad5c9393f0ee8d2fa6e5": {
+ "signature": "496cebb6ef8c488975d3e17d273ed75aaf360692092fad5c9393f0ee8d2fa6e5",
+ "alternativeSignatures": [
+ "4a15cde25604c2fefbb35e1bca736a52adf08b9bd4fd831ebc62f8c191456fee"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "f8038ec5a8db237cc5a61db38907b545a67dea1fc138a82075987108751803b6": {
+ "signature": "f8038ec5a8db237cc5a61db38907b545a67dea1fc138a82075987108751803b6",
+ "alternativeSignatures": [
+ "738bdb97e2215cc340de8e1d946e991aff52807fd5a88987aedd0f162f8a914a"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "ec7dffa74b192e2befeb5f8d106d343ac829c1f54afbc51fa03332f5821459bb": {
+ "signature": "ec7dffa74b192e2befeb5f8d106d343ac829c1f54afbc51fa03332f5821459bb",
+ "alternativeSignatures": [
+ "af03f8cf7282ec4d8a8504c3bffaecc910add504e9cee607f941300146579924"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "4ba331fb02a1c9b00d8efe609c0add83c84df931862ce8a637210a6d076e17cc": {
+ "signature": "4ba331fb02a1c9b00d8efe609c0add83c84df931862ce8a637210a6d076e17cc",
+ "alternativeSignatures": [
+ "e1ce7a23906cdc8a971743cabc574931d33c2602ff6ddc9bfb9744926f40d89a"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "3065a246a4cb4fe30c47ac0dbf1d861ce58547ad3e47f0ebb6f4b2cd2a1c7a57": {
+ "signature": "3065a246a4cb4fe30c47ac0dbf1d861ce58547ad3e47f0ebb6f4b2cd2a1c7a57",
+ "alternativeSignatures": [
+ "3103370dd85e0c83241e1bd317f95ff54d513078645cdc233e46b3469eae44cc"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "cd9bf4ca80a219226d865f50fcef00603f103aeb5de6b20739b6131cc93f0627": {
+ "signature": "cd9bf4ca80a219226d865f50fcef00603f103aeb5de6b20739b6131cc93f0627",
+ "alternativeSignatures": [
+ "3ac03fcff61b2d77b58b2281d15b75c39cdccd63f469dd344b834b3ba2a06b79"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "313118aa5546e399ee956e608c238dbb7a373a370e09eceaf4af3a8773177d94": {
+ "signature": "313118aa5546e399ee956e608c238dbb7a373a370e09eceaf4af3a8773177d94",
+ "alternativeSignatures": [
+ "8a3e783f2ad88d14c1ceb36948506f9f2b1f84ed11fc7a6b408a6c5af15eef28"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "4e4b8b48f9b12faefce0a0f46cfde7bd59cf00ecee76950067ce1502327e8d54": {
+ "signature": "4e4b8b48f9b12faefce0a0f46cfde7bd59cf00ecee76950067ce1502327e8d54",
+ "alternativeSignatures": [
+ "40b8c71bbfa07e9bb820f96aad69fc05545601885adf213368c51522f17d94d4"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "5c5bb9b79d4b1a4efee8780c23f2a5eb335a6883cca4cefcfb8d76da1c265b16": {
+ "signature": "5c5bb9b79d4b1a4efee8780c23f2a5eb335a6883cca4cefcfb8d76da1c265b16",
+ "alternativeSignatures": [
+ "01854731cb031864bd076052be4eabb3645eea73ae9524cce7b59563b358dd02"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "7b1cfd03dd8abdb161f3e2629a7f7c710a82da38fa9af5e51f2a7507bb7ba5a4": {
+ "signature": "7b1cfd03dd8abdb161f3e2629a7f7c710a82da38fa9af5e51f2a7507bb7ba5a4",
+ "alternativeSignatures": [
+ "f1fe214f27647b27d2794ecbdbd76e38e043c5a629a3948dade47fad22321c88"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "a2135b103b7d34c0f392332b3aaa2d28bf52c985f9f65c2d160894c1e0635f3b": {
+ "signature": "a2135b103b7d34c0f392332b3aaa2d28bf52c985f9f65c2d160894c1e0635f3b",
+ "alternativeSignatures": [
+ "7a5e29913c2a896bb563d60242a35862dfe76410397741f87e57c73fd17aabf3"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "0274534a741d5f50f942e00fcc8e54e74c4d35aa7052573266a6e9c4d0f3419d": {
+ "signature": "0274534a741d5f50f942e00fcc8e54e74c4d35aa7052573266a6e9c4d0f3419d",
+ "alternativeSignatures": [
+ "4d7af8bdbbb9a6170f97009683e8ac5ea036b6779a28e648356efcbe78a0823f"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "3c05fb7481204e4daf9b987bdd3ba892aabb09ad6e6ac40fe08acf7970777950": {
+ "signature": "3c05fb7481204e4daf9b987bdd3ba892aabb09ad6e6ac40fe08acf7970777950",
+ "alternativeSignatures": [
+ "4539af99fcf1916c2c61423ab58b83df362487d477e9025683938f619e8daf69"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "1ab8313dc7cb1c6dfd307ca7ea4a9184a02fa034e1ca98da212a1176b0efdc8e": {
+ "signature": "1ab8313dc7cb1c6dfd307ca7ea4a9184a02fa034e1ca98da212a1176b0efdc8e",
+ "alternativeSignatures": [
+ "629838eca3b4c5cc2abd965503686210ea7713860efbf23105a53d21d263b7b5"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "2d96bfea5e94f27a26b2ec775d3bd190aea674fbecb6bd520c8dd4f403163d66": {
+ "signature": "2d96bfea5e94f27a26b2ec775d3bd190aea674fbecb6bd520c8dd4f403163d66",
+ "alternativeSignatures": [
+ "189a133549556b3cac247571be151410091e676fd89e2eeab9c874096c7fd4c5"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "b9263742d9ce048d8cd4954798dcd521a0cb11258485b68860e641761b2a6eca": {
+ "signature": "b9263742d9ce048d8cd4954798dcd521a0cb11258485b68860e641761b2a6eca",
+ "alternativeSignatures": [
+ "b57332c3aa3bedaf04276263a2b488235b3c27e8f77ebbacd9718e70cae31749"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "dc51ca0403b5cbd6dfac4ccd99a67cf9abd079a1f362defdb36e1d60131d6868": {
+ "signature": "dc51ca0403b5cbd6dfac4ccd99a67cf9abd079a1f362defdb36e1d60131d6868",
+ "alternativeSignatures": [
+ "4437e44f408153aa0cf2bc8e3877e9c1a393d17d53b5eafb3e601a88c4bd0649"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "cd4014f500554da32946b12a432f841e4ce0761ff6c32e745a869e0b31061e26": {
+ "signature": "cd4014f500554da32946b12a432f841e4ce0761ff6c32e745a869e0b31061e26",
+ "alternativeSignatures": [
+ "a6ae8b1615715bfda64e95d0bbc33b79eb8aab901f1a46324e07e251371440ec"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "e309c2b61b94f2cf5c5afae06d538966c3acc77c42ca2f5b988137680a75efea": {
+ "signature": "e309c2b61b94f2cf5c5afae06d538966c3acc77c42ca2f5b988137680a75efea",
+ "alternativeSignatures": [
+ "54782abbfbd93ddea2bf3d8d7a1de9465ec23f0c91d11407662b3c7ae6c25d6a"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "5fde3dd9ff62349764556570468afecfc9b89da90adb9b8b528fee7281376c8f": {
+ "signature": "5fde3dd9ff62349764556570468afecfc9b89da90adb9b8b528fee7281376c8f",
+ "alternativeSignatures": [
+ "b01c108479023577a128e94e4ffab96e5d82e511cd96a3f997e5733bb461e2f3"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "9ac4ce17aef332ac307fd4c00e62f13ce98c76eea0e5bee7c5e3ea5cf59c6c73": {
+ "signature": "9ac4ce17aef332ac307fd4c00e62f13ce98c76eea0e5bee7c5e3ea5cf59c6c73",
+ "alternativeSignatures": [
+ "157c0ca2f81014af90c3a869edb88447fd3542feeb77133705b05957fe272a69"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "ae0703707b012af8663e6a498b4b1689450f1c27ff08fb9e9e8b228403e5f1ea": {
+ "signature": "ae0703707b012af8663e6a498b4b1689450f1c27ff08fb9e9e8b228403e5f1ea",
+ "alternativeSignatures": [
+ "45f010586074c004b2f6aa5eeff0b6a04e8aeb543ff8434e8e751b9c0ace8c85"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "22884cb907c116eaf75a16c0ad3c1a98b14d442cb66c5c1c8beb549b98ffaeee": {
+ "signature": "22884cb907c116eaf75a16c0ad3c1a98b14d442cb66c5c1c8beb549b98ffaeee",
+ "alternativeSignatures": [
+ "995467e2c131fe3b3425311a8041fe56a207934fbf978d8330daf1b0649441f0"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "efc0141ae2956f8fe2dd6173ca1928566d6676cc0d151659b4a3a5a589939965": {
+ "signature": "efc0141ae2956f8fe2dd6173ca1928566d6676cc0d151659b4a3a5a589939965",
+ "alternativeSignatures": [
+ "66aed3f0f871e8236e8be9c0be200a97984763f1637f805ff0fb1850aa8062f9"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "25b1ddbd0c54d6875bb580d62bca649fd37dca6a1a9d89a5a8086fc992feaadd": {
+ "signature": "25b1ddbd0c54d6875bb580d62bca649fd37dca6a1a9d89a5a8086fc992feaadd",
+ "alternativeSignatures": [
+ "9114feec9dd50b246590253c38bb9030a322899added033ac16c01da72728f1b"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "324d46c283570bddc71cb7e31d8cec1c9824d152ff6eb0b80a2a8802a5d67a16": {
+ "signature": "324d46c283570bddc71cb7e31d8cec1c9824d152ff6eb0b80a2a8802a5d67a16",
+ "alternativeSignatures": [
+ "94c2ba32343d9eaec4157e8600687058757b72539a33dadf8da7d612a7dd7ed1"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "8a9c3796a3cdd503a401b6ab4f3065896d0821da5b3d3b5b70808c597cfe6ca9": {
+ "signature": "8a9c3796a3cdd503a401b6ab4f3065896d0821da5b3d3b5b70808c597cfe6ca9",
+ "alternativeSignatures": [
+ "db47717b20da11e9b308941e5633950d7c9a95ee9a384e34e610a64a6f0da355"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "77e2889a73f6b879b566d2db421b2477c647f60af7959e5b12b3527ea5b01dd6": {
+ "signature": "77e2889a73f6b879b566d2db421b2477c647f60af7959e5b12b3527ea5b01dd6",
+ "alternativeSignatures": [
+ "812aff1025a49aa0e6670f955d4af96d62f891386215eca7ac1130ded5cbbe25"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "60ace5acf172482414a807a10713ac65199744c29fa138b09f8c693466e43556": {
+ "signature": "60ace5acf172482414a807a10713ac65199744c29fa138b09f8c693466e43556",
+ "alternativeSignatures": [
+ "66688bff48060add7c5516256a486d192372ff944054a893bfe2936c69069f55"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "76c2bdeb39429e0cdffc3202cb1f56538b17f7126b4b805fe94593f152a8d58a": {
+ "signature": "76c2bdeb39429e0cdffc3202cb1f56538b17f7126b4b805fe94593f152a8d58a",
+ "alternativeSignatures": [
+ "7d097d8b9f5c4459ab990291325272db8518cb902a6259c168226954d68d2130"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "a907920b771b27ef0887e83e67e7251cf301ee05ba5c40ecc2c7be240660dcb8": {
+ "signature": "a907920b771b27ef0887e83e67e7251cf301ee05ba5c40ecc2c7be240660dcb8",
+ "alternativeSignatures": [
+ "98dcd04f2b3f8d4fb2120cc29f6fc8bb41b327e571b14ac5285ccf4798702811"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "e41dc299c0f98a1d2bce50019cca857d29f0087bad82f562af58da38d95079e4": {
+ "signature": "e41dc299c0f98a1d2bce50019cca857d29f0087bad82f562af58da38d95079e4",
+ "alternativeSignatures": [
+ "b1e6e3ca28c999af0185799a427b82c66c77c8d4e92d9a8d079c190ea566731c"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "578bc87a079ca3aff05025bbe5e3425b1f8153022be56004d2a5c5762e58c40f": {
+ "signature": "578bc87a079ca3aff05025bbe5e3425b1f8153022be56004d2a5c5762e58c40f",
+ "alternativeSignatures": [
+ "89231e414768042efca25c23c0a37c9bbfbf348ac8ffc524992dfdce69d95b85"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "61143a08fc3223dd334a7ebb8fff541e189c55d8b71ec97790db19f593e2b8dc": {
+ "signature": "61143a08fc3223dd334a7ebb8fff541e189c55d8b71ec97790db19f593e2b8dc",
+ "alternativeSignatures": [
+ "d6d701d07e38f64ec2e970e25a1a0d3615d4c43445f1e0d752eaa2e5a71a1ca7"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "59cd434568e99bb12afc0feb317f3dcc8c7a7d83d7e4e0bc881345190affa645": {
+ "signature": "59cd434568e99bb12afc0feb317f3dcc8c7a7d83d7e4e0bc881345190affa645",
+ "alternativeSignatures": [
+ "edc78de573298ca8525d97734819ee64c37bf6a272bee085b5c50a47609a75ac"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "841e11d8f869a0bc40a7076fb7b7fae1741a755802bb5097f98e82a9b583273c": {
+ "signature": "841e11d8f869a0bc40a7076fb7b7fae1741a755802bb5097f98e82a9b583273c",
+ "alternativeSignatures": [
+ "dd3b895a28f513e568f71db8f6f48f1175abc91e2b6a99156030270dc69a9f54"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "c2a14f506b2823105ade218b2e1fb9953c37816a30447e6571cd889455977b48": {
+ "signature": "c2a14f506b2823105ade218b2e1fb9953c37816a30447e6571cd889455977b48",
+ "alternativeSignatures": [
+ "c088b7e9b7604a7925876e3b1586ab119f5af24317518aaaad406f40329a3ae4"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "39e7dd901a698b8eff92669dcdc81833ff54d23541a7453e04ae4ebfcddbedf1": {
+ "signature": "39e7dd901a698b8eff92669dcdc81833ff54d23541a7453e04ae4ebfcddbedf1",
+ "alternativeSignatures": [
+ "6b45ce7f8dbc2a7ac982e950e706f14bd2ed9fca50d8b82a88a78bf7f8a885a3"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "6538fa0e8ddc84e3dca02f5e2dd11b7c6121d4badaddfa2c45d3ee958afc6a21": {
+ "signature": "6538fa0e8ddc84e3dca02f5e2dd11b7c6121d4badaddfa2c45d3ee958afc6a21",
+ "alternativeSignatures": [
+ "ceb2b310bb39e8a3d38d2472944bf8861f76d25f3ad010ed67be77091b229f04"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "8596f3f99e0c8b60cf6af4e5dac999ef84d8ed044f78164ee2394fa9f573a0c5": {
+ "signature": "8596f3f99e0c8b60cf6af4e5dac999ef84d8ed044f78164ee2394fa9f573a0c5",
+ "alternativeSignatures": [
+ "c8d91c5a64f69ada9eb2b14b860e0366988cae36fc761a14fbc9f17ad6a3dd9f"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "b0a8895add311cdfb64cb8d985d5b2d3f873513c9d99fc2316a536b457b3aefb": {
+ "signature": "b0a8895add311cdfb64cb8d985d5b2d3f873513c9d99fc2316a536b457b3aefb",
+ "alternativeSignatures": [
+ "a49aa1a692fa55fb5bf802f2c1398b47a82602fed8cf44801c1b24693ea423d6"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "2fe45ec16ad49da9a8059bd0563200b46fbfbe1c5b41e2dfe9135c4797eddabc": {
+ "signature": "2fe45ec16ad49da9a8059bd0563200b46fbfbe1c5b41e2dfe9135c4797eddabc",
+ "alternativeSignatures": [
+ "77771abf53389ca228889b1dd1b8c36fe8a22751bbfaf71ddfe26d1747cddca5"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "5a92904baaf54cb9038306aa1f1a61cf6c2901b16ca079b384d0142855fde69b": {
+ "signature": "5a92904baaf54cb9038306aa1f1a61cf6c2901b16ca079b384d0142855fde69b",
+ "alternativeSignatures": [
+ "1a83dd86169a6e824076584089253e32877561461a8b6efb40a3d676cd6b6f9b"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "f1b1ddca0ba9b0748ae69f50e8fead3a7d0daedb9ad1929d535b7e2446e4de6b": {
+ "signature": "f1b1ddca0ba9b0748ae69f50e8fead3a7d0daedb9ad1929d535b7e2446e4de6b",
+ "alternativeSignatures": [
+ "79b9f4c205b5f5e8a821466f67a882f9a0fb267c841c25cb8f96d5e333b84f12"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "a38eba7b6c6d7f5d55e9e936e7fd02e812c1bc29331e637009bd45d753b0873b": {
+ "signature": "a38eba7b6c6d7f5d55e9e936e7fd02e812c1bc29331e637009bd45d753b0873b",
+ "alternativeSignatures": [
+ "c59e305df6c93ad5a3d6f8d5f2e88aa7645ad059b630757bf17f7402feeba416"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "98fa4f1d971e4c48284fbcc002beaf73d8cecd88923574d245ceb3e3c180bee4": {
+ "signature": "98fa4f1d971e4c48284fbcc002beaf73d8cecd88923574d245ceb3e3c180bee4",
+ "alternativeSignatures": [
+ "ae41ace8ce16a5bf104635337f4bbac4ee4cef31ce85b119859ebe432a1b5594"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "ae3c6427f88cccc9485759ba4868e4bde5eff03e8c8ae5faf60738efc29ab928": {
+ "signature": "ae3c6427f88cccc9485759ba4868e4bde5eff03e8c8ae5faf60738efc29ab928",
+ "alternativeSignatures": [
+ "a14afcb468d99749bdcf155a08676d9da93f11f303f104a1550b17d49acfb044"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "8b05d5408f77302ffed60a7be43d07bc9ca925f387bceab00536ad8494317b94": {
+ "signature": "8b05d5408f77302ffed60a7be43d07bc9ca925f387bceab00536ad8494317b94",
+ "alternativeSignatures": [
+ "873598efe0367a4e323ddc99c4ae30f4894bcbb53d20fc7ca04bea6e196d8012"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "af958b91637f6c68a8326beebdaf3d1197ce4caa019452511976b37c4a8e7376": {
+ "signature": "af958b91637f6c68a8326beebdaf3d1197ce4caa019452511976b37c4a8e7376",
+ "alternativeSignatures": [
+ "ba5b5bc7d0e34d1b77be803d2f10efed8a25f839c33fb320b55e9344f15e1e05"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "fdf8bc738b4816e1b9767697e450a434f418c0826d4acba96b27b8446b343030": {
+ "signature": "fdf8bc738b4816e1b9767697e450a434f418c0826d4acba96b27b8446b343030",
+ "alternativeSignatures": [
+ "1e02a4a294cbd0e442d8e63c8d88e2c8dfd01d736a64fa4b95d1d73e775c393f"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "26f48dded87e6e44c453c17b6d01bff91cee1738b0987a939bbba8a03e7b4efa": {
+ "signature": "26f48dded87e6e44c453c17b6d01bff91cee1738b0987a939bbba8a03e7b4efa",
+ "alternativeSignatures": [
+ "8f9365ac9e5f82a55a1f8f052939c23f475b54bfb15dc8146a5de852d1950149"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "c05b088c8fbddfd75e8e13edfea4a8b53331d79cdc7e6f5b62fcdffc57de7dd3": {
+ "signature": "c05b088c8fbddfd75e8e13edfea4a8b53331d79cdc7e6f5b62fcdffc57de7dd3",
+ "alternativeSignatures": [
+ "c205456d3ec6f21ffc1db86d8a150bccd39d366f4e49e7fd8c2dadf6c3dafeac"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "f8a8125c28e06aa5de10ff5f65af3fb3ec0e2cca1e20633f48e9e5fe899eacde": {
+ "signature": "f8a8125c28e06aa5de10ff5f65af3fb3ec0e2cca1e20633f48e9e5fe899eacde",
+ "alternativeSignatures": [
+ "326a62ba1581b22e8e36db11b0b9ac7c3eadd736bc901c347eab14856fda4e26"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "2d7c981dfdca3b546ce92e44fe03210a486ab614847b8cd1ce7b90cc2bee764d": {
+ "signature": "2d7c981dfdca3b546ce92e44fe03210a486ab614847b8cd1ce7b90cc2bee764d",
+ "alternativeSignatures": [
+ "d46dd677712d67748a00c3c3b3798ed56febf01602bf275193eaab3616855ded"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "bb6fcf2c44c5051cf8018a3439d446f603f2f0de87e0bfee762531ddb5b093e6": {
+ "signature": "bb6fcf2c44c5051cf8018a3439d446f603f2f0de87e0bfee762531ddb5b093e6",
+ "alternativeSignatures": [
+ "17479a1580b7f5de80f187297f17796c8e1274bdc51513b9511f09e7d403dcd8"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "4617ea1ee0a4fa94bed15152d9751c5b458b18c3b9b19a80159cc134bea6c490": {
+ "signature": "4617ea1ee0a4fa94bed15152d9751c5b458b18c3b9b19a80159cc134bea6c490",
+ "alternativeSignatures": [
+ "a079243d53bc80d9bf0e7a5e8f0d4efeb12e55576bfffc6bdbfc88a9396a295c"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:44:09Z"
+ },
+ "10c65f0e446e94fc381f83522a8199091fd77fdfba69aa954ec4bb92da686f52": {
+ "signature": "10c65f0e446e94fc381f83522a8199091fd77fdfba69aa954ec4bb92da686f52",
+ "alternativeSignatures": [
+ "c0d995f38cde08fc4ca2797c17ca52635afb3aad0faa6e29b757fdd8fc00303c"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:41:50Z"
+ },
+ "3ccc0bbea776fb6014d6d84c39f56449a75ce24680b0ea43fb12bedc0c26e7ba": {
+ "signature": "3ccc0bbea776fb6014d6d84c39f56449a75ce24680b0ea43fb12bedc0c26e7ba",
+ "alternativeSignatures": [
+ "16252b79b14e2335807b6ee6c4f35ae85ccb8c398da816e8191b21efb2a811d6"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:41:50Z"
+ },
+ "9f74aff7ecf8b49fabb8100079de34265ac679fde925a3ec7777a137568abcf0": {
+ "signature": "9f74aff7ecf8b49fabb8100079de34265ac679fde925a3ec7777a137568abcf0",
+ "alternativeSignatures": [
+ "b64f3ed4dfb684f2eb4a315be53a5552f0e73a4e7c550434ff3f9e869a8068a8"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:41:50Z"
+ },
+ "4e372ad39340d58ec749b8b35db6f662788120c418236251a904ed7a02b26f79": {
+ "signature": "4e372ad39340d58ec749b8b35db6f662788120c418236251a904ed7a02b26f79",
+ "alternativeSignatures": [
+ "4c3d3f1e92770eb66d28de09806869afc36a309fba6cb4f3e39f85f015ec612f"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:41:50Z"
+ },
+ "a8c4c5912401633cd6a24c013b4d1d1afa605e9e11b45a53c0954dffd94009a0": {
+ "signature": "a8c4c5912401633cd6a24c013b4d1d1afa605e9e11b45a53c0954dffd94009a0",
+ "alternativeSignatures": [
+ "2d5b51696eb4973350286ff26c5f2f52e87a7d906c8d51f27a63ffe561dce262"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:41:50Z"
+ },
+ "101d617f00c1267dc4b8c5bc90af2a0e12d93a0b8541d012dfe0e39baeb3d6cc": {
+ "signature": "101d617f00c1267dc4b8c5bc90af2a0e12d93a0b8541d012dfe0e39baeb3d6cc",
+ "alternativeSignatures": [
+ "ec2f7d7c99c0173986cd1122844458283eff76b29b222f042d16a89c4b6b40be"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:41:50Z"
+ },
+ "ebd8f40de4ae8c1d9e0c1d377839e8ad6b4d2b2db1d2ac5922ad41c0508c7cbf": {
+ "signature": "ebd8f40de4ae8c1d9e0c1d377839e8ad6b4d2b2db1d2ac5922ad41c0508c7cbf",
+ "alternativeSignatures": [
+ "6f531a509a20fe06eee1794f5fe74bebca37272a091efb0d757b881dcf182d77"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:41:50Z"
+ },
+ "7c9997f829382c189a663d4d9f71e5302857d9cfe4fb7657c66495f80c2aa6e6": {
+ "signature": "7c9997f829382c189a663d4d9f71e5302857d9cfe4fb7657c66495f80c2aa6e6",
+ "alternativeSignatures": [
+ "eb3e5c00b11aa21204c68b19e8f0dd82d1eb67138140c2131b3c272488d3edda"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:41:50Z"
+ },
+ "fa25240f502255f9ba0f3d09884ce1b040509cfb2b344894a2f9abd0eb279c15": {
+ "signature": "fa25240f502255f9ba0f3d09884ce1b040509cfb2b344894a2f9abd0eb279c15",
+ "alternativeSignatures": [
+ "6e2068cbfef97f06bc5318a8efa439119eed351f51745015de4085b5a814b67f"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:41:50Z"
+ },
+ "2ae3625fb0105e3746fbffb89695431d805fc919afbc4174dd58bfef39ab08bb": {
+ "signature": "2ae3625fb0105e3746fbffb89695431d805fc919afbc4174dd58bfef39ab08bb",
+ "alternativeSignatures": [
+ "348deb3528889efec9bfd5b5313a13f94fa880c7664088b58755c57deecd74c9"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:41:50Z"
+ },
+ "368cf469e325fedbf07c937b954e74bd114b03afb91a29da1e0f1a7a7144387e": {
+ "signature": "368cf469e325fedbf07c937b954e74bd114b03afb91a29da1e0f1a7a7144387e",
+ "alternativeSignatures": [
+ "04ac302afe48ab1beb03d050181e22f92fe0f2c226c0c66033d23a57675c8d15"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:41:50Z"
+ },
+ "e5aa57841ec2f420215518afbb8397fd7088c1e4db81ccc48a6cab79177032b9": {
+ "signature": "e5aa57841ec2f420215518afbb8397fd7088c1e4db81ccc48a6cab79177032b9",
+ "alternativeSignatures": [
+ "99e170a3db5543ec385e0682277443d2b93fcfcc37f78388e17e4414b555964f"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:41:50Z"
+ },
+ "bfc505f062062660bf287444f0a57ff92ff1699085714842ef2bd6c9a0813358": {
+ "signature": "bfc505f062062660bf287444f0a57ff92ff1699085714842ef2bd6c9a0813358",
+ "alternativeSignatures": [
+ "10703d9aa76ddc0d1e59d6e6898a280ed392951fff2dcd88f4540dfc2d61461e"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:41:50Z"
+ },
+ "b9242b1520834b2f70cf242fc9c8157c9dfdefddfb2a3e03582dfea0ad877a17": {
+ "signature": "b9242b1520834b2f70cf242fc9c8157c9dfdefddfb2a3e03582dfea0ad877a17",
+ "alternativeSignatures": [
+ "9260180671830080380cd59f313fe8eddbc3cb9af4522ce8d2d95f87578c5b73"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:41:50Z"
+ },
+ "b1a9339a35ffbd188e99c63127d4c33ced432b00c68e3a5b8d578a998355ad5c": {
+ "signature": "b1a9339a35ffbd188e99c63127d4c33ced432b00c68e3a5b8d578a998355ad5c",
+ "alternativeSignatures": [
+ "b399d29ef57eae05e98464f5b3acc21b341b31f226f765d0c798b5f98123b923"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:41:50Z"
+ },
+ "085a187f0b076315a5e5bd4a0479219f08c4d7ce71e534060da90e2b8d9a4ae8": {
+ "signature": "085a187f0b076315a5e5bd4a0479219f08c4d7ce71e534060da90e2b8d9a4ae8",
+ "alternativeSignatures": [
+ "631768ebf31c65a1fe341447a0d51db8828f31d55af5972641b3610109261b09"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:41:50Z"
+ },
+ "0e504352e733e503aa53d59682e34cb078a4da5b230d7e82d280eba9b54a7b84": {
+ "signature": "0e504352e733e503aa53d59682e34cb078a4da5b230d7e82d280eba9b54a7b84",
+ "alternativeSignatures": [
+ "aaebb0a0284e277c87318e22f23496dc41bd35b88fb2799b4c0c6731013a9f10"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:41:50Z"
+ },
+ "9454ee0d2cd4c2cdcaeafa45e5d3faebf636987228e2a67ea538f7696cbace64": {
+ "signature": "9454ee0d2cd4c2cdcaeafa45e5d3faebf636987228e2a67ea538f7696cbace64",
+ "alternativeSignatures": [
+ "ab44a5347f2ed6f91703a5b6a0a560da9371dad68ecad0ee68eeb1c82ddd7fb1"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:41:50Z"
+ },
+ "b8f586ebebbe7c888384bf52e7d3e60345d4ef1b4b56b7b26cb1cd0e28b1b070": {
+ "signature": "b8f586ebebbe7c888384bf52e7d3e60345d4ef1b4b56b7b26cb1cd0e28b1b070",
+ "alternativeSignatures": [
+ "6401eec5958ccae66ac51dfdddc8d4cd04f4b4aba89e609f5c5ee8995f9c99f8"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:41:50Z"
+ },
+ "1b00c720089ff2c5cc73e011cb85b316b01790b3c89689d2bc02880a4ff59749": {
+ "signature": "1b00c720089ff2c5cc73e011cb85b316b01790b3c89689d2bc02880a4ff59749",
+ "alternativeSignatures": [
+ "be47ce55f3d22612290ae7d8014850231eb67dbc863b51c34b74177c040577ae"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:41:50Z"
+ },
+ "1f4a7a2ce78aadd99a2556cb31c2727069a5ac048833a4a2ccaa894f719a1006": {
+ "signature": "1f4a7a2ce78aadd99a2556cb31c2727069a5ac048833a4a2ccaa894f719a1006",
+ "alternativeSignatures": [
+ "1606182e875905b82eda3b9cbd5a6868d2e9472eef18f0a4c96cc6f502183bea"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:41:50Z"
+ },
+ "eae501e7915b6ed233083cd9f149630405fd8dc931cfa038654f55b7dc2654cd": {
+ "signature": "eae501e7915b6ed233083cd9f149630405fd8dc931cfa038654f55b7dc2654cd",
+ "alternativeSignatures": [
+ "bf53392b0b5a4031dc6b933debefa1f4c3f9167d58372874bb1265933afa8178"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:41:50Z"
+ },
+ "2f6f4e6a72db224200a020d98cbfc37faa0efa7af23c418b51ecde3d48563527": {
+ "signature": "2f6f4e6a72db224200a020d98cbfc37faa0efa7af23c418b51ecde3d48563527",
+ "alternativeSignatures": [
+ "f8786ceb2f9712bb5663f8978df206bd0f8e9c89ce7b2945e204b7ad6bc4f0b8"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:41:50Z"
+ },
+ "ff6a3b7c7ee7341d9085938546aec46a6d3262ae5e0c7d1e30617e80a69d06c7": {
+ "signature": "ff6a3b7c7ee7341d9085938546aec46a6d3262ae5e0c7d1e30617e80a69d06c7",
+ "alternativeSignatures": [
+ "6b18741df051828f9203f18b4bee9ca81761838ea20aaaaf79259b7c1863471c"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:41:50Z"
+ },
+ "a8f28b2c4847bae6af07b230f5dae49a44d77a6eb052e8b549bef87ae2a72035": {
+ "signature": "a8f28b2c4847bae6af07b230f5dae49a44d77a6eb052e8b549bef87ae2a72035",
+ "alternativeSignatures": [
+ "bd377b8b56c8fe836416748e243f8f4e96dcc53d2fdade7969bd843765db774d"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:41:50Z"
+ },
+ "06e92bfd0eb46daa68a0b0a7bfe38edaa6e0bfa7f442d330276c0898ace5d234": {
+ "signature": "06e92bfd0eb46daa68a0b0a7bfe38edaa6e0bfa7f442d330276c0898ace5d234",
+ "alternativeSignatures": [
+ "2ccf644dbd1aae74a8cf699ce2c0e3d60b5918e9ecd240d81ec9e1e134f2a2b5"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:41:50Z"
+ },
+ "932e38a90883d289bf67fc1488641df29780e56b1742ffbb60f65cd605b32392": {
+ "signature": "932e38a90883d289bf67fc1488641df29780e56b1742ffbb60f65cd605b32392",
+ "alternativeSignatures": [
+ "524219016b7b5bd138d936af385640d5c4b03ea06aeb0c987689ea05cf84e497"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:41:50Z"
+ },
+ "9cc7d9a29dd7371a50a5c72b86f8ad8fb7aa12f3f5306de91c020ae369bd40a2": {
+ "signature": "9cc7d9a29dd7371a50a5c72b86f8ad8fb7aa12f3f5306de91c020ae369bd40a2",
+ "alternativeSignatures": [
+ "252967670cd28d4e846c04cb22fefe5fb2de988827ddaf5b8eb6bba9ce5b27f8"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:41:50Z"
+ },
+ "2ea88c0feaa926ab1cea16bca03591f468c985c8db8ead7dccee4da9a6948983": {
+ "signature": "2ea88c0feaa926ab1cea16bca03591f468c985c8db8ead7dccee4da9a6948983",
+ "alternativeSignatures": [
+ "7200c32f924eaff6bd0fe9dadab1e6e7187a7a61b7670b3d39d9613a30e966c0"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:41:50Z"
+ },
+ "774fe55d5a9ccbbc86d4cbf54e7d2fc9800f5ad6e5def20a490dd166c40254dc": {
+ "signature": "774fe55d5a9ccbbc86d4cbf54e7d2fc9800f5ad6e5def20a490dd166c40254dc",
+ "alternativeSignatures": [
+ "7db56d4f6e17038f5b3a495a9d91047f9820e785b626bbeda3a6e8bec36b58d1"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:41:50Z"
+ },
+ "28de455e4aecc959e883c4a0fca06048fccc8357081f14a691e4765e13d1d3d1": {
+ "signature": "28de455e4aecc959e883c4a0fca06048fccc8357081f14a691e4765e13d1d3d1",
+ "alternativeSignatures": [
+ "58ac845ad84930023713c9797c6b71401663edff1b0b5fd4dbd58790469158b5"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:41:50Z"
+ },
+ "dff557b19659be6bc6b50fb092f4ed94fecae79e7f61136e9d872c153a92f3fd": {
+ "signature": "dff557b19659be6bc6b50fb092f4ed94fecae79e7f61136e9d872c153a92f3fd",
+ "alternativeSignatures": [
+ "2530e935a169b65713a579170e81b89080d60ae01432fa626a805ba1d0f78b63"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:41:50Z"
+ },
+ "11bd9f568fd440ccb8b315b3fb63d7ab5d552f1eeed24ae710b575f75e9a4792": {
+ "signature": "11bd9f568fd440ccb8b315b3fb63d7ab5d552f1eeed24ae710b575f75e9a4792",
+ "alternativeSignatures": [
+ "ba77a9aee53a85242527f53cd595427876979c0bd73beb9d5c40362146ad44b3"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:41:50Z"
+ },
+ "81ae1e002639fded27ac6a44eac7cc79d4a2ec0c5b11fc3ea1d0b68587567fff": {
+ "signature": "81ae1e002639fded27ac6a44eac7cc79d4a2ec0c5b11fc3ea1d0b68587567fff",
+ "alternativeSignatures": [
+ "0e9b5f31072bc8ec6bfe7bb37a488b48616c6957f5170f8ea222d861d6e1e8bf"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:41:50Z"
+ },
+ "9e9e6bb0ada4b9ec459dfbb6b257ade26eb35ea6e6ea1bd43cecb22185ff3286": {
+ "signature": "9e9e6bb0ada4b9ec459dfbb6b257ade26eb35ea6e6ea1bd43cecb22185ff3286",
+ "alternativeSignatures": [
+ "dd0105bb49ae56206281c413c1371fbe22ea43798574aec72df8b15f29636b5f"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:41:50Z"
+ },
+ "34e9ddf03ac5eb52c7debe7a40cf6d68872c35fc36bae0bc1c2e9e53e263382a": {
+ "signature": "34e9ddf03ac5eb52c7debe7a40cf6d68872c35fc36bae0bc1c2e9e53e263382a",
+ "alternativeSignatures": [
+ "82128c0ba0001c4aa1f32cc090cf1fcfc561e3f822a6e327d02fc73a3fc84cf3"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:41:50Z"
+ },
+ "917aaeadf5778e99a2fcf5a6005702e30d6de1de0155726e5d78bc02e8892575": {
+ "signature": "917aaeadf5778e99a2fcf5a6005702e30d6de1de0155726e5d78bc02e8892575",
+ "alternativeSignatures": [
+ "d00dd199647647b3643ac806c784bdfe0a1deb72fbc07df3ee52efe070708710"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:41:50Z"
+ },
+ "040747e183b8a0fa99fbe8624fe64256c32e08da6809386b8fa569c4287755fc": {
+ "signature": "040747e183b8a0fa99fbe8624fe64256c32e08da6809386b8fa569c4287755fc",
+ "alternativeSignatures": [
+ "b0aff1ee8332dad10264fe96fdf78fdb597567dd59a2b1d2d2092e17cec2d4af"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:41:50Z"
+ },
+ "b34be695dec0f8b5f39e04c9e9eab981859d6f38242f7b6b121c57b2c709ce43": {
+ "signature": "b34be695dec0f8b5f39e04c9e9eab981859d6f38242f7b6b121c57b2c709ce43",
+ "alternativeSignatures": [
+ "c531c0cc60c37ced7b8a8d2dc8563317972bcd0f541f2f8bd794bfbaa0da967e"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:41:50Z"
+ },
+ "28b6ebe464ba71c233bdfd04be5cb8b0f0350a18f37defb84131ac40abca3948": {
+ "signature": "28b6ebe464ba71c233bdfd04be5cb8b0f0350a18f37defb84131ac40abca3948",
+ "alternativeSignatures": [
+ "c9d376a37a6f17c21273dfdc2c68e754d76f3c1dbe823a374430c7471da53850"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:41:50Z"
+ },
+ "a006c017081d2daf93752c05a4c8dac604713b5a855925b4ddda77ba71915db5": {
+ "signature": "a006c017081d2daf93752c05a4c8dac604713b5a855925b4ddda77ba71915db5",
+ "alternativeSignatures": [
+ "9cc7278a371bb38d39d45b1275abe48de6111d369b58553e72ce0fbdcfa8add9"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:41:50Z"
+ },
+ "5ef6f72ceb24329d54f6938e8886c94a75dc48f049b979297b71c008f35a60df": {
+ "signature": "5ef6f72ceb24329d54f6938e8886c94a75dc48f049b979297b71c008f35a60df",
+ "alternativeSignatures": [
+ "7e6a8f6dcd966a21973348b5ed6d280c127cfcd01fb478a1d5545097dfc06f51"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:41:50Z"
+ },
+ "70499d510cc598d97f9cc77a6b2afa00b19f1fc3f24fc71f68bbea599cb972bb": {
+ "signature": "70499d510cc598d97f9cc77a6b2afa00b19f1fc3f24fc71f68bbea599cb972bb",
+ "alternativeSignatures": [
+ "26305f7f84070dd5684c13e94ac13c0ec2ae921db82031b2f7cc3758ccd6b524"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:41:50Z"
+ },
+ "7d6e31c61793a4bb5c8b248465f6a3a152646fc4d4e7ce67176d012b06220f08": {
+ "signature": "7d6e31c61793a4bb5c8b248465f6a3a152646fc4d4e7ce67176d012b06220f08",
+ "alternativeSignatures": [
+ "d2512abf39140f9c932c6db24223f061685aa5ac86cda0da7fc3686ab334da44"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:41:50Z"
+ },
+ "ad1459c1b67b45e6cee9ff8ea4ba7df7319687c04f4ce93777227fbaac434492": {
+ "signature": "ad1459c1b67b45e6cee9ff8ea4ba7df7319687c04f4ce93777227fbaac434492",
+ "alternativeSignatures": [
+ "8d50311c8b09d19bc4b63d0c0a26776ee4c558cd1d94dc0927fb58f604c0f095"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:41:50Z"
+ },
+ "75a1b852bfcc523cb65a929165d2ac936e27e4d07eddd4ccd9dd46de1f6724e8": {
+ "signature": "75a1b852bfcc523cb65a929165d2ac936e27e4d07eddd4ccd9dd46de1f6724e8",
+ "alternativeSignatures": [
+ "540cf4900d1af0b0e202c08e280fd2a0d50e5d60e7fd2ebed3d8c452ed82930d"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:41:50Z"
+ },
+ "ae290d2bc442e775419422b88a9de0f3227a10b5d6d68919e010c2a9f55d1ee8": {
+ "signature": "ae290d2bc442e775419422b88a9de0f3227a10b5d6d68919e010c2a9f55d1ee8",
+ "alternativeSignatures": [
+ "505fad15f6885a33160e83114a67c9eff79843369b509255a0a07bffcc400f18"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:41:50Z"
+ },
+ "4df4af63dbb7d92a10c3f63dcc8a4b9a7b88cd4ab00250f6bd397a724e365c01": {
+ "signature": "4df4af63dbb7d92a10c3f63dcc8a4b9a7b88cd4ab00250f6bd397a724e365c01",
+ "alternativeSignatures": [
+ "0c416687679d9ea3ed0d8cad43a4ce18fac156b41973d222279b71a41b62687c"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:41:50Z"
+ },
+ "d846d652f2a5ea85ea6268951a90ff193bc20c00b673e03e27f99592faa1ef54": {
+ "signature": "d846d652f2a5ea85ea6268951a90ff193bc20c00b673e03e27f99592faa1ef54",
+ "alternativeSignatures": [
+ "42866d82bca1c59bfb10acc932d2ee56129a90062bbb160402efa0742d97df9c"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 10:41:50Z"
+ },
+ "57dbd629f8ad79c28146d175246adbf859c7f027caafb3f5833a758a9878953b": {
+ "signature": "57dbd629f8ad79c28146d175246adbf859c7f027caafb3f5833a758a9878953b",
+ "alternativeSignatures": [
+ "8ce01ff8be61cff3d881a6c5ab573a133564fc30edf82b41282dafd6a54c2968"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 06:09:51Z"
+ },
+ "a911d4b5df49899886b86e80bcb556fcd131a6b03966f7d8c5db575e91d50bb3": {
+ "signature": "a911d4b5df49899886b86e80bcb556fcd131a6b03966f7d8c5db575e91d50bb3",
+ "alternativeSignatures": [
+ "79fa81d4b8d98a10d62e2156a0e4a75d088a0d28d20274fa9568daf1ba4c7496"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 06:09:51Z"
+ },
+ "3c9cd013591ab714038abdccca58bf72c3ddbbe5110ce0a4cc0604d8ba4e258f": {
+ "signature": "3c9cd013591ab714038abdccca58bf72c3ddbbe5110ce0a4cc0604d8ba4e258f",
+ "alternativeSignatures": [
+ "2729f5c1e571948f0dd77eedcf8a805c4d71e71e3223ae6792b22c4b4623232c"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 06:09:51Z"
+ },
+ "6ad1d487550fa8d76b6dac8336234a7c35afbd832afdd75d7c250c7a8fa99f38": {
+ "signature": "6ad1d487550fa8d76b6dac8336234a7c35afbd832afdd75d7c250c7a8fa99f38",
+ "alternativeSignatures": [
+ "90dac39174d57ab7e46771db8b516338f9b6f4bd678e79b3b07a05127fff3c4f"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 06:09:51Z"
+ },
+ "38504157743576059fa9271f746bd30c7a10fdbb390c9b03ad97dcdf90a8da17": {
+ "signature": "38504157743576059fa9271f746bd30c7a10fdbb390c9b03ad97dcdf90a8da17",
+ "alternativeSignatures": [
+ "a6649b84578f00977f2c13410634affb25e3401b5135dfcaf6f70acde0db5b7b"
+ ],
+ "memberOf": [
+ "default"
+ ],
+ "createdDate": "2023-12-19 06:09:51Z"
}
}
}
diff --git a/.pipelines/verifyAndSetLatestVCToolsVersion.ps1 b/.pipelines/verifyAndSetLatestVCToolsVersion.ps1
new file mode 100644
index 0000000000..1644c01e73
--- /dev/null
+++ b/.pipelines/verifyAndSetLatestVCToolsVersion.ps1
@@ -0,0 +1,5 @@
+$LatestVCToolsVersion = (([xml](& 'C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe' -latest -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -include packages -format xml)).instances.instance.packages.package | ? { $_.id -eq "Microsoft.VisualCpp.Redist.14.Latest" -and $_.chip -eq "x64" }).version;
+
+Write-Output "Latest VCToolsVersion: $LatestVCToolsVersion"
+Write-Output "Updating VCToolsVersion environment variable for job"
+Write-Output "##vso[task.setvariable variable=VCToolsVersion]$LatestVCToolsVersion"
\ No newline at end of file
diff --git a/.pipelines/versionAndSignCheck.ps1 b/.pipelines/versionAndSignCheck.ps1
index 42b66ed8bc..d5960efb64 100644
--- a/.pipelines/versionAndSignCheck.ps1
+++ b/.pipelines/versionAndSignCheck.ps1
@@ -24,6 +24,7 @@ $versionExceptions = @(
$nullVersionExceptions = @(
"codicon.ttf",
"e_sqlite3.dll",
+ "getfilesiginforedist.dll",
"vcamp140_app.dll",
"vcruntime140_app.dll",
"vcruntime140_1_app.dll",
diff --git a/Cpp.Build.props b/Cpp.Build.props
index 3279750b33..b98ae459a6 100644
--- a/Cpp.Build.props
+++ b/Cpp.Build.props
@@ -63,6 +63,7 @@
Guard
ProgramDatabase
+ true
Windows
@@ -77,7 +78,6 @@
_DEBUG;%(PreprocessorDefinitions)
Disabled
- true
MultiThreadedDebug
@@ -88,7 +88,6 @@
NDEBUG;%(PreprocessorDefinitions)
MaxSpeed
- false
MultiThreaded
true
true
@@ -113,6 +112,7 @@
v143
Unicode
true
+ Spectre
diff --git a/Directory.Build.props b/Directory.Build.props
index 9f8159a6d9..bc0da728c2 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -1,9 +1,9 @@
- Copyright (C) 2023 Microsoft Corporation
+ Copyright (C) 2024 Microsoft Corporation
Microsoft Corp.
- Copyright (C) 2023 Microsoft Corporation
+ Copyright (C) 2024 Microsoft Corporation
PowerToys
Microsoft Corporation
en-US
diff --git a/Directory.Packages.props b/Directory.Packages.props
index 93130d8eb7..960eeb08a8 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -18,33 +18,36 @@
-
-
+
+
-
-
+
+
-
-
-
-
+
+
+
+
+
+
-
+
-
+
+
@@ -57,24 +60,25 @@
-
-
-
-
+
+
+
+
-
+
+
-
-
-
+
+
+
-
+
diff --git a/NOTICE.md b/NOTICE.md
index 0c1780b2ba..5e0be0d037 100644
--- a/NOTICE.md
+++ b/NOTICE.md
@@ -788,6 +788,34 @@ SOFTWARE.
## Utility: Peek
+### The Quite OK Image Format reference decoder
+
+**Source**: https://github.com/phoboslab/qoi
+
+**Note**: [@pedrolamas](https://github.com/pedrolamas) translated and adapted the reference decoder code to C# that is in PowerToys from the original C++ implementation.
+
+MIT License
+
+Copyright (c) 2022 Dominic Szablewski
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
### UTF Unknown
We use the UTF.Unknown NuGet package for detecting encoding in text/code files.
@@ -1271,7 +1299,6 @@ EXHIBIT A -Mozilla Public License.
- Appium.WebDriver 4.4.5
- CommunityToolkit.Mvvm 8.2.0
- CommunityToolkit.WinUI.Animations 8.0.230907
-- CommunityToolkit.WinUI.Collections 8.0.230907
- CommunityToolkit.WinUI.Controls.Primitives 8.0.230907
- CommunityToolkit.WinUI.Controls.Segmented 8.0.230907
- CommunityToolkit.WinUI.Controls.SettingsControls 8.0.230907
@@ -1281,28 +1308,30 @@ EXHIBIT A -Mozilla Public License.
- CommunityToolkit.WinUI.UI.Controls.DataGrid 7.1.2
- CommunityToolkit.WinUI.UI.Controls.Markdown 7.1.2
- ControlzEx 6.0.0
-- HelixToolkit 2.20.2
-- HelixToolkit.Core.Wpf 2.20.2
+- HelixToolkit 2.24.0
+- HelixToolkit.Core.Wpf 2.24.0
- hyjiacan.pinyin4net 4.1.1
- Interop.Microsoft.Office.Interop.OneNote 1.1.0.2
- LazyCache 2.4.0
- Mages 2.0.1
- Markdig.Signed 0.27.0
-- Microsoft.CodeAnalysis.NetAnalyzers 7.0.3
-- Microsoft.Data.Sqlite 7.0.0
-- Microsoft.Extensions.DependencyInjection 7.0.0
-- Microsoft.Extensions.Hosting 7.0.1
-- Microsoft.Extensions.Hosting.WindowsServices 7.0.0
-- Microsoft.Extensions.Logging 7.0.0
+- Microsoft.CodeAnalysis.NetAnalyzers 8.0.0
+- Microsoft.Data.Sqlite 8.0.0
+- Microsoft.Extensions.DependencyInjection 8.0.0
+- Microsoft.Extensions.Hosting 8.0.0
+- Microsoft.Extensions.Hosting.WindowsServices 8.0.0
+- Microsoft.Extensions.Logging 8.0.0
+- Microsoft.Extensions.Logging.Abstractions 8.0.0
+- Microsoft.Extensions.ObjectPool 8.0.0
- Microsoft.NET.Test.Sdk 17.6.3
- Microsoft.Toolkit.Uwp.Notifications 7.1.2
- Microsoft.Web.WebView2 1.0.2088.41
-- Microsoft.Windows.Compatibility 7.0.3
+- Microsoft.Windows.Compatibility 8.0.0
- Microsoft.Windows.CsWin32 0.2.46-beta
- Microsoft.Windows.CsWinRT 2.0.4
- Microsoft.Windows.SDK.BuildTools 10.0.22621.756
- Microsoft.Windows.SDK.Contracts 10.0.19041.1
-- Microsoft.WindowsAppSDK 1.4.230913002
+- Microsoft.WindowsAppSDK 1.4.231115000
- Microsoft.Xaml.Behaviors.WinUI.Managed 2.0.9
- Microsoft.Xaml.Behaviors.Wpf 1.1.39
- ModernWpfUI 0.9.4
@@ -1316,22 +1345,23 @@ EXHIBIT A -Mozilla Public License.
- StreamJsonRpc 2.14.24
- StyleCop.Analyzers 1.2.0-beta.507
- System.CommandLine 2.0.0-beta4.22272.1
-- System.ComponentModel.Composition 7.0.0
-- System.Configuration.ConfigurationManager 6.0.0
-- System.Data.OleDb 7.0.0
-- System.Drawing.Common 7.0.0
+- System.ComponentModel.Composition 8.0.0
+- System.Configuration.ConfigurationManager 8.0.0
+- System.Data.OleDb 8.0.0
+- System.Drawing.Common 8.0.0
- System.IO.Abstractions 17.2.3
- System.IO.Abstractions.TestingHelpers 17.2.3
-- System.Management 7.0.2
+- System.Management 8.0.0
+- System.Management.Automation 7.4.0
- System.Reactive 6.0.0-preview.9
-- System.Runtime.Caching 7.0.0
-- System.ServiceProcess.ServiceController 7.0.1
-- System.Text.Encoding.CodePages 7.0.0
+- System.Runtime.Caching 8.0.0
+- System.ServiceProcess.ServiceController 8.0.0
+- System.Text.Encoding.CodePages 8.0.0
- UnicodeInformation 2.6.0
- UnitsNet 4.145.0
- UTF.Unknown 2.5.1
- Vanara.PInvoke.Shell32 3.4.11
- Vanara.PInvoke.User32 3.4.11
- WinUIEx 2.2.0
-- WPF-UI 3.0.0-preview.9
+- WPF-UI 3.0.0-preview.12
diff --git a/PowerToys.sln b/PowerToys.sln
index 9d11bcd4e0..d2b108b6f1 100644
--- a/PowerToys.sln
+++ b/PowerToys.sln
@@ -538,6 +538,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CropAndLock", "src\modules\
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CropAndLockModuleInterface", "src\modules\CropAndLock\CropAndLockModuleInterface\CropAndLockModuleInterface.vcxproj", "{3157FA75-86CF-4EE2-8F62-C43F776493C6}"
EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CmdNotFound", "src\modules\cmdNotFound\CmdNotFound\CmdNotFound.csproj", "{A37865FE-2881-449F-8ADB-B8CD373D6D79}"
+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}"
@@ -558,6 +562,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTests-QoiPreviewHandler
EndProject
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
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}"
@@ -2332,6 +2338,18 @@ Global
{3157FA75-86CF-4EE2-8F62-C43F776493C6}.Release|x64.Build.0 = Release|x64
{3157FA75-86CF-4EE2-8F62-C43F776493C6}.Release|x86.ActiveCfg = Release|x64
{3157FA75-86CF-4EE2-8F62-C43F776493C6}.Release|x86.Build.0 = Release|x64
+ {A37865FE-2881-449F-8ADB-B8CD373D6D79}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {A37865FE-2881-449F-8ADB-B8CD373D6D79}.Debug|ARM64.Build.0 = Debug|ARM64
+ {A37865FE-2881-449F-8ADB-B8CD373D6D79}.Debug|x64.ActiveCfg = Debug|x64
+ {A37865FE-2881-449F-8ADB-B8CD373D6D79}.Debug|x64.Build.0 = Debug|x64
+ {A37865FE-2881-449F-8ADB-B8CD373D6D79}.Debug|x86.ActiveCfg = Debug|x64
+ {A37865FE-2881-449F-8ADB-B8CD373D6D79}.Debug|x86.Build.0 = Debug|x64
+ {A37865FE-2881-449F-8ADB-B8CD373D6D79}.Release|ARM64.ActiveCfg = Release|ARM64
+ {A37865FE-2881-449F-8ADB-B8CD373D6D79}.Release|ARM64.Build.0 = Release|ARM64
+ {A37865FE-2881-449F-8ADB-B8CD373D6D79}.Release|x64.ActiveCfg = Release|x64
+ {A37865FE-2881-449F-8ADB-B8CD373D6D79}.Release|x64.Build.0 = Release|x64
+ {A37865FE-2881-449F-8ADB-B8CD373D6D79}.Release|x86.ActiveCfg = Release|x64
+ {A37865FE-2881-449F-8ADB-B8CD373D6D79}.Release|x86.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
@@ -2440,6 +2458,18 @@ Global
{F8FFFC12-A31A-4AFA-B3DF-14DCF42B5E38}.Release|x64.Build.0 = Release|x64
{F8FFFC12-A31A-4AFA-B3DF-14DCF42B5E38}.Release|x86.ActiveCfg = Release|x64
{F8FFFC12-A31A-4AFA-B3DF-14DCF42B5E38}.Release|x86.Build.0 = Release|x64
+ {0014D652-901F-4456-8D65-06FC5F997FB0}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {0014D652-901F-4456-8D65-06FC5F997FB0}.Debug|ARM64.Build.0 = Debug|ARM64
+ {0014D652-901F-4456-8D65-06FC5F997FB0}.Debug|x64.ActiveCfg = Debug|x64
+ {0014D652-901F-4456-8D65-06FC5F997FB0}.Debug|x64.Build.0 = Debug|x64
+ {0014D652-901F-4456-8D65-06FC5F997FB0}.Debug|x86.ActiveCfg = Debug|Win32
+ {0014D652-901F-4456-8D65-06FC5F997FB0}.Debug|x86.Build.0 = Debug|Win32
+ {0014D652-901F-4456-8D65-06FC5F997FB0}.Release|ARM64.ActiveCfg = Release|ARM64
+ {0014D652-901F-4456-8D65-06FC5F997FB0}.Release|ARM64.Build.0 = Release|ARM64
+ {0014D652-901F-4456-8D65-06FC5F997FB0}.Release|x64.ActiveCfg = Release|x64
+ {0014D652-901F-4456-8D65-06FC5F997FB0}.Release|x64.Build.0 = Release|x64
+ {0014D652-901F-4456-8D65-06FC5F997FB0}.Release|x86.ActiveCfg = Release|Win32
+ {0014D652-901F-4456-8D65-06FC5F997FB0}.Release|x86.Build.0 = Release|Win32
{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
@@ -2658,6 +2688,8 @@ Global
{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}
+ {A37865FE-2881-449F-8ADB-B8CD373D6D79} = {4C0D0746-BE5B-49EE-BD5D-A7811628AE8B}
+ {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}
@@ -2668,6 +2700,7 @@ Global
{6B04803D-B418-4833-A67E-B0FC966636A5} = {2F305555-C296-497E-AC20-5FA1B237996A}
{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}
{FE38FC07-1C05-4B57-ADA3-2FE2F53C6A52} = {D1D6BC88-09AE-4FB4-AD24-5DED46A791DD}
{3A9A791E-94A9-49F8-8401-C11CE288D5FB} = {D1D6BC88-09AE-4FB4-AD24-5DED46A791DD}
EndGlobalSection
diff --git a/README.md b/README.md
index 3717194ad6..110865b35c 100644
--- a/README.md
+++ b/README.md
@@ -17,20 +17,21 @@ Microsoft PowerToys is a set of utilities for power users to tune and streamline
| | Current utilities: | |
|--------------|--------------------|--------------|
-| [Always on Top](https://aka.ms/PowerToysOverview_AoT) | [PowerToys Awake](https://aka.ms/PowerToysOverview_Awake) | [Color Picker](https://aka.ms/PowerToysOverview_ColorPicker) |
-| [Crop And Lock](https://aka.ms/PowerToysOverview_CropAndLock) | [Environment Variables](https://aka.ms/PowerToysOverview_EnvironmentVariables) | [FancyZones](https://aka.ms/PowerToysOverview_FancyZones) |
-| [File Explorer Add-ons](https://aka.ms/PowerToysOverview_FileExplorerAddOns) | [File Locksmith](https://aka.ms/PowerToysOverview_FileLocksmith) | [Hosts File Editor](https://aka.ms/PowerToysOverview_HostsFileEditor) |
-| [Image Resizer](https://aka.ms/PowerToysOverview_ImageResizer) | [Keyboard Manager](https://aka.ms/PowerToysOverview_KeyboardManager) | [Mouse utilities](https://aka.ms/PowerToysOverview_MouseUtilities) |
-| [Mouse Without Borders](https://aka.ms/PowerToysOverview_MouseWithoutBorders) | [Peek](https://aka.ms/PowerToysOverview_Peek) | [Paste as Plain Text](https://aka.ms/PowerToysOverview_PastePlain) |
-| [PowerRename](https://aka.ms/PowerToysOverview_PowerRename) | [PowerToys Run](https://aka.ms/PowerToysOverview_PowerToysRun) | [Quick Accent](https://aka.ms/PowerToysOverview_QuickAccent) |
-| [Registry Preview](https://aka.ms/PowerToysOverview_RegistryPreview) | [Screen Ruler](https://aka.ms/PowerToysOverview_ScreenRuler) | [Shortcut Guide](https://aka.ms/PowerToysOverview_ShortcutGuide) |
-| [Text Extractor](https://aka.ms/PowerToysOverview_TextExtractor) | [Video Conference Mute](https://aka.ms/PowerToysOverview_VideoConference) |
+| [Always on Top](https://aka.ms/PowerToysOverview_AoT) | [PowerToys Awake](https://aka.ms/PowerToysOverview_Awake) | [Command Not Found](https://aka.ms/PowerToysOverview_CmdNotFound) |
+| [Color Picker](https://aka.ms/PowerToysOverview_ColorPicker) | [Crop And Lock](https://aka.ms/PowerToysOverview_CropAndLock) | [Environment Variables](https://aka.ms/PowerToysOverview_EnvironmentVariables) |
+| [FancyZones](https://aka.ms/PowerToysOverview_FancyZones) | [File Explorer Add-ons](https://aka.ms/PowerToysOverview_FileExplorerAddOns) | [File Locksmith](https://aka.ms/PowerToysOverview_FileLocksmith) |
+| [Hosts File Editor](https://aka.ms/PowerToysOverview_HostsFileEditor) | [Image Resizer](https://aka.ms/PowerToysOverview_ImageResizer) | [Keyboard Manager](https://aka.ms/PowerToysOverview_KeyboardManager) |
+| [Mouse utilities](https://aka.ms/PowerToysOverview_MouseUtilities) | [Mouse Without Borders](https://aka.ms/PowerToysOverview_MouseWithoutBorders) | [Peek](https://aka.ms/PowerToysOverview_Peek) |
+| [Paste as Plain Text](https://aka.ms/PowerToysOverview_PastePlain) | [PowerRename](https://aka.ms/PowerToysOverview_PowerRename) | [PowerToys Run](https://aka.ms/PowerToysOverview_PowerToysRun) |
+| [Quick Accent](https://aka.ms/PowerToysOverview_QuickAccent) | [Registry Preview](https://aka.ms/PowerToysOverview_RegistryPreview) | [Screen Ruler](https://aka.ms/PowerToysOverview_ScreenRuler) |
+| [Shortcut Guide](https://aka.ms/PowerToysOverview_ShortcutGuide) | [Text Extractor](https://aka.ms/PowerToysOverview_TextExtractor) | [Video Conference Mute](https://aka.ms/PowerToysOverview_VideoConference) |
## Installing and running Microsoft PowerToys
### Requirements
- Windows 11 or Windows 10 version 2004 (code name 20H1 / build number 19041) or newer.
+- x64 or ARM64 processor
- Our installer will install the following items:
- [Microsoft Edge WebView2 Runtime](https://go.microsoft.com/fwlink/p/?LinkId=2124703) bootstrapper. This will install the latest version.
@@ -39,19 +40,19 @@ Microsoft PowerToys is a set of utilities for power users to tune and streamline
Go to the [Microsoft PowerToys GitHub releases page][github-release-link] and click on `Assets` at the bottom to show the files available in the release. Please use the appropriate PowerToys installer that matches your machine's architecture and install scope. For most, it is `x64` and per-user.
-[github-next-release-work]: https://github.com/microsoft/PowerToys/issues?q=project%3Amicrosoft%2FPowerToys%2F49
-[github-current-release-work]: https://github.com/microsoft/PowerToys/issues?q=project%3Amicrosoft%2FPowerToys%2F48
-[ptUserX64]: https://github.com/microsoft/PowerToys/releases/download/v0.75.1/PowerToysUserSetup-0.75.1-x64.exe
-[ptUserArm64]: https://github.com/microsoft/PowerToys/releases/download/v0.75.1/PowerToysUserSetup-0.75.1-arm64.exe
-[ptMachineX64]: https://github.com/microsoft/PowerToys/releases/download/v0.75.1/PowerToysSetup-0.75.1-x64.exe
-[ptMachineArm64]: https://github.com/microsoft/PowerToys/releases/download/v0.75.1/PowerToysSetup-0.75.1-arm64.exe
-
+[github-next-release-work]: https://github.com/microsoft/PowerToys/issues?q=project%3Amicrosoft%2FPowerToys%2F50
+[github-current-release-work]: https://github.com/microsoft/PowerToys/issues?q=project%3Amicrosoft%2FPowerToys%2F49
+[ptUserX64]: https://github.com/microsoft/PowerToys/releases/download/v0.76.2/PowerToysUserSetup-0.76.2-x64.exe
+[ptUserArm64]: https://github.com/microsoft/PowerToys/releases/download/v0.76.2/PowerToysUserSetup-0.76.2-arm64.exe
+[ptMachineX64]: https://github.com/microsoft/PowerToys/releases/download/v0.76.2/PowerToysSetup-0.76.2-x64.exe
+[ptMachineArm64]: https://github.com/microsoft/PowerToys/releases/download/v0.76.2/PowerToysSetup-0.76.2-arm64.exe
+
| Description | Filename | sha256 hash |
|----------------|----------|-------------|
-| Per user - x64 | [PowerToysUserSetup-0.75.1-x64.exe][ptUserX64] | CFDAE52607689A695F4E4DDD7C1FE68400359AEF0D2B23C86122835E9D32A20F |
-| Per user - ARM64 | [PowerToysUserSetup-0.75.1-arm64.exe][ptUserArm64] | 9BAD3EF71DEDE70445416AC7369D115FAE095152722BC4F23EE393D8A10F45CA |
-| Machine wide - x64 | [PowerToysSetup-0.75.1-x64.exe][ptMachineX64] | 18FEB9377B0BA45189FFF4F89627B152DD794CCC15F005592B34A40A3EA62EA8 |
-| Machine wide - ARM64 | [PowerToysSetup-0.75.1-arm64.exe][ptMachineArm64] | F5CDF5A35876A0B581F446BF728B7AC52B6B701C0850D9CEA9A1874523745CFD |
+| Per user - x64 | [PowerToysUserSetup-0.76.2-x64.exe][ptUserX64] | 73D734FC34B3F9D7484081EC0F0B6ACD4789A55203A185904CC5C62ABD02AF16 |
+| Per user - ARM64 | [PowerToysUserSetup-0.76.2-arm64.exe][ptUserArm64] | 5284CC5DA399DC37858A2FD260C30F20C484BA1B5616D0EB67CD90A8A286CB8B |
+| Machine wide - x64 | [PowerToysSetup-0.76.2-x64.exe][ptMachineX64] | 72B87381C9E5C7447FB59D7CE478B3102C9CEE3C6EB3A6BC7EC7EC7D9EFAB2A0 |
+| Machine wide - ARM64 | [PowerToysSetup-0.76.2-arm64.exe][ptMachineArm64] | F28C7DA377C25309775AB052B2B19A299C26C41582D05B95C3492A4A8C952BFE |
This is our preferred method.
@@ -97,142 +98,158 @@ For guidance on developing for PowerToys, please read the [developer docs](/doc/
Our [prioritized roadmap][roadmap] of features and utilities that the core team is focusing on.
-### 0.75 - October 2023 Update
+### 0.76 - November 2023 Update
In this release, we focused on new features, stability and improvements.
**Highlights**
- - New utility: An environment variables editor with the functionality to configure profiles that can be enabled/disabled. Thanks [@niels9001](https://github.com/niels9001) for the design and UI work that made this possible!
- - Settings has a new Dashboard home page, with quick access for enabling modules, short descriptions and activation methods. Thanks [@niels9001](https://github.com/niels9001) for the design and UI work that made this possible!
- - Added a previewer to Peek that hosts File Explorer previewers to support every file type that a machine is currently able to preview. For example, this means that if Microsoft Office handlers are installed, Peek can preview Office files. Thanks [@dillydylann](https://github.com/dillydylann)!
+ - Upgrade to .NET 8. Thanks [@snickler](https://github.com/snickler)!
+ - Keyboard Manager can now remap keys and shortcuts to send sequences of unicode text.
+ - Modernized the Keyboard Manager Editor UI. Thanks [@dillydylann](https://github.com/dillydylann)!
+ - Modernized the PowerToys Run, Quick Accent and Text Extractor UIs. Thanks [@niels9001](https://github.com/niels9001)!
+ - New File Explorer Add-ons: QOI image Preview Handler and Thumbnail Provider. Thanks [@pedrolamas](https://github.com/pedrolamas)!
### General
+ - Updated the WebView 2 dependency to 1.0.2088.41. Thanks [@davidegiacometti](https://github.com/davidegiacometti)!
+ - Fixed unreadable color brushes used across WinUI3 applications for improved accessibility. Thanks [@niels9001](https://github.com/niels9001)!
+ - Flyouts used across WinUI3 applications are no longer constrained to the application's bounds. Thanks [@Jay-o-Way](https://github.com/Jay-o-Way)!
+ - Upgraded the WPF-UI dependency to preview.9 and then preview.11. Thanks [@niels9001](https://github.com/niels9001) and [@pomianowski](https://github.com/pomianowski)!
+ - Upgraded to .NET 8. Thanks [@snickler](https://github.com/snickler)!
+ - Updated the WinAppSDK dependency to 1.4.3.
- - Many typo fixes through the projects and documentation. Thanks [@brianteeman](https://github.com/brianteeman)!
- - Refactored and improved the logic across utilities for bringing a window to the foreground after activation.
+### Awake
-### Color Picker
+ - Added localization to the tray icon context menu.
- - After activating Color Picker, it's now possible to cancel the session by clicking the right mouse button. Thanks [@fredso90](https://github.com/fredso90)!
+### Crop And Lock
+
+ - Fixed restoring windows that were reparented while maximized.
### Environment Variables
- - Added a new utility: An environment variables editor that has the functionality to configure profiles that can be enabled/disabled. Thanks [@niels9001](https://github.com/niels9001) for the design and UI work that made this possible!
- - Shows in the title bar if it's running as an administrator. Thanks [@davidegiacometti](https://github.com/davidegiacometti)!
+
+ - Fixed crash caused by WinAppSDK version bump by replacing ListView elements with ItemsControl.
### FancyZones
- - Fixed an issue causing context menu pop-ups from some apps to automatically snap to a zone. (This was a hotfix for 0.74)
- - Applied the fix for the context menu pop-ups to the logic that decides which windows can be snapped.
- - Reworked the "Keep windows in their zones" option to include the work area and turn it on by default, fixing an incompatibility with the Copilot flyout.
- - Fixed an issue causing windows to be snapped while moving to a different virtual desktop.
+ - Reverted a change that caused some applications, like the Windows Calculator, to not snap correctly. (This was a hotfix for 0.75)
+ - FancyZones Editor will no longer apply a layout to the current monitor after editing it.
+ - Fixed and refactored the code that detected if a window can be snapped. Added tests to it with known application window styles to avoid regressions in the future.
### File Explorer add-ons
- - Fixed an issue blocking some SVG files from being previewed correctly. (This was a hotfix for 0.74)
- - Fixed crashes on invalid files in the STL Thumbnail generator.
+ - Solved an issue incorrectly detecting encoding when previewing code files preview.
+ - Fixed the background color for Gcode preview handler on dark theme. Thanks [@pedrolamas](https://github.com/pedrolamas)!
+ - New utilities: Preview Handler and Thumbnail Provider for QOI image files. Thanks [@pedrolamas](https://github.com/pedrolamas)!
+ - GCode Thumbnails are now in the 32 bit ARGB format. Thanks [@pedrolamas](https://github.com/pedrolamas)!
+ - Added the perceived type to SVG and QOI file thumbnails. Thanks [@pedrolamas](https://github.com/pedrolamas)!
### GPO
- - Added a global GPO rule that applies for all utilities unless it's overridden. Thanks [@htcfreek](https://github.com/htcfreek)!
- - Added GPO rules to control which PowerToys Run plugins should be enabled/disabled by policy. Thanks [@htcfreek](https://github.com/htcfreek)!
- * All plugins have to provide its plugin ID as static property in its Main method.
+ - Added the missing Environment Variables utility policy to the .admx and .adml files. (This was a hotfix for 0.75)
+ - Fixed some typos and text improvements in the .adml file. Thanks [@htcfreek](https://github.com/htcfreek)!
+
+### Hosts File Editor
+
+ - Added a proper warning when the hosts file is read-only and a button to make it writable. Thanks [@davidegiacometti](https://github.com/davidegiacometti)!
### Image Resizer
+
+ - Fixed a WPF-UI issue regarding the application's background brushes. Thanks [@niels9001](https://github.com/niels9001)!
- - Fixed wrong .bmp file association in the registry. Thanks [@meitinger](https://github.com/meitinger)!
+### Installer
+
+ - Included the Text Extractor and Awake localization files in the install process.
### Keyboard Manager
- - Visually distinguish between the Numpad and regular period characters in the UI.
- - This utility is now disabled by default on new installations, since it requires user configuration to affect keyboard behavior.
- - Fixed a typo in the Numpad Subtract key in the editor.
+ - Modernized the UI with the Fluent design. Thanks [@dillydylann](https://github.com/dillydylann)!
+ - Added the feature to remap keys and shortcuts to arbitrary unicode text sequences.
-### Mouse Highlighter
+### Mouse Without Borders
- - Removed the lower limit of fade delay and duration, to allow better signaling of doing a double click. Thanks [@fredso90](https://github.com/fredso90)!
-
-### Mouse Jump
-
- - The process now runs in the background, for a faster activation time. Thanks [@mikeclayton](https://github.com/mikeclayton)!
+ - Removed Thread.Suspend calls when exiting the utility. That call is deprecated, unneeded and was causing a silent crash.
### Peek
- - Reported file sizes will now more closely match what's reported by File Explorer. Thanks [@Deepak-Sangle](https://github.com/Deepak-Sangle)!
- - Added a previewer that hosts File Explorer previewers to support every file type that a machine is currently able to preview. Thanks [@dillydylann](https://github.com/dillydylann)!
- - Fixed an issue causing the preview of the first file to be stuck loading. Thanks [@davidegiacometti](https://github.com/davidegiacometti)!
- - Fixed showing the previously previewed video file when invoking Peek with a new file. Thanks [@davidegiacometti](https://github.com/davidegiacometti)!
- - Added the wrap and file formatting options to the Monaco previewer. Thanks [@davidegiacometti](https://github.com/davidegiacometti)!
-
-### PowerRename
-
- - Save data from the last run in a different file to avoid conflicting with changing settings in the Settings application.
+ - Added the possibility to pause/resume videos with the space bar. Thanks [@davidegiacometti](https://github.com/davidegiacometti)!
+ - Fixed high CPU usage when idle before initializing the main window. Thanks [@davidegiacometti](https://github.com/davidegiacometti)!
+ - Implemented Ctrl+W as a shortcut to close Peek. Thanks [@Physalis2](https://github.com/Physalis2)!
+ - Solved an issue incorrectly detecting encoding when previewing code files.
+ - Fixed background issues when peeking into HTML files after the WebView 2 upgrade.
### PowerToys Run
- - Fixed a case where the query wasn't being cleared after invoking a result action through the keyboard. Thanks [@davidegiacometti](https://github.com/davidegiacometti)!
- - Improved the shell selection option for Windows Terminal in the Shell plugin and improved the backend code for adding combo box options to plugins. Thanks [@htcfreek](https://github.com/htcfreek)!
- * The implementation of the combo box items has changed and isn't backward compatible. (Old plugins won't crash, but the combo box setting isn't shown in settings ui anymore.)
- - Added Unix time in milliseconds, fixed negative unix time input and improved error messages in the TimeDate plugin. Thanks [@htcfreek](https://github.com/htcfreek)!
- - The PowerToys plugin allows calling the new Environment Variables utility. Thanks [@davidegiacometti](https://github.com/davidegiacometti)!
- - Refactored and added support to VSCodium Stable, VSCodium Insider and Remote Tunnels workspaces. Thanks [@eternalphane](https://github.com/eternalphane)!
+ - Moved to WPF-UI and redesigned according to Fluent UX principles. Thanks [@niels9001](https://github.com/niels9001)!
+ - Fixed an issue causing 3rd party plugins to not have their custom settings correctly initialized with default values. (This was a hotfix for 0.75) Thanks [@waaverecords](https://github.com/waaverecords)!
+ - Fixed a crash in the VSCode plugin when the VSCode path had trailing backspaces. Thanks [@davidegiacometti](https://github.com/davidegiacometti)!
+ - Fixed a crash when trying to load invalid image icons.
+ - Fixed a crash in the Programs plugin when getting images for some .lnk files.
+ - Fixed a rare startup initialization error and removed cold start operations that were no longer needed. Thanks [@davidegiacometti](https://github.com/davidegiacometti)!
+ - Improved calculations for Windows File Time and Unix Epoch Time in the DateTime plugin. Thanks [@htcfreek](https://github.com/htcfreek)!
+ - Fixed a crash when trying to get the icon for a link that pointed to no file.
+ - Cleaned up code in the WindowWalker plugin improving the logic. Thanks [@davidegiacometti](https://github.com/davidegiacometti)!
### Quick Accent
- - Fixed characters that were removed from "All languages" because they were not in any single language. (This was a hotfix for 0.74)
- - Added Asturian characters to the Spanish character set. Thanks [@blakestack](https://github.com/blakestack)!
- - Added Greek characters with tonos. Thanks [@PesBandi](https://github.com/PesBandi)!
-
-### Registry Preview
-
- - Fixed a parsing error that crashed the Application. (This was a hotfix for 0.74)
- - Fixed opening file names with non-ASCII characters. Thanks [@randyrants](https://github.com/randyrants)!
- - Fixed wrong parsing when the file contained an assignment with spaces around the equals sign. Thanks [@randyrants](https://github.com/randyrants)!
- - Fixed key transversal issues when a key was a substring of a parent key. Thanks [@randyrants](https://github.com/randyrants)!
-
-### Runner
-
- - Fixed the update notification toast to show a Unicode arrow. Thanks [@TheJoeFin](https://github.com/TheJoeFin)!
+ - Moved from ModernWPF to WPF-UI. Thanks [@niels9001](https://github.com/niels9001)!
+ - Added support to the Finnish language character set. Thanks [@davidtlascelles](https://github.com/davidtlascelles)!
+ - Added currency symbols for Croatian, Gaeilge, Gàidhlig and Welsh. Thanks [@PesBandi](https://github.com/PesBandi)!
+ - Added a missing Latin letter ꝡ. Thanks [@cubedhuang](https://github.com/cubedhuang)!
+ - Added fraction characters. Thanks [@PesBandi](https://github.com/PesBandi)!
+ - Added support to the Danish language character set. Thanks [@PesBandi](https://github.com/PesBandi)!
+ - Added the Kazakhstani Tenge character to the Currencies characters set. Thanks [@PesBandi](https://github.com/PesBandi)!
+ - Renamed Slovakian to Slovak, which is the correct term. Thanks [@PesBandi](https://github.com/PesBandi)!
+ - Added the Greek language character set. Thanks [@mcbabo](https://github.com/mcbabo)!
### Settings
- - Added a new Dashboard home page, with quick access for enabling modules, short descriptions and activation methods. Thanks [@niels9001](https://github.com/niels9001) for the design and UI work that made this possible!
- - Fixed a typo in the Hosts File Editor page. Thanks [@Deepak-Sangle](https://github.com/Deepak-Sangle)!
- - Added a lock icon to the flyout listing of all modules when its enabled state is controlled by policy.
- - The "All apps" list in the flyout will now list all apps even if their enabled state is controlled by policy.
+ - When clicking a module's name on the Dashboard, it will navigate to that module's page.
+ - Fixed the clipping of information in the Backup and Restore section of the General Settings page. Thanks [@niels9001](https://github.com/niels9001)!
+ - Updated the File Explorer Add-ons fluent icon. Thanks [@niels9001](https://github.com/niels9001)!
+ - Added a warning when trying to set a shortcut that might conflict with "Alt Gr" key combinations.
+ - Added a direct link to the OOBE's "What's New page" from the main Settings window. Thanks [@iakrayna](https://github.com/iakrayna)!
+ - Changed mentions from Microsoft Docs to Microsoft Learn.
+ - Fixed the slow reaction to system theme changes.
-### Video Conference Mute
+### Text Extractor
- - Added an option to allow for the toolbar to hide after some time passed. Thanks [@quyenvsp](https://github.com/quyenvsp)!
- - Added an option to select to mute or unmute at startup. Thanks [@quyenvsp](https://github.com/quyenvsp)!
- - Fixed an issue causing a cascade of mute/unmute triggers.
+ - Move to WPF-UI, localization and light theme support. Thanks [@niels9001](https://github.com/niels9001)!
+ - Disabled by default on Windows 11, with a information box on Settings to prefer using the Windows Snipping Tool, which now supports OCR.
### Documentation
- - Updated the Group Policy documentation on learn.microsoft.com, removed the Group Policy documentation from the repository and linked to the published documentation on learn.microsoft.com instead.
+ - Fixed some typos in the README. Thanks [@Asymtode712](https://github.com/Asymtode712)!
+ - Reworked the gpo docs on learn.microsoft.com, adding .admx, registry and Intune information. Thanks [@htcfreek](https://github.com/htcfreek)!
### Development
- - Added project dependencies to the version project and headers to avoid building errors. Thanks [@johnterickson](https://github.com/johnterickson)!
- - Enabled Control Flow Guard in the C++ projects. Thanks [@DHowett](https://github.com/DHowett)!
- - Switched the release pipeline to the 1ES governed template. Thanks [@DHowett](https://github.com/DHowett)!
- - Styled XAML files and added a XAML Style checker to the solution, with a CI action to check if code being contributed is compliant. Thanks [@davidegiacometti](https://github.com/davidegiacometti)!
- - Suppressed redundant midl file warnings in PowerRename.
- - Add unit tests to FancyZones Editor. Thanks [@garv5014](https://github.com/garv5014), [@andrewbengordon](https://github.com/andrewbengordon) and [@Cwighty](https://github.com/Cwighty)!
- - Improved the Default Layouts internal structure in FancyZones Editor. Thanks [@garv5014](https://github.com/garv5014)!
- - Fixed code issues to allow building in Visual Studio 17.8 Preview 4.
+ - Updated the check-spelling ci action to 0.22. Thanks [@jsoref](https://github.com/jsoref)!
+ - Refactored the modules data model used between the Settings Dashboard and Flyout.
+ - Fixed a flaky interop test that was causing automated CI to hang occasionally.
+ - Increased the WebView 2 loading timeout to reduce flakiness in those tests. Thanks [@davidegiacometti](https://github.com/davidegiacometti)!
+ - Added support for building with the Dev Drive CopyOnWrite feature, increasing build speed. Thanks [@pedrolamas](https://github.com/pedrolamas)!
+ - Addressed the C# static analyzers suggestions. Thanks [@davidegiacometti](https://github.com/davidegiacometti)!
+ - Addressed the C++ static analyzers suggestions.
+ - PRs that only contain Markdown or text files changes no longer trigger the full CI. Thanks [@snickler](https://github.com/snickler)!
+ - Updated the Microsoft.Windows.CsWinRT to 2.0.4 to fix building with the official Visual Studio 17.8 release.
+ - Fixed new code quality issues caught by the official Visual Studio 17.8 release.
+ - Added a bot trigger to point contributors to the main new contribution issue on GitHub. Thanks [@Aaron-Junker](https://github.com/Aaron-Junker)!
+ - Removed unneeded entries from expect.txt.
+ - Turned off a new feature from Visual Studio that was adding the commit hash to the binary files Product Version.
+ - Refactored and reviewed the spellcheck entries into different files. Thanks [@Jay-o-Way](https://github.com/Jay-o-Way)!
+ - Added Spectre mitigation and SHA256 hash creation for some DLLs.
+ - Reverted the release pipeline template to a previous release that's stable for shipping PowerToys.
-#### What is being planned for version 0.76
+#### What is being planned for version 0.77
-For [v0.76][github-next-release-work], we'll work on the items below:
+For [v0.77][github-next-release-work], we'll work on the items below:
+ - New utility: Command Not Found
- Language selection
- - .NET 8 upgrade
- - Allowing Keyboard Manager to output arbitrary Unicode sequences
- Automated UI testing through WinAppDriver
- - Modernize and refresh the UX of PowerToys based on WPF. Here's Work in Progress previews for the modules "PowerToys Run" and "Color Picker":
-
-
+ - Develop support for Desired State Configuration
+ - Modernize and refresh the UX of PowerToys based on WPF. Here's the Work in Progress preview for "Color Picker":

diff --git a/doc/devdocs/common/FilePreviewCommon.md b/doc/devdocs/common/FilePreviewCommon.md
new file mode 100644
index 0000000000..7293e8c978
--- /dev/null
+++ b/doc/devdocs/common/FilePreviewCommon.md
@@ -0,0 +1,75 @@
+# [FilePreviewCommon](/src/common/FilePreviewCommon)
+
+This project contains common code used for previewing and displaying files.
+
+## Monaco preview
+
+Monaco preview enables to display developer files. It is based on [Microsoft's Monaco Editor](https://microsoft.github.io/monaco-editor/) which is maintained by the Visual Studio Code team.
+
+This previewer is used for the File Explorer Dev File Previewer, as well as PowerToys Peek.
+
+### Update Monaco Editor
+
+1. Download Monaco editor with [npm](https://www.npmjs.com/): Run `npm i monaco-editor` in the command prompt.
+2. Delete everything except the `min` folder (the minimised code) from the downloaded files.
+3. Copy the `min` folder into the `src/common/FilePreviewCommon/Assets/Monaco/monacoSRC` folder of the PowerToys project.
+4. Generate the JSON file as described in the generate [monaco_languages.json file](#monaco_languagesjson) section.
+
+### Add a new language definition
+
+As an example on how to add a new language definition you can look at the one for [registry files](/src/common/FilePreviewCommon/Assets/Monaco/customLanguages/reg.js).
+
+1. Add the new language definition (written with [Monarch](https://microsoft.github.io/monaco-editor/monarch.html)) as a new file to the [folder containing Monaco custom languages](/src/common/FilePreviewCommon/Assets/Monaco/customLanguages/) (Remember the file name and the string you used for "idDefinition" as you need it later.). The file should be formatted like in the example below. (Please change `idDefinition` to the name of your language.)
+
+```javascript
+export function idDefinition() {
+ return {
+ ...
+ }
+}
+```
+
+2. Add the following line to the [`monacoSpecialLanguages.js`](/src/common/FilePreviewCommon/Assets/Monaco/monacoSpecialLanguages.js) file, after the other import statements:
+
+```javascript
+import { idDefinition } from './customLanguages/file.js';
+```
+
+> Replace file.js with the name of your definition file from step 1. Please replace idDefinition with the string you used in step 1.
+
+3. In the [`monacoSpecialLanguages.js`](/src/common/FilePreviewCommon/Assets/Monaco/monacoSpecialLanguages.js) file add the following line into the `registerAdditionalLanguages` function:
+
+```javascript
+registerAdditionalNewLanguage("id", [".fileExtension"], idDefinition(), monaco)
+```
+
+> Replace id and idDefinition with your id and string used in step 1. Replace fileExtension with a set of file extensions you want the language to register to.
+
+ * The id can be anything. Recommended is one of the file extensions. For example "php" or "reg".
+
+4. Execute the steps described in the [monaco_languages.json](#monaco_languagesjson) section.
+
+### Add a new file extension to an existing language
+
+1. In the [`monacoSpecialLanguages.js`](/src/common/FilePreviewCommon/Assets/Monaco/monacoSpecialLanguages.js) file add the following line to the `registerAdditionalLanguages` function. (`existingId` is the id of the language you want to add the extension to. You can find these id's in the [`monaco_languages.json`](/src/common/FilePreviewCommon/Assets/Monaco/monaco_languages.json) file):
+
+```javascript
+registerAdditionalLanguage("id", [".fileExtension"], "existingId", monaco)
+```
+
+ * If for instance you want to add more extensions to the php language set the id to `phpExt` and the existingId to `php`.
+
+2. Copy the existing language definition into the `languageDefinitions` function in the same file. You can find the existing definitions in the following folder: [`/src/common/FilePreviewCommon/Assets/Monaco/monacoSRC/min/vs/basic-languages/`](/src/common/FilePreviewCommon/Assets/Monaco/monacoSRC/min/vs/basic-languages/).
+
+3. Execute the steps described in the [monaco_languages.json](#monaco_languagesjson) section.
+
+### monaco_languages.json
+
+[`monaco_languages.json`](/src/common/FilePreviewCommon/Assets/Monaco/monaco_languages.json) contains all extensions and IDs for the languages supported by Monaco. The [`MonacoHelper`](/src/common/FilePreviewCommon/MonacoHelper.cs) class and the installer are using this file to register preview handlers for the defined extensions.
+
+After updating Monaco Editor and/or adding a new language you should update the [`monaco_languages.json`](/src/common/FilePreviewCommon/Assets/Monaco/monaco_languages.json) file.
+
+1. Run the [`generateLanguagesJson.html`](/src/common/FilePreviewCommon/Assets/Monaco/generateLanguagesJson.html) file on a local webserver (as webbrowsers will block certain needed features when running the file locally.)
+ * This can for example be achieved by using the [Preview Server](https://marketplace.visualstudio.com/items?itemName=yuichinukiyama.vscode-preview-server) extension for Visual Studio Code: Open the file in Visual Studio Code, right click in the code editor and select `vscode-preview-server: Launch on browser`. The file will be opened in a browser.
+2. The browser will download the new `monaco_languages.json` file
+3. Replace the old file with the newly downloaded one in the source code folder.
diff --git a/doc/devdocs/common.md b/doc/devdocs/common/common.md
similarity index 98%
rename from doc/devdocs/common.md
rename to doc/devdocs/common/common.md
index 48db53733b..5d5d906a44 100644
--- a/doc/devdocs/common.md
+++ b/doc/devdocs/common/common.md
@@ -1,5 +1,7 @@
# Classes and structures
+> This document is outdated and will soon be renewed.
+
#### class Animation: [header](/src/common/animation.h) [source](/src/common/animation.cpp)
Animation helper class with two easing-in animations: linear and exponential.
diff --git a/doc/devdocs/common/readme.md b/doc/devdocs/common/readme.md
new file mode 100644
index 0000000000..0ba4ef5b03
--- /dev/null
+++ b/doc/devdocs/common/readme.md
@@ -0,0 +1,7 @@
+# Common
+
+The [common](/src/common) folder contains projects with code, that is used in multiple projects.
+
+## [FilePreviewCommon](FilePreviewCommon.md)
+
+This project contains common code for file previewing.
\ No newline at end of file
diff --git a/doc/devdocs/modules/launcher/new-plugin-checklist.md b/doc/devdocs/modules/launcher/new-plugin-checklist.md
index 3554e3af47..c3fcab39a8 100644
--- a/doc/devdocs/modules/launcher/new-plugin-checklist.md
+++ b/doc/devdocs/modules/launcher/new-plugin-checklist.md
@@ -3,6 +3,7 @@
- [ ] Microsoft plugin project name pattern: `Microsoft.PowerToys.Run.Plugin.{PluginName}`
- [ ] Community plugin project name pattern: `Community.PowerToys.Run.Plugin.{PluginName}`
- [ ] The project file should import `Version.props` and specify `$(Version).0`
+- [ ] If the plugin uses any 3rd party dependencies the project file should import `DynamicPlugin.props`
- [ ] Make sure `*.csproj` specify only x64 platform target
- [ ] The plugin has to contain a `plugin.json` file of the following format in its root folder
```
@@ -17,7 +18,8 @@
"Website": "https://aka.ms/powertoys",
"ExecuteFileName": string, // Should be {Type}.PowerToys.Run.Plugin.{PluginName}.dll
"IcoPathDark": string, // Path to dark theme icon. The path is relative to the root plugin folder
- "IcoPathLight": string // Path to light theme icon. The path is relative to the root plugin folder
+ "IcoPathLight": string // Path to light theme icon. The path is relative to the root plugin folder
+ "DynamicLoading": bool // Sets whether the plugin should dynamically load any dependencies isolated from the core application.
}
```
- [ ] Make sure your `Main` class contains a public, static string property for the `PluginID`. The plugin id has to be the same as the one in the `plugin.json`file.
diff --git a/doc/devdocs/modules/launcher/plugins/community.valuegenerator.md b/doc/devdocs/modules/launcher/plugins/community.valuegenerator.md
index 379e7d4894..4a580f090d 100644
--- a/doc/devdocs/modules/launcher/plugins/community.valuegenerator.md
+++ b/doc/devdocs/modules/launcher/plugins/community.valuegenerator.md
@@ -1,6 +1,6 @@
# Value Generator Plugin
-The Value Generator plugin is used to generate hashes for strings, to calculate base64 encodings and to generate GUIDs versions 1, 3, 4 and 5.
+The Value Generator plugin is used to generate hashes for strings, to calculate base64 encodings, escape and encode URLs/URIs and to generate GUIDs versions 1, 3, 4 and 5.

@@ -10,7 +10,7 @@ The Value Generator plugin is used to generate hashes for strings, to calculate
- The result of `string ResultToString()` will be used for the Result's title
- The `Description` field will be used for the Result's subtitle
-### [`HashRequest`](/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/Hashing/HashRequest.cs)
+### [`HashRequest`](/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/Generators/Hashing/HashRequest.cs)
- Implements IComputeRequest
- Supports the hashing algorithms from System.Security.Cryptography:
- MD5
@@ -20,19 +20,19 @@ The Value Generator plugin is used to generate hashes for strings, to calculate
- SHA512
- If other algorithms are added to System.Security.Cryptography, they can be added to the `_algorithms` dictionary. [`InputParser.ParseInput()`](#inputparser) will need to return a `HashRequest` for the algorithm in the query
-### [`Base64Request`](/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/Base64/Base64Request.cs)
+### [`Base64Request`](/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/Generators/Base64/Base64Request.cs)
- Implements IComputeRequest
- `Compute()` will populate `Result` with the base64 encoding of the byte array passed in the constructor
-### [`Base64DecodeRequest`](/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/Base64/Base64DecodeRequest.cs)
+### [`Base64DecodeRequest`](/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/Generators/Base64/Base64DecodeRequest.cs)
- Implements IComputeRequest
- `Compute()` will populate `Result` with the decoded byte array of the base64 string passed in the constructor
-### [`GUIDRequest`](/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/GUID/GUIDRequest.cs)
+### [`GUIDRequest`](/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/Generators/GUID/GUIDRequest.cs)
- Implements IComputeRequest
- Uses the [`GUIDGenerator`](#guidgenerator) class to generate or compute the requested GUID
-### [`GUIDGenerator`](/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/GUID/GUIDGenerator.cs)
+### [`GUIDGenerator`](/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/Generators/GUID/GUIDGenerator.cs)
- Utility class for generating or calculating GUIDs
- Generating GUID versions 1 and 4 is done using builtin APIs. [`UuidCreateSequential`](https://learn.microsoft.com/en-us/windows/win32/api/rpcdce/nf-rpcdce-uuidcreatesequential) for version 1 and `System.Guid.NewGuid()` for version 4
- Versions 3 and 5 take two parameters, a namespace and a name
@@ -40,6 +40,32 @@ The Value Generator plugin is used to generate hashes for strings, to calculate
- The `PredefinedNamespaces` dictionary contains aliases for the predefined namespaces
- The name can be any string
+### [`UrlEncodeRequest`](/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/Generators/Uri/UrlEncodeRequest.cs)
+- Implements IComputeRequest
+- `Compute()` will populate `Result` with the encoded url converted using `HttpUtility.UrlEncode()`.
+
+### [`UrlDecodeRequest`](/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/Generators/Uri/UrlDecodeRequest.cs)
+- Implements IComputeRequest
+- `Compute()` will populate `Result` with the decoded url converted using `HttpUtility.UrlDecode()`.
+
+### [`DataEscapeRequest`](/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/Generators/Uri/DataEscapeRequest.cs)
+- Implements IComputeRequest
+- `Compute()` will populate `Result` with the escaped data string converted using `System.Uri.EscapeDataString()`.
+
+### [`DataUnescapeRequest`](/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/Generators/Uri/DataUnescapeRequest.cs)
+- Implements IComputeRequest
+- `Compute()` will populate `Result` with the unescaped data string converted using `System.Uri.UnescapeDataString()`.
+
+### [`HexEscapeRequest`](/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/Generators/Uri/HexEscapeRequest.cs)
+- Implements IComputeRequest
+- `Compute()` will populate `Result` with the escaped data string converted using `System.Uri.HexEscape()`.
+- Only single characters are supported as input.
+
+### [`HexUnescapeRequest`](/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/Generators/Uri/HexUnescapeRequest.cs)
+- Implements IComputeRequest
+- `Compute()` will populate `Result` with the unescaped data string converted using `System.Uri.HexUnescape()`.
+- Only the first hexadecimal character in the string gets unescaped. The rest of the user input is ignored.
+
### [`InputParser`](/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/InputParser.cs)
- It is responsible only for parsing the query from the user
- Based on the user query, the `ParseInput()` method must return an object that implements the `IComputeRequest` interface or it must throw one of `FormatException` or `ArgumentException`
@@ -51,6 +77,6 @@ The Value Generator plugin is used to generate hashes for strings, to calculate
> The error message will not be shown to the user but a log message will be created
### Adding a new value generator
-1. To add a new value generator, create a folder under `/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/` and inside it add a class that implements `IComputeRequest`.
+1. To add a new value generator, create a folder under `/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/Generators/` and inside it add a class that implements `IComputeRequest`.
2. Add any utility classes that are specific to the new generator inside the same folder to keep them separated from the other generators.
3. Modify the `InputParser.ParseInput()` to handle a request for the new generator and return an instance of the class you created in step 1
\ No newline at end of file
diff --git a/doc/devdocs/modules/launcher/plugins/windowwalker.md b/doc/devdocs/modules/launcher/plugins/windowwalker.md
index bfdca89e1b..6a26f54e6f 100644
--- a/doc/devdocs/modules/launcher/plugins/windowwalker.md
+++ b/doc/devdocs/modules/launcher/plugins/windowwalker.md
@@ -52,7 +52,7 @@ The user can switch to the found windows, close them or kill their process.
- It is responsible for updating the search text and performing a fuzzy search on all the open windows.
### [`Window.cs`](/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/Window.cs)
-- The [`Window`](/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/Window.cs) class represents a specific window and has functions to get the name of the window, the state of the window (whether it is visible or not), the `SwitchTowindow` function which switches the desktop focus to the selected window and the `CloseThisWindow` function which closes the window. The `SwitchTowindow` action is performed when the user clicks on a window walker plugin result.
+- The [`Window`](/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/Window.cs) class represents a specific window and has functions to get the name of the window, the state of the window (whether it is visible or not), the `SwitchToWindow` function which switches the desktop focus to the selected window and the `CloseThisWindow` function which closes the window. The `switchToWindow` action is performed when the user clicks on a window walker plugin result.
- The `Window` class holds a static cache with the process information of all windows we know so far and each window instance has a property which holds its process information (name, file, ...). The process data in the cache and the window property are of the type `WindowProcess`.
- To get the desktop information for a window, we use the common [`VirtualDesktopHelper`](/src/modules/launcher/Wox.Plugin/Common/VirtualDesktop/VirtualDesktopHelper.cs) in `Wox.Plugin` project. The instance of `VirtualDesktopHelper` is cached in the [`Main`](/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Main.cs) class of the plugin at runtime. The desktop information is stored in a property of the type [`VDesktop`](/src/modules/launcher/Wox.Plugin/Common/VirtualDesktop/VDesktop.cs).
diff --git a/doc/devdocs/modules/peek/readme.md b/doc/devdocs/modules/peek/readme.md
new file mode 100644
index 0000000000..8bb73d62fc
--- /dev/null
+++ b/doc/devdocs/modules/peek/readme.md
@@ -0,0 +1,7 @@
+# PowerToys Peek
+
+> Documentation is currently under construction
+
+## Dev file previewer
+
+The previewer for developer files uses the project in [FileExplorerCommon] common project to render monaco. You can find its documentation here: [/doc/devdocs/common/FilePreviewCommon.md](/doc/devdocs/common/FilePreviewCommon.md).
\ No newline at end of file
diff --git a/doc/devdocs/modules/powerpreview/monaco/readme.md b/doc/devdocs/modules/powerpreview/monaco/readme.md
deleted file mode 100644
index ac9ae3eae2..0000000000
--- a/doc/devdocs/modules/powerpreview/monaco/readme.md
+++ /dev/null
@@ -1,24 +0,0 @@
-# Developer Preview (Monaco)
-
-Developer preview is based on [Microsoft's Monaco Editor](https://microsoft.github.io/monaco-editor/) which is maintained by the Visual Studio Code team.
-
-## Update monaco editor
-
-1. Download Monaco editor with npm: `npm i monaco-editor`.
-2. Delete everything except the `min` folder (the minimised code).
-3. Copy the `min` folder inside the [`monacoSRC`](/src/modules/previewpane/MonacoPreviewHandler/monacoSRC) folder.
-4. Generate the JSON file (see section below)
-
-## monaco_languages.json
-
-[`monaco_languages.json`](/src/modules/previewpane/MonacoPreviewHandler/monaco_languages.json) contains all extensions and Id's for the supported languages of Monaco. The [`FileHandler`](/src/modules/previewpane/MonacoPreviewHandler/FileHandler.cs) class and the installer are using this file.
-
-### Generate monaco_languages.json file
-
-After you updated monaco editor or adding a new language you should update the [`monaco_languages.json`](/src/modules/previewpane/MonacoPreviewHandler/monaco_languages.json) file.
-
-You have to run the file on a local webserver!
-
-1. Build monaco in debug mode.
-2. Open [generateLanguagesJson.html](/src/modules/previewpane/MonacoPreviewHandler/generateLanguagesJson.html) in a browser.
-3. Replace the old JSON file.
diff --git a/doc/devdocs/runner.md b/doc/devdocs/runner.md
index 3880309395..dab6fc8eb1 100644
--- a/doc/devdocs/runner.md
+++ b/doc/devdocs/runner.md
@@ -1,5 +1,5 @@
#### [`main.cpp`](/src/runner/main.cpp)
-Contains the executable starting point, initialization code and the list of known PowerToys. All singletones are also initialized here at the start. Loads all the powertoys by scanning the `./modules` folder and `enable()`s those marked as enabled in `%LOCALAPPDATA%\Microsoft\PowerToys\settings.json` config. Then it runs [a message loop](https://learn.microsoft.com/windows/win32/winmsg/using-messages-and-message-queues) for the tray UI. Note that this message loop also [handles lowlevel_keyboard_hook events](https://github.com/microsoft/PowerToys/blob/1760af50c8803588cb575167baae0439af38a9c1/src/runner/lowlevel_keyboard_event.cpp#L24).
+Contains the executable starting point, initialization code and the list of known PowerToys. All singletons are also initialized here at the start. Loads all the powertoys by scanning the `./modules` folder and `enable()`s those marked as enabled in `%LOCALAPPDATA%\Microsoft\PowerToys\settings.json` config. Then it runs [a message loop](https://learn.microsoft.com/windows/win32/winmsg/using-messages-and-message-queues) for the tray UI. Note that this message loop also [handles lowlevel_keyboard_hook events](https://github.com/microsoft/PowerToys/blob/1760af50c8803588cb575167baae0439af38a9c1/src/runner/lowlevel_keyboard_event.cpp#L24).
#### [`powertoy_module.h`](/src/runner/powertoy_module.h) and [`powertoy_module.cpp`](/src/runner/powertoy_module.cpp)
Contains code for initializing and managing the PowerToy modules. `PowertoyModule` is a RAII-style holder for the `PowertoyModuleIface` pointer, which we got by [invoking module DLL's `powertoy_create` function](https://github.com/microsoft/PowerToys/blob/1760af50c8803588cb575167baae0439af38a9c1/src/runner/powertoy_module.cpp#L13-L24).
diff --git a/doc/devdocs/settingsv2/runner-ipc.md b/doc/devdocs/settingsv2/runner-ipc.md
index 7b5d759c7b..465362fb19 100644
--- a/doc/devdocs/settingsv2/runner-ipc.md
+++ b/doc/devdocs/settingsv2/runner-ipc.md
@@ -4,7 +4,7 @@ The Settings v2 process uses two way IPC to communicate with the runner process.
## Initialization
- On the settings' side, the two way IPC delegates are contained with the [`ShellPage.xaml.cs`](/src/settings-ui/Settings.UI/Views/ShellPage.xaml.cs) file. The delegates are static and the views for all the powerToys send the ipc information to the viewmodels as `ShellPage.DefaultSndMSGCallBack`.
-- These delegates are initialized within the [`Mainwindow.xaml.cs`](/src/settings-ui/Settings.UI/MainWindow.xaml.cs) file in the `Settings.Runner` project.
+- These delegates are initialized within the [`MainWindow.xaml.cs`](/src/settings-ui/Settings.UI/MainWindow.xaml.cs) file in the `Settings.Runner` project.
## Types of IPC delegates
diff --git a/doc/devdocs/settingsv2/viewmodels.md b/doc/devdocs/settingsv2/viewmodels.md
index 8e5ab6a405..c3e17da46a 100644
--- a/doc/devdocs/settingsv2/viewmodels.md
+++ b/doc/devdocs/settingsv2/viewmodels.md
@@ -22,5 +22,5 @@ The viewmodels are located within the [`Settings.UI.Library`](/src/settings-ui/S
- Some viewmodels expect the runner to create the file instead of creating the file themselves, like in keyboard manager.
- The colorpicker powertoy creates the `settings.json` within the module. This must be taken care of when encapsulated within the settingsRepository.
- Currently, all modules use the `SettingsRepository` to access the General Settings config.
-- However, only Fancyzones, ShortcutGuide and PowerPreview use the `SettingsRepository` to access the module properties.
+- However, only FancyZones, ShortcutGuide and PowerPreview use the `SettingsRepository` to access the module properties.
diff --git a/doc/devdocs/tools/fancyzone-hit-test.md b/doc/devdocs/tools/fancyzones-hit-test.md
similarity index 95%
rename from doc/devdocs/tools/fancyzone-hit-test.md
rename to doc/devdocs/tools/fancyzones-hit-test.md
index b49207faa0..96856891f9 100644
--- a/doc/devdocs/tools/fancyzone-hit-test.md
+++ b/doc/devdocs/tools/fancyzones-hit-test.md
@@ -1,5 +1,5 @@
# [FancyZone hit test tool](/tools/FancyZone_HitTest/)
-
+
This tool tests the FancyZones layout selection logic. It displays a window with 5 zones. By hovering the mouse over the zones, the zone under the mouse cursor is highlighted. The sidebar shows different metrics that are used to determine which zone is under the mouse cursor.
diff --git a/doc/devdocs/tools/readme.md b/doc/devdocs/tools/readme.md
index 8794b77e3e..1bf19d610b 100644
--- a/doc/devdocs/tools/readme.md
+++ b/doc/devdocs/tools/readme.md
@@ -11,7 +11,7 @@ Following tools are currently available:
* [BugReportTool](bug-report-tool.md) - A tool to collect logs and system information for bug reports.
* [Build tools](build-tools.md) - A set of scripts that help building PowerToys.
* [Clean up tool](clean-up-tool.md) - A tool to clean up the PowerToys installation.
-* [FancyZones hit test](fancyzone-hit-test.md) - A tool to test FancyZones layout selection logic.
+* [FancyZones hit test](fancyzones-hit-test.md) - A tool to test FancyZones layout selection logic.
* [FancyZones draw layout test](fancyzones-draw-layout-test.md) - A tool to test FancyZones layout drawing logic.
* [FancyZones zonable tester](fancyzones-zonable-tester.md) - A tool to test if a window is zonable.
* [Monitor info report](monitor-info-report.md) - A small diagnostic tool which helps identifying WinAPI bugs related to the physical monitor detection.
diff --git a/doc/images/icons/Command Not Found.png b/doc/images/icons/Command Not Found.png
new file mode 100644
index 0000000000..8243b9f8c8
Binary files /dev/null and b/doc/images/icons/Command Not Found.png differ
diff --git a/doc/images/overview/Original/PowerLauncher.png b/doc/images/overview/Original/PowerLauncher.png
index 701969e2c7..597e64067f 100644
Binary files a/doc/images/overview/Original/PowerLauncher.png and b/doc/images/overview/Original/PowerLauncher.png differ
diff --git a/doc/images/overview/PowerLauncher_large.png b/doc/images/overview/PowerLauncher_large.png
index aecb74c9fb..063e51be4c 100644
Binary files a/doc/images/overview/PowerLauncher_large.png and b/doc/images/overview/PowerLauncher_large.png differ
diff --git a/doc/images/overview/PowerLauncher_small.png b/doc/images/overview/PowerLauncher_small.png
index cdf5776b37..0ef995180f 100644
Binary files a/doc/images/overview/PowerLauncher_small.png and b/doc/images/overview/PowerLauncher_small.png differ
diff --git a/doc/images/tools/fancyzone-hit-test.png b/doc/images/tools/fancyzones-hit-test.png
similarity index 100%
rename from doc/images/tools/fancyzone-hit-test.png
rename to doc/images/tools/fancyzones-hit-test.png
diff --git a/doc/thirdPartyRunPlugins.md b/doc/thirdPartyRunPlugins.md
index ed0f62acb5..bf85dd421c 100644
--- a/doc/thirdPartyRunPlugins.md
+++ b/doc/thirdPartyRunPlugins.md
@@ -33,3 +33,4 @@ Contact the developers of a plugin directly for assistance with a specific plugi
| [Quick Lookup](https://github.com/GTGalaxi/quick-lookup-ptrun) | [gtgalaxi](https://github.com/GTGalaxi) | Search across multiple cyber security tools |
| [Visual Studio](https://github.com/davidegiacometti/PowerToys-Run-VisualStudio) | [davidegiacometti](https://github.com/davidegiacometti) | Open Visual Studio recents |
| [WinGet](https://github.com/bostrot/PowerToysRunPluginWinget) | [bostrot](https://github.com/bostrot) | Search and install packages from WinGet |
+| [Scoop](https://github.com/Quriz/PowerToysRunScoop) | [Quriz](https://github.com/Quriz) | Search and install packages from Scoop |
diff --git a/installer/PowerToysSetup/CmdNotFound.wxs b/installer/PowerToysSetup/CmdNotFound.wxs
new file mode 100644
index 0000000000..3ac8445d88
--- /dev/null
+++ b/installer/PowerToysSetup/CmdNotFound.wxs
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/installer/PowerToysSetup/Common.wxi b/installer/PowerToysSetup/Common.wxi
index 4a1c93fc8e..6e68ce1986 100644
--- a/installer/PowerToysSetup/Common.wxi
+++ b/installer/PowerToysSetup/Common.wxi
@@ -18,6 +18,7 @@
+
diff --git a/installer/PowerToysSetup/PowerToysInstaller.wixproj b/installer/PowerToysSetup/PowerToysInstaller.wixproj
index 9992d919ae..8fb186ebb6 100644
--- a/installer/PowerToysSetup/PowerToysInstaller.wixproj
+++ b/installer/PowerToysSetup/PowerToysInstaller.wixproj
@@ -1,8 +1,8 @@
-
+
-
Version=$(Version);MonacoSRCHarvestPath=$(ProjectDir)..\..\x64\$(Configuration)\Assets\Monaco\monacoSRC
IF NOT DEFINED IsPipeline (
-call "$([MSBuild]::GetVsInstallRoot())\Common7\Tools\VsDevCmd.bat" -arch=amd64 -host_arch=amd64 -winsdk=10.0.19041.0
+call "$([MSBuild]::GetVsInstallRoot())\Common7\Tools\VsDevCmd.bat" -arch=amd64 -host_arch=amd64 -winsdk=10.0.19041.0 -vcvars_ver=$(VCToolsVersion)
SET PTRoot=$(SolutionDir)\..
call "..\..\..\publish.cmd" x64
)
call powershell.exe -NonInteractive -executionpolicy Unrestricted -File $(MSBuildThisFileDirectory)\generateMonacoWxs.ps1 -monacoWxsFile "$(MSBuildThisFileDirectory)\MonacoSRC.wxs"
-
+
Version=$(Version);MonacoSRCHarvestPath=$(ProjectDir)..\..\ARM64\$(Configuration)\Assets\Monaco\monacoSRC
IF NOT DEFINED IsPipeline (
-call "$([MSBuild]::GetVsInstallRoot())\Common7\Tools\VsDevCmd.bat" -arch=arm64 -host_arch=amd64 -winsdk=10.0.19041.0
+call "$([MSBuild]::GetVsInstallRoot())\Common7\Tools\VsDevCmd.bat" -arch=arm64 -host_arch=amd64 -winsdk=10.0.19041.0 -vcvars_ver=$(VCToolsVersion)
SET PTRoot=$(SolutionDir)\..
call "..\..\..\publish.cmd" arm64
)
call powershell.exe -NonInteractive -executionpolicy Unrestricted -File $(MSBuildThisFileDirectory)\generateMonacoWxs.ps1 -monacoWxsFile "$(MSBuildThisFileDirectory)\MonacoSRC.wxs"
-
+
Always
@@ -68,7 +68,7 @@ call powershell.exe -NonInteractive -executionpolicy Unrestricted -File $(MSBuil
- Release
+ Release
$(Platform)
3.10
022a9d30-7c4f-416d-a9df-5ff2661cc0ad
@@ -104,6 +104,7 @@ call powershell.exe -NonInteractive -executionpolicy Unrestricted -File $(MSBuil
+
@@ -181,18 +182,6 @@ call powershell.exe -NonInteractive -executionpolicy Unrestricted -File $(MSBuil
-->
-
+
-
\ No newline at end of file
diff --git a/installer/PowerToysSetup/Product.wxs b/installer/PowerToysSetup/Product.wxs
index 2dea1fab55..ee15ec090a 100644
--- a/installer/PowerToysSetup/Product.wxs
+++ b/installer/PowerToysSetup/Product.wxs
@@ -72,6 +72,7 @@
+
@@ -133,6 +134,7 @@
+
@@ -159,6 +161,9 @@
Installed AND (REMOVE="ALL")
+
+ Installed AND (NOT UPGRADINGPRODUCTCODE) AND (REMOVE="ALL")
+
Installed AND (NOT UPGRADINGPRODUCTCODE) AND (REMOVE="ALL")
@@ -200,6 +205,10 @@
Property="UnApplyModulesRegistryChangeSets"
Value="[INSTALLFOLDER]" />
+
+
@@ -252,7 +261,15 @@
BinaryKey="PTCustomActions"
DllEntry="UninstallServicesCA"
/>
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/installer/PowerToysSetup/Settings.wxs b/installer/PowerToysSetup/Settings.wxs
index 8306aadf16..a31903d643 100644
--- a/installer/PowerToysSetup/Settings.wxs
+++ b/installer/PowerToysSetup/Settings.wxs
@@ -19,12 +19,14 @@
+
+
@@ -45,6 +47,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -55,7 +70,9 @@
+
+
diff --git a/installer/PowerToysSetup/publish.cmd b/installer/PowerToysSetup/publish.cmd
index 1baf824d1b..18fa40b4aa 100644
--- a/installer/PowerToysSetup/publish.cmd
+++ b/installer/PowerToysSetup/publish.cmd
@@ -4,13 +4,10 @@ IF NOT DEFINED PTRoot (SET PTRoot=..\..)
SET PlatformArg=%1
IF NOT DEFINED PlatformArg (SET PlatformArg=x64)
+SET VCToolsVersion=!VCToolsVersion!
+SET ClearDevCommandPromptEnvVars=false
rem In case of Release we should not use Debug CRT in VCRT forwarders
-msbuild !PTRoot!\src\settings-ui\Settings.UI\PowerToys.Settings.csproj -t:Publish -p:Configuration="Release" -p:Platform="!PlatformArg!" -p:PowerToysRoot=!PTRoot! -p:AppxBundle=Never -p:VCRTForwarders-IncludeDebugCRT=false -p:PublishProfile=InstallationPublishProfile.pubxml
-
-rem In case of Release we should not use Debug CRT in VCRT forwarders
-msbuild !PTRoot!\src\modules\launcher\PowerLauncher\PowerLauncher.csproj -t:Publish -p:Configuration="Release" -p:Platform="!PlatformArg!" -p:AppxBundle=Never -p:PowerToysRoot=!PTRoot! -p:VCRTForwarders-IncludeDebugCRT=false -p:PublishProfile=InstallationPublishProfile.pubxml
-
msbuild !PTRoot!\src\modules\previewpane\MonacoPreviewHandler\MonacoPreviewHandler.csproj -t:Publish -p:Configuration="Release" -p:Platform="!PlatformArg!" -p:AppxBundle=Never -p:PowerToysRoot=!PTRoot! -p:VCRTForwarders-IncludeDebugCRT=false -p:PublishProfile=InstallationPublishProfile.pubxml
msbuild !PTRoot!\src\modules\previewpane\MarkdownPreviewHandler\MarkdownPreviewHandler.csproj -t:Publish -p:Configuration="Release" -p:Platform="!PlatformArg!" -p:AppxBundle=Never -p:PowerToysRoot=!PTRoot! -p:VCRTForwarders-IncludeDebugCRT=false -p:PublishProfile=InstallationPublishProfile.pubxml
@@ -18,5 +15,3 @@ msbuild !PTRoot!\src\modules\previewpane\MarkdownPreviewHandler\MarkdownPreviewH
msbuild !PTRoot!\src\modules\previewpane\SvgPreviewHandler\SvgPreviewHandler.csproj -t:Publish -p:Configuration="Release" -p:Platform="!PlatformArg!" -p:AppxBundle=Never -p:PowerToysRoot=!PTRoot! -p:VCRTForwarders-IncludeDebugCRT=false -p:PublishProfile=InstallationPublishProfile.pubxml
msbuild !PTRoot!\src\modules\previewpane\SvgThumbnailProvider\SvgThumbnailProvider.csproj -t:Publish -p:Configuration="Release" -p:Platform="!PlatformArg!" -p:AppxBundle=Never -p:PowerToysRoot=!PTRoot! -p:VCRTForwarders-IncludeDebugCRT=false -p:PublishProfile=InstallationPublishProfile.pubxml
-
-msbuild !PTRoot!\src\modules\FileLocksmith\FileLocksmithUI\FileLocksmithUI.csproj -t:Publish -p:Configuration="Release" -p:Platform="!PlatformArg!" -p:AppxBundle=Never -p:PowerToysRoot=!PTRoot! -p:VCRTForwarders-IncludeDebugCRT=false -p:PublishProfile=InstallationPublishProfile.pubxml
diff --git a/installer/PowerToysSetupCustomActions/CustomAction.cpp b/installer/PowerToysSetupCustomActions/CustomAction.cpp
index c76e2203f8..290df09898 100644
--- a/installer/PowerToysSetupCustomActions/CustomAction.cpp
+++ b/installer/PowerToysSetupCustomActions/CustomAction.cpp
@@ -433,7 +433,29 @@ UINT __stdcall RemoveWindowsServiceByName(std::wstring serviceName)
return ERROR_SUCCESS;
}
+UINT __stdcall UninstallCommandNotFoundModuleCA(MSIHANDLE hInstall)
+{
+ HRESULT hr = S_OK;
+ UINT er = ERROR_SUCCESS;
+ std::wstring installationFolder;
+ std::string command;
+ hr = WcaInitialize(hInstall, "UninstallCommandNotFoundModule");
+ ExitOnFailure(hr, "Failed to initialize");
+
+ hr = getInstallFolder(hInstall, installationFolder);
+ ExitOnFailure(hr, "Failed to get installFolder.");
+
+ command = "pwsh.exe";
+ command += " ";
+ command += "-NoProfile -NonInteractive -NoLogo -WindowStyle Hidden -ExecutionPolicy Unrestricted -File \"" + winrt::to_string(installationFolder) + "\\WinUI3Apps\\Assets\\Settings\\Scripts\\DisableModule.ps1" + "\"";
+
+ system(command.c_str());
+
+LExit:
+ er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
+ return WcaFinalize(er);
+}
UINT __stdcall UninstallServicesCA(MSIHANDLE hInstall)
{
diff --git a/installer/PowerToysSetupCustomActions/CustomAction.def b/installer/PowerToysSetupCustomActions/CustomAction.def
index 7c3c058d9c..6a503da797 100644
--- a/installer/PowerToysSetupCustomActions/CustomAction.def
+++ b/installer/PowerToysSetupCustomActions/CustomAction.def
@@ -22,4 +22,5 @@ EXPORTS
UninstallVirtualCameraDriverCA
UnRegisterContextMenuPackagesCA
UninstallEmbeddedMSIXCA
- UninstallServicesCA
\ No newline at end of file
+ UninstallServicesCA
+ UninstallCommandNotFoundModuleCA
\ No newline at end of file
diff --git a/src/.editorconfig b/src/.editorconfig
index 8a147c55e3..28245c30fc 100644
--- a/src/.editorconfig
+++ b/src/.editorconfig
@@ -96,4 +96,4 @@ end_of_line = crlf
dotnet_diagnostic.IDE0065.severity = none
# IDE0009: Add this or Me qualification
-dotnet_diagnostic.IDE0009.severity = none
+dotnet_diagnostic.IDE0009.severity = none
\ No newline at end of file
diff --git a/src/Version.props b/src/Version.props
index 6b54dbd99a..2042a73fbd 100644
--- a/src/Version.props
+++ b/src/Version.props
@@ -3,5 +3,8 @@
0.0.1
Local
+
+
+ SHA256
diff --git a/src/common/AllExperiments/AllExperiments.csproj b/src/common/AllExperiments/AllExperiments.csproj
index 65ca2c95b6..875d8b5d82 100644
--- a/src/common/AllExperiments/AllExperiments.csproj
+++ b/src/common/AllExperiments/AllExperiments.csproj
@@ -1,7 +1,7 @@
- net7.0-windows10.0.20348.0
+ net8.0-windows10.0.20348.0
10.0.19041.0
10.0.19041.0
enable
diff --git a/src/common/AllExperiments/Experiments.cs b/src/common/AllExperiments/Experiments.cs
index 38ac694637..2fdcaa0482 100644
--- a/src/common/AllExperiments/Experiments.cs
+++ b/src/common/AllExperiments/Experiments.cs
@@ -76,9 +76,10 @@ namespace AllExperiments
if (jsonDictionary != null)
{
- if (!jsonDictionary.ContainsKey("dataversion"))
+ if (!jsonDictionary.TryGetValue("dataversion", out object? value))
{
- jsonDictionary.Add("dataversion", dataVersion);
+ value = dataVersion;
+ jsonDictionary.Add("dataversion", value);
}
if (!jsonDictionary.ContainsKey("variantassignment"))
@@ -87,7 +88,7 @@ namespace AllExperiments
}
else
{
- var jsonDataVersion = jsonDictionary["dataversion"].ToString();
+ var jsonDataVersion = value.ToString();
if (jsonDataVersion != null && int.Parse(jsonDataVersion, CultureInfo.InvariantCulture) < dataVersion)
{
jsonDictionary["dataversion"] = dataVersion;
@@ -116,9 +117,9 @@ namespace AllExperiments
if (jsonDictionary != null)
{
- if (jsonDictionary.ContainsKey("variantassignment"))
+ if (jsonDictionary.TryGetValue("variantassignment", out object? value))
{
- if (jsonDictionary["variantassignment"].ToString() == "alternate" && AssignmentUnit != string.Empty)
+ if (value.ToString() == "alternate" && AssignmentUnit != string.Empty)
{
IsExperiment = true;
}
@@ -144,7 +145,7 @@ namespace AllExperiments
private string? AssignmentUnit { get; set; }
- private IVariantAssignmentRequest GetVariantAssignmentRequest()
+ private VariantAssignmentRequest GetVariantAssignmentRequest()
{
var jsonFilePath = CreateFilePath();
try
diff --git a/src/common/Common.UI/Common.UI.csproj b/src/common/Common.UI/Common.UI.csproj
index a4475f640c..102fc3ebbc 100644
--- a/src/common/Common.UI/Common.UI.csproj
+++ b/src/common/Common.UI/Common.UI.csproj
@@ -2,7 +2,7 @@
- net7.0-windows
+ net8.0-windows
win-x64;win-arm64
true
PowerToys.Common.UI
diff --git a/src/common/FilePreviewCommon/FilePreviewCommon.csproj b/src/common/FilePreviewCommon/FilePreviewCommon.csproj
index b0e64db6f6..da6b7bdbdb 100644
--- a/src/common/FilePreviewCommon/FilePreviewCommon.csproj
+++ b/src/common/FilePreviewCommon/FilePreviewCommon.csproj
@@ -3,13 +3,16 @@
- net7.0-windows
- win-x64;win-arm64
+ net8.0-windows
+ win-x64;win-arm64
$(Version).0
Microsoft Corporation
PowerToys
PowerToys FilePreviewCommon
PowerToys.FilePreviewCommon
+ true
+ true
+ enable
@@ -32,7 +35,7 @@
Always
- Always
+ Always
Always
diff --git a/src/common/FilePreviewCommon/Formatters/JsonFormatter.cs b/src/common/FilePreviewCommon/Formatters/JsonFormatter.cs
index 4f366fbff8..91b7013c6f 100644
--- a/src/common/FilePreviewCommon/Formatters/JsonFormatter.cs
+++ b/src/common/FilePreviewCommon/Formatters/JsonFormatter.cs
@@ -12,6 +12,12 @@ namespace Microsoft.PowerToys.FilePreviewCommon.Monaco.Formatters
///
public string LangSet => "json";
+ private static readonly JsonSerializerOptions _serializerOptions = new JsonSerializerOptions
+ {
+ WriteIndented = true,
+ Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
+ };
+
///
public string Format(string value)
{
@@ -22,11 +28,7 @@ namespace Microsoft.PowerToys.FilePreviewCommon.Monaco.Formatters
using (var jDocument = JsonDocument.Parse(value, new JsonDocumentOptions { CommentHandling = JsonCommentHandling.Skip }))
{
- return JsonSerializer.Serialize(jDocument, new JsonSerializerOptions
- {
- WriteIndented = true,
- Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
- });
+ return JsonSerializer.Serialize(jDocument, _serializerOptions);
}
}
}
diff --git a/src/common/FilePreviewCommon/Formatters/XmlFormatter.cs b/src/common/FilePreviewCommon/Formatters/XmlFormatter.cs
index b282c802ae..450e92a5b3 100644
--- a/src/common/FilePreviewCommon/Formatters/XmlFormatter.cs
+++ b/src/common/FilePreviewCommon/Formatters/XmlFormatter.cs
@@ -26,7 +26,7 @@ namespace Microsoft.PowerToys.FilePreviewCommon.Monaco.Formatters
var stringBuilder = new StringBuilder();
var xmlWriterSettings = new XmlWriterSettings()
{
- OmitXmlDeclaration = xmlDocument.FirstChild.NodeType != XmlNodeType.XmlDeclaration,
+ OmitXmlDeclaration = xmlDocument.FirstChild?.NodeType != XmlNodeType.XmlDeclaration,
Indent = true,
};
diff --git a/src/modules/previewpane/common/Utilities/GcodeHelper.cs b/src/common/FilePreviewCommon/GcodeHelper.cs
similarity index 98%
rename from src/modules/previewpane/common/Utilities/GcodeHelper.cs
rename to src/common/FilePreviewCommon/GcodeHelper.cs
index f614a099e4..62dc29554e 100644
--- a/src/modules/previewpane/common/Utilities/GcodeHelper.cs
+++ b/src/common/FilePreviewCommon/GcodeHelper.cs
@@ -8,7 +8,7 @@ using System.IO;
using System.Linq;
using System.Text;
-namespace Common.Utilities
+namespace Microsoft.PowerToys.FilePreviewCommon
{
///
/// Gcode file helper class.
diff --git a/src/modules/previewpane/common/Utilities/GcodeThumbnail.cs b/src/common/FilePreviewCommon/GcodeThumbnail.cs
similarity index 97%
rename from src/modules/previewpane/common/Utilities/GcodeThumbnail.cs
rename to src/common/FilePreviewCommon/GcodeThumbnail.cs
index 7715c3f53f..545d7aa04a 100644
--- a/src/modules/previewpane/common/Utilities/GcodeThumbnail.cs
+++ b/src/common/FilePreviewCommon/GcodeThumbnail.cs
@@ -5,9 +5,8 @@
using System;
using System.Drawing;
using System.IO;
-using PreviewHandlerCommon.Utilities;
-namespace Common.Utilities
+namespace Microsoft.PowerToys.FilePreviewCommon
{
///
/// Represents a gcode thumbnail.
diff --git a/src/modules/previewpane/common/Utilities/GcodeThumbnailFormat.cs b/src/common/FilePreviewCommon/GcodeThumbnailFormat.cs
similarity index 93%
rename from src/modules/previewpane/common/Utilities/GcodeThumbnailFormat.cs
rename to src/common/FilePreviewCommon/GcodeThumbnailFormat.cs
index bb4d84e0bc..1e471ed8c5 100644
--- a/src/modules/previewpane/common/Utilities/GcodeThumbnailFormat.cs
+++ b/src/common/FilePreviewCommon/GcodeThumbnailFormat.cs
@@ -2,7 +2,7 @@
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-namespace Common.Utilities
+namespace Microsoft.PowerToys.FilePreviewCommon
{
///
/// The gcode thumbnail image format.
diff --git a/src/common/FilePreviewCommon/MarkdownHelper.cs b/src/common/FilePreviewCommon/MarkdownHelper.cs
index 31013419ed..bb8a98440e 100644
--- a/src/common/FilePreviewCommon/MarkdownHelper.cs
+++ b/src/common/FilePreviewCommon/MarkdownHelper.cs
@@ -30,7 +30,7 @@ namespace Microsoft.PowerToys.FilePreviewCommon
// Extension to modify markdown AST.
HTMLParsingExtension extension = new HTMLParsingExtension(imagesBlockedCallBack);
- extension.FilePath = Path.GetDirectoryName(filePath);
+ extension.FilePath = Path.GetDirectoryName(filePath) ?? string.Empty;
// if you have a string with double space, some people view it as a new line.
// while this is against spec, even GH supports this. Technically looks like GH just trims whitespace
diff --git a/src/common/FilePreviewCommon/MonacoHelper.cs b/src/common/FilePreviewCommon/MonacoHelper.cs
index eac3826426..54b0ac93af 100644
--- a/src/common/FilePreviewCommon/MonacoHelper.cs
+++ b/src/common/FilePreviewCommon/MonacoHelper.cs
@@ -28,12 +28,12 @@ namespace Microsoft.PowerToys.FilePreviewCommon
new XmlFormatter(),
}.AsReadOnly();
- private static string _monacoDirectory;
+ private static string? _monacoDirectory;
public static string GetRuntimeMonacoDirectory()
{
string codeBase = Assembly.GetExecutingAssembly().Location;
- string path = Path.GetFullPath(Path.Combine(Path.GetDirectoryName(codeBase), "Assets", "Monaco"));
+ string path = Path.GetFullPath(Path.Combine(Path.GetDirectoryName(codeBase) ?? string.Empty, "Assets", "Monaco"));
if (Path.Exists(path))
{
return path;
@@ -41,7 +41,7 @@ namespace Microsoft.PowerToys.FilePreviewCommon
else
{
// We're likely in WinUI3Apps directory and need to go back to the base directory.
- return Path.GetFullPath(Path.Combine(Path.GetDirectoryName(codeBase), "..", "Assets", "Monaco"));
+ return Path.GetFullPath(Path.Combine(Path.GetDirectoryName(codeBase) ?? string.Empty, "..", "Assets", "Monaco"));
}
}
diff --git a/src/common/FilePreviewCommon/QoiImage.cs b/src/common/FilePreviewCommon/QoiImage.cs
new file mode 100644
index 0000000000..ac315eb832
--- /dev/null
+++ b/src/common/FilePreviewCommon/QoiImage.cs
@@ -0,0 +1,177 @@
+// 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.Buffers.Binary;
+using System.Drawing;
+using System.Drawing.Imaging;
+using System.IO;
+using System.Text;
+
+//// Based on https://github.com/phoboslab/qoi/blob/master/qoi.h
+
+namespace Microsoft.PowerToys.FilePreviewCommon
+{
+ ///
+ /// QOI Image helper.
+ ///
+ public static class QoiImage
+ {
+#pragma warning disable SA1310 // Field names should not contain underscore
+ private const byte QOI_OP_INDEX = 0x00; // 00xxxxxx
+ private const byte QOI_OP_DIFF = 0x40; // 01xxxxxx
+ private const byte QOI_OP_LUMA = 0x80; // 10xxxxxx
+ private const byte QOI_OP_RUN = 0xc0; // 11xxxxxx
+ private const byte QOI_OP_RGB = 0xfe; // 11111110
+ private const byte QOI_OP_RGBA = 0xff; // 11111111
+
+ private const byte QOI_MASK_2 = 0xc0; // 11000000
+
+ private const int QOI_MAGIC = 'q' << 24 | 'o' << 16 | 'i' << 8 | 'f';
+ private const int QOI_HEADER_SIZE = 14;
+
+ private const uint QOI_PIXELS_MAX = 400000000;
+
+ private const byte QOI_PADDING_LENGTH = 8;
+#pragma warning restore SA1310 // Field names should not contain underscore
+
+ private record struct QoiPixel(byte R, byte G, byte B, byte A)
+ {
+ public readonly int GetColorHash() => (R * 3) + (G * 5) + (B * 7) + (A * 11);
+ }
+
+ ///
+ /// Creates a from the specified QOI data stream.
+ ///
+ /// A that contains the QOI data.
+ /// The this method creates.
+ /// The stream does not have a valid QOI image format.
+ public static Bitmap FromStream(Stream stream)
+ {
+ var fileSize = stream.Length;
+
+ if (fileSize < QOI_HEADER_SIZE + QOI_PADDING_LENGTH)
+ {
+ throw new ArgumentException("Not enough data for a QOI file");
+ }
+
+ Bitmap? bitmap = null;
+
+ try
+ {
+ using var reader = new BinaryReader(stream, Encoding.UTF8, true);
+
+ var headerMagic = ReadUInt32BigEndian(reader);
+
+ if (headerMagic != QOI_MAGIC)
+ {
+ throw new ArgumentException("Invalid QOI file header");
+ }
+
+ var width = ReadUInt32BigEndian(reader);
+ var height = ReadUInt32BigEndian(reader);
+ var channels = reader.ReadByte();
+ var colorSpace = reader.ReadByte();
+
+ if (width == 0 || height == 0 || channels < 3 || channels > 4 || colorSpace > 1 || height >= QOI_PIXELS_MAX / width)
+ {
+ throw new ArgumentException("Invalid QOI file data");
+ }
+
+ var pixelFormat = channels == 4 ? PixelFormat.Format32bppArgb : PixelFormat.Format24bppRgb;
+
+ bitmap = new Bitmap((int)width, (int)height, pixelFormat);
+
+ var bitmapData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.WriteOnly, pixelFormat);
+ var dataLength = bitmapData.Height * bitmapData.Stride;
+
+ var index = new QoiPixel[64];
+ var pixel = new QoiPixel(0, 0, 0, 255);
+
+ var run = 0;
+ var chunksLen = fileSize - QOI_PADDING_LENGTH;
+
+ for (var dataIndex = 0; dataIndex < dataLength; dataIndex += channels)
+ {
+ if (run > 0)
+ {
+ run--;
+ }
+ else if (stream.Position < chunksLen)
+ {
+ var b1 = reader.ReadByte();
+
+ if (b1 == QOI_OP_RGB)
+ {
+ pixel.R = reader.ReadByte();
+ pixel.G = reader.ReadByte();
+ pixel.B = reader.ReadByte();
+ }
+ else if (b1 == QOI_OP_RGBA)
+ {
+ pixel.R = reader.ReadByte();
+ pixel.G = reader.ReadByte();
+ pixel.B = reader.ReadByte();
+ pixel.A = reader.ReadByte();
+ }
+ else if ((b1 & QOI_MASK_2) == QOI_OP_INDEX)
+ {
+ pixel = index[b1];
+ }
+ else if ((b1 & QOI_MASK_2) == QOI_OP_DIFF)
+ {
+ pixel.R += (byte)(((b1 >> 4) & 0x03) - 2);
+ pixel.G += (byte)(((b1 >> 2) & 0x03) - 2);
+ pixel.B += (byte)((b1 & 0x03) - 2);
+ }
+ else if ((b1 & QOI_MASK_2) == QOI_OP_LUMA)
+ {
+ var b2 = reader.ReadByte();
+ var vg = (b1 & 0x3f) - 32;
+ pixel.R += (byte)(vg - 8 + ((b2 >> 4) & 0x0f));
+ pixel.G += (byte)vg;
+ pixel.B += (byte)(vg - 8 + (b2 & 0x0f));
+ }
+ else if ((b1 & QOI_MASK_2) == QOI_OP_RUN)
+ {
+ run = b1 & 0x3f;
+ }
+
+ index[pixel.GetColorHash() % 64] = pixel;
+ }
+
+ unsafe
+ {
+ var bitmapPixel = (byte*)bitmapData.Scan0 + dataIndex;
+
+ bitmapPixel[0] = pixel.B;
+ bitmapPixel[1] = pixel.G;
+ bitmapPixel[2] = pixel.R;
+ if (channels == 4)
+ {
+ bitmapPixel[3] = pixel.A;
+ }
+ }
+ }
+
+ bitmap.UnlockBits(bitmapData);
+
+ return bitmap;
+ }
+ catch
+ {
+ bitmap?.Dispose();
+
+ throw;
+ }
+ }
+
+ private static uint ReadUInt32BigEndian(BinaryReader reader)
+ {
+ var buffer = reader.ReadBytes(4);
+
+ return BinaryPrimitives.ReadUInt32BigEndian(buffer);
+ }
+ }
+}
diff --git a/src/common/GPOWrapper/GPOWrapper.cpp b/src/common/GPOWrapper/GPOWrapper.cpp
index 77d81e8516..c3177d60db 100644
--- a/src/common/GPOWrapper/GPOWrapper.cpp
+++ b/src/common/GPOWrapper/GPOWrapper.cpp
@@ -12,6 +12,10 @@ namespace winrt::PowerToys::GPOWrapper::implementation
{
return static_cast(powertoys_gpo::getConfiguredAwakeEnabledValue());
}
+ GpoRuleConfigured GPOWrapper::GetConfiguredCmdNotFoundEnabledValue()
+ {
+ return static_cast(powertoys_gpo::getConfiguredCmdNotFoundEnabledValue());
+ }
GpoRuleConfigured GPOWrapper::GetConfiguredColorPickerEnabledValue()
{
return static_cast(powertoys_gpo::getConfiguredColorPickerEnabledValue());
diff --git a/src/common/GPOWrapper/GPOWrapper.h b/src/common/GPOWrapper/GPOWrapper.h
index c29fac95b6..bd153ed258 100644
--- a/src/common/GPOWrapper/GPOWrapper.h
+++ b/src/common/GPOWrapper/GPOWrapper.h
@@ -9,6 +9,7 @@ namespace winrt::PowerToys::GPOWrapper::implementation
GPOWrapper() = default;
static GpoRuleConfigured GetConfiguredAlwaysOnTopEnabledValue();
static GpoRuleConfigured GetConfiguredAwakeEnabledValue();
+ static GpoRuleConfigured GetConfiguredCmdNotFoundEnabledValue();
static GpoRuleConfigured GetConfiguredColorPickerEnabledValue();
static GpoRuleConfigured GetConfiguredCropAndLockEnabledValue();
static GpoRuleConfigured GetConfiguredFancyZonesEnabledValue();
diff --git a/src/common/GPOWrapper/GPOWrapper.idl b/src/common/GPOWrapper/GPOWrapper.idl
index d0e3ebbd4f..3b4c0eca28 100644
--- a/src/common/GPOWrapper/GPOWrapper.idl
+++ b/src/common/GPOWrapper/GPOWrapper.idl
@@ -13,6 +13,7 @@ namespace PowerToys
[default_interface] static runtimeclass GPOWrapper {
static GpoRuleConfigured GetConfiguredAlwaysOnTopEnabledValue();
static GpoRuleConfigured GetConfiguredAwakeEnabledValue();
+ static GpoRuleConfigured GetConfiguredCmdNotFoundEnabledValue();
static GpoRuleConfigured GetConfiguredColorPickerEnabledValue();
static GpoRuleConfigured GetConfiguredCropAndLockEnabledValue();
static GpoRuleConfigured GetConfiguredFancyZonesEnabledValue();
diff --git a/src/common/GPOWrapperProjection/GPOWrapper.cs b/src/common/GPOWrapperProjection/GPOWrapper.cs
index 92196323e5..5e1ef14748 100644
--- a/src/common/GPOWrapperProjection/GPOWrapper.cs
+++ b/src/common/GPOWrapperProjection/GPOWrapper.cs
@@ -27,6 +27,11 @@ namespace PowerToys.GPOWrapperProjection
return (GpoRuleConfigured)PowerToys.GPOWrapper.GPOWrapper.GetConfiguredFancyZonesEnabledValue();
}
+ public static GpoRuleConfigured GetConfiguredCmdNotFoundEnabledValue()
+ {
+ return (GpoRuleConfigured)PowerToys.GPOWrapper.GPOWrapper.GetConfiguredCmdNotFoundEnabledValue();
+ }
+
public static GpoRuleConfigured GetConfiguredColorPickerEnabledValue()
{
return (GpoRuleConfigured)PowerToys.GPOWrapper.GPOWrapper.GetConfiguredColorPickerEnabledValue();
diff --git a/src/common/GPOWrapperProjection/GPOWrapperProjection.csproj b/src/common/GPOWrapperProjection/GPOWrapperProjection.csproj
index 3fd2a3d1b9..5e16a1bae8 100644
--- a/src/common/GPOWrapperProjection/GPOWrapperProjection.csproj
+++ b/src/common/GPOWrapperProjection/GPOWrapperProjection.csproj
@@ -1,7 +1,7 @@
- net7.0-windows10.0.20348.0
+ net8.0-windows10.0.20348.0
10.0.19041.0
10.0.19041.0
enable
diff --git a/src/common/ManagedCommon/ColorFormatHelper.cs b/src/common/ManagedCommon/ColorFormatHelper.cs
index 8c40ea4978..08e62b921d 100644
--- a/src/common/ManagedCommon/ColorFormatHelper.cs
+++ b/src/common/ManagedCommon/ColorFormatHelper.cs
@@ -328,13 +328,13 @@ namespace ManagedCommon
char paramFormat;
string paramType = formatString.Substring(formatterPosition + 1, 2);
int paramCount = 3;
- if (DefaultFormatTypes.ContainsKey(paramType))
+ if (DefaultFormatTypes.TryGetValue(paramType, out char value))
{
// check the next char, which could be a formatter
if (formatterPosition >= formatString.Length - 3)
{
// not enough characters, end of string, no formatter, use the default one
- paramFormat = DefaultFormatTypes[paramType];
+ paramFormat = value;
paramCount = 2;
}
else
@@ -344,7 +344,7 @@ namespace ManagedCommon
// check if it a valid formatter
if (!FormatTypeToStringFormatters.ContainsKey(paramFormat))
{
- paramFormat = DefaultFormatTypes[paramType];
+ paramFormat = value;
paramCount = 2;
}
}
diff --git a/src/common/ManagedCommon/ManagedCommon.csproj b/src/common/ManagedCommon/ManagedCommon.csproj
index 05f9bd34e1..dbe6eca3f7 100644
--- a/src/common/ManagedCommon/ManagedCommon.csproj
+++ b/src/common/ManagedCommon/ManagedCommon.csproj
@@ -3,8 +3,8 @@
- net7.0-windows
- win-x64;win-arm64
+ net8.0-windows
+ win-x64;win-arm64
$(Version).0
Microsoft Corporation
PowerToys
diff --git a/src/common/ManagedCommon/ModuleType.cs b/src/common/ManagedCommon/ModuleType.cs
index 3a489711b0..0bbfaeeda3 100644
--- a/src/common/ManagedCommon/ModuleType.cs
+++ b/src/common/ManagedCommon/ModuleType.cs
@@ -9,6 +9,7 @@ namespace ManagedCommon
AlwaysOnTop,
Awake,
ColorPicker,
+ CmdNotFound,
CropAndLock,
EnvironmentVariables,
FancyZones,
diff --git a/src/common/ManagedTelemetry/Telemetry/ManagedTelemetry.csproj b/src/common/ManagedTelemetry/Telemetry/ManagedTelemetry.csproj
index 72dfa4fafd..19e1b0015c 100644
--- a/src/common/ManagedTelemetry/Telemetry/ManagedTelemetry.csproj
+++ b/src/common/ManagedTelemetry/Telemetry/ManagedTelemetry.csproj
@@ -2,7 +2,7 @@
- net7.0-windows
+ net8.0-windows
win-x64;win-arm64
$(Version).0
Microsoft Corporation
diff --git a/src/common/interop/PowerToys.Interop.vcxproj b/src/common/interop/PowerToys.Interop.vcxproj
index 5469432cd0..3f792f85ce 100644
--- a/src/common/interop/PowerToys.Interop.vcxproj
+++ b/src/common/interop/PowerToys.Interop.vcxproj
@@ -25,7 +25,7 @@
16.0
{F055103B-F80B-4D0C-BF48-057C55620033}
- net7.0-windows
+ net8.0-windows
ManagedCProj
PowerToysInterop
PowerToys.Interop
diff --git a/src/common/interop/interop-tests/Microsoft.Interop.Tests.csproj b/src/common/interop/interop-tests/Microsoft.Interop.Tests.csproj
index a89ba3f7ec..1847d53075 100644
--- a/src/common/interop/interop-tests/Microsoft.Interop.Tests.csproj
+++ b/src/common/interop/interop-tests/Microsoft.Interop.Tests.csproj
@@ -2,7 +2,7 @@
- net7.0-windows
+ net8.0-windows
false
win-x64;win-arm64
diff --git a/src/common/logger/logger_settings.h b/src/common/logger/logger_settings.h
index 91dd5faae8..cc1b3825ce 100644
--- a/src/common/logger/logger_settings.h
+++ b/src/common/logger/logger_settings.h
@@ -67,6 +67,8 @@ struct LogSettings
inline const static std::string cropAndLockLoggerName = "crop-and-lock";
inline const static std::wstring registryPreviewLogPath = L"Logs\\registryPreview-log.txt";
inline const static std::string environmentVariablesLoggerName = "environment-variables";
+ inline const static std::wstring cmdNotFoundLogPath = L"Logs\\cmd-not-found-log.txt";
+ inline const static std::string cmdNotFoundLoggerName = "cmd-not-found";
inline const static int retention = 30;
std::wstring logLevel;
LogSettings();
diff --git a/src/common/notifications/NotificationUtil.h b/src/common/notifications/NotificationUtil.h
new file mode 100644
index 0000000000..8fcf3d91d8
--- /dev/null
+++ b/src/common/notifications/NotificationUtil.h
@@ -0,0 +1,40 @@
+#pragma once
+
+#include
+#include
+#include
+#include
+
+#include "Generated Files/resource.h"
+
+namespace notifications
+{
+ // Non-Localizable strings
+ namespace NonLocalizable
+ {
+ const wchar_t RunAsAdminInfoPage[] = L"https://aka.ms/powertoysDetectedElevatedHelp";
+ const wchar_t ToastNotificationButtonUrl[] = L"powertoys://cant_drag_elevated_disable/";
+ }
+
+ inline void WarnIfElevationIsRequired(std::wstring title, std::wstring message, std::wstring button1, std::wstring button2)
+ {
+ using namespace NonLocalizable;
+
+ auto settings = PTSettingsHelper::load_general_settings();
+ auto enableWarningsElevatedApps = settings.GetNamedBoolean(L"enable_warnings_elevated_apps", true);
+
+ static bool warning_shown = false;
+ if (enableWarningsElevatedApps && !warning_shown && !is_toast_disabled(ElevatedDontShowAgainRegistryPath, ElevatedDisableIntervalInDays))
+ {
+ std::vector actions = {
+ link_button{ button1, RunAsAdminInfoPage },
+ link_button{ button2, ToastNotificationButtonUrl }
+ };
+ show_toast_with_activations(message,
+ title,
+ {},
+ std::move(actions));
+ warning_shown = true;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/common/notifications/dont_show_again.h b/src/common/notifications/dont_show_again.h
index 98657b1e7e..f1cdd0f322 100644
--- a/src/common/notifications/dont_show_again.h
+++ b/src/common/notifications/dont_show_again.h
@@ -4,8 +4,8 @@
namespace notifications
{
- const inline wchar_t CantDragElevatedDontShowAgainRegistryPath[] = LR"(SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\DontShowMeThisDialogAgain\{e16ea82f-6d94-4f30-bb02-d6d911588afd})";
- const inline int64_t CantDragElevatedDisableIntervalInDays = 30;
+ const inline wchar_t ElevatedDontShowAgainRegistryPath[] = LR"(SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\DontShowMeThisDialogAgain\{e16ea82f-6d94-4f30-bb02-d6d911588afd})";
+ const inline int64_t ElevatedDisableIntervalInDays = 30;
const inline wchar_t PreviewModulesDontShowAgainRegistryPath[] = LR"(SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\DontShowMeThisDialogAgain\{7e29e2b2-b31c-4dcd-b7b0-79c078b02430})";
const inline int64_t PreviewModulesDisableIntervalInDays = 30;
diff --git a/src/common/notifications/notifications.vcxproj b/src/common/notifications/notifications.vcxproj
index c667523188..ed998e2511 100644
--- a/src/common/notifications/notifications.vcxproj
+++ b/src/common/notifications/notifications.vcxproj
@@ -27,6 +27,7 @@
+
diff --git a/src/common/utils/elevation.h b/src/common/utils/elevation.h
index 177a4b24e2..62ab1c75d5 100644
--- a/src/common/utils/elevation.h
+++ b/src/common/utils/elevation.h
@@ -494,3 +494,30 @@ inline bool check_user_is_admin()
freeMemory(pSID, pGroupInfo);
return false;
}
+
+inline bool IsProcessOfWindowElevated(HWND window)
+{
+ DWORD pid = 0;
+ GetWindowThreadProcessId(window, &pid);
+ if (!pid)
+ {
+ return false;
+ }
+
+ wil::unique_handle hProcess{ OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION,
+ FALSE,
+ pid) };
+
+ wil::unique_handle token;
+
+ if (OpenProcessToken(hProcess.get(), TOKEN_QUERY, &token))
+ {
+ TOKEN_ELEVATION elevation;
+ DWORD size;
+ if (GetTokenInformation(token.get(), TokenElevation, &elevation, sizeof(elevation), &size))
+ {
+ return elevation.TokenIsElevated != 0;
+ }
+ }
+ return false;
+}
diff --git a/src/common/utils/excluded_apps.h b/src/common/utils/excluded_apps.h
index bbfdd93562..fed45a8b83 100644
--- a/src/common/utils/excluded_apps.h
+++ b/src/common/utils/excluded_apps.h
@@ -32,7 +32,7 @@ inline bool find_folder_in_path(const std::wstring& where, const std::vector& excludedApps)
+inline bool check_excluded_app_with_title(const HWND& hwnd, const std::vector& excludedApps)
{
WCHAR title[MAX_TITLE_LENGTH];
int len = GetWindowTextW(hwnd, title, MAX_TITLE_LENGTH);
@@ -42,23 +42,25 @@ inline bool check_excluded_app_with_title(const HWND& hwnd, std::wstring& proces
}
std::wstring titleStr(title);
- auto lastBackslashPos = processPath.find_last_of(L'\\');
- if (lastBackslashPos != std::wstring::npos)
+ CharUpperBuffW(titleStr.data(), static_cast(titleStr.length()));
+
+ for (const auto& app : excludedApps)
{
- processPath = processPath.substr(0, lastBackslashPos + 1); // retain up to the last backslash
- processPath.append(titleStr); // append the title
+ if (titleStr.contains(app))
+ {
+ return true;
+ }
}
- CharUpperBuffW(processPath.data(), static_cast(processPath.length()));
- return find_app_name_in_path(processPath, excludedApps);
+ return false;
}
-inline bool check_excluded_app(const HWND& hwnd, std::wstring& processPath, const std::vector& excludedApps)
+inline bool check_excluded_app(const HWND& hwnd, const std::wstring& processPath, const std::vector& excludedApps)
{
bool res = find_app_name_in_path(processPath, excludedApps);
if (!res)
{
- res = check_excluded_app_with_title(hwnd, processPath, excludedApps);
+ res = check_excluded_app_with_title(hwnd, excludedApps);
}
return res;
diff --git a/src/common/utils/gpo.h b/src/common/utils/gpo.h
index be88e0d22d..016bd744cc 100644
--- a/src/common/utils/gpo.h
+++ b/src/common/utils/gpo.h
@@ -24,6 +24,7 @@ namespace powertoys_gpo {
const std::wstring POLICY_CONFIGURE_ENABLED_GLOBAL_ALL_UTILITIES = L"ConfigureGlobalUtilityEnabledState";
const std::wstring POLICY_CONFIGURE_ENABLED_ALWAYS_ON_TOP = L"ConfigureEnabledUtilityAlwaysOnTop";
const std::wstring POLICY_CONFIGURE_ENABLED_AWAKE = L"ConfigureEnabledUtilityAwake";
+ const std::wstring POLICY_CONFIGURE_ENABLED_CMD_NOT_FOUND = L"ConfigureEnabledUtilityCmdNotFound";
const std::wstring POLICY_CONFIGURE_ENABLED_COLOR_PICKER = L"ConfigureEnabledUtilityColorPicker";
const std::wstring POLICY_CONFIGURE_ENABLED_CROP_AND_LOCK = L"ConfigureEnabledUtilityCropAndLock";
const std::wstring POLICY_CONFIGURE_ENABLED_FANCYZONES = L"ConfigureEnabledUtilityFancyZones";
@@ -224,6 +225,11 @@ namespace powertoys_gpo {
return getUtilityEnabledValue(POLICY_CONFIGURE_ENABLED_AWAKE);
}
+ inline gpo_rule_configured_t getConfiguredCmdNotFoundEnabledValue()
+ {
+ return getUtilityEnabledValue(POLICY_CONFIGURE_ENABLED_CMD_NOT_FOUND);
+ }
+
inline gpo_rule_configured_t getConfiguredColorPickerEnabledValue()
{
return getUtilityEnabledValue(POLICY_CONFIGURE_ENABLED_COLOR_PICKER);
diff --git a/src/common/utils/window.h b/src/common/utils/window.h
index cfcf20534a..dbce3a95ee 100644
--- a/src/common/utils/window.h
+++ b/src/common/utils/window.h
@@ -6,9 +6,13 @@
#include
#include
+#include
+#include
// Initializes and runs windows message loop
-inline int run_message_loop(const bool until_idle = false, const std::optional timeout_ms = {})
+inline int run_message_loop(const bool until_idle = false,
+ const std::optional timeout_ms = {},
+ std::unordered_map> wm_app_msg_callbacks = {})
{
MSG msg{};
bool stop = false;
@@ -24,11 +28,16 @@ inline int run_message_loop(const bool until_idle = false, const std::optionalsecond();
}
+
if (timeout_ms.has_value())
{
KillTimer(nullptr, timerId);
}
+
return static_cast(msg.wParam);
}
@@ -60,7 +69,7 @@ template
inline T GetWindowCreateParam(LPARAM lparam)
{
static_assert(sizeof(T) <= sizeof(void*));
- T data{ static_cast (reinterpret_cast(lparam)->lpCreateParams) };
+ T data{ static_cast(reinterpret_cast(lparam)->lpCreateParams) };
return data;
}
@@ -74,5 +83,5 @@ inline void StoreWindowParam(HWND window, T data)
template
inline T GetWindowParam(HWND window)
{
- return reinterpret_cast (GetWindowLongPtrW(window, GWLP_USERDATA));
+ return reinterpret_cast(GetWindowLongPtrW(window, GWLP_USERDATA));
}
diff --git a/src/common/version/version.h b/src/common/version/version.h
index 8c3ffd302d..b300619565 100644
--- a/src/common/version/version.h
+++ b/src/common/version/version.h
@@ -13,7 +13,7 @@
#define PRODUCT_VERSION_STRING FILE_VERSION_STRING
#define COMPANY_NAME "Microsoft Corporation"
-#define COPYRIGHT_NOTE "Copyright (C) 2023 Microsoft Corporation"
+#define COPYRIGHT_NOTE "Copyright (C) 2024 Microsoft Corporation"
#define PRODUCT_NAME "PowerToys"
#include
diff --git a/src/gpo/assets/PowerToys.admx b/src/gpo/assets/PowerToys.admx
index 0b135f665e..42ebfe3349 100644
--- a/src/gpo/assets/PowerToys.admx
+++ b/src/gpo/assets/PowerToys.admx
@@ -1,11 +1,11 @@
-
+
-
+
@@ -15,6 +15,7 @@
+
@@ -59,6 +60,16 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/src/gpo/assets/en-US/PowerToys.adml b/src/gpo/assets/en-US/PowerToys.adml
index de04d77c8b..2eb3c700b3 100644
--- a/src/gpo/assets/en-US/PowerToys.adml
+++ b/src/gpo/assets/en-US/PowerToys.adml
@@ -1,7 +1,7 @@
-
+
PowerToys
PowerToys
@@ -17,6 +17,7 @@
PowerToys version 0.73.0 or later
PowerToys version 0.75.0 or later
PowerToys version 0.76.0 or later
+ PowerToys version 0.77.0 or later
This policy configures the enabled state for all PowerToys utilities.
@@ -112,6 +113,7 @@ Note: Changes require a restart of PowerToys Run.
Always On Top: Configure enabled state
Awake: Configure enabled state
Color Picker: Configure enabled state
+ Command Not Found: Configure enabled state
Crop And Lock: Configure enabled state
Environment Variables: Configure enabled state
FancyZones: Configure enabled state
diff --git a/src/modules/EnvironmentVariables/EnvironmentVariables/EnvironmentVariables.csproj b/src/modules/EnvironmentVariables/EnvironmentVariables/EnvironmentVariables.csproj
index 8d10c65e2c..4d544d3b65 100644
--- a/src/modules/EnvironmentVariables/EnvironmentVariables/EnvironmentVariables.csproj
+++ b/src/modules/EnvironmentVariables/EnvironmentVariables/EnvironmentVariables.csproj
@@ -3,12 +3,12 @@
WinExe
- net7.0-windows10.0.20348.0
+ net8.0-windows10.0.20348.0
10.0.19041.0
10.0.19041.0
EnvironmentVariables
app.manifest
- win10-x64;win10-arm64
+ win-x64;win-arm64
true
true
true
@@ -34,10 +34,10 @@
- win10-x64
+ win-x64
- win10-arm64
+ win-arm64
diff --git a/src/modules/EnvironmentVariables/EnvironmentVariables/EnvironmentVariablesXAML/MainWindow.xaml.cs b/src/modules/EnvironmentVariables/EnvironmentVariables/EnvironmentVariablesXAML/MainWindow.xaml.cs
index ec24920054..4ab2cd4e5f 100644
--- a/src/modules/EnvironmentVariables/EnvironmentVariables/EnvironmentVariablesXAML/MainWindow.xaml.cs
+++ b/src/modules/EnvironmentVariables/EnvironmentVariables/EnvironmentVariablesXAML/MainWindow.xaml.cs
@@ -7,6 +7,7 @@ using System.Runtime.InteropServices;
using EnvironmentVariables.Helpers;
using EnvironmentVariables.Helpers.Win32;
using EnvironmentVariables.ViewModels;
+using ManagedCommon;
using Microsoft.UI.Dispatching;
using WinUIEx;
@@ -30,19 +31,20 @@ namespace EnvironmentVariables
Title = title;
AppTitleTextBlock.Text = title;
- RegisterWindow();
+ var handle = this.GetWindowHandle();
+ RegisterWindow(handle);
+
+ WindowHelpers.BringToForeground(handle);
}
private static readonly DispatcherQueue _dispatcherQueue = DispatcherQueue.GetForCurrentThread();
private static NativeMethods.WinProc newWndProc;
private static IntPtr oldWndProc = IntPtr.Zero;
- private void RegisterWindow()
+ private void RegisterWindow(IntPtr handle)
{
newWndProc = new NativeMethods.WinProc(WndProc);
- var handle = this.GetWindowHandle();
-
oldWndProc = NativeMethods.SetWindowLongPtr(handle, NativeMethods.WindowLongIndexFlags.GWL_WNDPROC, newWndProc);
}
diff --git a/src/modules/EnvironmentVariables/EnvironmentVariables/EnvironmentVariablesXAML/Views/MainPage.xaml b/src/modules/EnvironmentVariables/EnvironmentVariables/EnvironmentVariablesXAML/Views/MainPage.xaml
index 9857626f5d..7f22dac332 100644
--- a/src/modules/EnvironmentVariables/EnvironmentVariables/EnvironmentVariablesXAML/Views/MainPage.xaml
+++ b/src/modules/EnvironmentVariables/EnvironmentVariables/EnvironmentVariablesXAML/Views/MainPage.xaml
@@ -209,7 +209,7 @@
-
-
+
+
@@ -583,15 +582,14 @@
HorizontalAlignment="Right"
Visibility="Collapsed" />
-
-
+ ItemsSource="{Binding Variables, Mode=TwoWay}">
+
@@ -617,8 +615,8 @@
Visibility="Collapsed" />
-
-
+
+
diff --git a/src/modules/FileLocksmith/FileLocksmithLibInterop/FileLocksmithLibInterop.vcxproj b/src/modules/FileLocksmith/FileLocksmithLibInterop/FileLocksmithLibInterop.vcxproj
index 6335ae919e..50ba1ec7da 100644
--- a/src/modules/FileLocksmith/FileLocksmithLibInterop/FileLocksmithLibInterop.vcxproj
+++ b/src/modules/FileLocksmith/FileLocksmithLibInterop/FileLocksmithLibInterop.vcxproj
@@ -31,7 +31,7 @@
Win32Proj
{c604b37e-9d0e-4484-8778-e8b31b0e1b3a}
FileLocksmithLibInterop
- net7.0-windows
+ net8.0-windows
..\..\..\..\$(Platform)\$(Configuration)\WinUI3Apps\
PowerToys.FileLocksmithLib.Interop
diff --git a/src/modules/FileLocksmith/FileLocksmithUI/FileLocksmithUI.csproj b/src/modules/FileLocksmith/FileLocksmithUI/FileLocksmithUI.csproj
index 1adec90526..6d5ada2cef 100644
--- a/src/modules/FileLocksmith/FileLocksmithUI/FileLocksmithUI.csproj
+++ b/src/modules/FileLocksmith/FileLocksmithUI/FileLocksmithUI.csproj
@@ -5,14 +5,14 @@
PowerToys.FileLocksmith
PowerToys File Locksmith
WinExe
- net7.0-windows10.0.20348.0
+ net8.0-windows10.0.20348.0
10.0.19041.0
10.0.19041.0
..\..\..\..\$(Platform)\$(Configuration)\WinUI3Apps
PowerToys.FileLocksmithUI
PowerToys.FileLocksmithUI
app.manifest
- win10-x64;win10-arm64
+ win-x64;win-arm64
true
true
false
@@ -35,10 +35,10 @@
- win10-x64
+ win-x64
- win10-arm64
+ win-arm64
diff --git a/src/modules/FileLocksmith/FileLocksmithUI/Properties/PublishProfiles/InstallationPublishProfile.pubxml b/src/modules/FileLocksmith/FileLocksmithUI/Properties/PublishProfiles/InstallationPublishProfile.pubxml
index 1a0c71a859..800c6473ca 100644
--- a/src/modules/FileLocksmith/FileLocksmithUI/Properties/PublishProfiles/InstallationPublishProfile.pubxml
+++ b/src/modules/FileLocksmith/FileLocksmithUI/Properties/PublishProfiles/InstallationPublishProfile.pubxml
@@ -5,11 +5,11 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
FileSystem
- net7.0-windows10.0.20348.0
+ net8.0-windows10.0.20348.0
10.0.19041.0
10.0.19041.0
$(PowerToysRoot)\$(Platform)\$(Configuration)\WinUI3Apps
- win10-$(Platform)
+ win-$(Platform)
true
False
False
diff --git a/src/modules/Hosts/Hosts.Tests/Hosts.Tests.csproj b/src/modules/Hosts/Hosts.Tests/Hosts.Tests.csproj
index 3cbcdab9ec..c4ee03077a 100644
--- a/src/modules/Hosts/Hosts.Tests/Hosts.Tests.csproj
+++ b/src/modules/Hosts/Hosts.Tests/Hosts.Tests.csproj
@@ -2,10 +2,10 @@
- net7.0-windows10.0.20348.0
+ net8.0-windows10.0.20348.0
10.0.19041.0
10.0.19041.0
- win10-x64;win10-arm64
+ win-x64;win-arm64
false
false
false
diff --git a/src/modules/Hosts/Hosts/Hosts.csproj b/src/modules/Hosts/Hosts/Hosts.csproj
index f884172d9a..ba13f01b00 100644
--- a/src/modules/Hosts/Hosts/Hosts.csproj
+++ b/src/modules/Hosts/Hosts/Hosts.csproj
@@ -3,12 +3,12 @@
WinExe
- net7.0-windows10.0.20348.0
+ net8.0-windows10.0.20348.0
10.0.19041.0
10.0.19041.0
Hosts
app.manifest
- win10-x64;win10-arm64
+ win-x64;win-arm64
true
true
None
@@ -34,10 +34,10 @@
- win10-x64
+ win-x64
- win10-arm64
+ win-arm64
diff --git a/src/modules/Hosts/Hosts/Settings/UserSettings.cs b/src/modules/Hosts/Hosts/Settings/UserSettings.cs
index 237dcc1bbb..5c73dd3a17 100644
--- a/src/modules/Hosts/Hosts/Settings/UserSettings.cs
+++ b/src/modules/Hosts/Hosts/Settings/UserSettings.cs
@@ -17,7 +17,7 @@ namespace Hosts.Settings
private const string HostsModuleName = "Hosts";
private const int MaxNumberOfRetry = 5;
- private readonly ISettingsUtils _settingsUtils;
+ private readonly SettingsUtils _settingsUtils;
private readonly IFileSystemWatcher _watcher;
private readonly object _loadingSettingsLock = new object();
diff --git a/src/modules/Hosts/Hosts/ViewModels/MainViewModel.cs b/src/modules/Hosts/Hosts/ViewModels/MainViewModel.cs
index 48f8965e65..0c1ec5a837 100644
--- a/src/modules/Hosts/Hosts/ViewModels/MainViewModel.cs
+++ b/src/modules/Hosts/Hosts/ViewModels/MainViewModel.cs
@@ -289,7 +289,7 @@ namespace Hosts.ViewModels
Entries.RefreshFilter();
}
- // Ping and duplicate should't trigger a file save
+ // Ping and duplicate should not trigger a file save
if (e.PropertyName == nameof(Entry.Ping)
|| e.PropertyName == nameof(Entry.Pinging)
|| e.PropertyName == nameof(Entry.Duplicate))
diff --git a/src/modules/Hosts/HostsModuleInterface/dllmain.cpp b/src/modules/Hosts/HostsModuleInterface/dllmain.cpp
index e089c06975..85077c8dbe 100644
--- a/src/modules/Hosts/HostsModuleInterface/dllmain.cpp
+++ b/src/modules/Hosts/HostsModuleInterface/dllmain.cpp
@@ -51,9 +51,9 @@ private:
HANDLE m_hProcess = nullptr;
- HANDLE m_hShowEvent;
+ HANDLE m_hShowEvent{};
- HANDLE m_hShowAdminEvent;
+ HANDLE m_hShowAdminEvent{};
bool is_process_running()
{
diff --git a/src/modules/MeasureTool/MeasureToolCore/PowerToys.MeasureToolCore.vcxproj b/src/modules/MeasureTool/MeasureToolCore/PowerToys.MeasureToolCore.vcxproj
index ad51f8998b..b9a95730b5 100644
--- a/src/modules/MeasureTool/MeasureToolCore/PowerToys.MeasureToolCore.vcxproj
+++ b/src/modules/MeasureTool/MeasureToolCore/PowerToys.MeasureToolCore.vcxproj
@@ -1,7 +1,7 @@
-
-
+
+
true
@@ -146,8 +146,8 @@
-
-
+
+
@@ -156,9 +156,9 @@
-
-
-
-
+
+
+
+
\ No newline at end of file
diff --git a/src/modules/MeasureTool/MeasureToolCore/packages.config b/src/modules/MeasureTool/MeasureToolCore/packages.config
index ca3592e5b0..abb0cf1bdb 100644
--- a/src/modules/MeasureTool/MeasureToolCore/packages.config
+++ b/src/modules/MeasureTool/MeasureToolCore/packages.config
@@ -2,6 +2,6 @@
-
-
+
+
\ No newline at end of file
diff --git a/src/modules/MeasureTool/MeasureToolUI/MeasureToolUI.csproj b/src/modules/MeasureTool/MeasureToolUI/MeasureToolUI.csproj
index 23365eedc3..789b4e5ace 100644
--- a/src/modules/MeasureTool/MeasureToolUI/MeasureToolUI.csproj
+++ b/src/modules/MeasureTool/MeasureToolUI/MeasureToolUI.csproj
@@ -5,14 +5,14 @@
PowerToys.MeasureTool
PowerToys MeasureTool
WinExe
- net7.0-windows10.0.20348.0
+ net8.0-windows10.0.20348.0
10.0.19041.0
..\..\..\..\$(Platform)\$(Configuration)\WinUI3Apps
PowerToys.MeasureToolUI
PowerToys.MeasureToolUI
app.manifest
x86;x64;arm64
- win10-x86;win10-x64;win10-arm64
+ win-x86;win-x64;win-arm64
true
true
false
@@ -35,10 +35,10 @@
- win10-x64
+ win-x64
- win10-arm64
+ win-arm64
diff --git a/src/modules/MouseUtils/MouseJumpUI.UnitTests/MouseJumpUI.UnitTests.csproj b/src/modules/MouseUtils/MouseJumpUI.UnitTests/MouseJumpUI.UnitTests.csproj
index 701ef550a6..86100f4a8d 100644
--- a/src/modules/MouseUtils/MouseJumpUI.UnitTests/MouseJumpUI.UnitTests.csproj
+++ b/src/modules/MouseUtils/MouseJumpUI.UnitTests/MouseJumpUI.UnitTests.csproj
@@ -2,7 +2,7 @@
- net7.0-windows10.0.20348.0
+ net8.0-windows10.0.20348.0
10.0.19041.0
10.0.19041.0
{D9C5DE64-6849-4278-91AD-9660AECF2876}
diff --git a/src/modules/MouseUtils/MouseJumpUI/Helpers/LayoutHelper.cs b/src/modules/MouseUtils/MouseJumpUI/Helpers/LayoutHelper.cs
index 768a6f8ddd..025bba1d6e 100644
--- a/src/modules/MouseUtils/MouseJumpUI/Helpers/LayoutHelper.cs
+++ b/src/modules/MouseUtils/MouseJumpUI/Helpers/LayoutHelper.cs
@@ -16,10 +16,7 @@ internal static class LayoutHelper
public static LayoutInfo CalculateLayoutInfo(
LayoutConfig layoutConfig)
{
- if (layoutConfig is null)
- {
- throw new ArgumentNullException(nameof(layoutConfig));
- }
+ ArgumentNullException.ThrowIfNull(layoutConfig);
var builder = new LayoutInfo.Builder
{
diff --git a/src/modules/MouseUtils/MouseJumpUI/MouseJumpUI.csproj b/src/modules/MouseUtils/MouseJumpUI/MouseJumpUI.csproj
index d8cbe38df9..d2ec254c04 100644
--- a/src/modules/MouseUtils/MouseJumpUI/MouseJumpUI.csproj
+++ b/src/modules/MouseUtils/MouseJumpUI/MouseJumpUI.csproj
@@ -17,10 +17,10 @@
- win10-x64
+ win-x64
- win10-arm64
+ win-arm64
@@ -32,7 +32,7 @@
WinExe
MouseJumpUI
PowerToys.MouseJumpUI
- net7.0-windows10.0.20348.0
+ net8.0-windows10.0.20348.0
10.0.19041.0
10.0.19041.0
{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
diff --git a/src/modules/MouseWithoutBorders/App/Class/Common.Clipboard.cs b/src/modules/MouseWithoutBorders/App/Class/Common.Clipboard.cs
index 348c1f149e..0020edb552 100644
--- a/src/modules/MouseWithoutBorders/App/Class/Common.Clipboard.cs
+++ b/src/modules/MouseWithoutBorders/App/Class/Common.Clipboard.cs
@@ -45,6 +45,10 @@ namespace MouseWithoutBorders
private static string lastDragDropFile;
private static long clipboardCopiedTime;
+ internal static readonly char[] Comma = new char[] { ',' };
+ internal static readonly char[] Star = new char[] { '*' };
+ internal static readonly char[] NullSeparator = new char[] { '\0' };
+
internal static ID LastIDWithClipboardData { get; set; }
internal static string LastDragDropFile
@@ -406,7 +410,7 @@ namespace MouseWithoutBorders
try
{
- remoteMachine = postAct.Contains("mspaint,") ? postAct.Split(new char[] { ',' })[1] : Common.LastMachineWithClipboardData;
+ remoteMachine = postAct.Contains("mspaint,") ? postAct.Split(Comma)[1] : Common.LastMachineWithClipboardData;
remoteMachine = remoteMachine.Trim();
@@ -518,7 +522,7 @@ namespace MouseWithoutBorders
fileName = Common.GetStringU(header).Replace("\0", string.Empty);
Common.LogDebug("Header: " + fileName);
- string[] headers = fileName.Split(new char[] { '*' });
+ string[] headers = fileName.Split(Star);
if (headers.Length < 2 || !long.TryParse(headers[0], out long dataSize))
{
@@ -973,7 +977,7 @@ namespace MouseWithoutBorders
foreach (string txt in texts)
{
- if (string.IsNullOrEmpty(txt.Trim(new char[] { '\0' })))
+ if (string.IsNullOrEmpty(txt.Trim(NullSeparator)))
{
continue;
}
diff --git a/src/modules/MouseWithoutBorders/App/Class/Common.Encryption.cs b/src/modules/MouseWithoutBorders/App/Class/Common.Encryption.cs
index 7a0562b845..d557a8223c 100644
--- a/src/modules/MouseWithoutBorders/App/Class/Common.Encryption.cs
+++ b/src/modules/MouseWithoutBorders/App/Class/Common.Encryption.cs
@@ -22,7 +22,9 @@ namespace MouseWithoutBorders
{
internal partial class Common
{
- private static SymmetricAlgorithm symAl;
+#pragma warning disable SYSLIB0021
+ private static AesCryptoServiceProvider symAl;
+#pragma warning restore SYSLIB0021
private static string myKey;
private static uint magicNumber;
private static Random ran = new(); // Used for non encryption related functionality.
@@ -115,7 +117,7 @@ namespace MouseWithoutBorders
byte[] rv;
string myKey = Common.MyKey;
- if (!LegalKeyDictionary.ContainsKey(myKey))
+ if (!LegalKeyDictionary.TryGetValue(myKey, out byte[] value))
{
Rfc2898DeriveBytes key = new(
myKey,
@@ -127,7 +129,7 @@ namespace MouseWithoutBorders
}
else
{
- rv = LegalKeyDictionary[myKey];
+ rv = value;
}
return rv;
diff --git a/src/modules/MouseWithoutBorders/App/Class/Common.Helper.cs b/src/modules/MouseWithoutBorders/App/Class/Common.Helper.cs
index 54affce04b..5202eb6cc9 100644
--- a/src/modules/MouseWithoutBorders/App/Class/Common.Helper.cs
+++ b/src/modules/MouseWithoutBorders/App/Class/Common.Helper.cs
@@ -313,7 +313,8 @@ namespace MouseWithoutBorders
HasSwitchedMachineSinceLastCopy = true;
// Common.CreateLowIntegrityProcess("\"" + Path.GetDirectoryName(Application.ExecutablePath) + "\\MouseWithoutBordersHelper.exe\"", string.Empty, 0, false, 0);
- if (Process.GetProcessesByName(HelperProcessName)?.Any() != true)
+ var processes = Process.GetProcessesByName(HelperProcessName);
+ if (processes?.Length == 0)
{
Log("Unable to start helper process.");
Common.ShowToolTip("Error starting Mouse Without Borders Helper, clipboard sharing will not work!", 5000, ToolTipIcon.Error);
@@ -325,7 +326,8 @@ namespace MouseWithoutBorders
}
else
{
- if (Process.GetProcessesByName(HelperProcessName)?.Any() == true)
+ var processes = Process.GetProcessesByName(HelperProcessName);
+ if (processes?.Length > 0)
{
Log("Helper process found running.");
}
@@ -432,7 +434,7 @@ namespace MouseWithoutBorders
{
if (string.IsNullOrEmpty(Setting.Values.Username) && !Common.RunOnLogonDesktop)
{
- if (Program.User.ToLower(CultureInfo.CurrentCulture).Contains("system"))
+ if (Program.User.Contains("system", StringComparison.CurrentCultureIgnoreCase))
{
_ = Common.ImpersonateLoggedOnUserAndDoSomething(() =>
{
diff --git a/src/modules/MouseWithoutBorders/App/Class/Common.Launch.cs b/src/modules/MouseWithoutBorders/App/Class/Common.Launch.cs
index 02dbfd707b..80ffe9fd84 100644
--- a/src/modules/MouseWithoutBorders/App/Class/Common.Launch.cs
+++ b/src/modules/MouseWithoutBorders/App/Class/Common.Launch.cs
@@ -84,12 +84,11 @@ namespace MouseWithoutBorders
}
}
- [SuppressMessage("Microsoft.Globalization", "CA1304:SpecifyCultureInfo", MessageId = "System.String.ToLower", Justification = "Dotnet port with style preservation")]
internal static int CreateProcessInInputDesktopSession(string commandLine, string arg, string desktop, short wShowWindow, bool lowIntegrity = false)
// As user who runs explorer.exe
{
- if (!Program.User.ToLower(CultureInfo.InvariantCulture).Contains("system"))
+ if (!Program.User.Contains("system", StringComparison.InvariantCultureIgnoreCase))
{
ProcessStartInfo s = new(commandLine, arg);
s.WindowStyle = wShowWindow != 0 ? ProcessWindowStyle.Normal : ProcessWindowStyle.Hidden;
diff --git a/src/modules/MouseWithoutBorders/App/Class/Common.Service.cs b/src/modules/MouseWithoutBorders/App/Class/Common.Service.cs
index 2673d95c48..1b65270fd0 100644
--- a/src/modules/MouseWithoutBorders/App/Class/Common.Service.cs
+++ b/src/modules/MouseWithoutBorders/App/Class/Common.Service.cs
@@ -45,7 +45,7 @@ namespace MouseWithoutBorders
{
Process[] ps = Process.GetProcessesByName("MouseWithoutBordersSvc");
- if (ps.Any())
+ if (ps.Length != 0)
{
if (DateTime.UtcNow - lastStartServiceTime < TimeSpan.FromSeconds(5))
{
diff --git a/src/modules/MouseWithoutBorders/App/Class/InputSimulation.cs b/src/modules/MouseWithoutBorders/App/Class/InputSimulation.cs
index adb0c90bd0..8f6224e3f1 100644
--- a/src/modules/MouseWithoutBorders/App/Class/InputSimulation.cs
+++ b/src/modules/MouseWithoutBorders/App/Class/InputSimulation.cs
@@ -353,6 +353,7 @@ namespace MouseWithoutBorders.Class
private static bool ctrlDown;
private static bool altDown;
private static bool shiftDown;
+ internal static readonly string[] Args = new string[] { "CAD" };
private static void ResetModifiersState(HotkeySettings matchingHotkey)
{
@@ -456,7 +457,7 @@ namespace MouseWithoutBorders.Class
if (ctrlDown && altDown)
{
ctrlDown = altDown = false;
- new ServiceController("MouseWithoutBordersSvc").Start(new string[] { "CAD" });
+ new ServiceController("MouseWithoutBordersSvc").Start(Args);
}
break;
diff --git a/src/modules/MouseWithoutBorders/App/Class/MachinePool.cs b/src/modules/MouseWithoutBorders/App/Class/MachinePool.cs
index 51bbd88921..2420e43b37 100644
--- a/src/modules/MouseWithoutBorders/App/Class/MachinePool.cs
+++ b/src/modules/MouseWithoutBorders/App/Class/MachinePool.cs
@@ -156,7 +156,7 @@ namespace MouseWithoutBorders.Class
}
else if (list.Count >= 4)
{
- throw new ArgumentException("machineNames.Length > Common.MAX_MACHINE");
+ throw new ArgumentException($"The number of machines exceeded the maximum allowed limit of {Common.MAX_MACHINE}. Actual count: {list.Count}.");
}
_ = LearnMachine(name);
@@ -178,7 +178,7 @@ namespace MouseWithoutBorders.Class
}
else if (list.Count >= 4)
{
- throw new ArgumentException("infos.Length > Common.MAX_MACHINE");
+ throw new ArgumentException($"The number of machines exceeded the maximum allowed limit of {Common.MAX_MACHINE}. Actual count: {list.Count}.");
}
_ = LearnMachine(inf.Name);
diff --git a/src/modules/MouseWithoutBorders/App/Class/MachinePoolHelpers.cs b/src/modules/MouseWithoutBorders/App/Class/MachinePoolHelpers.cs
index 66175d8f55..d2162273fb 100644
--- a/src/modules/MouseWithoutBorders/App/Class/MachinePoolHelpers.cs
+++ b/src/modules/MouseWithoutBorders/App/Class/MachinePoolHelpers.cs
@@ -8,6 +8,9 @@ namespace MouseWithoutBorders.Class
{
internal static class MachinePoolHelpers
{
+ internal static readonly char[] Comma = new char[] { ',' };
+ internal static readonly char[] Colon = new char[] { ':' };
+
internal static MachineInf[] LoadMachineInfoFromMachinePoolStringSetting(string s)
{
if (s == null)
@@ -15,7 +18,7 @@ namespace MouseWithoutBorders.Class
throw new ArgumentNullException(s);
}
- string[] st = s.Split(new char[] { ',' });
+ string[] st = s.Split(Comma);
if (st.Length < Common.MAX_MACHINE)
{
@@ -25,7 +28,7 @@ namespace MouseWithoutBorders.Class
MachineInf[] rv = new MachineInf[Common.MAX_MACHINE];
for (int i = 0; i < Common.MAX_MACHINE; i++)
{
- string[] mc = st[i].Split(new char[] { ':' });
+ string[] mc = st[i].Split(Colon);
if (mc.Length == 2)
{
rv[i].Name = mc[0];
diff --git a/src/modules/MouseWithoutBorders/App/Class/Setting.cs b/src/modules/MouseWithoutBorders/App/Class/Setting.cs
index 46f647c151..edb74665cb 100644
--- a/src/modules/MouseWithoutBorders/App/Class/Setting.cs
+++ b/src/modules/MouseWithoutBorders/App/Class/Setting.cs
@@ -38,7 +38,7 @@ namespace MouseWithoutBorders.Class
{
internal bool Changed;
- private readonly ISettingsUtils _settingsUtils;
+ private readonly SettingsUtils _settingsUtils;
private readonly object _loadingSettingsLock = new object();
private readonly IFileSystemWatcher _watcher;
diff --git a/src/modules/MouseWithoutBorders/App/Class/SocketStuff.cs b/src/modules/MouseWithoutBorders/App/Class/SocketStuff.cs
index 106ba6941a..a3ea7e3c08 100644
--- a/src/modules/MouseWithoutBorders/App/Class/SocketStuff.cs
+++ b/src/modules/MouseWithoutBorders/App/Class/SocketStuff.cs
@@ -887,14 +887,14 @@ namespace MouseWithoutBorders.Class
if (!string.IsNullOrEmpty(Setting.Values.Name2IP))
{
- string[] name2ip = Setting.Values.Name2IP.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
+ string[] name2ip = Setting.Values.Name2IP.Split(Separator, StringSplitOptions.RemoveEmptyEntries);
string[] nameNip;
if (name2ip != null)
{
foreach (string st in name2ip)
{
- nameNip = st.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
+ nameNip = st.Split(BlankSeparator, StringSplitOptions.RemoveEmptyEntries);
if (nameNip != null && nameNip.Length >= 2 && nameNip[0].Trim().Equals(machineName, StringComparison.OrdinalIgnoreCase)
&& IPAddress.TryParse(nameNip[1].Trim(), out IPAddress ip) && !validAddressesSt.Contains("[" + ip.ToString() + "]")
@@ -1063,7 +1063,7 @@ namespace MouseWithoutBorders.Class
List localIPv4Addresses = GetMyIPv4Addresses().ToList();
- if (!localIPv4Addresses.Any())
+ if (localIPv4Addresses.Count == 0)
{
Common.Log($"No IPv4 resolved from the local machine: {Common.MachineName}");
return true;
@@ -1234,6 +1234,8 @@ namespace MouseWithoutBorders.Class
}
private long lastRemoteMachineID;
+ internal static readonly string[] Separator = new string[] { "\r\n" };
+ internal static readonly char[] BlankSeparator = new char[] { ' ' };
private void MainTCPRoutine(TcpSk tcp, string machineName, bool isClient)
{
diff --git a/src/modules/MouseWithoutBorders/App/Class/TcpServer.cs b/src/modules/MouseWithoutBorders/App/Class/TcpServer.cs
index 6e5478d71b..f7ea7ba094 100644
--- a/src/modules/MouseWithoutBorders/App/Class/TcpServer.cs
+++ b/src/modules/MouseWithoutBorders/App/Class/TcpServer.cs
@@ -104,6 +104,7 @@ namespace MouseWithoutBorders.Class
}
private static bool logged;
+ internal static readonly string[] Separator = new[] { " " };
private void LogError(string log)
{
@@ -146,7 +147,7 @@ namespace MouseWithoutBorders.Class
try
{
// Assuming the format of netstat's output is fixed.
- pid = int.Parse(portLogLine.Split(new[] { " " }, StringSplitOptions.RemoveEmptyEntries).Last(), CultureInfo.CurrentCulture);
+ pid = int.Parse(portLogLine.Split(Separator, StringSplitOptions.RemoveEmptyEntries).Last(), CultureInfo.CurrentCulture);
process = Process.GetProcessById(pid);
}
catch (Exception)
diff --git a/src/modules/MouseWithoutBorders/App/Form/Settings/SettingsForm.cs b/src/modules/MouseWithoutBorders/App/Form/Settings/SettingsForm.cs
index f6cf932811..a8195a79ad 100644
--- a/src/modules/MouseWithoutBorders/App/Form/Settings/SettingsForm.cs
+++ b/src/modules/MouseWithoutBorders/App/Form/Settings/SettingsForm.cs
@@ -123,13 +123,14 @@ namespace MouseWithoutBorders
}
private string lastMessage = string.Empty;
+ private static readonly string[] Separator = new string[] { "\r\n" };
internal void ShowTip(ToolTipIcon icon, string msg, int durationInMilliseconds)
{
int x = 0;
string text = msg + $"\r\n {(lastMessage.Equals(msg, StringComparison.OrdinalIgnoreCase) ? string.Empty : $"\r\nPrevious message/error: {lastMessage}")} ";
lastMessage = msg;
- int y = (-text.Split(new string[] { "\r\n" }, StringSplitOptions.None).Length * 15) - 30;
+ int y = (-text.Split(Separator, StringSplitOptions.None).Length * 15) - 30;
toolTipManual.Hide(this);
diff --git a/src/modules/MouseWithoutBorders/App/Form/frmMatrix.cs b/src/modules/MouseWithoutBorders/App/Form/frmMatrix.cs
index c786498f97..cea9daafc9 100644
--- a/src/modules/MouseWithoutBorders/App/Form/frmMatrix.cs
+++ b/src/modules/MouseWithoutBorders/App/Form/frmMatrix.cs
@@ -742,11 +742,13 @@ namespace MouseWithoutBorders
LoadMachines();
}
+ internal static readonly string[] Separator = new string[] { "\r\n" };
+
internal void ShowTip(ToolTipIcon icon, string text, int duration)
{
int x = 0;
text += "\r\n ";
- int y = (-text.Split(new string[] { "\r\n" }, StringSplitOptions.None).Length * 15) - 30;
+ int y = (-text.Split(Separator, StringSplitOptions.None).Length * 15) - 30;
toolTipManual.Hide(this);
diff --git a/src/modules/MouseWithoutBorders/App/Helper/MouseWithoutBordersHelper.csproj b/src/modules/MouseWithoutBorders/App/Helper/MouseWithoutBordersHelper.csproj
index af7ac9c3b3..18bf39e7e3 100644
--- a/src/modules/MouseWithoutBorders/App/Helper/MouseWithoutBordersHelper.csproj
+++ b/src/modules/MouseWithoutBorders/App/Helper/MouseWithoutBordersHelper.csproj
@@ -1,7 +1,7 @@
- net7.0-windows10.0.20348.0
+ net8.0-windows10.0.20348.0
10.0.19041.0
10.0.19041.0
WinExe
@@ -19,10 +19,10 @@
- win10-x64
+ win-x64
- win10-arm64
+ win-arm64
diff --git a/src/modules/MouseWithoutBorders/App/MouseWithoutBorders.csproj b/src/modules/MouseWithoutBorders/App/MouseWithoutBorders.csproj
index d84499b839..2e7a227a47 100644
--- a/src/modules/MouseWithoutBorders/App/MouseWithoutBorders.csproj
+++ b/src/modules/MouseWithoutBorders/App/MouseWithoutBorders.csproj
@@ -1,7 +1,7 @@
- net7.0-windows10.0.20348.0
+ net8.0-windows10.0.20348.0
10.0.19041.0
10.0.19041.0
WinExe
@@ -19,10 +19,10 @@
- win10-x64
+ win-x64
- win10-arm64
+ win-arm64
diff --git a/src/modules/MouseWithoutBorders/App/Service/MouseWithoutBordersService.csproj b/src/modules/MouseWithoutBorders/App/Service/MouseWithoutBordersService.csproj
index cd9de124a7..8a7d487fc5 100644
--- a/src/modules/MouseWithoutBorders/App/Service/MouseWithoutBordersService.csproj
+++ b/src/modules/MouseWithoutBorders/App/Service/MouseWithoutBordersService.csproj
@@ -1,7 +1,7 @@
- net7.0-windows10.0.20348.0
+ net8.0-windows10.0.20348.0
10.0.19041.0
10.0.19041.0
true
@@ -20,10 +20,10 @@
- win10-x64
+ win-x64
- win10-arm64
+ win-arm64
TRACE;DEBUG;SHOW_ON_WINLOGON CODE_ANALYSIS CUSTOMIZE_LOGON_SCREEN
diff --git a/src/modules/PowerOCR/PowerOCR/Helpers/ImageMethods.cs b/src/modules/PowerOCR/PowerOCR/Helpers/ImageMethods.cs
index 1e11a83801..241e1f7433 100644
--- a/src/modules/PowerOCR/PowerOCR/Helpers/ImageMethods.cs
+++ b/src/modules/PowerOCR/PowerOCR/Helpers/ImageMethods.cs
@@ -148,6 +148,8 @@ internal sealed class ImageMethods
return resultText.Trim();
}
+ internal static readonly char[] Separator = new char[] { '\n', '\r' };
+
public static async Task ExtractText(Bitmap bmp, Language? preferredLanguage, System.Windows.Point? singlePoint = null)
{
Language? selectedLanguage = preferredLanguage ?? GetOCRLanguage();
@@ -211,7 +213,7 @@ internal sealed class ImageMethods
if (culture.TextInfo.IsRightToLeft)
{
- string[] textListLines = text.ToString().Split(new char[] { '\n', '\r' });
+ string[] textListLines = text.ToString().Split(Separator);
_ = text.Clear();
foreach (string textLine in textListLines)
diff --git a/src/modules/PowerOCR/PowerOCR/Helpers/WrappingStream.cs b/src/modules/PowerOCR/PowerOCR/Helpers/WrappingStream.cs
index fc49112ef6..5b952d1f73 100644
--- a/src/modules/PowerOCR/PowerOCR/Helpers/WrappingStream.cs
+++ b/src/modules/PowerOCR/PowerOCR/Helpers/WrappingStream.cs
@@ -220,9 +220,6 @@ public class WrappingStream : Stream
private void ThrowIfDisposed()
{
// throws an ObjectDisposedException if this object has been disposed
- if (_streamBase == null)
- {
- throw new ObjectDisposedException(GetType().Name);
- }
+ ObjectDisposedException.ThrowIf(_streamBase == null, this);
}
}
diff --git a/src/modules/PowerOCR/PowerOCR/Models/ResultTable.cs b/src/modules/PowerOCR/PowerOCR/Models/ResultTable.cs
index 06d3afa009..812fd985f5 100644
--- a/src/modules/PowerOCR/PowerOCR/Models/ResultTable.cs
+++ b/src/modules/PowerOCR/PowerOCR/Models/ResultTable.cs
@@ -239,7 +239,7 @@ public class ResultTable
return rowAreas;
}
- private static void CheckIntersectionsWithWordBorders(int hitGridSpacing, ICollection wordBorders, ICollection rowAreas, int i, Rect horizontalLineRect)
+ private static void CheckIntersectionsWithWordBorders(int hitGridSpacing, ICollection wordBorders, List rowAreas, int i, Rect horizontalLineRect)
{
foreach (WordBorder wb in wordBorders)
{
diff --git a/src/modules/PowerOCR/PowerOCR/OCROverlay.xaml.cs b/src/modules/PowerOCR/PowerOCR/OCROverlay.xaml.cs
index 60ec8b3a3a..1c7f266169 100644
--- a/src/modules/PowerOCR/PowerOCR/OCROverlay.xaml.cs
+++ b/src/modules/PowerOCR/PowerOCR/OCROverlay.xaml.cs
@@ -49,7 +49,9 @@ public partial class OCROverlay : Window
Top = screenRectangle.Top >= 0 ? screenRectangle.Top : screenRectangle.Top + (screenRectangle.Height / 2);
InitializeComponent();
+
Wpf.Ui.Appearance.SystemThemeWatcher.Watch(this, Wpf.Ui.Controls.WindowBackdropType.None);
+
PopulateLanguageMenu();
}
diff --git a/src/modules/PowerOCR/PowerOCR/PowerOCR.csproj b/src/modules/PowerOCR/PowerOCR/PowerOCR.csproj
index 4116b0889c..10887afce7 100644
--- a/src/modules/PowerOCR/PowerOCR/PowerOCR.csproj
+++ b/src/modules/PowerOCR/PowerOCR/PowerOCR.csproj
@@ -15,10 +15,10 @@
- win10-x64
+ win-x64
- win10-arm64
+ win-arm64
@@ -28,7 +28,7 @@
PowerOCRLogo.png
PowerOCR
PowerToys.PowerOCR
- net7.0-windows10.0.20348.0
+ net8.0-windows10.0.20348.0
10.0.19041.0
10.0.19041.0
{2150E333-8FDC-42A3-9474-1A3956D46DE8}
diff --git a/src/modules/PowerOCR/PowerOCR/Settings/UserSettings.cs b/src/modules/PowerOCR/PowerOCR/Settings/UserSettings.cs
index d08bc5b020..a1a5ba6d72 100644
--- a/src/modules/PowerOCR/PowerOCR/Settings/UserSettings.cs
+++ b/src/modules/PowerOCR/PowerOCR/Settings/UserSettings.cs
@@ -16,7 +16,7 @@ namespace PowerOCR.Settings
[Export(typeof(IUserSettings))]
public class UserSettings : IUserSettings
{
- private readonly ISettingsUtils _settingsUtils;
+ private readonly SettingsUtils _settingsUtils;
private const string PowerOcrModuleName = "TextExtractor";
private const string DefaultActivationShortcut = "Win + Shift + O";
private const int MaxNumberOfRetry = 5;
diff --git a/src/modules/alwaysontop/AlwaysOnTop/AlwaysOnTop.base.rc b/src/modules/alwaysontop/AlwaysOnTop/AlwaysOnTop.base.rc
new file mode 100644
index 0000000000..75d478289a
--- /dev/null
+++ b/src/modules/alwaysontop/AlwaysOnTop/AlwaysOnTop.base.rc
@@ -0,0 +1,41 @@
+#include
+#include "resource.h"
+#include "../../../../common/version/version.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+#include "winres.h"
+#undef APSTUDIO_READONLY_SYMBOLS
+
+1 VERSIONINFO
+ FILEVERSION FILE_VERSION
+ PRODUCTVERSION PRODUCT_VERSION
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+#ifdef _DEBUG
+ FILEFLAGS VS_FF_DEBUG
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS VOS_NT_WINDOWS32
+ FILETYPE VFT_DLL
+ FILESUBTYPE VFT2_UNKNOWN
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "CompanyName", COMPANY_NAME
+ VALUE "FileDescription", FILE_DESCRIPTION
+ VALUE "FileVersion", FILE_VERSION_STRING
+ VALUE "InternalName", INTERNAL_NAME
+ VALUE "LegalCopyright", COPYRIGHT_NOTE
+ VALUE "OriginalFilename", ORIGINAL_FILENAME
+ VALUE "ProductName", PRODUCT_NAME
+ VALUE "ProductVersion", PRODUCT_VERSION_STRING
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
diff --git a/src/modules/alwaysontop/AlwaysOnTop/AlwaysOnTop.cpp b/src/modules/alwaysontop/AlwaysOnTop/AlwaysOnTop.cpp
index 31c774ea91..b9ec910c62 100644
--- a/src/modules/alwaysontop/AlwaysOnTop/AlwaysOnTop.cpp
+++ b/src/modules/alwaysontop/AlwaysOnTop/AlwaysOnTop.cpp
@@ -8,6 +8,10 @@
#include
#include
+#include
+#include
+#include
+
#include
#include
@@ -489,6 +493,10 @@ void AlwaysOnTop::HandleWinHookEvent(WinHookEvent* data) noexcept
break;
case EVENT_SYSTEM_FOREGROUND:
{
+ if (!is_process_elevated() && IsProcessOfWindowElevated(data->hwnd))
+ {
+ notifications::WarnIfElevationIsRequired(GET_RESOURCE_STRING(IDS_ALWAYSONTOP), GET_RESOURCE_STRING(IDS_SYSTEM_FOREGROUND_ELEVATED), GET_RESOURCE_STRING(IDS_SYSTEM_FOREGROUND_ELEVATED_LEARN_MORE), GET_RESOURCE_STRING(IDS_SYSTEM_FOREGROUND_ELEVATED_DIALOG_DONT_SHOW_AGAIN));
+ }
RefreshBorders();
}
break;
diff --git a/src/modules/alwaysontop/AlwaysOnTop/AlwaysOnTop.vcxproj b/src/modules/alwaysontop/AlwaysOnTop/AlwaysOnTop.vcxproj
index 169a53e243..c96fc19237 100644
--- a/src/modules/alwaysontop/AlwaysOnTop/AlwaysOnTop.vcxproj
+++ b/src/modules/alwaysontop/AlwaysOnTop/AlwaysOnTop.vcxproj
@@ -3,6 +3,9 @@
+
+
+
true
@@ -141,9 +144,12 @@
+
+
+
@@ -167,10 +173,17 @@
{6955446d-23f7-4023-9bb3-8657f904af99}
+
+
+ {1d5be09d-78c0-4fd7-af00-ae7c1af7c525}
-
+
+
+
+
+
diff --git a/src/modules/alwaysontop/AlwaysOnTop/AlwaysOnTop.vcxproj.filters b/src/modules/alwaysontop/AlwaysOnTop/AlwaysOnTop.vcxproj.filters
index 4a12888f4a..87de9dbf11 100644
--- a/src/modules/alwaysontop/AlwaysOnTop/AlwaysOnTop.vcxproj.filters
+++ b/src/modules/alwaysontop/AlwaysOnTop/AlwaysOnTop.vcxproj.filters
@@ -12,6 +12,9 @@
{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+ {A74B5AAC-E913-410D-8941-D73346CF47AE}
@@ -49,8 +52,22 @@
Source Files
+
+
+ Generated Files
+
+
+
+ Resource Files
+
+
+ Header Files
+
+
+ Resource Files
+
@@ -97,6 +114,9 @@
Header Files
+
+
+ Generated Files
diff --git a/src/modules/alwaysontop/AlwaysOnTop/Resources.resx b/src/modules/alwaysontop/AlwaysOnTop/Resources.resx
new file mode 100644
index 0000000000..17ce38ca69
--- /dev/null
+++ b/src/modules/alwaysontop/AlwaysOnTop/Resources.resx
@@ -0,0 +1,134 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ AlwaysOnTop
+ AlwaysOnTop is a product name, keep as is.
+
+
+ We've detected an application running with administrator privileges. This will prevent certain interactions with these applications.
+ administrator is context of user account.
+
+
+ Learn more
+
+
+ Don't show again
+
+
\ No newline at end of file
diff --git a/src/modules/alwaysontop/AlwaysOnTop/resource.base.h b/src/modules/alwaysontop/AlwaysOnTop/resource.base.h
new file mode 100644
index 0000000000..9dd2bfb332
--- /dev/null
+++ b/src/modules/alwaysontop/AlwaysOnTop/resource.base.h
@@ -0,0 +1,13 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by AlwaysOnTop.rc
+
+//////////////////////////////
+// Non-localizable
+
+#define FILE_DESCRIPTION "PowerToys.AlwaysOnTop"
+#define INTERNAL_NAME "PowerToys.AlwaysOnTop"
+#define ORIGINAL_FILENAME "PowerToys.AlwaysOnTop.exe"
+
+// Non-localizable
+//////////////////////////////
diff --git a/src/modules/awake/Awake/Awake.csproj b/src/modules/awake/Awake/Awake.csproj
index 58576db33c..9f09482fdb 100644
--- a/src/modules/awake/Awake/Awake.csproj
+++ b/src/modules/awake/Awake/Awake.csproj
@@ -2,7 +2,7 @@
WinExe
- net7.0-windows10.0.20348.0
+ net8.0-windows10.0.20348.0
10.0.19041.0
10.0.19041.0
win-x64;win-arm64
@@ -24,10 +24,10 @@
- win10-x64
+ win-x64
- win10-arm64
+ win-arm64
diff --git a/src/modules/awake/Awake/Core/ExtensionMethods.cs b/src/modules/awake/Awake/Core/ExtensionMethods.cs
index 00d07fe799..d669791b3f 100644
--- a/src/modules/awake/Awake/Core/ExtensionMethods.cs
+++ b/src/modules/awake/Awake/Core/ExtensionMethods.cs
@@ -11,15 +11,9 @@ namespace Awake.Core
{
public static void AddRange(this ICollection target, IEnumerable source)
{
- if (target == null)
- {
- throw new ArgumentNullException(nameof(target));
- }
+ ArgumentNullException.ThrowIfNull(target);
- if (source == null)
- {
- throw new ArgumentNullException(nameof(source));
- }
+ ArgumentNullException.ThrowIfNull(source);
foreach (var element in source)
{
diff --git a/src/modules/awake/Awake/Core/Manager.cs b/src/modules/awake/Awake/Core/Manager.cs
index 6016a4551e..09b3bbc3e8 100644
--- a/src/modules/awake/Awake/Core/Manager.cs
+++ b/src/modules/awake/Awake/Core/Manager.cs
@@ -28,6 +28,9 @@ namespace Awake.Core
///
public class Manager
{
+ private static readonly CompositeFormat AwakeMinutes = System.Text.CompositeFormat.Parse(Properties.Resources.AWAKE_MINUTES);
+ private static readonly CompositeFormat AwakeHours = System.Text.CompositeFormat.Parse(Properties.Resources.AWAKE_HOURS);
+
private static BlockingCollection _stateQueue;
private static CancellationTokenSource _tokenSource;
@@ -276,9 +279,9 @@ namespace Awake.Core
{
Dictionary optionsList = new Dictionary
{
- { string.Format(CultureInfo.InvariantCulture, Resources.AWAKE_MINUTES, 30), 1800 },
+ { string.Format(CultureInfo.InvariantCulture, AwakeMinutes, 30), 1800 },
{ Resources.AWAKE_1_HOUR, 3600 },
- { string.Format(CultureInfo.InvariantCulture, Resources.AWAKE_HOURS, 2), 7200 },
+ { string.Format(CultureInfo.InvariantCulture, AwakeHours, 2), 7200 },
};
return optionsList;
}
diff --git a/src/modules/awake/Awake/Program.cs b/src/modules/awake/Awake/Program.cs
index 7475e98725..2baab45c29 100644
--- a/src/modules/awake/Awake/Program.cs
+++ b/src/modules/awake/Awake/Program.cs
@@ -47,6 +47,11 @@ namespace Awake
#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
private static ManualResetEvent _exitSignal = new ManualResetEvent(false);
+ internal static readonly string[] AliasesConfigOption = new[] { "--use-pt-config", "-c" };
+ internal static readonly string[] AliasesDisplayOption = new[] { "--display-on", "-d" };
+ internal static readonly string[] AliasesTimeOption = new[] { "--time-limit", "-t" };
+ internal static readonly string[] AliasesPidOption = new[] { "--pid", "-p" };
+ internal static readonly string[] AliasesExpireAtOption = new[] { "--expire-at", "-e" };
private static int Main(string[] args)
{
@@ -86,7 +91,7 @@ namespace Awake
Logger.LogInfo("Parsing parameters...");
Option configOption = new(
- aliases: new[] { "--use-pt-config", "-c" },
+ aliases: AliasesConfigOption,
getDefaultValue: () => false,
description: $"Specifies whether {Core.Constants.AppName} will be using the PowerToys configuration file for managing the state.")
{
@@ -95,7 +100,7 @@ namespace Awake
};
Option displayOption = new(
- aliases: new[] { "--display-on", "-d" },
+ aliases: AliasesDisplayOption,
getDefaultValue: () => true,
description: "Determines whether the display should be kept awake.")
{
@@ -104,7 +109,7 @@ namespace Awake
};
Option timeOption = new(
- aliases: new[] { "--time-limit", "-t" },
+ aliases: AliasesTimeOption,
getDefaultValue: () => 0,
description: "Determines the interval, in seconds, during which the computer is kept awake.")
{
@@ -113,7 +118,7 @@ namespace Awake
};
Option pidOption = new(
- aliases: new[] { "--pid", "-p" },
+ aliases: AliasesPidOption,
getDefaultValue: () => 0,
description: $"Bind the execution of {Core.Constants.AppName} to another process. When the process ends, the system will resume managing the current sleep and display state.")
{
@@ -122,7 +127,7 @@ namespace Awake
};
Option expireAtOption = new(
- aliases: new[] { "--expire-at", "-e" },
+ aliases: AliasesExpireAtOption,
getDefaultValue: () => string.Empty,
description: $"Determines the end date/time when {Core.Constants.AppName} will back off and let the system manage the current sleep and display state.")
{
diff --git a/src/modules/cmdNotFound/CmdNotFound/CmdNotFound.csproj b/src/modules/cmdNotFound/CmdNotFound/CmdNotFound.csproj
new file mode 100644
index 0000000000..65e6a0436e
--- /dev/null
+++ b/src/modules/cmdNotFound/CmdNotFound/CmdNotFound.csproj
@@ -0,0 +1,69 @@
+
+
+
+
+ net8.0-windows10.0.22621.0
+ 10.0.19041.0
+ 10.0.19041.0
+ win-x64;win-arm64
+ enable
+ Microsoft Corporation
+ PowerToys
+ enable
+ PowerToys CommandNotFound
+ PowerToys.CmdNotFound
+ false
+ true
+ ..\..\..\..\$(Platform)\$(Configuration)
+ false
+ false
+ true
+ true
+
+
+
+
+ win-x64
+
+
+ win-arm64
+
+
+
+ DEBUG;TRACE
+ full
+ prompt
+ 4
+ false
+
+
+
+ TRACE;RELEASE
+ true
+ pdbonly
+ prompt
+ 4
+
+
+
+
+ contentFiles
+ all
+ runtime; compile; build; native; analyzers; buildtransitive
+
+
+ contentFiles
+ all
+
+
+ PreserveNewest
+ PreserveNewest
+
+
+
+
+
+
+
+
+
diff --git a/src/modules/cmdNotFound/CmdNotFound/Init.cs b/src/modules/cmdNotFound/CmdNotFound/Init.cs
new file mode 100644
index 0000000000..4d4ecb6d60
--- /dev/null
+++ b/src/modules/cmdNotFound/CmdNotFound/Init.cs
@@ -0,0 +1,57 @@
+// 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.Management.Automation;
+using System.Management.Automation.Subsystem;
+using System.Management.Automation.Subsystem.Feedback;
+using System.Management.Automation.Subsystem.Prediction;
+
+namespace WinGetCommandNotFound
+{
+ public sealed class Init : IModuleAssemblyInitializer, IModuleAssemblyCleanup
+ {
+ internal const string Id = "e5351aa4-dfde-4d4d-bf0f-1a2f5a37d8d6";
+
+ public void OnImport()
+ {
+ if (!Platform.IsWindows || !IsWinGetInstalled())
+ {
+ return;
+ }
+
+ SubsystemManager.RegisterSubsystem(SubsystemKind.FeedbackProvider, WinGetCommandNotFoundFeedbackPredictor.Singleton);
+ SubsystemManager.RegisterSubsystem(SubsystemKind.CommandPredictor, WinGetCommandNotFoundFeedbackPredictor.Singleton);
+ }
+
+ public void OnRemove(PSModuleInfo psModuleInfo)
+ {
+ if (!IsWinGetInstalled())
+ {
+ return;
+ }
+
+ SubsystemManager.UnregisterSubsystem(new Guid(Id));
+ SubsystemManager.UnregisterSubsystem(new Guid(Id));
+ }
+
+ private bool IsWinGetInstalled()
+ {
+ // Ensure WinGet is installed
+ using (var pwsh = PowerShell.Create(RunspaceMode.CurrentRunspace))
+ {
+ var results = pwsh.AddCommand("Get-Command")
+ .AddParameter("Name", "winget")
+ .AddParameter("CommandType", "Application")
+ .Invoke();
+
+ if (results.Count is 0)
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+ }
+}
diff --git a/src/modules/cmdNotFound/CmdNotFound/PooledPowerShellObjectPolicy.cs b/src/modules/cmdNotFound/CmdNotFound/PooledPowerShellObjectPolicy.cs
new file mode 100644
index 0000000000..75d2ba8922
--- /dev/null
+++ b/src/modules/cmdNotFound/CmdNotFound/PooledPowerShellObjectPolicy.cs
@@ -0,0 +1,34 @@
+// 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.Management.Automation;
+using System.Management.Automation.Runspaces;
+using Microsoft.Extensions.ObjectPool;
+
+namespace WinGetCommandNotFound
+{
+ public sealed class PooledPowerShellObjectPolicy : IPooledObjectPolicy
+ {
+ private static readonly string[] WingetClientModuleName = new[] { "Microsoft.WinGet.Client" };
+
+ public PowerShell Create()
+ {
+ var iss = InitialSessionState.CreateDefault2();
+ iss.ImportPSModule(WingetClientModuleName);
+ return PowerShell.Create(iss);
+ }
+
+ public bool Return(PowerShell obj)
+ {
+ if (obj != null)
+ {
+ obj.Commands.Clear();
+ obj.Streams.ClearStreams();
+ return true;
+ }
+
+ return false;
+ }
+ }
+}
diff --git a/src/modules/cmdNotFound/CmdNotFound/Telemetry/CmdNotFoundFeedbackProvidedEvent.cs b/src/modules/cmdNotFound/CmdNotFound/Telemetry/CmdNotFoundFeedbackProvidedEvent.cs
new file mode 100644
index 0000000000..83563bbe35
--- /dev/null
+++ b/src/modules/cmdNotFound/CmdNotFound/Telemetry/CmdNotFoundFeedbackProvidedEvent.cs
@@ -0,0 +1,16 @@
+// 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.Tracing;
+using Microsoft.PowerToys.Telemetry;
+using Microsoft.PowerToys.Telemetry.Events;
+
+namespace WinGetCommandNotFound.Telemetry
+{
+ [EventData]
+ public class CmdNotFoundFeedbackProvidedEvent : EventBase, IEvent
+ {
+ public PartA_PrivTags PartA_PrivTags => PartA_PrivTags.ProductAndServiceUsage;
+ }
+}
diff --git a/src/modules/cmdNotFound/CmdNotFound/Telemetry/CmdNotFoundSuggestionProvidedEvent.cs b/src/modules/cmdNotFound/CmdNotFound/Telemetry/CmdNotFoundSuggestionProvidedEvent.cs
new file mode 100644
index 0000000000..2f55dbbb39
--- /dev/null
+++ b/src/modules/cmdNotFound/CmdNotFound/Telemetry/CmdNotFoundSuggestionProvidedEvent.cs
@@ -0,0 +1,16 @@
+// 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.Tracing;
+using Microsoft.PowerToys.Telemetry;
+using Microsoft.PowerToys.Telemetry.Events;
+
+namespace WinGetCommandNotFound.Telemetry
+{
+ [EventData]
+ public class CmdNotFoundSuggestionProvidedEvent : EventBase, IEvent
+ {
+ public PartA_PrivTags PartA_PrivTags => PartA_PrivTags.ProductAndServiceUsage;
+ }
+}
diff --git a/src/modules/cmdNotFound/CmdNotFound/WinGetCommandNotFound.psd1 b/src/modules/cmdNotFound/CmdNotFound/WinGetCommandNotFound.psd1
new file mode 100644
index 0000000000..c7a1118eac
--- /dev/null
+++ b/src/modules/cmdNotFound/CmdNotFound/WinGetCommandNotFound.psd1
@@ -0,0 +1,11 @@
+@{
+ ModuleVersion = '0.1.0'
+ GUID = '28c9afa2-92e5-413e-8e53-44b2d7a83ac6'
+ Author = 'Carlos Zamora'
+ CompanyName = "Microsoft Corporation"
+ Copyright = "Copyright (c) Microsoft Corporation."
+ Description = 'Enable suggestions on how to install missing commands via winget'
+ PowerShellVersion = '7.4'
+ NestedModules = @('PowerToys.CmdNotFound.dll')
+ RequiredModules = @(@{ModuleName = 'Microsoft.WinGet.Client'; ModuleVersion = "0.2.1"; })
+}
diff --git a/src/modules/cmdNotFound/CmdNotFound/WinGetCommandNotFoundFeedbackPredictor.cs b/src/modules/cmdNotFound/CmdNotFound/WinGetCommandNotFoundFeedbackPredictor.cs
new file mode 100644
index 0000000000..405898ef35
--- /dev/null
+++ b/src/modules/cmdNotFound/CmdNotFound/WinGetCommandNotFoundFeedbackPredictor.cs
@@ -0,0 +1,217 @@
+// 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;
+using System.Collections.ObjectModel;
+using System.Globalization;
+using System.Management.Automation;
+using System.Management.Automation.Subsystem.Feedback;
+using System.Management.Automation.Subsystem.Prediction;
+using ManagedCommon;
+using Microsoft.Extensions.ObjectPool;
+using Microsoft.PowerToys.Telemetry;
+
+namespace WinGetCommandNotFound
+{
+ public sealed class WinGetCommandNotFoundFeedbackPredictor : IFeedbackProvider, ICommandPredictor
+ {
+ private readonly Guid _guid;
+
+ private readonly ObjectPool _pool;
+
+ private const int _maxSuggestions = 20;
+
+ private List? _candidates;
+
+ private bool _warmedUp;
+
+ public static WinGetCommandNotFoundFeedbackPredictor Singleton { get; } = new WinGetCommandNotFoundFeedbackPredictor(Init.Id);
+
+ private WinGetCommandNotFoundFeedbackPredictor(string guid)
+ {
+ Logger.InitializeLogger("\\CmdNotFound\\Logs");
+
+ _guid = new Guid(guid);
+
+ var provider = new DefaultObjectPoolProvider();
+ _pool = provider.Create(new PooledPowerShellObjectPolicy());
+ _pool.Return(_pool.Get());
+ Task.Run(() => WarmUp());
+ }
+
+ public Guid Id => _guid;
+
+ public string Name => "Windows Package Manager - WinGet";
+
+ public string Description => "Finds missing commands that can be installed via WinGet.";
+
+ public Dictionary? FunctionsToDefine => null;
+
+ private void WarmUp()
+ {
+ var ps = _pool.Get();
+ try
+ {
+ ps.AddCommand("Find-WinGetPackage")
+ .AddParameter("Count", 1)
+ .Invoke();
+ }
+ finally
+ {
+ _pool.Return(ps);
+ _warmedUp = true;
+ }
+ }
+
+ ///
+ /// Gets feedback based on the given commandline and error record.
+ ///
+ public FeedbackItem? GetFeedback(FeedbackContext context, CancellationToken token)
+ {
+ var target = (string)context.LastError!.TargetObject;
+ if (target is not null)
+ {
+ try
+ {
+ bool tooManySuggestions = false;
+ string packageMatchFilterField = "command";
+ var pkgList = FindPackages(target, ref tooManySuggestions, ref packageMatchFilterField);
+ if (pkgList.Count == 0)
+ {
+ return null;
+ }
+
+ // Build list of suggestions
+ _candidates = new List();
+ foreach (var pkg in pkgList)
+ {
+ _candidates.Add(string.Format(CultureInfo.InvariantCulture, "winget install --id {0}", pkg.Members["Id"].Value.ToString()));
+ }
+
+ // Build footer message
+ var footerMessage = tooManySuggestions ?
+ string.Format(CultureInfo.InvariantCulture, "Additional results can be found using \"winget search --{0} {1}\"", packageMatchFilterField, target) :
+ null;
+
+ PowerToysTelemetry.Log.WriteEvent(new Telemetry.CmdNotFoundFeedbackProvidedEvent());
+
+ return new FeedbackItem(
+ "Try installing this package using winget:",
+ _candidates,
+ footerMessage,
+ FeedbackDisplayLayout.Portrait);
+ }
+ catch (Exception ex)
+ {
+ Logger.LogError("GetFeedback failed to execute", ex);
+ return new FeedbackItem($"Failed to execute PowerToys Command Not Found.{Environment.NewLine}This is a known issue if PowerShell 7 is installed from the Store or MSIX. If that isn't your case, please report an issue.", new List(), FeedbackDisplayLayout.Portrait);
+ }
+ }
+
+ return null;
+ }
+
+ private Collection FindPackages(string query, ref bool tooManySuggestions, ref string packageMatchFilterField)
+ {
+ if (!_warmedUp)
+ {
+ return new Collection();
+ }
+
+ var ps = _pool.Get();
+ try
+ {
+ var common = new Hashtable()
+ {
+ ["Source"] = "winget",
+ };
+
+ // 1) Search by command
+ var pkgList = ps.AddCommand("Find-WinGetPackage")
+ .AddParameter("Command", query)
+ .AddParameter("MatchOption", "StartsWithCaseInsensitive")
+ .AddParameters(common)
+ .Invoke();
+ if (pkgList.Count > 0)
+ {
+ tooManySuggestions = pkgList.Count > _maxSuggestions;
+ packageMatchFilterField = "command";
+ return pkgList;
+ }
+
+ // 2) No matches found,
+ // search by name
+ ps.Commands.Clear();
+ pkgList = ps.AddCommand("Find-WinGetPackage")
+ .AddParameter("Name", query)
+ .AddParameter("MatchOption", "ContainsCaseInsensitive")
+ .AddParameters(common)
+ .Invoke();
+ if (pkgList.Count > 0)
+ {
+ tooManySuggestions = pkgList.Count > _maxSuggestions;
+ packageMatchFilterField = "name";
+ return pkgList;
+ }
+
+ // 3) No matches found,
+ // search by moniker
+ ps.Commands.Clear();
+ pkgList = ps.AddCommand("Find-WinGetPackage")
+ .AddParameter("Moniker", query)
+ .AddParameter("MatchOption", "ContainsCaseInsensitive")
+ .AddParameters(common)
+ .Invoke();
+ tooManySuggestions = pkgList.Count > _maxSuggestions;
+ packageMatchFilterField = "moniker";
+ return pkgList;
+ }
+ finally
+ {
+ _pool.Return(ps);
+ }
+ }
+
+ public bool CanAcceptFeedback(PredictionClient client, PredictorFeedbackKind feedback)
+ {
+ return feedback switch
+ {
+ PredictorFeedbackKind.CommandLineAccepted => true,
+ _ => false,
+ };
+ }
+
+ public SuggestionPackage GetSuggestion(PredictionClient client, PredictionContext context, CancellationToken cancellationToken)
+ {
+ if (_candidates is not null)
+ {
+ string input = context.InputAst.Extent.Text;
+ List? result = null;
+
+ foreach (string c in _candidates)
+ {
+ if (c.StartsWith(input, StringComparison.OrdinalIgnoreCase))
+ {
+ result ??= new List(_candidates.Count);
+ result.Add(new PredictiveSuggestion(c));
+ }
+ }
+
+ if (result is not null)
+ {
+ PowerToysTelemetry.Log.WriteEvent(new Telemetry.CmdNotFoundSuggestionProvidedEvent());
+ return new SuggestionPackage(result);
+ }
+ }
+
+ return default;
+ }
+
+ public void OnCommandLineAccepted(PredictionClient client, IReadOnlyList history)
+ {
+ // Reset the candidate state.
+ _candidates = null;
+ }
+ }
+}
diff --git a/src/modules/cmdNotFound/CmdNotFoundModuleInterface/CmdNotFoundModuleInterface.rc b/src/modules/cmdNotFound/CmdNotFoundModuleInterface/CmdNotFoundModuleInterface.rc
new file mode 100644
index 0000000000..e9ac022fc5
--- /dev/null
+++ b/src/modules/cmdNotFound/CmdNotFoundModuleInterface/CmdNotFoundModuleInterface.rc
@@ -0,0 +1,108 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include
+#include "resource.h"
+#include "../../../common/version/version.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "winres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+1 VERSIONINFO
+FILEVERSION FILE_VERSION
+PRODUCTVERSION PRODUCT_VERSION
+FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+#ifdef _DEBUG
+FILEFLAGS VS_FF_DEBUG
+#else
+FILEFLAGS 0x0L
+#endif
+FILEOS VOS_NT_WINDOWS32
+FILETYPE VFT_DLL
+FILESUBTYPE VFT2_UNKNOWN
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0" // US English (0x0409), Unicode (0x04B0) charset
+ BEGIN
+ VALUE "CompanyName", COMPANY_NAME
+ VALUE "FileDescription", FILE_DESCRIPTION
+ VALUE "FileVersion", FILE_VERSION_STRING
+ VALUE "InternalName", INTERNAL_NAME
+ VALUE "LegalCopyright", COPYRIGHT_NOTE
+ VALUE "OriginalFilename", ORIGINAL_FILENAME
+ VALUE "ProductName", PRODUCT_NAME
+ VALUE "ProductVersion", PRODUCT_VERSION_STRING
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200 // US English (0x0409), Unicode (1200) charset
+ END
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (United States) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""winres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE
+BEGIN
+ IDS_CMD_NOT_FOUND_NAME "Command Not Found"
+END
+
+#endif // English (United States) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/src/modules/cmdNotFound/CmdNotFoundModuleInterface/CmdNotFoundModuleInterface.vcxproj b/src/modules/cmdNotFound/CmdNotFoundModuleInterface/CmdNotFoundModuleInterface.vcxproj
new file mode 100644
index 0000000000..a7fd427c2a
--- /dev/null
+++ b/src/modules/cmdNotFound/CmdNotFoundModuleInterface/CmdNotFoundModuleInterface.vcxproj
@@ -0,0 +1,107 @@
+
+
+
+ 17.0
+ Win32Proj
+ {0014d652-901f-4456-8d65-06fc5f997fb0}
+ CmdNotFoundModuleInterface
+ PowerToys.CmdNotFoundModuleInterface
+ v143
+ CmdNotFoundModuleInterface
+
+
+
+ DynamicLibrary
+ true
+ Unicode
+
+
+ DynamicLibrary
+ false
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+ ..\..\..\..\$(Platform)\$(Configuration)\
+
+
+
+ Level3
+ true
+ WIN32;_DEBUG;CMDNOTFOUNDMODULEINTERFACE_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
+ true
+ Use
+
+
+ Windows
+ true
+ false
+ Shlwapi.lib;$(CoreLibraryDependencies);%(AdditionalDependencies)
+
+
+
+
+ Level3
+ true
+ true
+ true
+ WIN32;NDEBUG;CMDNOTFOUNDMODULEINTERFACE_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
+ true
+ Use
+
+
+ Windows
+ true
+ true
+ true
+ false
+ Shlwapi.lib;$(CoreLibraryDependencies);%(AdditionalDependencies)
+
+
+
+
+ ..\..\..\common\Telemetry;..\..\;..\..\..\;%(AdditionalIncludeDirectories)
+
+
+
+
+
+ Header Files
+
+
+
+
+
+ Source Files
+
+
+
+ Create
+
+
+
+
+ {d9b8fc84-322a-4f9f-bbb9-20915c47ddfd}
+
+
+ {6955446d-23f7-4023-9bb3-8657f904af99}
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/modules/cmdNotFound/CmdNotFoundModuleInterface/CmdNotFoundModuleInterface.vcxproj.filters b/src/modules/cmdNotFound/CmdNotFoundModuleInterface/CmdNotFoundModuleInterface.vcxproj.filters
new file mode 100644
index 0000000000..1834d3ae88
--- /dev/null
+++ b/src/modules/cmdNotFound/CmdNotFoundModuleInterface/CmdNotFoundModuleInterface.vcxproj.filters
@@ -0,0 +1,45 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+
+
+ Resource Files
+
+
+
\ No newline at end of file
diff --git a/src/modules/cmdNotFound/CmdNotFoundModuleInterface/dllmain.cpp b/src/modules/cmdNotFound/CmdNotFoundModuleInterface/dllmain.cpp
new file mode 100644
index 0000000000..edb8e6455b
--- /dev/null
+++ b/src/modules/cmdNotFound/CmdNotFoundModuleInterface/dllmain.cpp
@@ -0,0 +1,158 @@
+// dllmain.cpp : Defines the entry point for the DLL application.
+#include "pch.h"
+
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "resource.h"
+#include "trace.h"
+
+BOOL APIENTRY DllMain(HMODULE /*hModule*/, DWORD ul_reason_for_call, LPVOID /*lpReserved*/)
+{
+ switch (ul_reason_for_call)
+ {
+ case DLL_PROCESS_ATTACH:
+ Trace::RegisterProvider();
+ break;
+ case DLL_THREAD_ATTACH:
+ case DLL_THREAD_DETACH:
+ break;
+ case DLL_PROCESS_DETACH:
+ Trace::UnregisterProvider();
+ break;
+ }
+ return TRUE;
+}
+
+const static wchar_t* MODULE_NAME = L"Command Not Found";
+const static wchar_t* MODULE_DESC = L"A module that detects an error thrown by a command in PowerShell and suggests a relevant WinGet package to install, if available.";
+
+inline const std::wstring ModuleKey = L"CmdNotFound";
+
+class CmdNotFound : public PowertoyModuleIface
+{
+ std::wstring app_name;
+ std::wstring app_key;
+
+private:
+ bool m_enabled = false;
+
+ void install_module()
+ {
+ auto module_path = get_module_folderpath();
+
+ std::string command = "pwsh.exe";
+ command += " ";
+ command += "-NoProfile -NonInteractive -NoLogo -WindowStyle Hidden -ExecutionPolicy Unrestricted -File \"" + winrt::to_string(module_path) + "\\WinUI3Apps\\Assets\\Settings\\Scripts\\EnableModule.ps1" + "\"" + " -scriptPath \"" + winrt::to_string(module_path) + "\"";
+
+ int ret = system(command.c_str());
+
+ if (ret != 0)
+ {
+ Logger::error("Running EnableModule.ps1 script failed.");
+ }
+ else
+ {
+ Logger::info("Module installed successfully.");
+ Trace::EnableCmdNotFoundGpo(true);
+ }
+ }
+
+ void uninstall_module()
+ {
+ auto module_path = get_module_folderpath();
+
+ std::string command = "pwsh.exe";
+ command += " ";
+ command += "-NoProfile -NonInteractive -NoLogo -WindowStyle Hidden -ExecutionPolicy Unrestricted -File \"" + winrt::to_string(module_path) + "\\WinUI3Apps\\Assets\\Settings\\Scripts\\DisableModule.ps1" + "\"";
+
+ int ret = system(command.c_str());
+
+ if (ret != 0)
+ {
+ Logger::error("Running EnableModule.ps1 script failed.");
+ }
+ else
+ {
+ Logger::info("Module uninstalled successfully.");
+ Trace::EnableCmdNotFoundGpo(false);
+ }
+ }
+
+public:
+ CmdNotFound()
+ {
+ app_name = GET_RESOURCE_STRING(IDS_CMD_NOT_FOUND_NAME);
+ app_key = ModuleKey;
+ LoggerHelpers::init_logger(app_key, L"ModuleInterface", LogSettings::cmdNotFoundLoggerName);
+ Logger::info("CmdNotFound object is constructing");
+
+ powertoys_gpo::gpo_rule_configured_t gpo_rule_configured_value = gpo_policy_enabled_configuration();
+ if (gpo_rule_configured_value == powertoys_gpo::gpo_rule_configured_t::gpo_rule_configured_enabled)
+ {
+ install_module();
+ m_enabled = true;
+ }
+ else if (gpo_rule_configured_value == powertoys_gpo::gpo_rule_configured_t::gpo_rule_configured_disabled)
+ {
+ uninstall_module();
+ m_enabled = false;
+ }
+ }
+
+ virtual powertoys_gpo::gpo_rule_configured_t gpo_policy_enabled_configuration() override
+ {
+ return powertoys_gpo::getConfiguredCmdNotFoundEnabledValue();
+ }
+
+ virtual void destroy() override
+ {
+ delete this;
+ }
+
+ virtual const wchar_t* get_name() override
+ {
+ return MODULE_NAME;
+ }
+
+ virtual const wchar_t* get_key() override
+ {
+ return app_key.c_str();
+ }
+
+ virtual bool get_config(wchar_t* /*buffer*/, int* /*buffer_size*/) override
+ {
+ return false;
+ }
+
+ virtual void set_config(const wchar_t* config) override
+ {
+ }
+
+ virtual void enable()
+ {
+ }
+
+ virtual void disable()
+ {
+ }
+
+ virtual bool is_enabled() override
+ {
+ return m_enabled;
+ }
+};
+
+extern "C" __declspec(dllexport) PowertoyModuleIface* __cdecl powertoy_create()
+{
+ return new CmdNotFound();
+}
diff --git a/src/modules/cmdNotFound/CmdNotFoundModuleInterface/pch.cpp b/src/modules/cmdNotFound/CmdNotFoundModuleInterface/pch.cpp
new file mode 100644
index 0000000000..64b7eef6d6
--- /dev/null
+++ b/src/modules/cmdNotFound/CmdNotFoundModuleInterface/pch.cpp
@@ -0,0 +1,5 @@
+// pch.cpp: source file corresponding to the pre-compiled header
+
+#include "pch.h"
+
+// When you are using pre-compiled headers, this source file is necessary for compilation to succeed.
diff --git a/src/modules/cmdNotFound/CmdNotFoundModuleInterface/pch.h b/src/modules/cmdNotFound/CmdNotFoundModuleInterface/pch.h
new file mode 100644
index 0000000000..96a774ab2a
--- /dev/null
+++ b/src/modules/cmdNotFound/CmdNotFoundModuleInterface/pch.h
@@ -0,0 +1,16 @@
+// pch.h: This is a precompiled header file.
+// Files listed below are compiled only once, improving build performance for future builds.
+// This also affects IntelliSense performance, including code completion and many code browsing features.
+// However, files listed here are ALL re-compiled if any one of them is updated between builds.
+// Do not add files here that you will be updating frequently as this negates the performance advantage.
+
+#ifndef PCH_H
+#define PCH_H
+
+#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
+// Windows Header Files
+#include
+
+#include
+
+#endif //PCH_H
diff --git a/src/modules/cmdNotFound/CmdNotFoundModuleInterface/resource.h b/src/modules/cmdNotFound/CmdNotFoundModuleInterface/resource.h
new file mode 100644
index 0000000000..9b16533a8a
--- /dev/null
+++ b/src/modules/cmdNotFound/CmdNotFoundModuleInterface/resource.h
@@ -0,0 +1,21 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by Awake.rc
+//
+#define IDS_CMD_NOT_FOUND_NAME 101
+
+
+#define FILE_DESCRIPTION "PowerToys Command Not Found"
+#define INTERNAL_NAME "PowerToys.CmdNotFoundModuleInterface"
+#define ORIGINAL_FILENAME "PowerToys.CmdNotFoundModuleInterface.dll"
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 102
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1001
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/src/modules/cmdNotFound/CmdNotFoundModuleInterface/trace.cpp b/src/modules/cmdNotFound/CmdNotFoundModuleInterface/trace.cpp
new file mode 100644
index 0000000000..255c46ea99
--- /dev/null
+++ b/src/modules/cmdNotFound/CmdNotFoundModuleInterface/trace.cpp
@@ -0,0 +1,30 @@
+#include "pch.h"
+#include "trace.h"
+
+TRACELOGGING_DEFINE_PROVIDER(
+ g_hProvider,
+ "Microsoft.PowerToys",
+ // {38e8889b-9731-53f5-e901-e8a7c1753074}
+ (0x38e8889b, 0x9731, 0x53f5, 0xe9, 0x01, 0xe8, 0xa7, 0xc1, 0x75, 0x30, 0x74),
+ TraceLoggingOptionProjectTelemetry());
+
+void Trace::RegisterProvider()
+{
+ TraceLoggingRegister(g_hProvider);
+}
+
+void Trace::UnregisterProvider()
+{
+ TraceLoggingUnregister(g_hProvider);
+}
+
+// Log if the user has CmdNotFound enabled or disabled
+void Trace::EnableCmdNotFoundGpo(const bool enabled) noexcept
+{
+ TraceLoggingWrite(
+ g_hProvider,
+ "CmdNotFound_EnableCmdNotFound",
+ ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance),
+ TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE),
+ TraceLoggingBoolean(enabled, "Enabled"));
+}
diff --git a/src/modules/cmdNotFound/CmdNotFoundModuleInterface/trace.h b/src/modules/cmdNotFound/CmdNotFoundModuleInterface/trace.h
new file mode 100644
index 0000000000..4294c510a6
--- /dev/null
+++ b/src/modules/cmdNotFound/CmdNotFoundModuleInterface/trace.h
@@ -0,0 +1,11 @@
+#pragma once
+
+class Trace
+{
+public:
+ static void RegisterProvider();
+ static void UnregisterProvider();
+
+ // Log if the user has CmdNotFound enabled or disabled
+ static void EnableCmdNotFoundGpo(const bool enabled) noexcept;
+};
diff --git a/src/modules/colorPicker/ColorPickerUI/Behaviors/ResizeBehavior.cs b/src/modules/colorPicker/ColorPickerUI/Behaviors/ResizeBehavior.cs
index 5424f44acd..6d020a752b 100644
--- a/src/modules/colorPicker/ColorPickerUI/Behaviors/ResizeBehavior.cs
+++ b/src/modules/colorPicker/ColorPickerUI/Behaviors/ResizeBehavior.cs
@@ -20,7 +20,7 @@ namespace ColorPicker.Behaviors
private static readonly TimeSpan _animationTimeSmaller = _animationTime;
private static readonly IEasingFunction _easeFunctionSmaller = new QuadraticEase() { EasingMode = EasingMode.EaseIn };
- private static void CustomAnimation(DependencyProperty prop, IAnimatable sender, double fromValue, double toValue)
+ private static void CustomAnimation(DependencyProperty prop, FrameworkElement sender, double fromValue, double toValue)
{
// if the animation is to/from a value of 0, it will cancel the current animation
DoubleAnimation move = null;
diff --git a/src/modules/colorPicker/ColorPickerUI/ColorPickerUI.csproj b/src/modules/colorPicker/ColorPickerUI/ColorPickerUI.csproj
index ed1926d3ae..41516fb3f3 100644
--- a/src/modules/colorPicker/ColorPickerUI/ColorPickerUI.csproj
+++ b/src/modules/colorPicker/ColorPickerUI/ColorPickerUI.csproj
@@ -14,10 +14,10 @@
- win10-x64
+ win-x64
- win10-arm64
+ win-arm64
@@ -25,7 +25,7 @@
WinExe
ColorPicker
PowerToys.ColorPickerUI
- net7.0-windows10.0.20348.0
+ net8.0-windows10.0.20348.0
10.0.19041.0
10.0.19041.0
{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
diff --git a/src/modules/colorPicker/ColorPickerUI/Common/RangeObservableCollection.cs b/src/modules/colorPicker/ColorPickerUI/Common/RangeObservableCollection.cs
index 599890bdac..7c9e87f092 100644
--- a/src/modules/colorPicker/ColorPickerUI/Common/RangeObservableCollection.cs
+++ b/src/modules/colorPicker/ColorPickerUI/Common/RangeObservableCollection.cs
@@ -28,10 +28,7 @@ namespace ColorPicker.Common
public void AddRange(IEnumerable list)
{
- if (list == null)
- {
- throw new ArgumentNullException(nameof(list));
- }
+ ArgumentNullException.ThrowIfNull(list);
_suppressNotification = true;
diff --git a/src/modules/colorPicker/ColorPickerUI/Controls/ColorPickerControl.xaml.cs b/src/modules/colorPicker/ColorPickerUI/Controls/ColorPickerControl.xaml.cs
index 7c5fe0e26e..b7fbdbc67a 100644
--- a/src/modules/colorPicker/ColorPickerUI/Controls/ColorPickerControl.xaml.cs
+++ b/src/modules/colorPicker/ColorPickerUI/Controls/ColorPickerControl.xaml.cs
@@ -329,7 +329,7 @@ namespace ColorPicker.Controls
newHexString = newHexString.ToLowerInvariant();
// Return only with hashtag if user typed it before
- bool addHashtag = oldValue.StartsWith("#", StringComparison.InvariantCulture);
+ bool addHashtag = oldValue.StartsWith('#');
return addHashtag ? "#" + newHexString : newHexString;
}
@@ -348,7 +348,7 @@ namespace ColorPicker.Controls
else
{
// Hex with or without hashtag and six characters
- return hexCodeText.StartsWith("#", StringComparison.InvariantCulture) ? hexCodeText : "#" + hexCodeText;
+ return hexCodeText.StartsWith('#') ? hexCodeText : "#" + hexCodeText;
}
}
diff --git a/src/modules/colorPicker/ColorPickerUI/Helpers/SerializationHelper.cs b/src/modules/colorPicker/ColorPickerUI/Helpers/SerializationHelper.cs
index 9df21d0411..4b31c42384 100644
--- a/src/modules/colorPicker/ColorPickerUI/Helpers/SerializationHelper.cs
+++ b/src/modules/colorPicker/ColorPickerUI/Helpers/SerializationHelper.cs
@@ -8,6 +8,7 @@ using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text.Json;
+using System.Text.Json.Serialization;
using System.Windows.Media;
using ColorPicker.Models;
@@ -21,6 +22,9 @@ namespace ColorPicker.Helpers
internal static class SerializationHelper
{
+ public static readonly JsonSerializerOptions DefaultOptions = new JsonSerializerOptions { WriteIndented = false };
+ public static readonly JsonSerializerOptions IndentedOptions = new JsonSerializerOptions { WriteIndented = true };
+
public static Dictionary> ConvertToDesiredColorFormats(
IList colorsToExport,
IEnumerable colorRepresentations,
@@ -116,10 +120,7 @@ namespace ColorPicker.Helpers
public static string ToJson(this Dictionary> source, bool indented = true)
{
- var options = new JsonSerializerOptions
- {
- WriteIndented = indented,
- };
+ var options = indented ? IndentedOptions : DefaultOptions;
return JsonSerializer.Serialize(source, options);
}
diff --git a/src/modules/colorPicker/ColorPickerUI/Helpers/ZoomWindowHelper.cs b/src/modules/colorPicker/ColorPickerUI/Helpers/ZoomWindowHelper.cs
index a67c8b7359..0b38ebbc42 100644
--- a/src/modules/colorPicker/ColorPickerUI/Helpers/ZoomWindowHelper.cs
+++ b/src/modules/colorPicker/ColorPickerUI/Helpers/ZoomWindowHelper.cs
@@ -91,7 +91,7 @@ namespace ColorPicker.Helpers
ShowZoomWindow(point);
}
- private static BitmapSource BitmapToImageSource(Bitmap bitmap)
+ private static BitmapImage BitmapToImageSource(Bitmap bitmap)
{
using (MemoryStream memory = new MemoryStream())
{
diff --git a/src/modules/colorPicker/ColorPickerUI/Settings/UserSettings.cs b/src/modules/colorPicker/ColorPickerUI/Settings/UserSettings.cs
index 4ab33f09a1..477465e84f 100644
--- a/src/modules/colorPicker/ColorPickerUI/Settings/UserSettings.cs
+++ b/src/modules/colorPicker/ColorPickerUI/Settings/UserSettings.cs
@@ -22,7 +22,7 @@ namespace ColorPicker.Settings
[Export(typeof(IUserSettings))]
public class UserSettings : IUserSettings
{
- private readonly ISettingsUtils _settingsUtils;
+ private readonly SettingsUtils _settingsUtils;
private const string ColorPickerModuleName = "ColorPicker";
private const string ColorPickerHistoryFilename = "colorHistory.json";
private const string DefaultActivationShortcut = "Ctrl + Break";
@@ -36,6 +36,11 @@ namespace ColorPicker.Settings
private bool _loadingColorsHistory;
+ private static readonly JsonSerializerOptions _serializerOptions = new JsonSerializerOptions
+ {
+ WriteIndented = true,
+ };
+
[ImportingConstructor]
public UserSettings(Helpers.IThrottledActionInvoker throttledActionInvoker)
{
@@ -58,7 +63,7 @@ namespace ColorPicker.Settings
{
if (!_loadingColorsHistory)
{
- _settingsUtils.SaveSettings(JsonSerializer.Serialize(ColorHistory, new JsonSerializerOptions { WriteIndented = true }), ColorPickerModuleName, ColorPickerHistoryFilename);
+ _settingsUtils.SaveSettings(JsonSerializer.Serialize(ColorHistory, _serializerOptions), ColorPickerModuleName, ColorPickerHistoryFilename);
}
}
diff --git a/src/modules/colorPicker/UnitTest-ColorPickerUI/UnitTest-ColorPickerUI.csproj b/src/modules/colorPicker/UnitTest-ColorPickerUI/UnitTest-ColorPickerUI.csproj
index e9cf5ee42a..009be36014 100644
--- a/src/modules/colorPicker/UnitTest-ColorPickerUI/UnitTest-ColorPickerUI.csproj
+++ b/src/modules/colorPicker/UnitTest-ColorPickerUI/UnitTest-ColorPickerUI.csproj
@@ -2,7 +2,7 @@
- net7.0-windows10.0.20348.0
+ net8.0-windows10.0.20348.0
10.0.19041.0
10.0.19041.0
{090CD7B7-3B0C-4D1D-BC98-83EB5D799BC1}
diff --git a/src/modules/fancyzones/FancyZonesLib/FancyZones.cpp b/src/modules/fancyzones/FancyZonesLib/FancyZones.cpp
index f708a2d4f8..d69b1898ac 100644
--- a/src/modules/fancyzones/FancyZonesLib/FancyZones.cpp
+++ b/src/modules/fancyzones/FancyZonesLib/FancyZones.cpp
@@ -394,15 +394,6 @@ void FancyZones::WindowCreated(HWND window) noexcept
return;
}
- // Hotfix
- // Avoid automatically moving popup windows, as they can be just popup menus.
- bool isPopup = FancyZonesWindowUtils::IsPopupWindow(window);
- bool hasThickFrame = FancyZonesWindowUtils::HasThickFrame(window);
- if (isPopup && !hasThickFrame)
- {
- return;
- }
-
// Avoid already stamped (zoned) windows
const bool isZoned = !FancyZonesWindowProperties::RetrieveZoneIndexProperty(window).empty();
if (isZoned)
@@ -1005,41 +996,42 @@ void FancyZones::RefreshLayouts() noexcept
bool FancyZones::ShouldProcessSnapHotkey(DWORD vkCode) noexcept
{
- auto window = GetForegroundWindow();
+ if (!FancyZonesSettings::settings().overrideSnapHotkeys)
+ {
+ return false;
+ }
+ auto window = GetForegroundWindow();
if (!FancyZonesWindowProcessing::IsProcessable(window))
{
return false;
}
- if (FancyZonesSettings::settings().overrideSnapHotkeys)
+ HMONITOR monitor = WorkAreaKeyFromWindow(window);
+
+ auto workArea = m_workAreaConfiguration.GetWorkArea(monitor);
+ if (!workArea)
{
- HMONITOR monitor = WorkAreaKeyFromWindow(window);
+ Logger::error(L"No work area for processing snap hotkey");
+ return false;
+ }
- auto workArea = m_workAreaConfiguration.GetWorkArea(monitor);
- if (!workArea)
+ const auto& layout = workArea->GetLayout();
+ if (!layout)
+ {
+ Logger::error(L"No layout for processing snap hotkey");
+ return false;
+ }
+
+ if (layout->Zones().size() > 0)
+ {
+ if (vkCode == VK_UP || vkCode == VK_DOWN)
{
- Logger::error(L"No work area for processing snap hotkey");
- return false;
+ return FancyZonesSettings::settings().moveWindowsBasedOnPosition;
}
-
- const auto& layout = workArea->GetLayout();
- if (!layout)
+ else
{
- Logger::error(L"No layout for processing snap hotkey");
- return false;
- }
-
- if (layout->Zones().size() > 0)
- {
- if (vkCode == VK_UP || vkCode == VK_DOWN)
- {
- return FancyZonesSettings::settings().moveWindowsBasedOnPosition;
- }
- else
- {
- return true;
- }
+ return true;
}
}
diff --git a/src/modules/fancyzones/FancyZonesLib/FancyZonesLib.vcxproj b/src/modules/fancyzones/FancyZonesLib/FancyZonesLib.vcxproj
index faf124b3ef..f7fccae0e4 100644
--- a/src/modules/fancyzones/FancyZonesLib/FancyZonesLib.vcxproj
+++ b/src/modules/fancyzones/FancyZonesLib/FancyZonesLib.vcxproj
@@ -61,7 +61,6 @@
-
diff --git a/src/modules/fancyzones/FancyZonesLib/FancyZonesLib.vcxproj.filters b/src/modules/fancyzones/FancyZonesLib/FancyZonesLib.vcxproj.filters
index 220b0cc22f..c955adacd6 100644
--- a/src/modules/fancyzones/FancyZonesLib/FancyZonesLib.vcxproj.filters
+++ b/src/modules/fancyzones/FancyZonesLib/FancyZonesLib.vcxproj.filters
@@ -153,9 +153,6 @@
Header Files
-
- Header Files
-
Header Files
diff --git a/src/modules/fancyzones/FancyZonesLib/FancyZonesWindowProcessing.cpp b/src/modules/fancyzones/FancyZonesLib/FancyZonesWindowProcessing.cpp
index 102392ba91..3fc9c4e09d 100644
--- a/src/modules/fancyzones/FancyZonesLib/FancyZonesWindowProcessing.cpp
+++ b/src/modules/fancyzones/FancyZonesLib/FancyZonesWindowProcessing.cpp
@@ -5,52 +5,69 @@
#include
#include
-bool FancyZonesWindowProcessing::IsProcessable(HWND window) noexcept
+FancyZonesWindowProcessing::ProcessabilityType FancyZonesWindowProcessing::DefineWindowType(HWND window) noexcept
{
- const bool isSplashScreen = FancyZonesWindowUtils::IsSplashScreen(window);
- if (isSplashScreen)
- {
- return false;
- }
-
const bool windowMinimized = IsIconic(window);
if (windowMinimized)
{
- return false;
+ return ProcessabilityType::Minimized;
}
- const bool standard = FancyZonesWindowUtils::IsStandardWindow(window);
- if (!standard)
+ auto style = GetWindowLong(window, GWL_STYLE);
+ auto exStyle = GetWindowLong(window, GWL_EXSTYLE);
+
+ if (!FancyZonesWindowUtils::HasStyle(style, WS_VISIBLE))
{
- return false;
+ return ProcessabilityType::NotVisible;
}
- // popup could be the window we don't want to snap: start menu, notification popup, tray window, etc.
- // also, popup could be the windows we want to snap disregarding the "allowSnapPopupWindows" setting, e.g. Telegram
- bool isPopup = FancyZonesWindowUtils::IsPopupWindow(window) && !FancyZonesWindowUtils::HasThickFrameAndMinimizeMaximizeButtons(window);
- if (isPopup && !FancyZonesSettings::settings().allowSnapPopupWindows)
+ if (FancyZonesWindowUtils::HasStyle(exStyle, WS_EX_TOOLWINDOW))
{
- return false;
+ return ProcessabilityType::ToolWindow;
+ }
+
+ if (!FancyZonesWindowUtils::IsRoot(window))
+ {
+ // child windows such as buttons, combo boxes, etc.
+ return ProcessabilityType::NonRootWindow;
+ }
+
+ bool isPopup = FancyZonesWindowUtils::HasStyle(style, WS_POPUP);
+ bool hasThickFrame = FancyZonesWindowUtils::HasStyle(style, WS_THICKFRAME);
+ bool hasCaption = FancyZonesWindowUtils::HasStyle(style, WS_CAPTION);
+ bool hasMinimizeMaximizeButtons = FancyZonesWindowUtils::HasStyle(style, WS_MINIMIZEBOX) || FancyZonesWindowUtils::HasStyle(style, WS_MAXIMIZEBOX);
+ if (isPopup && !(hasThickFrame && (hasCaption || hasMinimizeMaximizeButtons)))
+ {
+ // popup windows we want to snap: e.g. Calculator, Telegram
+ // popup windows we don't want to snap: start menu, notification popup, tray window, etc.
+ // WS_CAPTION, WS_MINIMIZEBOX, WS_MAXIMIZEBOX are used for filtering out menus,
+ // e.g., in Edge "Running as admin" menu when creating a new PowerToys issue.
+ return ProcessabilityType::NonProcessablePopupWindow;
}
// allow child windows
auto hasOwner = FancyZonesWindowUtils::HasVisibleOwner(window);
if (hasOwner && !FancyZonesSettings::settings().allowSnapChildWindows)
{
- return false;
+ return ProcessabilityType::ChildWindow;
}
if (FancyZonesWindowUtils::IsExcluded(window))
{
- return false;
+ return ProcessabilityType::Excluded;
}
// Switch between virtual desktops results with posting same windows messages that also indicate
// creation of new window. We need to check if window being processed is on currently active desktop.
if (!VirtualDesktop::instance().IsWindowOnCurrentDesktop(window))
{
- return false;
+ return ProcessabilityType::NotCurrentVirtualDesktop;
}
- return true;
+ return ProcessabilityType::Processable;
+}
+
+bool FancyZonesWindowProcessing::IsProcessable(HWND window) noexcept
+{
+ return DefineWindowType(window) == ProcessabilityType::Processable;
}
diff --git a/src/modules/fancyzones/FancyZonesLib/FancyZonesWindowProcessing.h b/src/modules/fancyzones/FancyZonesLib/FancyZonesWindowProcessing.h
index 21fbcfbad2..e6a16b9fe4 100644
--- a/src/modules/fancyzones/FancyZonesLib/FancyZonesWindowProcessing.h
+++ b/src/modules/fancyzones/FancyZonesLib/FancyZonesWindowProcessing.h
@@ -2,5 +2,20 @@
namespace FancyZonesWindowProcessing
{
+ enum class ProcessabilityType
+ {
+ Processable = 0,
+ SplashScreen,
+ Minimized,
+ ToolWindow,
+ NotVisible,
+ NonRootWindow,
+ NonProcessablePopupWindow,
+ ChildWindow,
+ Excluded,
+ NotCurrentVirtualDesktop
+ };
+
+ ProcessabilityType DefineWindowType(HWND window) noexcept;
bool IsProcessable(HWND window) noexcept;
}
\ No newline at end of file
diff --git a/src/modules/fancyzones/FancyZonesLib/MonitorUtils.cpp b/src/modules/fancyzones/FancyZonesLib/MonitorUtils.cpp
index 25e5a8b217..549e94cfd5 100644
--- a/src/modules/fancyzones/FancyZonesLib/MonitorUtils.cpp
+++ b/src/modules/fancyzones/FancyZonesLib/MonitorUtils.cpp
@@ -360,7 +360,7 @@ namespace MonitorUtils
if (GetMonitorInfo(monitor, &destMi))
{
RECT newPosition = FitOnScreen(placement.rcNormalPosition, originMi.rcWork, destMi.rcWork);
- FancyZonesWindowUtils::SizeWindowToRect(window, newPosition);
+ FancyZonesWindowUtils::SizeWindowToRect(window, newPosition, false);
}
}
}
diff --git a/src/modules/fancyzones/FancyZonesLib/NotificationUtil.h b/src/modules/fancyzones/FancyZonesLib/NotificationUtil.h
deleted file mode 100644
index 7686f409be..0000000000
--- a/src/modules/fancyzones/FancyZonesLib/NotificationUtil.h
+++ /dev/null
@@ -1,35 +0,0 @@
-#pragma once
-
-#include
-#include
-#include
-
-namespace FancyZonesNotifications
-{
- // Non-Localizable strings
- namespace NonLocalizable
- {
- const wchar_t FancyZonesRunAsAdminInfoPage[] = L"https://aka.ms/powertoysDetectedElevatedHelp";
- const wchar_t ToastNotificationButtonUrl[] = L"powertoys://cant_drag_elevated_disable/";
- }
-
- inline void WarnIfElevationIsRequired()
- {
- using namespace notifications;
- using namespace NonLocalizable;
-
- static bool warning_shown = false;
- if (!warning_shown && !is_toast_disabled(CantDragElevatedDontShowAgainRegistryPath, CantDragElevatedDisableIntervalInDays))
- {
- std::vector actions = {
- link_button{ GET_RESOURCE_STRING(IDS_CANT_DRAG_ELEVATED_LEARN_MORE), FancyZonesRunAsAdminInfoPage },
- link_button{ GET_RESOURCE_STRING(IDS_CANT_DRAG_ELEVATED_DIALOG_DONT_SHOW_AGAIN), ToastNotificationButtonUrl }
- };
- show_toast_with_activations(GET_RESOURCE_STRING(IDS_CANT_DRAG_ELEVATED),
- GET_RESOURCE_STRING(IDS_FANCYZONES),
- {},
- std::move(actions));
- warning_shown = true;
- }
- }
-}
diff --git a/src/modules/fancyzones/FancyZonesLib/Resources.resx b/src/modules/fancyzones/FancyZonesLib/Resources.resx
index b8b7d6639b..c3bd69de97 100644
--- a/src/modules/fancyzones/FancyZonesLib/Resources.resx
+++ b/src/modules/fancyzones/FancyZonesLib/Resources.resx
@@ -215,7 +215,7 @@
FancyZones
- FancyZone is a product name, keep as is.
+ FancyZones is a product name, keep as is.
We've detected an application running with administrator privileges. This will prevent certain interactions with these applications.
@@ -243,19 +243,19 @@
FancyZones persisted data path not found. Please report the bug to
- "Report bug to" will have a URL after. FancyZone is a product name, keep as is.
+ "Report bug to" will have a URL after. FancyZones is a product name, keep as is.
The FancyZones editor failed to start. Please report the bug to
- "Report bug to" will have a URL after. FancyZone is a product name, keep as is.
+ "Report bug to" will have a URL after. FancyZones is a product name, keep as is.
Failed to load the FancyZones settings. Default settings will be used.
- FancyZone is a product name, keep as is.
+ FancyZones is a product name, keep as is.
Failed to save the FancyZones settings. Please retry again later, if the problem persists report the bug to
- "Report bug to" will have a URL after. FancyZone is a product name, keep as is.
+ "Report bug to" will have a URL after. FancyZones is a product name, keep as is.
Enable quick layout switch
diff --git a/src/modules/fancyzones/FancyZonesLib/Settings.cpp b/src/modules/fancyzones/FancyZonesLib/Settings.cpp
index 51d9b52846..9cc886fe5c 100644
--- a/src/modules/fancyzones/FancyZonesLib/Settings.cpp
+++ b/src/modules/fancyzones/FancyZonesLib/Settings.cpp
@@ -33,7 +33,6 @@ namespace NonLocalizable
const wchar_t ShowOnAllMonitorsID[] = L"fancyzones_show_on_all_monitors";
const wchar_t SpanZonesAcrossMonitorsID[] = L"fancyzones_span_zones_across_monitors";
const wchar_t MakeDraggedWindowTransparentID[] = L"fancyzones_makeDraggedWindowTransparent";
- const wchar_t AllowPopupWindowSnapID[] = L"fancyzones_allowPopupWindowSnap";
const wchar_t AllowChildWindowSnapID[] = L"fancyzones_allowChildWindowSnap";
const wchar_t DisableRoundCornersOnSnapping[] = L"fancyzones_disableRoundCornersOnSnap";
@@ -127,7 +126,6 @@ void FancyZonesSettings::LoadSettings()
SetBoolFlag(values, NonLocalizable::WindowSwitchingToggleID, SettingId::WindowSwitching, m_settings.windowSwitching);
SetBoolFlag(values, NonLocalizable::SystemThemeID, SettingId::SystemTheme, m_settings.systemTheme);
SetBoolFlag(values, NonLocalizable::ShowZoneNumberID, SettingId::ShowZoneNumber, m_settings.showZoneNumber);
- SetBoolFlag(values, NonLocalizable::AllowPopupWindowSnapID, SettingId::AllowSnapPopupWindows, m_settings.allowSnapPopupWindows);
SetBoolFlag(values, NonLocalizable::AllowChildWindowSnapID, SettingId::AllowSnapChildWindows, m_settings.allowSnapChildWindows);
SetBoolFlag(values, NonLocalizable::DisableRoundCornersOnSnapping, SettingId::DisableRoundCornersOnSnapping, m_settings.disableRoundCorners);
diff --git a/src/modules/fancyzones/FancyZonesLib/Settings.h b/src/modules/fancyzones/FancyZonesLib/Settings.h
index 51024ad5bb..a9bcbeaa17 100644
--- a/src/modules/fancyzones/FancyZonesLib/Settings.h
+++ b/src/modules/fancyzones/FancyZonesLib/Settings.h
@@ -44,7 +44,6 @@ struct Settings
bool makeDraggedWindowTransparent = true;
bool systemTheme = true;
bool showZoneNumber = true;
- bool allowSnapPopupWindows = false;
bool allowSnapChildWindows = false;
bool disableRoundCorners = false;
std::wstring zoneColor = L"#AACDFF";
diff --git a/src/modules/fancyzones/FancyZonesLib/SettingsConstants.h b/src/modules/fancyzones/FancyZonesLib/SettingsConstants.h
index 1bcac306ca..a789d86484 100644
--- a/src/modules/fancyzones/FancyZonesLib/SettingsConstants.h
+++ b/src/modules/fancyzones/FancyZonesLib/SettingsConstants.h
@@ -32,7 +32,6 @@ enum class SettingId
NextTabHotkey,
PrevTabHotkey,
ExcludedApps,
- AllowSnapPopupWindows,
AllowSnapChildWindows,
DisableRoundCornersOnSnapping,
};
\ No newline at end of file
diff --git a/src/modules/fancyzones/FancyZonesLib/WindowMouseSnap.cpp b/src/modules/fancyzones/FancyZonesLib/WindowMouseSnap.cpp
index a69aaa7ef7..0a7251c78c 100644
--- a/src/modules/fancyzones/FancyZonesLib/WindowMouseSnap.cpp
+++ b/src/modules/fancyzones/FancyZonesLib/WindowMouseSnap.cpp
@@ -4,7 +4,6 @@
#include
#include
#include
-#include
#include
#include
#include
@@ -12,6 +11,7 @@
#include
#include
+#include
WindowMouseSnap::WindowMouseSnap(HWND window, const std::unordered_map>& activeWorkAreas) :
m_window(window),
@@ -20,8 +20,6 @@ WindowMouseSnap::WindowMouseSnap(HWND window, const std::unordered_map WindowMouseSnap::Create(HWND window, const std::unordered_map>& activeWorkAreas)
{
- if (!FancyZonesWindowProcessing::IsProcessable(window) ||
- FancyZonesWindowUtils::IsCursorTypeIndicatingSizeEvent())
+ if (FancyZonesWindowUtils::IsCursorTypeIndicatingSizeEvent() || !FancyZonesWindowProcessing::IsProcessable(window))
{
return nullptr;
}
- if (!is_process_elevated() && FancyZonesWindowUtils::IsProcessOfWindowElevated(window))
+ if (!is_process_elevated() && IsProcessOfWindowElevated(window))
{
// Notifies user if unable to drag elevated window
- FancyZonesNotifications::WarnIfElevationIsRequired();
+ notifications::WarnIfElevationIsRequired(GET_RESOURCE_STRING(IDS_FANCYZONES), GET_RESOURCE_STRING(IDS_CANT_DRAG_ELEVATED), GET_RESOURCE_STRING(IDS_CANT_DRAG_ELEVATED_LEARN_MORE), GET_RESOURCE_STRING(IDS_CANT_DRAG_ELEVATED_DIALOG_DONT_SHOW_AGAIN));
return nullptr;
}
@@ -111,13 +108,8 @@ void WindowMouseSnap::MoveSizeUpdate(HMONITOR monitor, POINT const& ptScreen, bo
void WindowMouseSnap::MoveSizeEnd()
{
if (m_snappingMode)
- {
- const bool hasNoVisibleOwner = !FancyZonesWindowUtils::HasVisibleOwner(m_window);
- const bool isStandardWindow = FancyZonesWindowUtils::IsStandardWindow(m_window);
-
- if ((isStandardWindow == false && hasNoVisibleOwner == true &&
- m_windowProperties.isStandardWindow == true && m_windowProperties.hasNoVisibleOwner == true) ||
- FancyZonesWindowUtils::IsWindowMaximized(m_window))
+ {
+ if (FancyZonesWindowUtils::IsWindowMaximized(m_window))
{
// Abort the zoning, this is a Chromium based tab that is merged back with an existing window
// or if the window is maximized by Windows when the cursor hits the screen top border
diff --git a/src/modules/fancyzones/FancyZonesLib/WindowMouseSnap.h b/src/modules/fancyzones/FancyZonesLib/WindowMouseSnap.h
index 5891771e14..cf8f2615ac 100644
--- a/src/modules/fancyzones/FancyZonesLib/WindowMouseSnap.h
+++ b/src/modules/fancyzones/FancyZonesLib/WindowMouseSnap.h
@@ -24,8 +24,6 @@ private:
struct WindowProperties
{
- // True if from the styles the window looks like a standard window
- bool isStandardWindow = false;
// True if the window is a top-level window that does not have a visible owner
bool hasNoVisibleOwner = false;
// Properties to restore after dragging
diff --git a/src/modules/fancyzones/FancyZonesLib/WindowUtils.cpp b/src/modules/fancyzones/FancyZonesLib/WindowUtils.cpp
index 8d83a7cab7..3de75ce764 100644
--- a/src/modules/fancyzones/FancyZonesLib/WindowUtils.cpp
+++ b/src/modules/fancyzones/FancyZonesLib/WindowUtils.cpp
@@ -15,7 +15,7 @@
namespace NonLocalizable
{
const wchar_t PowerToysAppFZEditor[] = L"POWERTOYS.FANCYZONESEDITOR.EXE";
- const wchar_t SplashClassName[] = L"MsoSplash";
+ const char SplashClassName[] = "MsoSplash";
const wchar_t CoreWindow[] = L"Windows.UI.Core.CoreWindow";
const wchar_t SearchUI[] = L"SearchUI.exe";
const wchar_t SystemAppsFolder[] = L"SYSTEMAPPS";
@@ -122,17 +122,6 @@ namespace
}
}
-bool FancyZonesWindowUtils::IsSplashScreen(HWND window)
-{
- wchar_t className[MAX_PATH];
- if (GetClassName(window, className, MAX_PATH) == 0)
- {
- return false;
- }
-
- return wcscmp(NonLocalizable::SplashClassName, className) == 0;
-}
-
bool FancyZonesWindowUtils::IsWindowMaximized(HWND window) noexcept
{
WINDOWPLACEMENT placement{};
@@ -164,71 +153,9 @@ bool FancyZonesWindowUtils::HasVisibleOwner(HWND window) noexcept
return rect.top != rect.bottom && rect.left != rect.right;
}
-bool FancyZonesWindowUtils::IsStandardWindow(HWND window)
+bool FancyZonesWindowUtils::IsRoot(HWND window) noexcept
{
- // True if from the styles the window looks like a standard window
-
- if (GetAncestor(window, GA_ROOT) != window)
- {
- return false;
- }
-
- auto style = GetWindowLong(window, GWL_STYLE);
- auto exStyle = GetWindowLong(window, GWL_EXSTYLE);
-
- bool isToolWindow = (exStyle & WS_EX_TOOLWINDOW) == WS_EX_TOOLWINDOW;
- bool isVisible = (style & WS_VISIBLE) == WS_VISIBLE;
- if (isToolWindow || !isVisible)
- {
- return false;
- }
-
- return true;
-}
-
-bool FancyZonesWindowUtils::IsPopupWindow(HWND window) noexcept
-{
- auto style = GetWindowLong(window, GWL_STYLE);
- return ((style & WS_POPUP) == WS_POPUP);
-}
-
-bool FancyZonesWindowUtils::HasThickFrame(HWND window) noexcept
-{
- auto style = GetWindowLong(window, GWL_STYLE);
- return ((style & WS_THICKFRAME) == WS_THICKFRAME);
-}
-
-bool FancyZonesWindowUtils::HasThickFrameAndMinimizeMaximizeButtons(HWND window) noexcept
-{
- auto style = GetWindowLong(window, GWL_STYLE);
- return ((style & WS_THICKFRAME) == WS_THICKFRAME && (style & WS_MINIMIZEBOX) == WS_MINIMIZEBOX && (style & WS_MAXIMIZEBOX) == WS_MAXIMIZEBOX);
-}
-
-bool FancyZonesWindowUtils::IsProcessOfWindowElevated(HWND window)
-{
- DWORD pid = 0;
- GetWindowThreadProcessId(window, &pid);
- if (!pid)
- {
- return false;
- }
-
- wil::unique_handle hProcess{ OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION,
- FALSE,
- pid) };
-
- wil::unique_handle token;
-
- if (OpenProcessToken(hProcess.get(), TOKEN_QUERY, &token))
- {
- TOKEN_ELEVATION elevation;
- DWORD size;
- if (GetTokenInformation(token.get(), TokenElevation, &elevation, sizeof(elevation), &size))
- {
- return elevation.TokenIsElevated != 0;
- }
- }
- return false;
+ return GetAncestor(window, GA_ROOT) == window;
}
bool FancyZonesWindowUtils::IsExcluded(HWND window)
@@ -248,12 +175,12 @@ bool FancyZonesWindowUtils::IsExcluded(HWND window)
return false;
}
-bool FancyZonesWindowUtils::IsExcludedByUser(const HWND& hwnd, std::wstring& processPath) noexcept
+bool FancyZonesWindowUtils::IsExcludedByUser(const HWND& hwnd, const std::wstring& processPath) noexcept
{
return (check_excluded_app(hwnd, processPath, FancyZonesSettings::settings().excludedAppsArray));
}
-bool FancyZonesWindowUtils::IsExcludedByDefault(const HWND& hwnd, std::wstring& processPath) noexcept
+bool FancyZonesWindowUtils::IsExcludedByDefault(const HWND& hwnd, const std::wstring& processPath) noexcept
{
static std::vector defaultExcludedFolders = { NonLocalizable::SystemAppsFolder };
if (find_folder_in_path(processPath, defaultExcludedFolders))
@@ -261,9 +188,14 @@ bool FancyZonesWindowUtils::IsExcludedByDefault(const HWND& hwnd, std::wstring&
return true;
}
- std::array class_name;
- GetClassNameA(hwnd, class_name.data(), static_cast(class_name.size()));
- if (is_system_window(hwnd, class_name.data()))
+ std::array className;
+ GetClassNameA(hwnd, className.data(), static_cast(className.size()));
+ if (is_system_window(hwnd, className.data()))
+ {
+ return true;
+ }
+
+ if (strcmp(NonLocalizable::SplashClassName, className.data()) == 0)
{
return true;
}
@@ -294,7 +226,7 @@ void FancyZonesWindowUtils::SwitchToWindow(HWND window) noexcept
}
}
-void FancyZonesWindowUtils::SizeWindowToRect(HWND window, RECT rect) noexcept
+void FancyZonesWindowUtils::SizeWindowToRect(HWND window, RECT rect, BOOL snapZone) noexcept
{
WINDOWPLACEMENT placement{};
::GetWindowPlacement(window, &placement);
@@ -306,8 +238,15 @@ void FancyZonesWindowUtils::SizeWindowToRect(HWND window, RECT rect) noexcept
::GetWindowPlacement(window, &placement);
}
+ BOOL maximizeLater = false;
if (IsWindowVisible(window))
{
+ // If is not snap zone then need keep maximize state (move to active monitor)
+ if (!snapZone && placement.showCmd == SW_SHOWMAXIMIZED)
+ {
+ maximizeLater = true;
+ }
+
// Do not restore minimized windows. We change their placement though so they restore to the correct zone.
if ((placement.showCmd != SW_SHOWMINIMIZED) &&
(placement.showCmd != SW_MINIMIZE))
@@ -335,6 +274,12 @@ void FancyZonesWindowUtils::SizeWindowToRect(HWND window, RECT rect) noexcept
Logger::error(L"SetWindowPlacement failed, {}", get_last_error_or_default(GetLastError()));
}
+ // make sure window is moved to the correct monitor before maximize.
+ if (maximizeLater)
+ {
+ placement.showCmd = SW_SHOWMAXIMIZED;
+ }
+
// Do it again, allowing Windows to resize the window and set correct scaling
// This fixes Issue #365
result = ::SetWindowPlacement(window, &placement);
diff --git a/src/modules/fancyzones/FancyZonesLib/WindowUtils.h b/src/modules/fancyzones/FancyZonesLib/WindowUtils.h
index 80a265e0ab..9382bccf0b 100644
--- a/src/modules/fancyzones/FancyZonesLib/WindowUtils.h
+++ b/src/modules/fancyzones/FancyZonesLib/WindowUtils.h
@@ -15,21 +15,23 @@
namespace FancyZonesWindowUtils
{
- bool IsSplashScreen(HWND window);
bool IsWindowMaximized(HWND window) noexcept;
bool HasVisibleOwner(HWND window) noexcept;
- bool IsStandardWindow(HWND window);
- bool IsPopupWindow(HWND window) noexcept;
- bool HasThickFrame(HWND window) noexcept;
- bool HasThickFrameAndMinimizeMaximizeButtons(HWND window) noexcept;
+ bool IsRoot(HWND window) noexcept;
+
+ constexpr bool HasStyle(LONG style, LONG styleToCheck) noexcept
+ {
+ return ((style & styleToCheck) == styleToCheck);
+ }
+
bool IsProcessOfWindowElevated(HWND window); // If HWND is already dead, we assume it wasn't elevated
bool IsExcluded(HWND window);
- bool IsExcludedByUser(const HWND& hwnd, std::wstring& processPath) noexcept;
- bool IsExcludedByDefault(const HWND& hwnd, std::wstring& processPath) noexcept;
+ bool IsExcludedByUser(const HWND& hwnd, const std::wstring& processPath) noexcept;
+ bool IsExcludedByDefault(const HWND& hwnd, const std::wstring& processPath) noexcept;
void SwitchToWindow(HWND window) noexcept;
- void SizeWindowToRect(HWND window, RECT rect) noexcept; // Parameter rect must be in screen coordinates (e.g. obtained from GetWindowRect)
+ void SizeWindowToRect(HWND window, RECT rect, BOOL snapZone = true) noexcept; // Parameter rect must be in screen coordinates (e.g. obtained from GetWindowRect)
void SaveWindowSizeAndOrigin(HWND window) noexcept;
void RestoreWindowSize(HWND window) noexcept;
void RestoreWindowOrigin(HWND window) noexcept;
diff --git a/src/modules/fancyzones/FancyZonesLib/trace.cpp b/src/modules/fancyzones/FancyZonesLib/trace.cpp
index f2669a16dd..4c6024fe5a 100644
--- a/src/modules/fancyzones/FancyZonesLib/trace.cpp
+++ b/src/modules/fancyzones/FancyZonesLib/trace.cpp
@@ -57,7 +57,6 @@
#define SpanZonesAcrossMonitorsKey "SpanZonesAcrossMonitors"
#define MakeDraggedWindowTransparentKey "MakeDraggedWindowTransparent"
#define AllowSnapChildWindows "AllowSnapChildWindows"
-#define AllowSnapPopupWindows "AllowSnapPopupWindows"
#define DisableRoundCornersOnSnapping "DisableRoundCornersOnSnapping"
#define ZoneColorKey "ZoneColor"
#define ZoneBorderColorKey "ZoneBorderColor"
@@ -323,7 +322,6 @@ void Trace::SettingsTelemetry(const Settings& settings) noexcept
TraceLoggingBoolean(settings.spanZonesAcrossMonitors, SpanZonesAcrossMonitorsKey),
TraceLoggingBoolean(settings.makeDraggedWindowTransparent, MakeDraggedWindowTransparentKey),
TraceLoggingBoolean(settings.allowSnapChildWindows, AllowSnapChildWindows),
- TraceLoggingBoolean(settings.allowSnapPopupWindows, AllowSnapPopupWindows),
TraceLoggingBoolean(settings.disableRoundCorners, DisableRoundCornersOnSnapping),
TraceLoggingWideString(settings.zoneColor.c_str(), ZoneColorKey),
TraceLoggingWideString(settings.zoneBorderColor.c_str(), ZoneBorderColorKey),
diff --git a/src/modules/fancyzones/FancyZonesTests/UnitTests/UnitTests.vcxproj b/src/modules/fancyzones/FancyZonesTests/UnitTests/UnitTests.vcxproj
index 545e236642..c0da418a8f 100644
--- a/src/modules/fancyzones/FancyZonesTests/UnitTests/UnitTests.vcxproj
+++ b/src/modules/fancyzones/FancyZonesTests/UnitTests/UnitTests.vcxproj
@@ -56,6 +56,7 @@
+
diff --git a/src/modules/fancyzones/FancyZonesTests/UnitTests/UnitTests.vcxproj.filters b/src/modules/fancyzones/FancyZonesTests/UnitTests/UnitTests.vcxproj.filters
index c8679dd8dc..0732c34ad4 100644
--- a/src/modules/fancyzones/FancyZonesTests/UnitTests/UnitTests.vcxproj.filters
+++ b/src/modules/fancyzones/FancyZonesTests/UnitTests/UnitTests.vcxproj.filters
@@ -66,6 +66,9 @@
Source Files
+
+ Source Files
+
diff --git a/src/modules/fancyzones/FancyZonesTests/UnitTests/Util.cpp b/src/modules/fancyzones/FancyZonesTests/UnitTests/Util.cpp
index 6f638085e7..740ceb94b3 100644
--- a/src/modules/fancyzones/FancyZonesTests/UnitTests/Util.cpp
+++ b/src/modules/fancyzones/FancyZonesTests/UnitTests/Util.cpp
@@ -8,8 +8,7 @@ namespace Mocks
class HwndCreator
{
public:
- HwndCreator(const std::wstring& title = L"");
-
+ HwndCreator(const std::wstring& title, const std::wstring& className, DWORD exStyle, DWORD style, HWND parentWindow);
~HwndCreator();
HWND operator()(HINSTANCE hInst);
@@ -20,23 +19,30 @@ namespace Mocks
inline HINSTANCE getHInstance() const { return m_hInst; }
inline const std::wstring& getTitle() const { return m_windowTitle; }
inline const std::wstring& getWindowClassName() const { return m_windowClassName; }
+ inline DWORD getExStyle() const noexcept { return m_exStyle; }
+ inline DWORD getStyle() const noexcept { return m_style; }
+ inline HWND getParentWindow() const noexcept { return m_parentWindow; }
private:
std::wstring m_windowTitle;
std::wstring m_windowClassName;
+ DWORD m_exStyle{ 0 };
+ DWORD m_style{ 0 };
+ HWND m_parentWindow{ NULL };
std::mutex m_mutex;
std::condition_variable m_conditionVar;
bool m_conditionFlag;
HANDLE m_thread;
- HINSTANCE m_hInst;
+ HINSTANCE m_hInst{};
HWND m_hWnd;
};
- HWND WindowCreate(HINSTANCE hInst)
+ HWND WindowCreate(HINSTANCE hInst, const std::wstring& title /*= L""*/, const std::wstring& className /*= L""*/,
+ DWORD exStyle, DWORD style, HWND parentWindow)
{
- return HwndCreator()(hInst);
+ return HwndCreator(title, className, exStyle, style, parentWindow)(hInst);
}
}
@@ -85,8 +91,21 @@ DWORD WINAPI ThreadProc(LPVOID lpParam)
if (RegisterDLLWindowClass(creator->getWindowClassName().c_str(), creator) != 0)
{
- auto hWnd = CreateWindowEx(0, creator->getWindowClassName().c_str(), creator->getTitle().c_str(), WS_EX_APPWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 10, 10, nullptr, nullptr, creator->getHInstance(), NULL);
- SetWindowPos(hWnd, HWND_TOPMOST, 10, 10, 100, 100, SWP_SHOWWINDOW);
+ auto hWnd = CreateWindowEx(creator->getExStyle(),
+ creator->getWindowClassName().c_str(),
+ creator->getTitle().c_str(),
+ creator->getStyle(),
+ CW_USEDEFAULT, CW_USEDEFAULT,
+ CW_USEDEFAULT, CW_USEDEFAULT,
+ creator->getParentWindow(),
+ nullptr,
+ creator->getHInstance(),
+ NULL);
+
+ ShowWindow(hWnd, SW_SHOW);
+ // wait after ShowWindow to make sure that it's finished and shown
+ std::this_thread::sleep_for(std::chrono::milliseconds(100));
+
creator->setHwnd(hWnd);
creator->setCondition(true);
@@ -95,8 +114,6 @@ DWORD WINAPI ThreadProc(LPVOID lpParam)
TranslateMessage(&messages);
DispatchMessage(&messages);
}
-
- creator->setHwnd(hWnd);
}
else
{
@@ -108,8 +125,16 @@ DWORD WINAPI ThreadProc(LPVOID lpParam)
namespace Mocks
{
- HwndCreator::HwndCreator(const std::wstring& title) :
- m_windowTitle(title), m_windowClassName(std::to_wstring(++s_classId)), m_conditionFlag(false), m_thread(nullptr), m_hInst(HINSTANCE{}), m_hWnd(nullptr)
+ HwndCreator::HwndCreator(const std::wstring& title, const std::wstring& className, DWORD exStyle, DWORD style, HWND parentWindow) :
+ m_windowTitle(title),
+ m_windowClassName(className.empty() ? std::to_wstring(++s_classId) : className),
+ m_exStyle(exStyle),
+ m_style(style),
+ m_parentWindow(parentWindow),
+ m_conditionFlag(false),
+ m_thread(nullptr),
+ m_hInst(HINSTANCE{}),
+ m_hWnd(nullptr)
{
}
diff --git a/src/modules/fancyzones/FancyZonesTests/UnitTests/Util.h b/src/modules/fancyzones/FancyZonesTests/UnitTests/Util.h
index f473c0b9e4..df3b2cb16a 100644
--- a/src/modules/fancyzones/FancyZonesTests/UnitTests/Util.h
+++ b/src/modules/fancyzones/FancyZonesTests/UnitTests/Util.h
@@ -123,7 +123,8 @@ namespace Mocks
return reinterpret_cast(++s_nextInstance);
}
- HWND WindowCreate(HINSTANCE hInst);
+ HWND WindowCreate(HINSTANCE hInst, const std::wstring& title = L"", const std::wstring& className = L""
+ , DWORD exStyle = 0, DWORD style = 0, HWND parentWindow = nullptr);
}
namespace Helpers
diff --git a/src/modules/fancyzones/FancyZonesTests/UnitTests/WindowProcessingTests.Spec.cpp b/src/modules/fancyzones/FancyZonesTests/UnitTests/WindowProcessingTests.Spec.cpp
new file mode 100644
index 0000000000..58c50f1026
--- /dev/null
+++ b/src/modules/fancyzones/FancyZonesTests/UnitTests/WindowProcessingTests.Spec.cpp
@@ -0,0 +1,202 @@
+#include "pch.h"
+
+#include
+#include
+#include
+
+#include "Util.h"
+
+#include
+
+using namespace Microsoft::VisualStudio::CppUnitTestFramework;
+
+namespace Microsoft
+{
+ namespace VisualStudio
+ {
+ namespace CppUnitTestFramework
+ {
+ template<>
+ std::wstring ToString(const FancyZonesWindowProcessing::ProcessabilityType& type)
+ {
+ return std::to_wstring((int)type);
+ }
+
+ }
+ }
+}
+
+namespace FancyZonesUnitTests
+{
+ TEST_CLASS (WindowProcessingUnitTests)
+ {
+ HINSTANCE hInst{};
+
+ TEST_METHOD_CLEANUP(CleanUp)
+ {
+ FancyZonesSettings::instance().SetSettings(Settings{});
+ }
+
+ TEST_METHOD (MinimizedWindow)
+ {
+ HWND window = Mocks::WindowCreate(hInst);
+ ShowWindow(window, SW_MINIMIZE);
+ std::this_thread::sleep_for(std::chrono::milliseconds(100)); // let ShowWindow finish
+ Assert::IsTrue(IsIconic(window));
+
+ Assert::AreEqual(FancyZonesWindowProcessing::ProcessabilityType::Minimized, FancyZonesWindowProcessing::DefineWindowType(window));
+ Assert::IsFalse(FancyZonesWindowProcessing::IsProcessable(window));
+ }
+
+ TEST_METHOD (ToolWindow)
+ {
+ HWND window = Mocks::WindowCreate(hInst, L"", L"", WS_EX_TOOLWINDOW);
+
+ Assert::AreEqual(FancyZonesWindowProcessing::ProcessabilityType::ToolWindow, FancyZonesWindowProcessing::DefineWindowType(window));
+ Assert::IsFalse(FancyZonesWindowProcessing::IsProcessable(window));
+ }
+
+ TEST_METHOD (InvisibleWindow)
+ {
+ HWND window = Mocks::WindowCreate(hInst);
+ ShowWindow(window, SW_HIDE);
+ std::this_thread::sleep_for(std::chrono::milliseconds(100)); // let ShowWindow finish
+
+ Assert::AreEqual(FancyZonesWindowProcessing::ProcessabilityType::NotVisible, FancyZonesWindowProcessing::DefineWindowType(window));
+ Assert::IsFalse(FancyZonesWindowProcessing::IsProcessable(window));
+ }
+
+ TEST_METHOD(NonRootWindow)
+ {
+ HWND rootWindow = Mocks::WindowCreate(hInst, L"RootWindow", L"", 0, WS_TILEDWINDOW | WS_CLIPCHILDREN);
+ Assert::IsTrue(FancyZonesWindowUtils::IsRoot(rootWindow));
+
+ HWND window = CreateWindow(WC_COMBOBOX, TEXT(""), CBS_DROPDOWN | CBS_HASSTRINGS | WS_CHILD | WS_OVERLAPPED | WS_VISIBLE, 0, 0, 10, 10, rootWindow, NULL, hInst, NULL);
+ Assert::IsFalse(FancyZonesWindowUtils::IsRoot(window));
+
+ Assert::AreEqual(FancyZonesWindowProcessing::ProcessabilityType::NonRootWindow, FancyZonesWindowProcessing::DefineWindowType(window));
+ Assert::IsFalse(FancyZonesWindowProcessing::IsProcessable(window));
+ }
+
+ TEST_METHOD (Popup_App)
+ {
+ HWND window = Mocks::WindowCreate(hInst, L"", L"", 0, WS_TILEDWINDOW | WS_POPUP);
+
+ Assert::AreEqual(FancyZonesWindowProcessing::ProcessabilityType::Processable, FancyZonesWindowProcessing::DefineWindowType(window));
+ Assert::IsTrue(FancyZonesWindowProcessing::IsProcessable(window));
+ }
+
+ TEST_METHOD (Popup_Menu)
+ {
+ HWND window = Mocks::WindowCreate(hInst, L"", L"", 0, WS_POPUP | WS_TILED | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
+
+ Assert::AreEqual(FancyZonesWindowProcessing::ProcessabilityType::NonProcessablePopupWindow, FancyZonesWindowProcessing::DefineWindowType(window));
+ Assert::IsFalse(FancyZonesWindowProcessing::IsProcessable(window));
+ }
+
+ TEST_METHOD (Popup_MenuEdge)
+ {
+ HWND window = Mocks::WindowCreate(hInst, L"", L"", 0, WS_POPUP | WS_TILED | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_THICKFRAME | WS_SIZEBOX);
+
+ Assert::AreEqual(FancyZonesWindowProcessing::ProcessabilityType::NonProcessablePopupWindow, FancyZonesWindowProcessing::DefineWindowType(window));
+ Assert::IsFalse(FancyZonesWindowProcessing::IsProcessable(window));
+ }
+
+ TEST_METHOD (Popup_Calculator)
+ {
+ HWND window = Mocks::WindowCreate(hInst, L"", L"", 0, WS_BORDER | WS_CLIPSIBLINGS | WS_DLGFRAME | WS_GROUP | WS_POPUP | WS_POPUPWINDOW | WS_SIZEBOX | WS_TABSTOP | WS_TILEDWINDOW);
+
+ Assert::AreEqual(FancyZonesWindowProcessing::ProcessabilityType::Processable, FancyZonesWindowProcessing::DefineWindowType(window));
+ Assert::IsTrue(FancyZonesWindowProcessing::IsProcessable(window));
+ }
+
+ TEST_METHOD (Popup_CalculatorTopmost)
+ {
+ HWND window = Mocks::WindowCreate(hInst, L"", L"", 0, WS_BORDER | WS_CAPTION | WS_CLIPSIBLINGS | WS_DLGFRAME | WS_OVERLAPPED | WS_POPUP | WS_POPUPWINDOW | WS_SIZEBOX | WS_SYSMENU | WS_THICKFRAME);
+
+ Assert::AreEqual(FancyZonesWindowProcessing::ProcessabilityType::Processable, FancyZonesWindowProcessing::DefineWindowType(window));
+ Assert::IsTrue(FancyZonesWindowProcessing::IsProcessable(window));
+ }
+
+ TEST_METHOD(Popup_FacebookMessenger)
+ {
+ HWND window = Mocks::WindowCreate(hInst, L"", L"", 0, WS_GROUP | WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_POPUP | WS_TABSTOP | WS_THICKFRAME);
+
+ Assert::AreEqual(FancyZonesWindowProcessing::ProcessabilityType::Processable, FancyZonesWindowProcessing::DefineWindowType(window));
+ Assert::IsTrue(FancyZonesWindowProcessing::IsProcessable(window));
+ }
+
+ TEST_METHOD (ChildWindow_OptionDisabled)
+ {
+ FancyZonesSettings::instance().SetSettings(Settings{ .allowSnapChildWindows = false });
+ HWND parentWindow = Mocks::WindowCreate(hInst, L"", L"", 0, WS_TILEDWINDOW);
+ if (!IsWindowVisible(parentWindow))
+ {
+ // skip the test if the parent window isn't visible.
+ // test can run locally, but will fail in CI because of the configuration
+ return;
+ }
+
+ HWND window = Mocks::WindowCreate(hInst, L"", L"", 0, 0, parentWindow);
+ Assert::IsTrue(IsWindowVisible(window), L"Child window not visible");
+ Assert::IsTrue(FancyZonesWindowUtils::HasVisibleOwner(window), L"Child window doesn't have visible owner");
+
+ Assert::AreEqual(FancyZonesWindowProcessing::ProcessabilityType::ChildWindow, FancyZonesWindowProcessing::DefineWindowType(window));
+ Assert::IsFalse(FancyZonesWindowProcessing::IsProcessable(window));
+ }
+
+ TEST_METHOD (ChildWindow_OptionEnabled)
+ {
+ FancyZonesSettings::instance().SetSettings(Settings{ .allowSnapChildWindows = true });
+ HWND parentWindow = Mocks::WindowCreate(hInst, L"", L"", 0, WS_TILEDWINDOW);
+ if (!IsWindowVisible(parentWindow))
+ {
+ // skip the test if the parent window isn't visible.
+ // test can run locally, but will fail in CI because of the configuration
+ return;
+ }
+
+ HWND window = Mocks::WindowCreate(hInst, L"", L"", 0, 0, parentWindow);
+
+ Assert::AreEqual(FancyZonesWindowProcessing::ProcessabilityType::Processable, FancyZonesWindowProcessing::DefineWindowType(window));
+ Assert::IsTrue(FancyZonesWindowProcessing::IsProcessable(window));
+ }
+
+ TEST_METHOD (ExcludedApp_ByDefault)
+ {
+ // set class from the excluded list
+ HWND window = Mocks::WindowCreate(hInst, L"", L"SysListView32");
+
+ Assert::AreEqual(FancyZonesWindowProcessing::ProcessabilityType::Excluded, FancyZonesWindowProcessing::DefineWindowType(window));
+ Assert::IsFalse(FancyZonesWindowProcessing::IsProcessable(window));
+ }
+
+ TEST_METHOD (ExcludedApp_ByDefault_SplashScreen)
+ {
+ HWND window = Mocks::WindowCreate(hInst, L"", L"MsoSplash");
+
+ Assert::AreEqual(FancyZonesWindowProcessing::ProcessabilityType::Excluded, FancyZonesWindowProcessing::DefineWindowType(window));
+ Assert::IsFalse(FancyZonesWindowProcessing::IsProcessable(window));
+ }
+
+ TEST_METHOD (ExcludedApp_ByUser)
+ {
+ // case sensitive, should be uppercase
+ FancyZonesSettings::instance().SetSettings(Settings{ .excludedAppsArray = { L"TEST_EXCLUDED" } });
+
+ // exclude by window title
+ HWND window = Mocks::WindowCreate(hInst, L"Test_Excluded");
+
+ Assert::AreEqual(FancyZonesWindowProcessing::ProcessabilityType::Excluded, FancyZonesWindowProcessing::DefineWindowType(window));
+ Assert::IsFalse(FancyZonesWindowProcessing::IsProcessable(window));
+ }
+
+ TEST_METHOD (ProcessableWindow)
+ {
+ HWND window = Mocks::WindowCreate(hInst, L"", L"", 0, WS_TILEDWINDOW);
+
+ Assert::AreEqual(FancyZonesWindowProcessing::ProcessabilityType::Processable, FancyZonesWindowProcessing::DefineWindowType(window));
+ Assert::IsTrue(FancyZonesWindowProcessing::IsProcessable(window));
+ }
+ };
+}
\ No newline at end of file
diff --git a/src/modules/fancyzones/FancyZonesTests/UnitTests/WorkArea.Spec.cpp b/src/modules/fancyzones/FancyZonesTests/UnitTests/WorkArea.Spec.cpp
index 0506e0c6d4..ce3963a3eb 100644
--- a/src/modules/fancyzones/FancyZonesTests/UnitTests/WorkArea.Spec.cpp
+++ b/src/modules/fancyzones/FancyZonesTests/UnitTests/WorkArea.Spec.cpp
@@ -249,7 +249,7 @@ namespace FancyZonesUnitTests
AppliedLayouts::instance().ApplyLayout(m_workAreaId, layout);
const auto workArea = WorkArea::Create(m_hInst, m_workAreaId, m_parentUniqueId, m_workAreaRect);
- const auto window = Mocks::WindowCreate(m_hInst);
+ const auto window = Mocks::WindowCreate(m_hInst, L"", L"", 0, WS_THICKFRAME);
SetWindowPos(window, nullptr, 150, 150, 450, 550, SWP_SHOWWINDOW);
diff --git a/src/modules/fancyzones/UnitTests-FancyZonesEditor/UnitTests-FancyZonesEditor.csproj b/src/modules/fancyzones/UnitTests-FancyZonesEditor/UnitTests-FancyZonesEditor.csproj
index a146ad62b2..8d1972207f 100644
--- a/src/modules/fancyzones/UnitTests-FancyZonesEditor/UnitTests-FancyZonesEditor.csproj
+++ b/src/modules/fancyzones/UnitTests-FancyZonesEditor/UnitTests-FancyZonesEditor.csproj
@@ -1,7 +1,7 @@
- net7.0-windows10.0.20348.0
+ net8.0-windows10.0.20348.0
10.0.19041.0
10.0.19041.0
enable
diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/CanvasEditorWindow.xaml b/src/modules/fancyzones/editor/FancyZonesEditor/CanvasEditorWindow.xaml
index 9541ff53f5..805d8efbf0 100644
--- a/src/modules/fancyzones/editor/FancyZonesEditor/CanvasEditorWindow.xaml
+++ b/src/modules/fancyzones/editor/FancyZonesEditor/CanvasEditorWindow.xaml
@@ -74,8 +74,8 @@
TabIndex="2" />
diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/CanvasZone.xaml.cs b/src/modules/fancyzones/editor/FancyZonesEditor/CanvasZone.xaml.cs
index ac9c8ac7c3..1429bda4f8 100644
--- a/src/modules/fancyzones/editor/FancyZonesEditor/CanvasZone.xaml.cs
+++ b/src/modules/fancyzones/editor/FancyZonesEditor/CanvasZone.xaml.cs
@@ -237,7 +237,7 @@ namespace FancyZonesEditor
private SnappyHelperBase snappyX;
private SnappyHelperBase snappyY;
- private SnappyHelperBase NewMagneticSnapper(bool isX, ResizeMode mode)
+ private SnappyHelperMagnetic NewMagneticSnapper(bool isX, ResizeMode mode)
{
Rect workingArea = App.Overlay.WorkArea;
int screenAxisOrigin = (int)(isX ? workingArea.Left : workingArea.Top);
@@ -245,7 +245,7 @@ namespace FancyZonesEditor
return new SnappyHelperMagnetic(Model.Zones, ZoneIndex, isX, mode, screenAxisOrigin, screenAxisSize);
}
- private SnappyHelperBase NewNonMagneticSnapper(bool isX, ResizeMode mode)
+ private SnappyHelperNonMagnetic NewNonMagneticSnapper(bool isX, ResizeMode mode)
{
Rect workingArea = App.Overlay.WorkArea;
int screenAxisOrigin = (int)(isX ? workingArea.Left : workingArea.Top);
diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Controls/CustomSliderAutomationPeer.cs b/src/modules/fancyzones/editor/FancyZonesEditor/Controls/CustomSliderAutomationPeer.cs
index 01e17f70b8..5971f2c722 100644
--- a/src/modules/fancyzones/editor/FancyZonesEditor/Controls/CustomSliderAutomationPeer.cs
+++ b/src/modules/fancyzones/editor/FancyZonesEditor/Controls/CustomSliderAutomationPeer.cs
@@ -3,6 +3,7 @@
// See the LICENSE file in the project root for more information.
using System.Globalization;
+using System.Text;
using System.Windows.Automation.Peers;
using System.Windows.Controls;
@@ -10,6 +11,8 @@ namespace FancyZonesEditor.Controls
{
internal sealed class CustomSliderAutomationPeer : SliderAutomationPeer
{
+ private static readonly CompositeFormat CustomSliderAnnounce = System.Text.CompositeFormat.Parse(Properties.Resources.Custom_slider_announce);
+
private string name = string.Empty;
public CustomSliderAutomationPeer(Slider owner)
@@ -29,7 +32,7 @@ namespace FancyZonesEditor.Controls
string announce = string.Format(
CultureInfo.CurrentCulture,
- Properties.Resources.Custom_slider_announce,
+ CustomSliderAnnounce,
name,
element.Minimum,
element.Maximum,
diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/EditorWindow.cs b/src/modules/fancyzones/editor/FancyZonesEditor/EditorWindow.cs
index b79e66c07f..81993a5cf2 100644
--- a/src/modules/fancyzones/editor/FancyZonesEditor/EditorWindow.cs
+++ b/src/modules/fancyzones/editor/FancyZonesEditor/EditorWindow.cs
@@ -18,7 +18,7 @@ namespace FancyZonesEditor
EditingLayout = editingLayout;
}
- protected void OnSaveApplyTemplate(object sender, RoutedEventArgs e)
+ protected void OnSave(object sender, RoutedEventArgs e)
{
Logger.LogTrace();
@@ -31,15 +31,8 @@ namespace FancyZonesEditor
EditingLayout.Persist();
- MainWindowSettingsModel settings = ((App)Application.Current).MainWindowSettings;
- settings.SetAppliedModel(EditingLayout);
- App.Overlay.Monitors[App.Overlay.CurrentDesktop].SetLayoutSettings(EditingLayout);
-
App.FancyZonesEditorIO.SerializeLayoutTemplates();
App.FancyZonesEditorIO.SerializeCustomLayouts();
- App.FancyZonesEditorIO.SerializeAppliedLayouts();
- App.FancyZonesEditorIO.SerializeDefaultLayouts();
- App.FancyZonesEditorIO.SerializeLayoutHotkeys();
Close();
}
diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/FancyZonesEditor.csproj b/src/modules/fancyzones/editor/FancyZonesEditor/FancyZonesEditor.csproj
index 6c876344dd..dae02ff5ba 100644
--- a/src/modules/fancyzones/editor/FancyZonesEditor/FancyZonesEditor.csproj
+++ b/src/modules/fancyzones/editor/FancyZonesEditor/FancyZonesEditor.csproj
@@ -17,15 +17,15 @@
- win10-x64
+ win-x64
- win10-arm64
+ win-arm64
{5CCC8468-DEC8-4D36-99D4-5C891BEBD481}
- net7.0-windows10.0.20348.0
+ net8.0-windows10.0.20348.0
10.0.19041.0
10.0.19041.0
{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/GridEditorWindow.xaml b/src/modules/fancyzones/editor/FancyZonesEditor/GridEditorWindow.xaml
index 63e440cc19..c49d7e5118 100644
--- a/src/modules/fancyzones/editor/FancyZonesEditor/GridEditorWindow.xaml
+++ b/src/modules/fancyzones/editor/FancyZonesEditor/GridEditorWindow.xaml
@@ -72,8 +72,8 @@
TabIndex="1" />
diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml.cs b/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml.cs
index 944222b73d..383b10181a 100644
--- a/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml.cs
+++ b/src/modules/fancyzones/editor/FancyZonesEditor/MainWindow.xaml.cs
@@ -6,6 +6,7 @@ using System;
using System.Collections.Generic;
using System.Globalization;
using System.Runtime.InteropServices;
+using System.Text;
using System.Windows;
using System.Windows.Automation;
using System.Windows.Automation.Peers;
@@ -36,6 +37,10 @@ namespace FancyZonesEditor
private bool haveTriedToGetFocusAlready;
+ private static readonly CompositeFormat EditTemplate = System.Text.CompositeFormat.Parse(Properties.Resources.Edit_Template);
+ private static readonly CompositeFormat PixelValue = System.Text.CompositeFormat.Parse(Properties.Resources.Pixel_Value);
+ private static readonly CompositeFormat TemplateZoneCountValue = System.Text.CompositeFormat.Parse(Properties.Resources.Template_Zone_Count_Value);
+
public int WrapPanelItemSize { get; set; } = DefaultWrapPanelItemSize;
public MainWindow(bool spanZonesAcrossMonitors, Rect workArea)
@@ -335,7 +340,7 @@ namespace FancyZonesEditor
App.Overlay.StartEditing(_settings.SelectedModel);
Keyboard.ClearFocus();
- EditLayoutDialogTitle.Text = string.Format(CultureInfo.CurrentCulture, Properties.Resources.Edit_Template, ((LayoutModel)dataContext).Name);
+ EditLayoutDialogTitle.Text = string.Format(CultureInfo.CurrentCulture, EditTemplate, ((LayoutModel)dataContext).Name);
await EditLayoutDialog.ShowAsync();
}
@@ -567,7 +572,7 @@ namespace FancyZonesEditor
FrameworkElementAutomationPeer.FromElement(SensitivityInput) as SliderAutomationPeer;
string activityId = "sliderValueChanged";
- string value = string.Format(CultureInfo.CurrentCulture, Properties.Resources.Pixel_Value, SensitivityInput.Value);
+ string value = string.Format(CultureInfo.CurrentCulture, PixelValue, SensitivityInput.Value);
if (peer != null && value != null)
{
@@ -588,7 +593,7 @@ namespace FancyZonesEditor
FrameworkElementAutomationPeer.FromElement(TemplateZoneCount) as SliderAutomationPeer;
string activityId = "templateZoneCountValueChanged";
- string value = string.Format(CultureInfo.CurrentCulture, Properties.Resources.Template_Zone_Count_Value, TemplateZoneCount.Value);
+ string value = string.Format(CultureInfo.CurrentCulture, TemplateZoneCountValue, TemplateZoneCount.Value);
if (peer != null && value != null)
{
@@ -609,7 +614,7 @@ namespace FancyZonesEditor
FrameworkElementAutomationPeer.FromElement(Spacing) as SliderAutomationPeer;
string activityId = "spacingValueChanged";
- string value = string.Format(CultureInfo.CurrentCulture, Properties.Resources.Pixel_Value, Spacing.Value);
+ string value = string.Format(CultureInfo.CurrentCulture, PixelValue, Spacing.Value);
if (peer != null && value != null)
{
diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Models/LayoutHotkeysModel.cs b/src/modules/fancyzones/editor/FancyZonesEditor/Models/LayoutHotkeysModel.cs
index 54311b4b03..f8b783768a 100644
--- a/src/modules/fancyzones/editor/FancyZonesEditor/Models/LayoutHotkeysModel.cs
+++ b/src/modules/fancyzones/editor/FancyZonesEditor/Models/LayoutHotkeysModel.cs
@@ -43,12 +43,12 @@ namespace FancyZonesEditor.Models
public bool SelectKey(string key, string uuid)
{
- if (!SelectedKeys.ContainsKey(key))
+ if (!SelectedKeys.TryGetValue(key, out string value))
{
return false;
}
- if (SelectedKeys[key] == uuid)
+ if (value == uuid)
{
return true;
}
diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Models/LayoutModel.cs b/src/modules/fancyzones/editor/FancyZonesEditor/Models/LayoutModel.cs
index 95b4f5f064..ef2b2a4617 100644
--- a/src/modules/fancyzones/editor/FancyZonesEditor/Models/LayoutModel.cs
+++ b/src/modules/fancyzones/editor/FancyZonesEditor/Models/LayoutModel.cs
@@ -377,6 +377,7 @@ namespace FancyZonesEditor.Models
public void Persist()
{
PersistData();
+ FirePropertyChanged(nameof(PersistData));
}
public void LayoutHotkeys_PropertyChanged(object sender, PropertyChangedEventArgs e)
diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Models/MainWindowSettingsModel.cs b/src/modules/fancyzones/editor/FancyZonesEditor/Models/MainWindowSettingsModel.cs
index 5e64d2fdb1..58ee764d59 100644
--- a/src/modules/fancyzones/editor/FancyZonesEditor/Models/MainWindowSettingsModel.cs
+++ b/src/modules/fancyzones/editor/FancyZonesEditor/Models/MainWindowSettingsModel.cs
@@ -2,6 +2,7 @@
// 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.Collections.ObjectModel;
using System.ComponentModel;
@@ -231,7 +232,7 @@ namespace FancyZonesEditor
{
foreach (LayoutModel model in CustomModels)
{
- if (model.Uuid == currentApplied.ZonesetUuid.ToUpperInvariant())
+ if (string.Equals(model.Uuid, currentApplied.ZonesetUuid, StringComparison.OrdinalIgnoreCase))
{
// found match
foundModel = model;
diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Utils/RelayCommand.cs b/src/modules/fancyzones/editor/FancyZonesEditor/Utils/RelayCommand.cs
index ecb0d0f285..d24f7cdfd3 100644
--- a/src/modules/fancyzones/editor/FancyZonesEditor/Utils/RelayCommand.cs
+++ b/src/modules/fancyzones/editor/FancyZonesEditor/Utils/RelayCommand.cs
@@ -20,10 +20,7 @@ namespace FancyZonesEditor.Utils
public RelayCommand(Action