Compare commits

..

1 Commits

Author SHA1 Message Date
vanzue
4e4d0a610f wire things up for cmdpal & kbm 2026-03-12 18:11:41 +08:00
1542 changed files with 30395 additions and 135054 deletions

View File

@@ -57,7 +57,6 @@ body:
- Environment Variables
- FancyZones
- FancyZones Editor
- Grab And Move
- File Locksmith
- "File Explorer: Preview Pane"
- "File Explorer: Thumbnail preview"
@@ -70,7 +69,6 @@ body:
- Mouse Without Borders
- New+
- Peek
- Power Display
- PowerRename
- PowerToys Run
- Quick Accent

View File

@@ -1,7 +1,6 @@
# COLORS
argb
Bgr
bgra
BLACKONWHITE
BLUEGRAY
@@ -19,7 +18,6 @@ OLIVEGREEN
PALEBLUE
PArgb
Pbgra
SRGBTo
WHITEONBLACK
@@ -30,7 +28,6 @@ RUS
AYUV
bak
HDP
Bcl
bgcode
Deflatealgorithm
@@ -51,7 +48,6 @@ resw
resx
srt
Stereolithography
taskmgr
terabyte
UYVY
xbf
@@ -128,7 +124,6 @@ HOLDSPACE
HOLDBACKSPACE
IDIGNORE
KBDLLHOOKSTRUCT
keydowns
keyevent
LAlt
LBUTTON
@@ -187,12 +182,6 @@ xmlutil
# Prefix
pcs
# EXPRTK / C++ MATH
ifunction
isinf
isnan
# User32.SYSTEM_METRICS_INDEX.cs
CLEANBOOT
@@ -308,8 +297,6 @@ pwa
AOT
Aot
ify
TFM
# YML
onefuzz
@@ -317,7 +304,6 @@ onefuzz
# NameInCode
leilzh
mengyuanchen
contoso
# DllName
testhost
@@ -337,61 +323,17 @@ MRUCMPPROC
MRUINFO
REGSTR
#Xaml
NVI
Storyboards
# Misc Win32 APIs and PInvokes
DEFAULTTONEAREST
INVOKEIDLIST
LCMAP
MEMORYSTATUSEX
ABE
Mdt
HTCAPTION
POSCHANGED
QPC
QUERYPOS
SETAUTOHIDEBAR
ULW
WINDOWPOS
WINEVENTPROC
WORKERW
FULLSCREENAPP
ACLO
CACLI
DOENVSUBST
FILESYSONLY
URLIS
WAITTIMEOUT
DEFAULTTONEAREST
DWRITE
LWIN
VCENTER
VREDRAW
# COM/WinRT interface prefixes and type fragments
BAlt
BShift
Cmanifest
Cmodule
Cuuid
Dng
IApplication
IDisposable
IEnum
IFolder
IInitialize
IMemory
IOle
ipreview
IProperty
IShell
ithumbnail
IVirtual
# Test frameworks
MSTEST
# PowerRename metadata pattern abbreviations (used in tests and regex patterns)
DDDD
@@ -403,12 +345,6 @@ YYY
# Unicode
precomposed
# names of characters
zwsp
# mermaid
autonumber
# GitHub issue/PR commands
azp
feedbackhub
@@ -425,10 +361,3 @@ Nonpaged
# XAML
Untargeted
# Program names
SEARCHHOST
SHELLEXPERIENCEHOST
SHELLHOST
STARTMENUEXPERIENCEHOST
WIDGETBOARD

View File

@@ -178,9 +178,7 @@ Taras
TBM
Teutsch
tilovell
traies
Triet
udit
urnotdfs
vednig
waaverecords
@@ -209,7 +207,6 @@ Bilibili
BVID
capturevideosample
cmdow
contoso
Contoso
Controlz
cortana
@@ -226,7 +223,6 @@ Moq
mozilla
mspaint
Newtonsoft
NVIDIA
onenote
openai
Quickime

View File

@@ -1,26 +1,9 @@
accelscroll
acq
adr
Adr
APPLYTOSUBMENUS
AUDCLNT
axisdefer
axisflip
axisstart
BGRX
bitmaps
blits
BREAKSCR
BUFFERFLAGS
Cands
capturepath
centiseconds
CLASSW
coeffs
coprime
CREATEDIBSECTION
CREATESTRUCTW
crossfades
Ctl
CTLCOLOR
CTLCOLORBTN
@@ -28,185 +11,53 @@ CTLCOLORDLG
CTLCOLOREDIT
CTLCOLORLISTBOX
CTrim
DBuffer
ddx
ddy
DEVSOURCE
DFCS
dlg
dlu
DONTCARE
downsample
DRAWITEM
DRAWITEMSTRUCT
droppedband
Droppedband
dsum
dupburst
dupsegments
DWLP
EDITCONTROL
ENABLEHOOK
ENDOFSTREAM
expectedlock
fabsf
fastscroll
FDE
GETCHANNELRECT
GETCHECK
GETCOUNT
GETSCREENSAVEACTIVE
GETSCREENSAVETIMEOUT
GETTHUMBRECT
GIFs
hcfdark
hcfwhitespace
HTBOTTOMRIGHT
HTHEME
htol
ICONINFORMATION
ICONWARNING
igc
Inj
jumprecover
KSDATAFORMAT
latestcapture
ldx
LEFTNOWORDWRAP
legitjumps
letterbox
lld
llu
llums
logfont
lookback
lround
lte
luma
Luma
manualdrop
maskcache
maxstep
MENUINFO
MFSTARTUP
mfxhw
mic
middledrop
MJPEG
MMRESULT
momentumreversal
mrate
mrt
narrowstrip
ncapture
ncm
nduplicates
niterations
nmonitor
NONCLIENTMETRICS
NONOTIFY
nonvle
nredraw
nstop
nsubpixel
ntorn
nvw
osc
OWNERDRAW
PBGRA
periodictrap
pillarbox
pfdc
playhead
pointerreuse
PSWA
pwfx
qpc
Qpc
quantums
RCZOOMITSCR
readback
READERF
realcapture
REFKNOWNFOLDERID
reposted
RETURNCMD
SCREENSAVE
SCRNSAVE
SCRNSAVECONFIGURE
scrnsavw
Scrnsavw
scrollramp
SCROLLSIZEGRIP
selftest
SETBARCOLOR
SETBKCOLOR
SETDEFID
SETRECT
SETSCREENSAVETIMEOUT
SHAREMODE
SHAREVIOLATION
shortlist
slowthenfast
smallstart
SNIPOCR
sqrtf
ssi
startuprecovery
stf
stopafter
STREAMFLAGS
submix
sxx
sxy
synthesising
syy
tallportal
tci
tcsicmp
TEXTMETRIC
tinystep
tme
toolbars
TRACKMOUSEEVENT
Unadvise
vaddq
vaddvq
vandq
vcgeq
vdup
VIDCAP
vld
vle
Vle
VLE
vminq
vmlal
vmull
vqaddq
vshrn
vsntprintf
vsnwprintf
vsync
WASAPI
WAVEFORMATEX
WAVEFORMATEXTENSIBLE
webcam
Webcam
webcams
wfopen
wideportal
wil
WMU
wrapjump
wtol
WTSSESSION
WTSUn
XEnd
XStart
XStep
YInternal
ZMBS
zncc
Zncc
ZNCC

View File

@@ -1,3 +1,6 @@
# D2D
#D?2D
# Repeated letters
\b([a-z])\g{-1}{2,}\b
@@ -11,7 +14,7 @@
^.*\b[Cc][Ss][Pp][Ee][Ll]{2}:\s*[Dd][Ii][Ss][Aa][Bb][Ll][Ee]-[Ll][Ii][Nn][Ee]\b
# copyright
Copyright (?:\([Cc]\)|©|)(?:[-\d, ]|and)+(?: [A-Z][a-z]+ [A-Z][a-z]+,?)+
Copyright (?:\([Cc]\)|)(?:[-\d, ]|and)+(?: [A-Z][a-z]+ [A-Z][a-z]+,?)+
# patch hunk comments
^@@ -\d+(?:,\d+|) \+\d+(?:,\d+|) @@ .*
@@ -19,10 +22,10 @@ Copyright (?:\([Cc]\)|©|)(?:[-\d, ]|and)+(?: [A-Z][a-z]+ [A-Z][a-z]+,?)+
index (?:[0-9a-z]{7,40},|)[0-9a-z]{7,40}\.\.[0-9a-z]{7,40}
# file permissions
(?:^|['"`\s])(?!-+\s)[-bcdLlpsw](?:[-r][-w][-Ssx]){2}[-r][-w][-SsTtx]\+?['"`\s]
['"`\s][-bcdLlpsw](?:[-r][-w][-Ssx]){2}[-r][-w][-SsTtx]\+?['"`\s]
# css fonts
\bfont(?:-family(?:[-\w+]*)|):[^;}]+
\bfont(?:-family|):[^;}]+
# css url wrappings
\burl\([^)]+\)
@@ -87,9 +90,6 @@ arn:aws:[-/:\w]+
# AWS VPC
vpc-\w+
# Azure AD
\baad\.\w{48}\b
# While you could try to match `http://` and `https://` by using `s?` in `https?://`, sometimes there
# YouTube url
\b(?:(?:www\.|)youtube\.com|youtu.be)/(?:channel/|embed/|user/|playlist\?list=|watch\?v=|v/|)[-a-zA-Z0-9?&=_%]*
@@ -171,7 +171,7 @@ themes\.googleusercontent\.com/static/fonts/[^/\s"]+/v\d+/[^.]+.
GHSA(?:-[0-9a-z]{4}){3}
# GitHub actions
\buses:\s+(['"]?)[-\w.]+/[-\w./]+@[-\w.]+\g{-1}
\buses:\s+[-\w.]+/[-\w./]+@[-\w.]+
# GitLab commit
\bgitlab\.[^/\s"]*/\S+/\S+/commit/[0-9a-f]{7,16}#[0-9a-f]{40}\b
@@ -240,7 +240,7 @@ accounts\.binance\.com/[a-z/]*oauth/authorize\?[-0-9a-zA-Z&%]*
\bmedium\.com/@?[^/\s"]+/[-\w]+
# microsoft
\b(?:https?://|)(?:(?:(?:blogs|download\.visualstudio|docs|msdn2?|research)\.|)microsoft|blogs\.msdn)\.co(?:m|\.\w\w)/[-_a-zA-Z0-9()=./%?#]*
\b(?:https?://|)(?:(?:(?:blogs|download\.visualstudio|docs|msdn2?|research)\.|)microsoft|blogs\.msdn)\.co(?:m|\.\w\w)/[-_a-zA-Z0-9()=./%]*
# powerbi
\bapp\.powerbi\.com/reportEmbed/[^"' ]*
# vs devops
@@ -414,7 +414,7 @@ ipfs://[0-9a-zA-Z]{3,}
\bgetopts\s+(?:"[^"]+"|'[^']+')
# ANSI color codes
(?:\\(?:u00|x)1[Bb]|\\03[1-7]|\x1b|\\u\{1[Bb]\})\[(?:\d+(?:;\d+)*|)m
(?:\\(?:u00|x)1[Bb]|\\03[1-7]|\x1b|\\u\{1[Bb]\})\[\d+(?:;\d+)*m
# URL escaped characters
%[0-9A-F][A-F](?=[A-Za-z])
@@ -431,7 +431,7 @@ sha\d+:[0-9a-f]*?[a-f]{3,}[0-9a-f]*
# sha-... -- uses a fancy capture
(\\?['"]|")[0-9a-f]{40,}\g{-1}
# hex runs
\b(?=(?:[a-fA-F]{0,2}\d)*[a-fA-F]{3})[0-9a-fA-F]{16,}\b
\b[0-9a-fA-F]{16,}\b
# hex in url queries
=[0-9a-fA-F]*?(?:[A-F]{3,}|[a-f]{3,})[0-9a-fA-F]*?&
# ssh
@@ -455,11 +455,7 @@ LS0tLS1CRUdJT.*
# uuid:
\b[0-9a-fA-F]{8}-(?:[0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}\b
# unicode escaped characters (4)
\\u[0-9a-fA-F]{4}
# hex digits including css/html color classes
# hex digits including css/html color classes:
(?:[\\0][xX]|\\u\{?|[uU]\+|#x?|%23|&H)[0-9_a-fA-FgGrR]*?[a-fA-FgGrR]{2,}[0-9_a-fA-FgGrR]*(?:[uUlL]{0,3}|[iu]\d+)\b
# integrity
@@ -482,7 +478,7 @@ Name\[[^\]]+\]=.*
(?:(?:\b|_|(?<=[a-z]))I|(?:\b|_)(?:nsI|isA))(?=(?:[A-Z][a-z]{2,})+(?:[A-Z\d]|\b))
# python
#\b(?i)py(?!gment|gmy|lon|ramid|ro|th)(?=[a-z]{2,})
#\b(?i)py(?!gments|gmy|lon|ramid|ro|th)(?=[a-z]{2,})
# crypt
(['"])\$2[ayb]\$.{56}\g{-1}
@@ -502,21 +498,12 @@ Name\[[^\]]+\]=.*
# go.sum
\bh1:\S+
# golang print-f-style functions
#(?i)(?<=append|comma|debug|equal|err|error|exit|fatal|format|info|log|name|panic|print|skip|scan|string|trace|true|warn|warning|wrap|write)(?:f|ln)(?:[ (]|$)
# golang regular expression
(?<!")\br".+?"
# imports
^import\s+(?:(?:static|type)\s+|)(?:[\w.]|\{\s*\w*?(?:,\s*(?:\w*|\*))+\s*\})+(?:\s+from (['"]).*?\g{-1}|)
^import\s+(?:(?:static|type)\s+|)(?:[\w.]|\{\s*\w*?(?:,\s*(?:\w*|\*))+\s*\})+
# scala modules
#("[^"]+"\s*%%?\s*){2,3}"[^"]+"
# Dataframes / NumPy
#\b(?:df|np)\.\w{3,}
# container images
image: [-\w./:@]+
@@ -546,18 +533,12 @@ content: (['"])[-a-zA-Z=;:/0-9+]*=\g{-1}
# Note that there's a high false positive rate, remove the `?=` and search for the regex to see if the matches seem like reasonable strings
(?<!['"])\b(?:B|BR|Br|F|FR|Fr|R|RB|RF|Rb|Rf|U|UR|Ur|b|bR|br|f|fR|fr|r|rB|rF|rb|rf|u|uR|ur)['"](?=[A-Z]{3,}|[A-Z][a-z]{2,}|[a-z]{3,})
# Regular expression for word breaks
#\\b(?=[a-z]{2})
# Regular expressions for (P|p)assword
\([A-Z]\|[a-z]\)[a-z]+
# Java regular expressions
Pattern\.(?:compile|matches)\(".*"
# JavaScript regular expressions
# javascript exec/test regex
/.{3,}?/[gim]*\.(?:exec|test)\(
# javascript test regex
/.{3,}/[gim]*\.test\(
# javascript match regex
\.match\(/[^/\s"]{3,}/[gim]*\s*
# javascript match regex
@@ -584,7 +565,7 @@ perl(?:\s+-[a-zA-Z]\w*)+
regexp?\.MustCompile\((?:`[^`]*`|".*"|'.*')\)
# regex choice
#\((?:\?:|)[^)|]+(?<! )\|(?!(?:jq|xargs)\b)[^)| ][^)]*\)
# \(\?:[^)]+\|[^)]+\)
# proto
^\s*(\w+)\s\g{-1} =
@@ -607,9 +588,6 @@ urn:shemas-jetbrains-com
# Debian changelog severity
[-\w]+ \(.*\) (?:\w+|baseline|unstable|experimental); urgency=(?:low|medium|high|emergency|critical)\b
# Red Hat Package management spec file dependencies
^(?:Build|)Requires: [-.\w]+
# kubernetes pod status lists
# https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-phase
\w+(?:-\w+)+\s+\d+/\d+\s+(?:Running|Pending|Succeeded|Failed|Unknown)\s+
@@ -664,8 +642,6 @@ PrependWithABINamepsace
>[-a-zA-Z=;:/0-9+]{3,}=</
# base64 encoded content, possibly wrapped in mime
#(?:^|[\s=;:?])[-a-zA-Z=;:/0-9+]{50,}(?:[\s=;:?]|$)
# jwt
(?:\be[wy][-a-zA-Z=;:/0-9+]+\.){2}[-_\w]+
# base64 encoded json
\beyJ[-a-zA-Z=;:/0-9+]+
# base64 encoded pkcs
@@ -703,9 +679,9 @@ systemd.*?running in system mode \([-+].*\)$
# Non-English
# Even repositories expecting pure English content can unintentionally have Non-English content... People will occasionally mistakenly enter [homoglyphs](https://en.wikipedia.org/wiki/Homoglyph) which are essentially typos, and using this pattern will mean check-spelling will not complain about them.
# .
#
# If the content to be checked should be written in English and the only Non-English items will be people's names, then you can consider adding this.
# .
#
# Alternatively, if you're using check-spelling v0.0.25+, and you would like to _check_ the Non-English content for spelling errors, you can. For information on how to do so, see:
# https://docs.check-spelling.dev/Feature:-Configurable-word-characters.html#unicode
[a-zA-Z]*[ÀÁÂÃÄÅÆČÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæčçèéêëìíîïðñòóôõöøùúûüýÿĀāŁłŃńŅņŒœŚśŠšŜŝŸŽžź][a-zA-Z]{3}[a-zA-ZÀÁÂÃÄÅÆČÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæčçèéêëìíîïðñòóôõöøùúûüýÿĀāŁłŃńŅņŒœŚśŠšŜŝŸŽžź]*|[a-zA-Z]{3,}[ÀÁÂÃÄÅÆČÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæčçèéêëìíîïðñòóôõöøùúûüýÿĀāŁłŃńŅņŒœŚśŠšŜŝŸŽžź]|[ÀÁÂÃÄÅÆČÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæčçèéêëìíîïðñòóôõöøùúûüýÿĀāŁłŃńŅņŒœŚśŠšŜŝŸŽžź][a-zA-Z]{3,}
@@ -717,7 +693,7 @@ systemd.*?running in system mode \([-+].*\)$
# This corpus only had capital letters, but you probably want lowercase ones as well.
\b[LN]'+[a-z]{2,}\b
# LaTeX
# latex (check-spelling >= 0.0.22)
\\\w{2,}\{
# American Mathematical Society (AMS) / Doxygen
@@ -744,6 +720,7 @@ nolint:\s*[\w,]+
# cygwin paths
/cygdrive/[a-zA-Z]/(?:Program Files(?: \(.*?\)| ?)(?:/[-+.~\\/()\w ]+)*|[-+.~\\/()\w])+
# in check-spelling@v0.0.22+, printf markers aren't automatically consumed
# printf markers
#(?<!\\)\\[nrt](?=[a-z]{2,})
# alternate printf markers if you run into latex and friends
@@ -772,12 +749,12 @@ W/"[^"]+"
# Compiler flags (Unix, Java/Scala)
# Use if you have things like `-Pdocker` and want to treat them as `docker`
#(?:^|[\t ,>"'`=\[(#])-(?:(?:J-|)[DPWXY]|[Llf])(?=[A-Z]{2,}|[A-Z][a-z]|[a-z]{2,})
#(?:^|[\t ,>"'`=(#])-(?:(?:J-|)[DPWXY]|[Llf])(?=[A-Z]{2,}|[A-Z][a-z]|[a-z]{2,})
# Compiler flags (Windows / PowerShell)
# This is a subset of the more general compiler flags pattern.
# It avoids matching `-Path` to prevent it from being treated as `ath`
#(?:^|[\t ,"'`=\[(#])-(?:[DPL](?=[A-Z]{2,})|[WXYlf](?=[A-Z]{2,}|[A-Z][a-z]|[a-z]{2,}))
#(?:^|[\t ,"'`=(#])-(?:[DPL](?=[A-Z]{2,})|[WXYlf](?=[A-Z]{2,}|[A-Z][a-z]|[a-z]{2,}))
# Compiler flags (linker)
,-B
@@ -785,7 +762,7 @@ W/"[^"]+"
# Library prefix
# e.g., `lib`+`archive`, `lib`+`raw`, `lib`+`unwind`
# (ignores some words that happen to start with `lib`)
(?:\b|_)[Ll]ib(?!era[lt])(?:re(?=office)|era|)(?!ero|erty|rar(?:i(?:an|es)|y))(?=[a-z])
(?:\b|_)[Ll]ib(?:re(?=office)|)(?!era[lt]|ero|erty|rar(?:i(?:an|es)|y))(?=[a-z])
# iSCSI iqn (approximate regex)
\biqn\.[0-9]{4}-[0-9]{2}(?:[\.-][a-z][a-z0-9]*)*\b
@@ -796,9 +773,9 @@ W/"[^"]+"
# curl arguments
\b(?:\\n|)curl(?:\.exe|)(?:\s+-[a-zA-Z]{1,2}\b)*(?:\s+-[a-zA-Z]{3,})(?:\s+-[a-zA-Z]+)*
# set arguments
\b(?:bash|(?<!\.)sh|set)(?:\s+[-+][abefimouxE]{1,2})*\s+[-+][abefimouxE]{3,}(?:\s+[-+][abefimouxE]+)*
\b(?:bash|sh|set)(?:\s+[-+][abefimouxE]{1,2})*\s+[-+][abefimouxE]{3,}(?:\s+[-+][abefimouxE]+)*
# tar arguments
\b(?:\\n|)g?tar(?:\.exe|)(?:\s-C \S+|(?:\s+--[-a-zA-Z]+|\s+-[a-zA-Z]+|\s[ABGJMOPRSUWZacdfh-pr-xz]+\b)(?:=[^ ]*|))+
\b(?:\\n|)g?tar(?:\.exe|)(?:(?:\s+--[-a-zA-Z]+|\s+-[a-zA-Z]+|\s[ABGJMOPRSUWZacdfh-pr-xz]+\b)(?:=[^ ]*|))+
# tput arguments -- https://man7.org/linux/man-pages/man5/terminfo.5.html -- technically they can be more than 5 chars long...
\btput\s+(?:(?:-[SV]|-T\s*\w+)\s+)*\w{3,5}\b
# macOS temp folders

View File

@@ -112,8 +112,6 @@
^src/modules/cmdpal/Microsoft\.CmdPal\.UI/Settings/InternalPage\.SampleData\.cs$
^src/modules/cmdpal/Tests/Microsoft\.CmdPal\.Common\.UnitTests/.*\.TestData\.cs$
^src/modules/cmdpal/Tests/Microsoft\.CmdPal\.Common\.UnitTests/Text/.*\.cs$
^src/modules/cmdpal/Tests/Microsoft\.CommandPalette\.Extensions\.Toolkit\.UnitTests/FuzzyMatcherComparisonTests.cs$
^src/modules/cmdpal/Tests/Microsoft\.CommandPalette\.Extensions\.Toolkit\.UnitTests/FuzzyMatcherDiacriticsTests.cs$
^src/modules/colorPicker/ColorPickerUI/Shaders/GridShader\.cso$
^src/modules/launcher/Plugins/Microsoft\.PowerToys\.Run\.Plugin\.TimeDate/Properties/
^src/modules/MouseUtils/MouseJumpUI/MainForm\.resx$
@@ -142,7 +140,8 @@
^tools/project_template/ModuleTemplate/resource\.h$
^tools/Verification scripts/Check preview handler registration\.ps1$
ignore$
^src/modules/registrypreview/RegistryPreviewUILib/Controls/HexBox/.*$
^src/common/CalculatorEngineCommon/exprtk\.hpp$
src/modules/cmdpal/ext/SamplePagesExtension/Pages/SampleMarkdownImagesPage.cs
^src/modules/powerrename/unittests/testdata/avif_test\.avif$
^src/modules/powerrename/unittests/testdata/heif_test\.heic$
^deps/spdlog-msvc-fix/

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -1,30 +1,10 @@
# See https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples:-patterns
Inno Setup
FFmpeg
# https://github.com/MicrosoftEdge/edge-launcher
MIcrosoftEdgeLauncherCsharp
# x64
(?:(?<=[a-df-z])x|(?<=[A-Z]X))64
# reversed irreversible binomials
\b(?:mouse down and up|low and high)\b
# marker to ignore all code on line
^.*/\* #no-spell-check-line \*/.*$
# marker for ignoring a comment to the end of the line
// #no-spell-check.*$
# JavaScript regex literals that start with \b can be reported as "b..." words.
# Example: /\bclass\s+.../
^\s*/\\[b].{3,}?/[gim]*\s*(?:\)(?:;|$)|,$)
# GitHub API header token used in code (not natural language).
\bx-ratelimit-reset\b
# Gaelic
Gàidhlig
@@ -91,14 +71,11 @@ StringComparer.OrdinalIgnoreCase\) \{.*\}
# the last line of mimetype="application/x-microsoft.net.object.bytearray.base64" things in .resx files
^\s*[-a-zA-Z=;:/0-9+]*[-a-zA-Z;:/0-9+][-a-zA-Z=;:/0-9+]*=$
# DateTime Formats
Get-Date -Format \w+|DateTime\.Now(?::|\.ToString\(")\w+
# Automatically suggested patterns
# hit-count: 5402 file-count: 1339
# IServiceProvider / isAThing
(?:(?:\b|_|(?<=[a-z]))[A-Z]|(?:\b|_)(?:nsI|isA))(?=(?:[A-Z][a-z]{2,})+(?:[A-Z\d]|\b))
(?:(?:\b|_|(?<=[a-z]))[IT]|(?:\b|_)(?:nsI|isA))(?=(?:[A-Z][a-z]{2,})+(?:[A-Z\d]|\b))
# hit-count: 2073 file-count: 842
# #includes
@@ -182,10 +159,6 @@ aka\.ms/[a-zA-Z0-9]+
# kubernetes crd patterns
^\s*pattern: .*$
# hit-count: 7 file-count: 3
# unicode escaped characters (4)
\\u[0-9a-fA-F]{4}
# hit-count: 5 file-count: 3
# URL escaped characters
%[0-9A-F][A-F](?=[A-Za-z])
@@ -198,10 +171,6 @@ aka\.ms/[a-zA-Z0-9]+
# medium
\bmedium\.com/@?[^/\s"]+/[-\w:/*.]+
# hit-count: 2 file-count: 2
# tar arguments
\b(?:\\n|)g?tar(?:\.exe|)(?:\s-C \S+|(?:\s+--[-a-zA-Z]+|\s+-[a-zA-Z]+|\s[ABGJMOPRSUWZacdfh-pr-xz]+\b)(?:=[^ ]*|))+
# hit-count: 2 file-count: 1
# While you could try to match `http://` and `https://` by using `s?` in `https?://`, sometimes there
# YouTube url
@@ -215,9 +184,22 @@ aka\.ms/[a-zA-Z0-9]+
# curl arguments
\b(?:\\n|)curl(?:\.exe|)(?:\s+-[a-zA-Z]{1,2}\b)*(?:\s+-[a-zA-Z]{3,})(?:\s+-[a-zA-Z]+)*
# hit-count: 1 file-count: 1
# tar arguments
\b(?:\\n|)g?tar(?:\.exe|)(?:(?:\s+--[-a-zA-Z]+|\s+-[a-zA-Z]+|\s[ABGJMOPRSUWZacdfh-pr-xz]+\b)(?:=[^ ]*|))+
# #pragma lib
^\s*#pragma comment\(lib, ".*?"\)
# UnitTests
\[DataRow\(.*\)\]
# AdditionalDependencies
<AdditionalDependencies>.*<
# the last line of mimetype="application/x-microsoft.net.object.bytearray.base64" things in .resx files
^\s*[-a-zA-Z=;:/0-9+]*[-a-zA-Z;:/0-9+][-a-zA-Z=;:/0-9+]*=$
RegExp\(@?([`'"]).*?\g{-1}\)|(?:escapes|regEx):\s*(?:/.*/|([`'"]).*?\g{-1})|return/.*?/
# Questionably acceptable forms of `in to`
@@ -237,15 +219,13 @@ RegExp\(@?([`'"]).*?\g{-1}\)|(?:escapes|regEx):\s*(?:/.*/|([`'"]).*?\g{-1})|retu
# mount
\bmount\s+-t\s+(\w+)\s+\g{-1}\b
# C types and repeated CSS values
\s(auto|await|buffalo|center|div|inherit|long|LONG|none|normal|solid|thin|transparent|very)(?:\s\g{-1})+\s
\s(auto|buffalo|center|div|inherit|long|LONG|none|normal|solid|thin|transparent|very)(?:\s\g{-1})+\s
# C enum and struct
\b(?:enum|struct)\s+(\w+)\s+\g{-1}\b
# go templates
\s(\w+)\s+\g{-1}\s+\`(?:graphql|inject|json|yaml):
# doxygen / javadoc / .net
(?:[\\@](?:brief|defgroup|groupname|link|t?param|return|retval)|(?:public|private|\[Parameter(?:\(.+\)|)\])(?:\s+(?:static|override|readonly|required|virtual))*)(?:\s+\{\w+\}|)\s+(\w+)\s+\g{-1}\s
# C# getter/setter
\s(\w+)\s+\g{-1}\s*\{\s*[gs]et;
# macOS file path
(?:Contents\W+|(?!iOS)/)MacOS\b

View File

@@ -1,30 +1,23 @@
attache
aroynt.*
bellows?
^attache$
^bellows?$
benefitting
occurences?
.*dnt
dependan.*
developement
developp?e
Devers?
devex.*
devide
Devinn?[ae]
devisals?
devisors?
diables?
hasta?
hastat.*
immediatly
inisle
inital
linge
oer
^dependan.*
^develope$
^developement$
^developpe
^Devers?$
^devex
^devide
^Devinn?[ae]
^devisal
^devisor
^diables?$
^oer$
Sorce
[Ss]pae.*
Teh
untill
untilling
venders?
wether.*
^[Ss]pae.*
^Teh$
^untill$
^untilling$
^venders?$
^wether.*

View File

@@ -163,7 +163,7 @@ configuration:
association: Collaborator
then:
- addReply:
reply: We've identified this issue as a duplicate of an existing one and are closing this thread so discussion stays in one place.<br/><br/>Please see the comment above for the link to the original tracking issue, and feel free to subscribe there for updates.
reply: Hi! We've identified this issue as a duplicate of another one that already exists on this Issue Tracker. This specific instance is being closed in favor of tracking the concern over on the referenced thread. Thanks for your report!
- closeIssue
- removeLabel:
label: Needs-Triage
@@ -233,30 +233,6 @@ configuration:
- addReply:
reply: Hi! Thanks for making us aware of the problem. We raised the issue with our internal localization team. This issue should be fixed hopefully in the next version of PowerToys.
description:
- if:
- payloadType: Issue_Comment
- commentContains:
pattern: '\/need-monitor-info'
isRegex: True
- hasLabel:
label: Product-Cursor Wrap
- or:
- activitySenderHasAssociation:
association: Owner
- activitySenderHasAssociation:
association: Member
- activitySenderHasAssociation:
association: Collaborator
then:
- removeLabel:
label: Needs-Triage
- removeLabel:
label: Needs-Team-Response
- addLabel:
label: Needs-Author-Feedback
- addReply:
reply: "To help debug your layout, please run [this script](https://github.com/microsoft/PowerToys/blob/main/src/modules/MouseUtils/CursorWrap/CursorWrapTests/Capture-MonitorLayout.ps1) and attach the generated JSON output to this thread.\n\nThis allows us to better understand the issue and investigate potential fixes."
description:
- if:
- payloadType: Issue_Comment
- commentContains:
@@ -266,5 +242,16 @@ configuration:
- addReply:
reply: Hi! Your last comment indicates to our system, that you might want to contribute to this feature/fix this bug. Thank you! Please make us aware on our ["Would you like to contribute to PowerToys?" thread](https://github.com/microsoft/PowerToys/issues/28769), as we don't see all the comments. <br /><br />_I'm a bot (beep!) so please excuse any mistakes I may make_
description:
- if:
- payloadType: Issues
- isAction:
action: Opened
- bodyContains:
pattern: 'Area\(s\) with issue\?\s*\nWorkspaces'
isRegex: True
then:
- addLabel:
label: Product-Workspaces
description:
onFailure:
onSuccess:

View File

@@ -1,377 +0,0 @@
#!/usr/bin/env node
/**
* Detects telemetry-event additions/modifications in a pull request and
* posts (or updates) a PR comment when telemetry-related changes are found.
*
* This script is executed by .github/workflows/telemetry-pr-check.yml.
* Keep both files aligned when changing trigger behavior, env usage, or messaging.
*/
const fs = require('node:fs');
const REVIEWER_LOGIN = 'chatasweetie';
const REVIEWER_MENTION = `@${REVIEWER_LOGIN}`;
const COMMENT_MARKER = '<!-- telemetry-event-check -->';
const COMMENT_BODY_WITH_PRIVACY_UPDATE = `${COMMENT_MARKER}
Thank you for contributing to PowerToys. We've detected that this PR might include a new or modified telemetry event. After this PR is merged, please follow these next steps:
- [ ] Reach out to Jessica (${REVIEWER_MENTION}) to follow up on the next steps: https://aka.ms/pt-telemetry-process
`;
const COMMENT_BODY_WITHOUT_PRIVACY_UPDATE = `${COMMENT_MARKER}
Thank you for contributing to PowerToys. We've detected that this PR might include a new or modified telemetry event. Please ensure the following before merging:
- [ ] Add your telemetry events to [DATA_AND_PRIVACY](https://github.com/microsoft/PowerToys/blob/main/DATA_AND_PRIVACY.md).md within this PR.
- [ ] Reach out to Jessica (${REVIEWER_MENTION}) to follow up on the next steps: https://aka.ms/pt-telemetry-process`;
const TELEMETRY_PATH_PATTERNS = [
/(^|\/)trace\.(h|hpp|cpp|cs)$/i,
/(^|\/)telemetry\//i,
/(^|\/)events\/.+event\.cs$/i,
/^src\/common\/Telemetry\//i,
/^src\/common\/ManagedTelemetry\//i,
/^src\/runner\/trace\.(h|cpp)$/i,
/^src\/settings-ui\/.+\/Telemetry\//i,
];
const TELEMETRY_LINE_PATTERNS = [
/TraceLoggingWriteWrapper\s*\(/,
/\bTraceLoggingWrite\s*\(/,
/\bTRACELOGGING_DEFINE_PROVIDER\b/,
/\bTraceLoggingOptionProjectTelemetry\b/,
/\bProjectTelemetryPrivacyDataTag\b/,
/\bPROJECT_KEYWORD_MEASURE\b/,
/\bRegisterProvider\s*\(/,
/\bUnregisterProvider\s*\(/,
/\bPowerToysTelemetry\.Log\.WriteEvent\s*\(/,
/\bclass\s+\w+\s*:\s*EventBase\s*,\s*IEvent\b/,
/\bclass\s+\w+\s*:\s*TelemetryBase\b/,
/\bPartA_PrivTags\b/,
/\[EventData\]/,
/\bEventName\b/,
];
function requireEnv(name) {
const value = process.env[name];
if (!value) {
throw new Error(`Missing required environment variable: ${name}`);
}
return value;
}
function validateRepository(repository) {
if (!/^[^/]+\/[^/]+$/.test(repository)) {
throw new Error(
`GITHUB_REPOSITORY must be in owner/repo format, received: ${JSON.stringify(repository)}`
);
}
}
function readEventPayload(eventPath) {
let raw;
try {
raw = fs.readFileSync(eventPath, 'utf8');
} catch (error) {
throw new Error(`Failed to read event payload at ${eventPath}: ${error.message}`);
}
try {
return JSON.parse(raw);
} catch (error) {
throw new Error(`Failed to parse JSON from ${eventPath}: ${error.message}`);
}
}
function resolvePullNumber(event) {
const fromPullRequest = event?.pull_request?.number;
const fromWorkflowDispatch = event?.inputs?.pr_number;
const rawPullNumber = fromPullRequest ?? fromWorkflowDispatch;
if (rawPullNumber === undefined || rawPullNumber === null || rawPullNumber === '') {
throw new Error(
'Unable to determine pull request number from event payload. Expected pull_request.number or inputs.pr_number.'
);
}
const pullNumber = Number.parseInt(String(rawPullNumber), 10);
if (!Number.isInteger(pullNumber) || pullNumber <= 0) {
throw new Error(`Invalid pull request number: ${JSON.stringify(rawPullNumber)}`);
}
return pullNumber;
}
function isTelemetryPath(filePath) {
return TELEMETRY_PATH_PATTERNS.some((pattern) => pattern.test(filePath));
}
function changedLinesFromPatch(patch) {
if (!patch) {
return [];
}
return patch
.split('\n')
.filter((line) => {
if (line.startsWith('+++') || line.startsWith('---')) {
return false;
}
return line.startsWith('+') || line.startsWith('-');
})
.map((line) => line.slice(1));
}
function hasTelemetryLineSignal(lines) {
return lines.some((line) => TELEMETRY_LINE_PATTERNS.some((pattern) => pattern.test(line)));
}
async function apiRequest(url, method = 'GET', body) {
const token = requireEnv('GITHUB_TOKEN');
let response;
try {
response = await fetch(url, {
method,
headers: {
Authorization: `Bearer ${token}`,
Accept: 'application/vnd.github+json',
'Content-Type': 'application/json',
},
body: body ? JSON.stringify(body) : undefined,
});
} catch (error) {
throw new Error(`Network error during ${method} ${url}: ${error.message}`);
}
if (!response.ok) {
const text = await response.text();
const rateLimitReset = response.headers.get('x-ratelimit-reset');
const rateLimitHint =
response.status === 403 && rateLimitReset
? ` (rate limit reset at epoch ${rateLimitReset})`
: '';
throw new Error(`${method} ${url} failed (${response.status})${rateLimitHint}: ${text}`);
}
if (response.status === 204) {
return null;
}
try {
return await response.json();
} catch (error) {
throw new Error(`Failed to parse JSON response for ${method} ${url}: ${error.message}`);
}
}
async function getAllPullFiles(apiBaseUrl, repository, pullNumber) {
const files = [];
let page = 1;
while (true) {
const url = `${apiBaseUrl}/repos/${repository}/pulls/${pullNumber}/files?per_page=100&page=${page}`;
const batch = await apiRequest(url);
if (!Array.isArray(batch)) {
throw new Error(`Unexpected response while listing PR files on page ${page}.`);
}
if (batch.length === 0) {
break;
}
files.push(...batch);
if (batch.length < 100) {
break;
}
page += 1;
}
return files;
}
async function getPullRequest(apiBaseUrl, repository, pullNumber) {
const url = `${apiBaseUrl}/repos/${repository}/pulls/${pullNumber}`;
const pullRequest = await apiRequest(url);
if (!pullRequest || typeof pullRequest !== 'object') {
throw new Error('Unexpected response while fetching pull request details.');
}
return pullRequest;
}
async function ensureReviewerRequested(apiBaseUrl, repository, pullNumber, pullRequest) {
const authorLogin = String(pullRequest?.user?.login || '').toLowerCase();
const targetReviewer = REVIEWER_LOGIN.toLowerCase();
if (authorLogin === targetReviewer) {
console.log(`Skipping reviewer request: ${REVIEWER_LOGIN} is the PR author.`);
return;
}
const requestedReviewers = Array.isArray(pullRequest?.requested_reviewers)
? pullRequest.requested_reviewers
: [];
const alreadyRequested = requestedReviewers.some(
(reviewer) => String(reviewer?.login || '').toLowerCase() === targetReviewer
);
if (alreadyRequested) {
console.log(`Reviewer ${REVIEWER_LOGIN} is already requested.`);
return;
}
const url = `${apiBaseUrl}/repos/${repository}/pulls/${pullNumber}/requested_reviewers`;
try {
await apiRequest(url, 'POST', { reviewers: [REVIEWER_LOGIN] });
console.log(`Requested reviewer ${REVIEWER_LOGIN}.`);
} catch (error) {
// Reviewer request should not fail the telemetry guidance workflow.
console.warn(
`Unable to request reviewer ${REVIEWER_LOGIN}: ${error instanceof Error ? error.message : String(error)}`
);
}
}
async function findExistingTelemetryComment(apiBaseUrl, repository, pullNumber) {
let page = 1;
while (true) {
const commentsUrl = `${apiBaseUrl}/repos/${repository}/issues/${pullNumber}/comments?per_page=100&page=${page}`;
const comments = await apiRequest(commentsUrl);
if (!Array.isArray(comments)) {
throw new Error(`Unexpected response while listing issue comments on page ${page}.`);
}
const existing = comments.find(
(comment) => typeof comment.body === 'string' && comment.body.includes(COMMENT_MARKER)
);
if (existing) {
return existing;
}
if (comments.length < 100) {
return null;
}
page += 1;
}
}
function detectTelemetryChanges(files) {
const matches = [];
for (const file of files) {
const filename = file.filename || '';
const telemetryPath = isTelemetryPath(filename);
const changedLines = changedLinesFromPatch(file.patch);
const telemetryLineSignal = hasTelemetryLineSignal(changedLines);
// Some large diffs omit patch content. If the file path is telemetry-centric,
// treat it as a telemetry modification to avoid false negatives.
const patchUnavailable = !file.patch && telemetryPath;
if (telemetryPath || telemetryLineSignal || patchUnavailable) {
matches.push({
filename,
telemetryPath,
telemetryLineSignal,
patchUnavailable,
});
}
}
return matches;
}
function hasDataAndPrivacyChange(files) {
return files.some((file) => {
const filename = (file.filename || '').toLowerCase();
return filename === 'data_and_privacy.md';
});
}
async function upsertPrComment(apiBaseUrl, repository, pullNumber, body) {
const existing = await findExistingTelemetryComment(apiBaseUrl, repository, pullNumber);
if (existing) {
const updateUrl = `${apiBaseUrl}/repos/${repository}/issues/comments/${existing.id}`;
await apiRequest(updateUrl, 'PATCH', { body });
console.log(`Updated existing telemetry comment (id: ${existing.id}).`);
return;
}
const createUrl = `${apiBaseUrl}/repos/${repository}/issues/${pullNumber}/comments`;
await apiRequest(createUrl, 'POST', { body });
console.log('Created telemetry comment on PR.');
}
async function main() {
const eventPath = requireEnv('GITHUB_EVENT_PATH');
const repository = requireEnv('GITHUB_REPOSITORY');
const apiBaseUrl = process.env.GITHUB_API_URL || 'https://api.github.com';
validateRepository(repository);
let parsedApiBaseUrl;
try {
parsedApiBaseUrl = new URL(apiBaseUrl);
} catch {
throw new Error(`Invalid GITHUB_API_URL: ${JSON.stringify(apiBaseUrl)}`);
}
const event = readEventPayload(eventPath);
const pullNumber = resolvePullNumber(event);
console.log(`Event name: ${process.env.GITHUB_EVENT_NAME || 'unknown'}`);
console.log(`Repository: ${repository}`);
console.log(`PR number: ${pullNumber}`);
const files = await getAllPullFiles(parsedApiBaseUrl.origin, repository, pullNumber);
if (files.length === 0) {
console.log('No changed files found for PR; skipping telemetry comment update.');
return;
}
const matches = detectTelemetryChanges(files);
const dataAndPrivacyChanged = hasDataAndPrivacyChange(files);
console.log(`Scanned ${files.length} changed files.`);
console.log(`Telemetry matches found: ${matches.length}.`);
console.log(`DATA_AND_PRIVACY.md changed: ${dataAndPrivacyChanged}.`);
if (matches.length === 0) {
console.log('No telemetry-related additions/modifications detected.');
return;
}
for (const match of matches) {
console.log(
`- ${match.filename} (telemetryPath=${match.telemetryPath}, telemetryLineSignal=${match.telemetryLineSignal}, patchUnavailable=${match.patchUnavailable})`
);
}
try {
const pullRequest = await getPullRequest(parsedApiBaseUrl.origin, repository, pullNumber);
await ensureReviewerRequested(parsedApiBaseUrl.origin, repository, pullNumber, pullRequest);
} catch (error) {
console.warn(
'Failed to fetch PR details or request reviewer; continuing to post telemetry guidance comment.'
);
console.warn(error instanceof Error ? error.stack || error.message : error);
}
const commentBody = dataAndPrivacyChanged
? COMMENT_BODY_WITH_PRIVACY_UPDATE
: COMMENT_BODY_WITHOUT_PRIVACY_UPDATE;
await upsertPrComment(apiBaseUrl, repository, pullNumber, commentBody);
}
main().catch((error) => {
console.error('Telemetry PR check failed.');
console.error(error instanceof Error ? error.stack || error.message : error);
process.exit(1);
});

View File

@@ -1,12 +1,12 @@
---
name: release-note-generation
description: Toolkit for generating PowerToys release notes from GitHub milestone PRs or commit ranges. Use when asked to create release notes, summarize milestone PRs, generate changelog, prepare release documentation, generate PR review summaries locally for release notes, update README for a new release, manage PR milestones, collect PRs between commits/tags, or prepare release assets (download installers and compute installer hashes).
description: Toolkit for generating PowerToys release notes from GitHub milestone PRs or commit ranges. Use when asked to create release notes, summarize milestone PRs, generate changelog, prepare release documentation, request Copilot reviews for PRs, update README for a new release, manage PR milestones, or collect PRs between commits/tags. Supports PR collection by milestone or commit range, milestone assignment, grouping by label, summarization with external contributor attribution, and README version bumping.
license: Complete terms in LICENSE.txt
---
# Release Note Generation Skill
Generate professional release notes for PowerToys milestones by collecting merged PRs, summarizing each PR with the local CLI agent, grouping by label, and producing user-facing summaries.
Generate professional release notes for PowerToys milestones by collecting merged PRs, requesting Copilot code reviews, grouping by label, and producing user-facing summaries.
## Output Directory
@@ -26,17 +26,16 @@ Generated Files/ReleaseNotes/
- Generate release notes for a milestone
- Summarize PRs merged in a release
- Generate per-PR review summaries locally for release-notes copy
- Request Copilot reviews for milestone PRs
- Assign milestones to PRs missing them
- Collect PRs between two commits/tags
- Update README.md for a new version
- Prepare GitHub release assets (download installers/symbols + compute hashes)
## Prerequisites
- **GitHub CLI (`gh`) installed and authenticated** — The collection script uses `gh pr view` and `gh api graphql` to fetch PR metadata and co-author information. Run `gh auth status` to verify; if not logged in, run `gh auth login` first. See [Step 1.0.0](./references/step1-collection.md) for details.
- MCP Server: github-mcp-server installed (used to fetch PR diffs/files for the local-agent review step)
- For [prepare-release-assets.ps1](./scripts/prepare-release-assets.ps1) only: **Azure CLI** authenticated against the Microsoft tenant (`az login`) with the `azure-devops` extension; access to the `microsoft/Dart` ADO project
- MCP Server: github-mcp-server installed
- GitHub Copilot code review enabled for the org/repo
## Required Variables
@@ -66,12 +65,12 @@ Generated Files/ReleaseNotes/
└────────────────────────────────┘
┌────────────────────────────────┐
│ 3.1 Local-agent PR summaries
│ (writes CopilotSummary) │
│ 3.1 Request Reviews (Copilot)
└────────────────────────────────┘
┌────────────────────────────────┐
│ 3.2 (Optional) Refresh PR data │
│ 3.2 Refresh PR data
│ (CopilotSummary) │
└────────────────────────────────┘
┌────────────────────────────────┐
@@ -94,7 +93,7 @@ Generated Files/ReleaseNotes/
| 1.1 | Collect PRs | From previous release tag on `stable` branch → `sorted_prs.csv` |
| 1.2 | Assign Milestones | Ensure all PRs have correct milestone |
| 2.12.4 | Label PRs | Auto-suggest + human label low-confidence |
| 3.13.3 | Reviews & Grouping | Local agent summarizes each PR diff into `CopilotSummary` → (optional refresh) → group by label |
| 3.13.3 | Reviews & Grouping | Request Copilot reviews → refresh → group by label |
| 4.14.2 | Summaries & Final | Generate grouped summaries, then consolidate |
## Detailed workflow docs
@@ -115,7 +114,6 @@ Do not read all steps at once—only read the step you are executing.
| [group-prs-by-label.ps1](./scripts/group-prs-by-label.ps1) | Group PRs into CSVs |
| [collect-or-apply-milestones.ps1](./scripts/collect-or-apply-milestones.ps1) | Assign milestones |
| [diff_prs.ps1](./scripts/diff_prs.ps1) | Incremental PR diff |
| [prepare-release-assets.ps1](./scripts/prepare-release-assets.ps1) | Download installers + symbols from an ADO build, compute SHA256, emit the "Installer Hashes" markdown table for the GitHub release page |
## References
@@ -135,6 +133,5 @@ Do not read all steps at once—only read the step you are executing.
|-------|----------|
| `gh` command not found | Install GitHub CLI and add to PATH |
| No PRs returned | Verify milestone title matches exactly |
| Empty `CopilotSummary` for many PRs | Run Step 3.1 (local-agent summaries). Do **not** use `mcp_github_request_copilot_review` from a CLI/coding agent — the GitHub API rejects bot-initiated review requests, so the column will stay empty. |
| Empty CopilotSummary | Request Copilot reviews first, then re-run dump |
| Many unlabeled PRs | Return to labeling step before grouping |
| `prepare-release-assets.ps1` fails with "Failed to acquire ADO access token" | Run `az login` and ensure you have access to the `microsoft/Dart` ADO project |

View File

@@ -1,40 +1,22 @@
# Step 3: Local Agent Reviews and Grouping
# Step 3: Copilot Reviews and Grouping
## 3.0 To-do
- 3.1 Generate PR Summaries with the Local Agent
- 3.2 (Optional) Refresh PR Data
- 3.1 Request Copilot Reviews (Agent Mode)
- 3.2 Refresh PR Data
- 3.3 Group PRs by Label
## 3.1 Generate PR Summaries with the Local Agent
## 3.1 Request Copilot Reviews (Agent Mode)
> ⚠️ **Do not use `mcp_github_request_copilot_review` (or any "request Copilot review" tool that calls the GitHub API).**
> When this skill is driven from a CLI / coding agent, the request is made from a bot identity and the GitHub API rejects it ("Bot reviewers cannot be requested"). The PR ends up with no Copilot review and `CopilotSummary` stays empty.
>
> Instead, **the local agent that is running this skill performs the review itself** and writes the summary directly into `sorted_prs.csv`.
Use MCP tools to request Copilot reviews for all PRs in `Generated Files/ReleaseNotes/sorted_prs.csv`:
For every PR listed in `Generated Files/ReleaseNotes/sorted_prs.csv` whose `CopilotSummary` is empty:
1. Fetch the PR diff using a tool that does **not** post anything back to GitHub. Any of these works:
- `mcp_github_pull_request_read` with `method: get_diff`
- `mcp_github_pull_request_read` with `method: get_files` (when the diff is large)
- `gh pr diff <PR_NUMBER> --repo microsoft/PowerToys`
2. Read the PR title, body, and diff. Produce a 13 sentence, user-facing summary in the same style as a Copilot PR review (focus on observable behavior change, not implementation details).
3. Write the summary into the `CopilotSummary` column for that PR row in `Generated Files/ReleaseNotes/sorted_prs.csv`. Preserve all other columns and the existing row order.
**Batching guidance**
- Process PRs in the order they appear in `sorted_prs.csv`.
- Generate summaries for **all** PRs in one pass before continuing to Step 3.3, so the human reviewer can validate them together.
- For very large diffs, summarize from `get_files` (filenames + per-file patches) rather than the full diff.
- Skip PRs that already have a non-empty `CopilotSummary` (e.g. PRs where a human reviewer already pasted one). Do not overwrite existing summaries.
**Why not post the summary back to the PR?** Posting a comment from the agent's identity would not be picked up by `dump-prs-since-commit.ps1` (which only matches Copilot bot authors), and it adds noise to the PR. Writing straight into the CSV keeps the artifact self-contained.
- Use `mcp_github_request_copilot_review` for each PR ID
- Do NOT generate or run scripts for this step
---
## 3.2 (Optional) Refresh PR Data
## 3.2 Refresh PR Data
Only re-run the collection script if PR metadata on GitHub has changed (new labels, retitled PRs, etc.) since Step 1.1. **Skip this step if you only want to preserve the locally generated `CopilotSummary` values from Step 3.1**, because re-running the dump will overwrite the CSV.
Re-run the collection script to capture Copilot review summaries into the `CopilotSummary` column:
```powershell
pwsh ./.github/skills/release-note-generation/scripts/dump-prs-since-commit.ps1 `
@@ -42,8 +24,6 @@ pwsh ./.github/skills/release-note-generation/scripts/dump-prs-since-commit.ps1
-OutputDir 'Generated Files/ReleaseNotes'
```
If you do refresh, redo Step 3.1 afterwards to repopulate `CopilotSummary`.
---
## 3.3 Group PRs by Label
@@ -55,4 +35,3 @@ pwsh ./.github/skills/release-note-generation/scripts/group-prs-by-label.ps1 -Cs
Creates `Generated Files/ReleaseNotes/grouped_csv/` with one CSV per label combination.
**Validation:** The `Unlabeled.csv` file should be minimal (ideally empty). If many PRs remain unlabeled, return to Step 2 (see [step2-labeling.md](./step2-labeling.md)).

View File

@@ -16,7 +16,7 @@ For each CSV in `Generated Files/ReleaseNotes/grouped_csv/`, create a markdown f
- Use the “Verb-ed + Scenario + Impact” sentence structure—make readers think, “Thats exactly what I need” or “Yes, thats an awesome fix.”; The "impact" can be end-user focused (written to convey user excitement) or technical (performance/stability) when user-facing impact is minimal.
- If nothing special on impact or unclear impact, mark as needing human summary
- Source from Title, Body, and CopilotSummary (prefer CopilotSummary when available)
- The `NeedThanks` column contains a comma-separated list of external contributor usernames who should be credited (empty = no attribution needed, all authors are core team). For each non-empty `NeedThanks` value, append a `by` attribution that lists **every** contributor, matching GitHub's standard contributor-attribution style: `by [@user1](https://github.com/user1)` for a single contributor, `by [@user1](https://github.com/user1) and [@user2](https://github.com/user2)` for two, or `by [@user1](https://github.com/user1), [@user2](https://github.com/user2), and [@user3](https://github.com/user3)` for three or more. In the final consolidated release notes (Step 4.2), the attribution follows the PR link, e.g. `…in [#1234](url) by [@user](url)`. Do not use "Thanks @user!" phrasing.
- The `NeedThanks` column contains a comma-separated list of external contributor usernames who should be thanked (empty = no thanks needed, all authors are core team). For each non-empty `NeedThanks` value, append thanks for **every** listed contributor: `Thanks [@user1](https://github.com/user1)!` for a single contributor, or `Thanks [@user1](https://github.com/user1) and [@user2](https://github.com/user2)!` for two, or `Thanks [@user1](https://github.com/user1), [@user2](https://github.com/user2), and [@user3](https://github.com/user3)!` for three or more.
- Do NOT include PR numbers in bullet lines
- Do NOT mention “security” or “privacy” issues, since these are not known and could be leveraged by attackers in earlier versions. Instead, describe the user-facing scenario, usage, or impact.
- If confidence < 70%, write: `Human Summary Needed: <PR full link>`

View File

@@ -1,334 +0,0 @@
<#
.SYNOPSIS
Prepares the binary assets for a PowerToys GitHub release: downloads the
four installers (per-user/per-machine x x64/arm64) and the symbol archives
from an ADO pipeline build, computes SHA256 hashes, and emits the
"Installer Hashes" markdown table.
.DESCRIPTION
Given an ADO Dart pipeline build id (e.g. from
https://microsoft.visualstudio.com/Dart/_build/results?buildId=NNN),
downloads the four installer EXEs and the per-arch symbol zips into a
single per-version folder, then writes a hashes.md alongside them with a
markdown table ready to paste into the GitHub release notes.
Requires: az login (Azure CLI authenticated), az devops extension.
.EXAMPLE
.\prepare-release-assets.ps1 -BuildId 145505247
.\prepare-release-assets.ps1 -BuildId 145505247 -OutputFolder D:\Releases
#>
param(
[Parameter(Mandatory = $true)]
[int]$BuildId,
[string]$OutputFolder = "$env:USERPROFILE\Downloads",
[string]$Organization = "https://dev.azure.com/microsoft",
[string]$Project = "Dart",
[string]$GitHubRepo = "microsoft/PowerToys"
)
$ErrorActionPreference = "Stop"
$env:AZURE_CORE_NO_PROMPT = "true"
# --- Helpers -----------------------------------------------------------------
# Invoke an `az` CLI command and capture stderr in $script:LastAzError so
# callers can surface the underlying message (expired login, blocked extension,
# tenant policy, ...) instead of swallowing it with `2>$null`.
function Invoke-Az {
$tmpErr = [System.IO.Path]::GetTempFileName()
try {
$output = & az @args 2>$tmpErr
# Get-Content -Raw returns $null for an empty file, and calling .Trim()
# on $null throws under $ErrorActionPreference = 'Stop' -- which would
# turn every successful (no-stderr) az call into a fatal error. Guard
# explicitly so $script:LastAzError is always a (possibly empty) string.
$rawErr = Get-Content $tmpErr -Raw -ErrorAction SilentlyContinue
$script:LastAzError = if ($null -eq $rawErr) { '' } else { $rawErr.Trim() }
return $output
}
finally {
Remove-Item $tmpErr -Force -ErrorAction SilentlyContinue
}
}
# Build an ADO artifact download URL from scratch instead of regex-replacing
# the URL returned by `az pipelines runs artifact list`. Preserves any other
# query parameters and only swaps `format` and `subPath`, so we don't break if
# the upstream URL shape ever changes.
function Get-ArtifactDownloadUrl {
param(
[Parameter(Mandatory)][string]$BaseUrl,
[Parameter(Mandatory)][string]$SubPath,
[Parameter(Mandatory)][ValidateSet('file', 'zip')][string]$Format
)
$encodedSubPath = [Uri]::EscapeDataString($SubPath)
$idx = $BaseUrl.IndexOf('?')
if ($idx -lt 0) {
return "${BaseUrl}?format=${Format}&subPath=${encodedSubPath}"
}
$base = $BaseUrl.Substring(0, $idx)
$kept = $BaseUrl.Substring($idx + 1) -split '&' | Where-Object {
$_ -and -not ($_ -match '^(format|subPath)=')
}
$kept = @($kept) + @("format=$Format", "subPath=$encodedSubPath")
return "${base}?$($kept -join '&')"
}
# Download a single ADO artifact file with bearer auth and a small retry/backoff
# loop. A transient network blip on a ~200 MB installer or symbol zip otherwise
# aborts the entire release-prep run.
function Invoke-AdoDownload {
param(
[Parameter(Mandatory)][string]$Url,
[Parameter(Mandatory)][string]$DestPath,
[Parameter(Mandatory)][string]$Token,
[int]$MaxAttempts = 3
)
$lastError = $null
for ($attempt = 1; $attempt -le $MaxAttempts; $attempt++) {
$webClient = New-Object System.Net.WebClient
$webClient.Headers.Add("Authorization", "Bearer $Token")
try {
$webClient.DownloadFile($Url, $DestPath)
return
}
catch {
$lastError = $_
if (Test-Path $DestPath) {
Remove-Item $DestPath -Force -ErrorAction SilentlyContinue
}
if ($attempt -lt $MaxAttempts) {
$backoffSec = [int][Math]::Pow(2, $attempt) # 2, 4, 8 ...
Write-Host " Attempt $attempt failed: $($_.Exception.Message). Retrying in ${backoffSec}s..." -ForegroundColor Yellow
Start-Sleep -Seconds $backoffSec
}
}
finally {
$webClient.Dispose()
}
}
throw "Download failed after $MaxAttempts attempts. Last error: $($lastError.Exception.Message)`nURL: $Url"
}
# -----------------------------------------------------------------------------
# Work around broken az extensions: if the default extension dir has
# inaccessible files, redirect to a clean directory.
$defaultExtDir = "$env:USERPROFILE\.azure\cliextensions"
if (-not $env:AZURE_EXTENSION_DIR -and (Test-Path $defaultExtDir)) {
$broken = Get-ChildItem "$defaultExtDir\*\*.dist-info" -Directory -ErrorAction SilentlyContinue | Where-Object {
try { [System.IO.Directory]::GetFiles($_.FullName) | Out-Null; $false } catch { $true }
}
if ($broken) {
$cleanDir = "$env:USERPROFILE\.azure\cliextensions_clean"
Write-Host " Detected broken az extension, redirecting to $cleanDir" -ForegroundColor Yellow
$env:AZURE_EXTENSION_DIR = $cleanDir
if (-not (Test-Path $cleanDir)) { New-Item -ItemType Directory -Path $cleanDir -Force | Out-Null }
}
}
# Ensure azure-devops extension is installed
$ext = Invoke-Az extension list --query "[?name=='azure-devops']" -o tsv
if (-not $ext) {
Write-Host "Installing azure-devops extension..." -ForegroundColor Yellow
Invoke-Az extension add --name azure-devops --yes | Out-Null
if ($LASTEXITCODE -ne 0) {
Write-Error "Failed to install azure-devops extension. (az: $script:LastAzError)"
exit 1
}
}
# Configure az devops defaults
Invoke-Az devops configure --defaults organization=$Organization project=$Project | Out-Null
if ($LASTEXITCODE -ne 0) {
Write-Error "Failed to configure az devops defaults. (az: $script:LastAzError)"
exit 1
}
# --- Step 1: Get build info to determine version ---
Write-Host "Fetching build $BuildId info..." -ForegroundColor Cyan
$buildJson = Invoke-Az pipelines build show --id $BuildId --output json
if (-not $buildJson) {
Write-Error "Could not fetch build $BuildId. Are you logged in (az login)? (az: $script:LastAzError)"
exit 1
}
$build = $buildJson | ConvertFrom-Json
$versionParam = $build.templateParameters.VersionNumber
if (-not $versionParam) {
Write-Error "Could not determine version from build $BuildId"
exit 1
}
Write-Host " Version: $versionParam" -ForegroundColor DarkGray
# --- Step 2: Get artifact metadata once ---
Write-Host "Fetching artifact metadata..." -ForegroundColor Cyan
$artifactsJson = Invoke-Az pipelines runs artifact list --run-id $BuildId --output json
if (-not $artifactsJson) {
Write-Error "Could not list artifacts for build $BuildId. (az: $script:LastAzError)"
exit 1
}
$artifacts = $artifactsJson | ConvertFrom-Json
# --- Step 3: Prepare destination folder ---
$destFolder = Join-Path $OutputFolder "PowerToys-v$versionParam"
if (-not (Test-Path $destFolder)) {
New-Item -ItemType Directory -Path $destFolder -Force | Out-Null
}
Write-Host " Destination: $destFolder" -ForegroundColor DarkGray
# --- Step 4: Get an ADO access token once ---
$token = Invoke-Az account get-access-token --resource "499b84ac-1321-427f-aa17-267ca6975798" --query accessToken -o tsv
if (-not $token) {
Write-Error "Failed to acquire ADO access token. Run 'az login' first. (az: $script:LastAzError)"
exit 1
}
# --- Step 5: Define the four installers to download ---
$targets = @(
[pscustomobject]@{ Description = "Per user - x64"; Scope = "perUser"; Arch = "x64"; Artifact = "build-x64-Release"; FileName = "PowerToysUserSetup-$versionParam-x64.exe" }
[pscustomobject]@{ Description = "Per user - ARM64"; Scope = "perUser"; Arch = "arm64"; Artifact = "build-arm64-Release"; FileName = "PowerToysUserSetup-$versionParam-arm64.exe" }
[pscustomobject]@{ Description = "Machine wide - x64"; Scope = "perMachine"; Arch = "x64"; Artifact = "build-x64-Release"; FileName = "PowerToysSetup-$versionParam-x64.exe" }
[pscustomobject]@{ Description = "Machine wide - ARM64"; Scope = "perMachine"; Arch = "arm64"; Artifact = "build-arm64-Release"; FileName = "PowerToysSetup-$versionParam-arm64.exe" }
)
# --- Step 6: Download each installer (skip if already present) ---
foreach ($t in $targets) {
$destPath = Join-Path $destFolder $t.FileName
if (Test-Path $destPath) {
$sizeMB = [math]::Round((Get-Item $destPath).Length / 1MB, 1)
Write-Host "[skip] $($t.FileName) already exists ($sizeMB MB)" -ForegroundColor DarkGray
continue
}
$artifact = $artifacts | Where-Object { $_.name -eq $t.Artifact }
if (-not $artifact) {
Write-Error "Artifact '$($t.Artifact)' not found in build $BuildId. Available: $(($artifacts | ForEach-Object name) -join ', ')"
exit 1
}
$fileUrl = Get-ArtifactDownloadUrl -BaseUrl $artifact.resource.downloadUrl -SubPath "/$($t.FileName)" -Format file
Write-Host "Downloading $($t.FileName) ..." -ForegroundColor Cyan
try {
Invoke-AdoDownload -Url $fileUrl -DestPath $destPath -Token $token
}
catch {
Write-Error "Download failed for $($t.FileName): $_"
exit 1
}
$sizeMB = [math]::Round((Get-Item $destPath).Length / 1MB, 1)
Write-Host " Saved ($sizeMB MB)" -ForegroundColor Green
}
# --- Step 6b: Download symbols (one zip per arch) ---
$symbolTargets = @(
[pscustomobject]@{ Arch = "x64"; Artifact = "build-x64-Release"; SubPath = "/symbols-x64" }
[pscustomobject]@{ Arch = "arm64"; Artifact = "build-arm64-Release"; SubPath = "/symbols-arm64" }
)
foreach ($s in $symbolTargets) {
$finalZip = Join-Path $destFolder "symbols-$($s.Arch).zip"
if (Test-Path $finalZip) {
$sizeMB = [math]::Round((Get-Item $finalZip).Length / 1MB, 1)
Write-Host "[skip] symbols-$($s.Arch).zip already exists ($sizeMB MB)" -ForegroundColor DarkGray
continue
}
$artifact = $artifacts | Where-Object { $_.name -eq $s.Artifact }
if (-not $artifact) {
Write-Error "Artifact '$($s.Artifact)' not found in build $BuildId."
exit 1
}
# Symbols are downloaded as a folder => keep format=zip and append subPath
$symbolsUrl = Get-ArtifactDownloadUrl -BaseUrl $artifact.resource.downloadUrl -SubPath $s.SubPath -Format zip
$tmpZip = Join-Path ([System.IO.Path]::GetTempPath()) ("ptsym-$($s.Arch)-$([Guid]::NewGuid().ToString('N')).zip")
$tmpExtract = Join-Path ([System.IO.Path]::GetTempPath()) ("ptsym-$($s.Arch)-$([Guid]::NewGuid().ToString('N'))")
$stageRoot = Join-Path ([System.IO.Path]::GetTempPath()) ("ptsym-stage-$([Guid]::NewGuid().ToString('N'))")
try {
Write-Host "Downloading symbols-$($s.Arch).zip ..." -ForegroundColor Cyan
try {
Invoke-AdoDownload -Url $symbolsUrl -DestPath $tmpZip -Token $token
}
catch {
Write-Error "Symbols download failed for $($s.Arch): $_"
exit 1
}
Write-Host " Extracting..." -ForegroundColor DarkGray
Expand-Archive -Path $tmpZip -DestinationPath $tmpExtract -Force
# Walk down while the current dir holds exactly one subfolder and no files.
$current = Get-Item $tmpExtract
while ($true) {
$children = Get-ChildItem -LiteralPath $current.FullName -Force
$subDirs = @($children | Where-Object { $_.PSIsContainer })
$files = @($children | Where-Object { -not $_.PSIsContainer })
if ($subDirs.Count -eq 1 -and $files.Count -eq 0) {
$current = $subDirs[0]
}
else {
break
}
}
# Stage to a folder named symbols-<arch> so the zip extracts to that name.
$stageInner = Join-Path $stageRoot "symbols-$($s.Arch)"
New-Item -ItemType Directory -Path $stageInner -Force | Out-Null
Get-ChildItem -LiteralPath $current.FullName -Force | ForEach-Object {
Copy-Item -LiteralPath $_.FullName -Destination $stageInner -Recurse -Force
}
Write-Host " Repacking to $finalZip ..." -ForegroundColor DarkGray
if (Test-Path $finalZip) { Remove-Item $finalZip -Force }
Compress-Archive -Path "$stageInner\*" -DestinationPath $finalZip -CompressionLevel Optimal
$sizeMB = [math]::Round((Get-Item $finalZip).Length / 1MB, 1)
Write-Host " Saved symbols-$($s.Arch).zip ($sizeMB MB)" -ForegroundColor Green
}
catch {
# Don't leave a half-built zip behind if anything in the pipeline blew up.
if (Test-Path $finalZip) { Remove-Item $finalZip -Force -ErrorAction SilentlyContinue }
throw
}
finally {
Remove-Item $tmpZip -Force -ErrorAction SilentlyContinue
Remove-Item $tmpExtract -Recurse -Force -ErrorAction SilentlyContinue
Remove-Item $stageRoot -Recurse -Force -ErrorAction SilentlyContinue
}
}
# --- Step 7: Compute SHA256 and build markdown ---
Write-Host "`nComputing SHA256 hashes..." -ForegroundColor Cyan
$sb = [System.Text.StringBuilder]::new()
[void]$sb.AppendLine("## Installer Hashes")
[void]$sb.AppendLine("")
[void]$sb.AppendLine("| Description | Filename | sha256 hash |")
[void]$sb.AppendLine("| --- | --- | --- |")
foreach ($t in $targets) {
$destPath = Join-Path $destFolder $t.FileName
$hash = (Get-FileHash -Path $destPath -Algorithm SHA256).Hash.ToUpper()
[void]$sb.AppendLine("| $($t.Description) | $($t.FileName) | $hash |")
Write-Host " $($t.FileName) $hash" -ForegroundColor DarkGray
}
$markdown = $sb.ToString()
$mdPath = Join-Path $destFolder "hashes.md"
Set-Content -Path $mdPath -Value $markdown -Encoding UTF8
Write-Host "`nMarkdown written to: $mdPath" -ForegroundColor Green
Write-Host "`n----- Installer Hashes -----`n" -ForegroundColor Yellow
Write-Host $markdown
Write-Host "Draft a new GitHub release at: https://github.com/$GitHubRepo/releases/new?tag=v$versionParam" -ForegroundColor Green

View File

@@ -1,165 +0,0 @@
---
name: wpf-to-winui3-migration
description: Guide for migrating PowerToys modules from WPF to WinUI 3 (Windows App SDK). Use when asked to migrate WPF code, convert WPF XAML to WinUI, replace System.Windows namespaces with Microsoft.UI.Xaml, update Dispatcher to DispatcherQueue, replace DynamicResource with ThemeResource, migrate imaging APIs from System.Windows.Media.Imaging to Windows.Graphics.Imaging, convert WPF Window to WinUI Window, migrate .resx to .resw resources, migrate custom Observable/RelayCommand to CommunityToolkit.Mvvm source generators, handle WPF-UI (Lepo) to WinUI native control migration, or fix installer/build pipeline issues after migration. Keywords: WPF, WinUI, WinUI3, migration, porting, convert, namespace, XAML, Dispatcher, DispatcherQueue, imaging, BitmapImage, Window, ContentDialog, ThemeResource, DynamicResource, ResourceLoader, resw, resx, CommunityToolkit, ObservableProperty, WPF-UI, SizeToContent, AppWindow, SoftwareBitmap.
license: Complete terms in LICENSE.txt
---
# WPF to WinUI 3 Migration Skill
Migrate PowerToys modules from WPF (`System.Windows.*`) to WinUI 3 (`Microsoft.UI.Xaml.*` / Windows App SDK). Based on patterns validated in the ImageResizer module migration.
## When to Use This Skill
- Migrate a PowerToys module from WPF to WinUI 3
- Convert WPF XAML files to WinUI 3 XAML
- Replace `System.Windows` namespaces with `Microsoft.UI.Xaml`
- Migrate `Dispatcher` usage to `DispatcherQueue`
- Migrate custom `Observable`/`RelayCommand` to CommunityToolkit.Mvvm source generators
- Replace WPF-UI (Lepo) controls with native WinUI 3 controls
- Convert imaging code from `System.Windows.Media.Imaging` to `Windows.Graphics.Imaging`
- Handle WPF `Window` vs WinUI `Window` differences (sizing, positioning, SizeToContent)
- Migrate resource files from `.resx` to `.resw` with `ResourceLoader`
- Fix installer/build pipeline issues after WinUI 3 migration
- Update project files, NuGet packages, and signing config
## Prerequisites
- Visual Studio 2022 17.4+
- Windows App SDK NuGet package (`Microsoft.WindowsAppSDK`)
- .NET 8+ with `net8.0-windows10.0.19041.0` TFM
- Windows 10 1803+ (April 2018 Update or newer)
## Migration Strategy
### Recommended Order
1. **Project file** — Update TFM, NuGet packages, set `<UseWinUI>true</UseWinUI>`
2. **Data models and business logic** — No UI dependencies, migrate first
3. **MVVM framework** — Replace custom Observable/RelayCommand with CommunityToolkit.Mvvm
4. **Resource strings** — Migrate `.resx``.resw`, introduce `ResourceLoaderInstance`
5. **Services and utilities** — Replace `System.Windows` types, async-ify imaging code
6. **ViewModels** — Update Dispatcher usage, binding patterns
7. **Views/Pages** — Starting from leaf pages with fewest dependencies
8. **Main page / shell** — Last, since it depends on everything
9. **App.xaml / startup code** — Merge carefully (do NOT overwrite WinUI 3 boilerplate)
10. **Installer & build pipeline** — Update WiX, signing, build events
11. **Tests** — Adapt for WinUI 3 runtime, async patterns
### Key Principles
- **Do NOT overwrite `App.xaml` / `App.xaml.cs`** — WinUI 3 has different application lifecycle boilerplate. Merge your resources and initialization code into the generated WinUI 3 App class.
- **Do NOT create Exe→WinExe `ProjectReference`** — Extract shared code to a Library project. This causes phantom build artifacts.
- **Use `Lazy<T>` for resource-dependent statics** — `ResourceLoader` is not available at class-load time in all contexts.
## Quick Reference Tables
### Namespace Mapping
| WPF | WinUI 3 |
|-----|---------|
| `System.Windows` | `Microsoft.UI.Xaml` |
| `System.Windows.Controls` | `Microsoft.UI.Xaml.Controls` |
| `System.Windows.Media` | `Microsoft.UI.Xaml.Media` |
| `System.Windows.Media.Imaging` | `Microsoft.UI.Xaml.Media.Imaging` (UI) / `Windows.Graphics.Imaging` (processing) |
| `System.Windows.Input` | `Microsoft.UI.Xaml.Input` |
| `System.Windows.Data` | `Microsoft.UI.Xaml.Data` |
| `System.Windows.Threading` | `Microsoft.UI.Dispatching` |
| `System.Windows.Interop` | `WinRT.Interop` |
### Critical API Replacements
| WPF | WinUI 3 | Notes |
|-----|---------|-------|
| `Dispatcher.Invoke()` | `DispatcherQueue.TryEnqueue()` | Different return type (`bool`) |
| `Dispatcher.CheckAccess()` | `DispatcherQueue.HasThreadAccess` | Property vs method |
| `Application.Current.Dispatcher` | Store `DispatcherQueue` in static field | See [Threading](./references/threading-and-windowing.md) |
| `MessageBox.Show()` | `ContentDialog` | Must set `XamlRoot` |
| `DynamicResource` | `ThemeResource` | Theme-reactive only |
| `clr-namespace:` | `using:` | XAML namespace prefix |
| `{x:Static props:Resources.Key}` | `x:Uid` or `ResourceLoader.GetString()` | .resx → .resw |
| `DataType="{x:Type m:Foo}"` | Remove or use code-behind | `x:Type` not supported |
| `Properties.Resources.MyString` | `ResourceLoaderInstance.ResourceLoader.GetString("MyString")` | Lazy-init pattern |
| `Application.Current.MainWindow` | Custom `App.Window` static property | Must track manually |
| `SizeToContent="Height"` | Custom `SizeToContent()` via `AppWindow.Resize()` | See [Windowing](./references/threading-and-windowing.md) |
| `MouseLeftButtonDown` | `PointerPressed` | Mouse → Pointer events |
| `Pack URI (pack://...)` | `ms-appx:///` | Resource URI scheme |
| `Observable` (custom base) | `ObservableObject` + `[ObservableProperty]` | CommunityToolkit.Mvvm |
| `RelayCommand` (custom) | `[RelayCommand]` source generator | CommunityToolkit.Mvvm |
| `JpegBitmapEncoder` | `BitmapEncoder.CreateAsync(JpegEncoderId, stream)` | Async, unified API |
| `encoder.QualityLevel = 85` | `BitmapPropertySet { "ImageQuality", 0.85f }` | int 1-100 → float 0-1 |
### NuGet Package Migration
| WPF | WinUI 3 |
|-----|---------|
| `Microsoft.Xaml.Behaviors.Wpf` | `Microsoft.Xaml.Behaviors.WinUI.Managed` |
| `WPF-UI` (Lepo) | Remove — use native WinUI 3 controls |
| `CommunityToolkit.Mvvm` | `CommunityToolkit.Mvvm` (same) |
| `Microsoft.Toolkit.Wpf.*` | `CommunityToolkit.WinUI.*` |
| (none) | `Microsoft.WindowsAppSDK` |
| (none) | `Microsoft.Windows.SDK.BuildTools` |
| (none) | `WinUIEx` (optional, for window helpers) |
| (none) | `CommunityToolkit.WinUI.Converters` |
### XAML Syntax Changes
| WPF | WinUI 3 |
|-----|---------|
| `xmlns:local="clr-namespace:MyApp"` | `xmlns:local="using:MyApp"` |
| `{DynamicResource Key}` | `{ThemeResource Key}` |
| `{x:Static Type.Member}` | `{x:Bind}` or code-behind |
| `{x:Type local:MyType}` | Not supported |
| `<Style.Triggers>` / `<DataTrigger>` | `VisualStateManager` |
| `{Binding}` in `Setter.Value` | Not supported — use `StaticResource` |
| `Content="{x:Static p:Resources.Cancel}"` | `x:Uid="Cancel"` with `.Content` in `.resw` |
| `<ui:FluentWindow>` / `<ui:Button>` (WPF-UI) | Native `<Window>` / `<Button>` |
| `<ui:NumberBox>` / `<ui:ProgressRing>` (WPF-UI) | Native `<NumberBox>` / `<ProgressRing>` |
| `BasedOn="{StaticResource {x:Type ui:Button}}"` | `BasedOn="{StaticResource DefaultButtonStyle}"` |
| `IsDefault="True"` / `IsCancel="True"` | `Style="{StaticResource AccentButtonStyle}"` / handle via KeyDown |
| `<AccessText>` | Not available — use `AccessKey` property |
| `<behaviors:Interaction.Triggers>` | Migrate to code-behind or WinUI behaviors |
## Detailed Reference Docs
Read only the section relevant to your current task:
- [Namespace and API Mapping](./references/namespace-api-mapping.md) — Full type mapping, NuGet changes, project file, CsWinRT interop
- [XAML Migration Guide](./references/xaml-migration.md) — XAML syntax, WPF-UI removal, markup extensions, styles, resources, data binding
- [Threading and Window Management](./references/threading-and-windowing.md) — Dispatcher, DispatcherQueue, SizeToContent, AppWindow, HWND interop, custom entry point
- [Imaging API Migration](./references/imaging-migration.md) — BitmapEncoder/Decoder, SoftwareBitmap, CodecHelper, async patterns, int→uint
- [PowerToys-Specific Patterns](./references/powertoys-patterns.md) — MVVM migration, ResourceLoader, Lazy init, installer, signing, test adaptation, build pipeline
## Common Pitfalls (from ImageResizer migration)
| Pitfall | Solution |
|---------|----------|
| `ContentDialog` throws "does not have a XamlRoot" | Set `dialog.XamlRoot = this.Content.XamlRoot` before `ShowAsync()` |
| `FilePicker` throws error in desktop app | Call `WinRT.Interop.InitializeWithWindow.Initialize(picker, hwnd)` |
| `Window.Dispatcher` returns null | Use `Window.DispatcherQueue` instead |
| Resources on `Window` element not found | Move resources to root layout container (`Grid.Resources`) |
| `VisualStateManager` on `Window` fails | Use `UserControl` or `Page` inside the Window |
| Satellite assembly installer errors (`WIX0103`) | Remove `.resources.dll` refs from `Resources.wxs`; WinUI 3 uses `.pri` |
| Phantom `.exe`/`.deps.json` in root output dir | Avoid Exe→WinExe `ProjectReference`; use Library project |
| `ResourceLoader` crash at static init | Wrap in `Lazy<T>` or null-coalescing property — see [Lazy Init](./references/powertoys-patterns.md#lazy-initialization-for-resource-dependent-statics) |
| `SizeToContent` not available | Implement manual content measurement + `AppWindow.Resize()` with DPI scaling |
| `x:Bind` default mode is `OneTime` | Explicitly set `Mode=OneWay` or `Mode=TwoWay` |
| `DynamicResource` / `x:Static` not compiling | Replace with `ThemeResource` / `ResourceLoader` or `x:Uid` |
| `IValueConverter.Convert` signature mismatch | Last param: `CultureInfo``string` (language tag) |
| Test project can't resolve WPF types | Add `<UseWPF>true</UseWPF>` temporarily; remove after imaging migration |
| Pixel dimension type mismatch (`int` vs `uint`) | WinRT uses `uint` for pixel sizes — add `u` suffix in test assertions |
| `$(SolutionDir)` empty in standalone project build | Use `$(MSBuildThisFileDirectory)` with relative paths instead |
| JPEG quality value wrong after migration | WPF: int 1-100; WinRT: float 0.0-1.0 |
| MSIX packaging fails in PreBuildEvent | Move to PostBuildEvent; artifacts not ready at PreBuild time |
| RC file icon path with forward slashes | Use double-backslash escaping: `..\\ui\\Assets\\icon.ico` |
## Troubleshooting
| Issue | Solution |
|-------|----------|
| Build fails after namespace rename | Check for lingering `System.Windows` usings; some types have no direct equivalent |
| Missing `PresentationCore.dll` at runtime | Ensure ALL imaging code uses `Windows.Graphics.Imaging`, not `System.Windows.Media.Imaging` |
| `DataContext` not working on Window | WinUI 3 `Window` is not a `DependencyObject`; use a root `Page` or `UserControl` |
| XAML designer not available | WinUI 3 does not support XAML Designer; use Hot Reload instead |
| NuGet restore failures | Run `build-essentials.cmd` after adding `Microsoft.WindowsAppSDK` package |
| `Parallel.ForEach` compilation error | Migrate to `Parallel.ForEachAsync` for async imaging operations |
| Signing check fails on leaked artifacts | Run `generateAllFileComponents.ps1`; verify only `WinUI3Apps\\` paths in signing config |

View File

@@ -1,287 +0,0 @@
# Imaging API Migration
Migrating from WPF (`System.Windows.Media.Imaging` / `PresentationCore.dll`) to WinRT (`Windows.Graphics.Imaging`). Based on the ImageResizer migration.
## Why This Migration Is Required
WinUI 3 apps deployed as self-contained do NOT include `PresentationCore.dll`. Any code using `System.Windows.Media.Imaging` will throw `FileNotFoundException` at runtime. ALL imaging code must use WinRT APIs.
| Purpose | Namespace |
|---------|-----------|
| UI display (`Image.Source`) | `Microsoft.UI.Xaml.Media.Imaging` |
| Image processing (encode/decode/transform) | `Windows.Graphics.Imaging` |
## Architecture Change: Pipeline vs Declarative
The fundamental architecture differs:
**WPF**: In-memory pipeline of bitmap objects. Decode → transform → encode synchronously.
```csharp
var decoder = BitmapDecoder.Create(stream, ...);
var transform = new TransformedBitmap(decoder.Frames[0], new ScaleTransform(...));
var encoder = new JpegBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(transform, ...));
encoder.Save(outputStream);
```
**WinRT**: Declarative transform model. Configure transforms on the encoder, which handles pixel manipulation internally. All async.
```csharp
var decoder = await BitmapDecoder.CreateAsync(winrtStream);
var encoder = await BitmapEncoder.CreateForTranscodingAsync(outputStream, decoder);
encoder.BitmapTransform.ScaledWidth = newWidth;
encoder.BitmapTransform.ScaledHeight = newHeight;
encoder.BitmapTransform.InterpolationMode = BitmapInterpolationMode.Fant;
await encoder.FlushAsync();
```
## Core Type Mapping
### Decoders
| WPF | WinRT | Notes |
|-----|-------|-------|
| `BitmapDecoder.Create(stream, options, cache)` | `BitmapDecoder.CreateAsync(stream)` | Async, auto-detects format |
| `JpegBitmapDecoder` / `PngBitmapDecoder` / etc. | `BitmapDecoder.CreateAsync(stream)` | Single unified decoder |
| `decoder.Frames[0]` | `await decoder.GetFrameAsync(0)` | Async frame access |
| `decoder.Frames.Count` | `decoder.FrameCount` (uint) | `int``uint` |
| `decoder.CodecInfo.ContainerFormat` | `decoder.DecoderInformation.CodecId` | Different property path |
| `decoder.Frames[0].PixelWidth` (int) | `decoder.PixelWidth` (uint) | `int``uint` |
| `WmpBitmapDecoder` | Not available | WMP/HDP not supported |
### Encoders
| WPF | WinRT | Notes |
|-----|-------|-------|
| `new JpegBitmapEncoder()` | `BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, stream)` | Async factory |
| `new PngBitmapEncoder()` | `BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, stream)` | No interlace control |
| `encoder.Frames.Add(frame)` | `encoder.SetSoftwareBitmap(bitmap)` | Different API |
| `encoder.Save(stream)` | `await encoder.FlushAsync()` | Async |
### Encoder Properties (Strongly-Typed → BitmapPropertySet)
WPF had type-specific encoder subclasses. WinRT uses a generic property set:
```csharp
// WPF
case JpegBitmapEncoder jpeg: jpeg.QualityLevel = 85; // int 1-100
case PngBitmapEncoder png: png.Interlace = PngInterlaceOption.On;
case TiffBitmapEncoder tiff: tiff.Compression = TiffCompressOption.Lzw;
// WinRT — JPEG quality (float 0.0-1.0)
await encoder.BitmapProperties.SetPropertiesAsync(new BitmapPropertySet
{
{ "ImageQuality", new BitmapTypedValue(0.85f, PropertyType.Single) }
});
// WinRT — TIFF compression (via BitmapPropertySet at creation time)
var props = new BitmapPropertySet
{
{ "TiffCompressionMethod", new BitmapTypedValue((byte)2, PropertyType.UInt8) }
};
var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.TiffEncoderId, stream, props);
```
**JPEG quality scale change**: WPF int `1-100` → WinRT float `0.0-1.0`. Divide by 100.
### Bitmap Types
| WPF | WinRT | Notes |
|-----|-------|-------|
| `BitmapSource` | `SoftwareBitmap` | Central pixel-data type |
| `BitmapImage` | `BitmapImage` (in `Microsoft.UI.Xaml.Media.Imaging`) | UI display only |
| `FormatConvertedBitmap` | `SoftwareBitmap.Convert()` | |
| `TransformedBitmap` + `ScaleTransform` | `BitmapTransform` via encoder | Declarative |
| `CroppedBitmap` | `BitmapTransform.Bounds` | |
### Metadata
| WPF | WinRT | Notes |
|-----|-------|-------|
| `BitmapMetadata` | `BitmapProperties` | Different API surface |
| `BitmapMetadata.Clone()` | No equivalent | Cannot selectively clone |
| Selective metadata removal | Not supported | All-or-nothing only |
**Two encoder creation strategies for metadata:**
- `CreateForTranscodingAsync()` — preserves ALL metadata from source
- `CreateAsync()` — creates fresh encoder with NO metadata
This eliminated ~258 lines of manual metadata manipulation code (`BitmapMetadataExtension.cs`) in ImageResizer.
### Interpolation Modes
| WPF `BitmapScalingMode` | WinRT `BitmapInterpolationMode` |
|------------------------|-------------------------------|
| `HighQuality` / `Fant` | `Fant` |
| `Linear` | `Linear` |
| `NearestNeighbor` | `NearestNeighbor` |
| `Unspecified` / `LowQuality` | `Linear` |
## Stream Interop
WinRT imaging requires `IRandomAccessStream` instead of `System.IO.Stream`:
```csharp
using var stream = File.OpenRead(path);
var winrtStream = stream.AsRandomAccessStream(); // Extension method
var decoder = await BitmapDecoder.CreateAsync(winrtStream);
```
**Critical**: For transcode, seek the input stream back to 0 before creating the encoder:
```csharp
winrtStream.Seek(0);
var encoder = await BitmapEncoder.CreateForTranscodingAsync(outputStream, decoder);
```
## CodecHelper Pattern (from ImageResizer)
WPF stored container format GUIDs in `settings.json`. WinRT uses different codec IDs. Create a `CodecHelper` to bridge them:
```csharp
internal static class CodecHelper
{
// Maps WPF container format GUIDs (stored in settings JSON) to WinRT encoder IDs
private static readonly Dictionary<Guid, Guid> LegacyGuidToEncoderId = new()
{
[new Guid("19e4a5aa-5662-4fc5-a0c0-1758028e1057")] = BitmapEncoder.JpegEncoderId,
[new Guid("1b7cfaf4-713f-473c-bbcd-6137425faeaf")] = BitmapEncoder.PngEncoderId,
[new Guid("0af1d87e-fcfe-4188-bdeb-a7906471cbe3")] = BitmapEncoder.BmpEncoderId,
[new Guid("163bcc30-e2e9-4f0b-961d-a3e9fdb788a3")] = BitmapEncoder.TiffEncoderId,
[new Guid("1f8a5601-7d4d-4cbd-9c82-1bc8d4eeb9a5")] = BitmapEncoder.GifEncoderId,
};
// Maps decoder IDs to corresponding encoder IDs
private static readonly Dictionary<Guid, Guid> DecoderIdToEncoderId = new()
{
[BitmapDecoder.JpegDecoderId] = BitmapEncoder.JpegEncoderId,
[BitmapDecoder.PngDecoderId] = BitmapEncoder.PngEncoderId,
// ...
};
public static Guid GetEncoderIdFromLegacyGuid(Guid legacyGuid)
=> LegacyGuidToEncoderId.GetValueOrDefault(legacyGuid, Guid.Empty);
public static Guid GetEncoderIdForDecoder(BitmapDecoder decoder)
=> DecoderIdToEncoderId.GetValueOrDefault(decoder.DecoderInformation.CodecId, Guid.Empty);
}
```
This preserves backward compatibility with existing `settings.json` files that contain WPF-era GUIDs.
## ImagingEnums Pattern (from ImageResizer)
WPF-specific enums (`PngInterlaceOption`, `TiffCompressOption`) from `System.Windows.Media.Imaging` are used in settings JSON. Create custom enums with identical integer values for backward-compatible deserialization:
```csharp
// Replace System.Windows.Media.Imaging.PngInterlaceOption
public enum PngInterlaceOption { Default = 0, On = 1, Off = 2 }
// Replace System.Windows.Media.Imaging.TiffCompressOption
public enum TiffCompressOption { Default = 0, None = 1, Ccitt3 = 2, Ccitt4 = 3, Lzw = 4, Rle = 5, Zip = 6 }
```
## Async Migration Patterns
### Method Signatures
All imaging operations become async:
| Before | After |
|--------|-------|
| `void Execute(file, settings)` | `async Task ExecuteAsync(file, settings)` |
| `IEnumerable<Error> Process()` | `async Task<IEnumerable<Error>> ProcessAsync()` |
### Parallel Processing
```csharp
// WPF (synchronous)
Parallel.ForEach(Files, new ParallelOptions { MaxDegreeOfParallelism = ... },
(file, state, i) => { Execute(file, settings); });
// WinRT (async)
await Parallel.ForEachAsync(Files, new ParallelOptions { MaxDegreeOfParallelism = ... },
async (file, ct) => { await ExecuteAsync(file, settings); });
```
### CLI Async Bridge
CLI entry points must bridge async to sync:
```csharp
return RunSilentModeAsync(cliOptions).GetAwaiter().GetResult();
```
### Task.Factory.StartNew → Task.Run
```csharp
// WPF
_ = Task.Factory.StartNew(StartExecutingWork, token, TaskCreationOptions.LongRunning, TaskScheduler.Default);
// WinUI 3
_ = Task.Run(() => StartExecutingWorkAsync());
```
## SoftwareBitmap as Interface Type
When modules expose imaging interfaces (e.g., AI super-resolution), change parameter/return types:
```csharp
// WPF
BitmapSource ApplySuperResolution(BitmapSource source, int scale, string filePath);
// WinRT
SoftwareBitmap ApplySuperResolution(SoftwareBitmap source, int scale, string filePath);
```
This eliminates manual `BitmapSource ↔ SoftwareBitmap` conversion code (unsafe `IMemoryBufferByteAccess` COM interop).
## MultiFrame Image Handling
```csharp
// WinRT multi-frame encode (e.g., multi-page TIFF, animated GIF)
for (uint i = 0; i < decoder.FrameCount; i++)
{
if (i > 0)
await encoder.GoToNextFrameAsync();
var frame = await decoder.GetFrameAsync(i);
var bitmap = await frame.GetSoftwareBitmapAsync(
frame.BitmapPixelFormat,
BitmapAlphaMode.Premultiplied,
transform,
ExifOrientationMode.IgnoreExifOrientation,
ColorManagementMode.DoNotColorManage);
encoder.SetSoftwareBitmap(bitmap);
}
await encoder.FlushAsync();
```
## int → uint for Pixel Dimensions
WinRT uses `uint` for all pixel dimensions. This affects:
- `decoder.PixelWidth` / `decoder.PixelHeight``uint`
- `BitmapTransform.ScaledWidth` / `ScaledHeight``uint`
- `SoftwareBitmap` constructor — `uint` parameters
- Test assertions: `Assert.AreEqual(96, ...)``Assert.AreEqual(96u, ...)`
## Display SoftwareBitmap in UI
```csharp
var source = new SoftwareBitmapSource();
// Must convert to Bgra8/Premultiplied for display
if (bitmap.BitmapPixelFormat != BitmapPixelFormat.Bgra8 ||
bitmap.BitmapAlphaMode != BitmapAlphaMode.Premultiplied)
{
bitmap = SoftwareBitmap.Convert(bitmap, BitmapPixelFormat.Bgra8, BitmapAlphaMode.Premultiplied);
}
await source.SetBitmapAsync(bitmap);
myImage.Source = source;
```
## Known Limitations
| Feature | WPF | WinRT | Impact |
|---------|-----|-------|--------|
| PNG interlace | `PngBitmapEncoder.Interlace` | Not available | Always non-interlaced |
| Metadata stripping | Selective via `BitmapMetadata.Clone()` | All-or-nothing | Orientation EXIF also removed |
| Pixel formats | Many (`Pbgra32`, `Bgr24`, `Indexed8`, ...) | Primarily `Bgra8`, `Rgba8`, `Gray8/16` | Convert to `Bgra8` |
| WMP/HDP format | `WmpBitmapDecoder` | Not available | Not supported |
| Pixel differences | WPF scaler | `BitmapInterpolationMode.Fant` | Not bit-identical |

View File

@@ -1,226 +0,0 @@
# Namespace and API Mapping Reference
Complete reference for mapping WPF types to WinUI 3 equivalents, based on the ImageResizer migration.
## Root Namespace Mapping
| WPF Namespace | WinUI 3 Namespace |
|---------------|-------------------|
| `System.Windows` | `Microsoft.UI.Xaml` |
| `System.Windows.Automation` | `Microsoft.UI.Xaml.Automation` |
| `System.Windows.Automation.Peers` | `Microsoft.UI.Xaml.Automation.Peers` |
| `System.Windows.Controls` | `Microsoft.UI.Xaml.Controls` |
| `System.Windows.Controls.Primitives` | `Microsoft.UI.Xaml.Controls.Primitives` |
| `System.Windows.Data` | `Microsoft.UI.Xaml.Data` |
| `System.Windows.Documents` | `Microsoft.UI.Xaml.Documents` |
| `System.Windows.Input` | `Microsoft.UI.Xaml.Input` |
| `System.Windows.Markup` | `Microsoft.UI.Xaml.Markup` |
| `System.Windows.Media` | `Microsoft.UI.Xaml.Media` |
| `System.Windows.Media.Animation` | `Microsoft.UI.Xaml.Media.Animation` |
| `System.Windows.Media.Imaging` | `Microsoft.UI.Xaml.Media.Imaging` |
| `System.Windows.Navigation` | `Microsoft.UI.Xaml.Navigation` |
| `System.Windows.Shapes` | `Microsoft.UI.Xaml.Shapes` |
| `System.Windows.Threading` | `Microsoft.UI.Dispatching` |
| `System.Windows.Interop` | `WinRT.Interop` |
## Core Type Mapping
| WPF Type | WinUI 3 Type |
|----------|-------------|
| `System.Windows.Application` | `Microsoft.UI.Xaml.Application` |
| `System.Windows.Window` | `Microsoft.UI.Xaml.Window` (NOT a DependencyObject) |
| `System.Windows.DependencyObject` | `Microsoft.UI.Xaml.DependencyObject` |
| `System.Windows.DependencyProperty` | `Microsoft.UI.Xaml.DependencyProperty` |
| `System.Windows.FrameworkElement` | `Microsoft.UI.Xaml.FrameworkElement` |
| `System.Windows.UIElement` | `Microsoft.UI.Xaml.UIElement` |
| `System.Windows.Visibility` | `Microsoft.UI.Xaml.Visibility` |
| `System.Windows.Thickness` | `Microsoft.UI.Xaml.Thickness` |
| `System.Windows.CornerRadius` | `Microsoft.UI.Xaml.CornerRadius` |
| `System.Windows.Media.Color` | `Windows.UI.Color` (note: `Windows.UI`, not `Microsoft.UI`) |
| `System.Windows.Media.Colors` | `Microsoft.UI.Colors` |
## Controls Mapping
### Direct Mapping (namespace-only change)
These controls exist in both frameworks with the same name — change `System.Windows.Controls` to `Microsoft.UI.Xaml.Controls`:
`Button`, `TextBox`, `TextBlock`, `ComboBox`, `CheckBox`, `ListBox`, `ListView`, `Image`, `StackPanel`, `Grid`, `Border`, `ScrollViewer`, `ContentControl`, `UserControl`, `Page`, `Frame`, `Slider`, `ProgressBar`, `ToolTip`, `RadioButton`, `ToggleButton`
### Controls With Different Names or Behavior
| WPF | WinUI 3 | Notes |
|-----|---------|-------|
| `MessageBox` | `ContentDialog` | Must set `XamlRoot` before `ShowAsync()` |
| `ContextMenu` | `MenuFlyout` | Different API surface |
| `TabControl` | `TabView` | Different API |
| `Menu` | `MenuBar` | Different API |
| `StatusBar` | Custom `StackPanel` layout | No built-in equivalent |
| `AccessText` | Not available | Use `AccessKey` property on target control |
### WPF-UI (Lepo) to Native WinUI 3
ImageResizer used the `WPF-UI` library (Lepo) for Fluent styling. These must be replaced with native WinUI 3 equivalents:
| WPF-UI (Lepo) | WinUI 3 Native | Notes |
|----------------|---------------|-------|
| `<ui:FluentWindow>` | `<Window>` | Native window + `ExtendsContentIntoTitleBar` |
| `<ui:Button>` | `<Button>` | Native button |
| `<ui:NumberBox>` | `<NumberBox>` | Built into WinUI 3 |
| `<ui:ProgressRing>` | `<ProgressRing>` | Built into WinUI 3 |
| `<ui:SymbolIcon>` | `<SymbolIcon>` or `<FontIcon>` | Built into WinUI 3 |
| `<ui:InfoBar>` | `<InfoBar>` | Built into WinUI 3 |
| `<ui:TitleBar>` | Custom title bar via `SetTitleBar()` | Use `ExtendsContentIntoTitleBar` |
| `<ui:ThemesDictionary>` | `<XamlControlsResources>` | In merged dictionaries |
| `<ui:ControlsDictionary>` | Remove | Not needed — WinUI 3 has its own control styles |
| `BasedOn="{StaticResource {x:Type ui:Button}}"` | `BasedOn="{StaticResource DefaultButtonStyle}"` | Named style keys |
## Input Event Mapping
| WPF Event | WinUI 3 Event | Notes |
|-----------|--------------|-------|
| `MouseLeftButtonDown` | `PointerPressed` | Check `IsLeftButtonPressed` on args |
| `MouseLeftButtonUp` | `PointerReleased` | Check pointer properties |
| `MouseRightButtonDown` | `RightTapped` | Or `PointerPressed` with right button check |
| `MouseMove` | `PointerMoved` | Uses `PointerRoutedEventArgs` |
| `MouseWheel` | `PointerWheelChanged` | Different event args |
| `MouseEnter` | `PointerEntered` | |
| `MouseLeave` | `PointerExited` | |
| `MouseDoubleClick` | `DoubleTapped` | Different event args |
| `KeyDown` | `KeyDown` | Same name, args type: `KeyRoutedEventArgs` |
| `PreviewKeyDown` | No direct equivalent | Use `KeyDown` with handled pattern |
## IValueConverter Signature Change
| WPF | WinUI 3 |
|-----|---------|
| `Convert(object value, Type targetType, object parameter, CultureInfo culture)` | `Convert(object value, Type targetType, object parameter, string language)` |
| `ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)` | `ConvertBack(object value, Type targetType, object parameter, string language)` |
Last parameter changes from `CultureInfo` to `string` (BCP-47 language tag). All converter classes must be updated.
## Types That Moved to Different Hierarchies
| WPF | WinUI 3 | Notes |
|-----|---------|-------|
| `System.Windows.Threading.Dispatcher` | `Microsoft.UI.Dispatching.DispatcherQueue` | Completely different API |
| `System.Windows.Threading.DispatcherPriority` | `Microsoft.UI.Dispatching.DispatcherQueuePriority` | Only 3 levels: High/Normal/Low |
| `System.Windows.Interop.HwndSource` | `WinRT.Interop.WindowNative` | For HWND interop |
| `System.Windows.Interop.WindowInteropHelper` | `WinRT.Interop.WindowNative.GetWindowHandle()` | |
| `System.Windows.SystemColors` | Resource keys via `ThemeResource` | No direct static class |
| `System.Windows.SystemParameters` | Win32 API or `DisplayInformation` | No direct equivalent |
## NuGet Package Migration
| WPF | WinUI 3 | Notes |
|-----|---------|-------|
| Built into .NET (no NuGet needed) | `Microsoft.WindowsAppSDK` | Required |
| `PresentationCore` / `PresentationFramework` | `Microsoft.WinUI` (transitive) | |
| `Microsoft.Xaml.Behaviors.Wpf` | `Microsoft.Xaml.Behaviors.WinUI.Managed` | |
| `WPF-UI` (Lepo) | **Remove** — use native WinUI 3 controls | |
| `CommunityToolkit.Mvvm` | `CommunityToolkit.Mvvm` (same) | |
| `Microsoft.Toolkit.Wpf.*` | `CommunityToolkit.WinUI.*` | |
| (none) | `Microsoft.Windows.SDK.BuildTools` | Required |
| (none) | `WinUIEx` | Optional, window helpers |
| (none) | `CommunityToolkit.WinUI.Converters` | Optional |
| (none) | `CommunityToolkit.WinUI.Extensions` | Optional |
| (none) | `Microsoft.Web.WebView2` | If using WebView |
## Project File Changes
### WPF .csproj
```xml
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net8.0-windows</TargetFramework>
<UseWPF>true</UseWPF>
<ApplicationManifest>ImageResizerUI.dev.manifest</ApplicationManifest>
<ApplicationIcon>Resources\ImageResizer.ico</ApplicationIcon>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
</PropertyGroup>
</Project>
```
### WinUI 3 .csproj
```xml
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net8.0-windows10.0.19041.0</TargetFramework>
<UseWinUI>true</UseWinUI>
<SelfContained>true</SelfContained>
<WindowsAppSDKSelfContained>true</WindowsAppSDKSelfContained>
<WindowsPackageType>None</WindowsPackageType>
<EnablePreviewMsixTooling>true</EnablePreviewMsixTooling>
<ApplicationManifest>app.manifest</ApplicationManifest>
<ApplicationIcon>Assets\ImageResizer\ImageResizer.ico</ApplicationIcon>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<DefineConstants>DISABLE_XAML_GENERATED_MAIN,TRACE</DefineConstants>
<ProjectPriFileName>PowerToys.ModuleName.pri</ProjectPriFileName>
</PropertyGroup>
</Project>
```
Key changes:
- `UseWPF``UseWinUI`
- TFM: `net8.0-windows``net8.0-windows10.0.19041.0`
- Add `WindowsPackageType=None` for unpackaged desktop apps
- Add `SelfContained=true` + `WindowsAppSDKSelfContained=true`
- Add `DISABLE_XAML_GENERATED_MAIN` if using custom `Program.cs` entry point
- Set `ProjectPriFileName` to match your module's assembly name
- Move icon from `Resources/` to `Assets/<Module>/`
### XAML ApplicationDefinition Setup
WinUI 3 requires explicit `ApplicationDefinition` declaration:
```xml
<ItemGroup>
<Page Remove="ImageResizerXAML\App.xaml" />
</ItemGroup>
<ItemGroup>
<ApplicationDefinition Include="ImageResizerXAML\App.xaml" />
</ItemGroup>
```
### CsWinRT Interop (for GPO and native references)
If the module references native C++ projects (like `GPOWrapper`):
```xml
<PropertyGroup>
<CsWinRTIncludes>PowerToys.GPOWrapper</CsWinRTIncludes>
<CsWinRTGeneratedFilesDir>$(OutDir)</CsWinRTGeneratedFilesDir>
</PropertyGroup>
```
Change `GPOWrapperProjection.csproj` reference to direct `GPOWrapper.vcxproj` reference.
### InternalsVisibleTo Migration
Move from code file to `.csproj`:
```csharp
// DELETE: Properties/InternalsVisibleTo.cs
// [assembly: InternalsVisibleTo("ImageResizer.Test")]
```
```xml
<!-- ADD to .csproj: -->
<ItemGroup>
<InternalsVisibleTo Include="ImageResizer.Test" />
</ItemGroup>
```
### Items to Remove from .csproj
```xml
<!-- DELETE: WPF resource embedding -->
<EmbeddedResource Update="Properties\Resources.resx">...</EmbeddedResource>
<Resource Include="Resources\ImageResizer.ico" />
<Compile Update="Properties\Resources.Designer.cs">...</Compile>
<FrameworkReference Include="Microsoft.WindowsDesktop.App.WPF" /> <!-- from CLI project -->
```

View File

@@ -1,516 +0,0 @@
# PowerToys-Specific Migration Patterns
Patterns and conventions specific to the PowerToys codebase, based on the ImageResizer migration.
## Project Structure
### Before (WPF Module)
```
src/modules/<module>/
├── <Module>UI/
│ ├── <Module>UI.csproj # OutputType=WinExe, UseWPF=true
│ ├── App.xaml / App.xaml.cs
│ ├── MainWindow.xaml / .cs
│ ├── Views/
│ ├── ViewModels/
│ ├── Helpers/
│ │ ├── Observable.cs # Custom INotifyPropertyChanged
│ │ └── RelayCommand.cs # Custom ICommand
│ ├── Properties/
│ │ ├── Resources.resx # WPF resource strings
│ │ ├── Resources.Designer.cs
│ │ └── InternalsVisibleTo.cs
│ └── Telemetry/
├── <Module>CLI/
│ └── <Module>CLI.csproj # OutputType=Exe
└── tests/
```
### After (WinUI 3 Module)
```
src/modules/<module>/
├── <Module>UI/
│ ├── <Module>UI.csproj # OutputType=WinExe, UseWinUI=true
│ ├── Program.cs # Custom entry point (DISABLE_XAML_GENERATED_MAIN)
│ ├── app.manifest # Single manifest file
│ ├── ImageResizerXAML/
│ │ ├── App.xaml / App.xaml.cs # WinUI 3 App class
│ │ ├── MainWindow.xaml / .cs
│ │ └── Views/
│ ├── Converters/ # WinUI 3 IValueConverter (string language)
│ ├── ViewModels/
│ ├── Helpers/
│ │ └── ResourceLoaderInstance.cs # Static ResourceLoader accessor
│ ├── Utilities/
│ │ └── CodecHelper.cs # WPF→WinRT codec ID mapping (if imaging)
│ ├── Models/
│ │ └── ImagingEnums.cs # Custom enums replacing WPF imaging enums
│ ├── Strings/
│ │ └── en-us/
│ │ └── Resources.resw # WinUI 3 resource strings
│ └── Assets/
│ └── <Module>/
│ └── <Module>.ico # Moved from Resources/
├── <Module>Common/ # NEW: shared library for CLI
│ └── <Module>Common.csproj # OutputType=Library
├── <Module>CLI/
│ └── <Module>CLI.csproj # References Common, NOT UI
└── tests/
```
### Critical: CLI Dependency Pattern
**Do NOT** create `ProjectReference` from Exe to WinExe. This causes phantom build artifacts (`.exe`, `.deps.json`, `.runtimeconfig.json`) in the root output directory.
```
WRONG: ImageResizerCLI (Exe) → ImageResizerUI (WinExe) ← phantom artifacts
CORRECT: ImageResizerCLI (Exe) → ImageResizerCommon (Library)
ImageResizerUI (WinExe) → ImageResizerCommon (Library)
```
Follow the `FancyZonesCLI``FancyZonesEditorCommon` pattern.
### Files to Delete
| File | Reason |
|------|--------|
| `Properties/Resources.resx` | Replaced by `Strings/en-us/Resources.resw` |
| `Properties/Resources.Designer.cs` | Auto-generated; no longer needed |
| `Properties/InternalsVisibleTo.cs` | Moved to `.csproj` `<InternalsVisibleTo>` |
| `Helpers/Observable.cs` | Replaced by `CommunityToolkit.Mvvm.ObservableObject` |
| `Helpers/RelayCommand.cs` | Replaced by `CommunityToolkit.Mvvm.Input` |
| `Resources/*.ico` / `Resources/*.png` | Moved to `Assets/<Module>/` |
| WPF `.dev.manifest` / `.prod.manifest` | Replaced by single `app.manifest` |
| WPF-specific converters | Replaced by WinUI 3 converters with `string language` |
---
## MVVM Migration: Custom → CommunityToolkit.Mvvm Source Generators
### Observable Base Class → ObservableObject + [ObservableProperty]
**Before (custom Observable):**
```csharp
public class ResizeSize : Observable
{
private int _id;
public int Id { get => _id; set => Set(ref _id, value); }
private ResizeFit _fit;
public ResizeFit Fit
{
get => _fit;
set
{
Set(ref _fit, value);
UpdateShowHeight();
}
}
private bool _showHeight = true;
public bool ShowHeight { get => _showHeight; set => Set(ref _showHeight, value); }
private void UpdateShowHeight() { ShowHeight = Fit == ResizeFit.Stretch || Unit != ResizeUnit.Percent; }
}
```
**After (CommunityToolkit.Mvvm source generators):**
```csharp
public partial class ResizeSize : ObservableObject // MUST be partial
{
[ObservableProperty]
[JsonPropertyName("Id")]
private int _id;
[ObservableProperty]
[NotifyPropertyChangedFor(nameof(ShowHeight))] // Replaces manual UpdateShowHeight()
private ResizeFit _fit;
// Computed property — no backing field, no manual update method
public bool ShowHeight => Fit == ResizeFit.Stretch || Unit != ResizeUnit.Percent;
}
```
Key changes:
- Class must be `partial` for source generators
- `Observable``ObservableObject` (from CommunityToolkit.Mvvm)
- Manual `Set(ref _field, value)``[ObservableProperty]` attribute
- `PropertyChanged` dependencies → `[NotifyPropertyChangedFor(nameof(...))]`
- Computed properties with manual `UpdateXxx()` → direct expression body
### Custom Name Setter with Transform
For properties that transform the value before storing:
```csharp
// Cannot use [ObservableProperty] because of value transformation
private string _name;
public string Name
{
get => _name;
set => SetProperty(ref _name, ReplaceTokens(value)); // SetProperty from ObservableObject
}
```
### RelayCommand → [RelayCommand] Source Generator
```csharp
// DELETE: Helpers/RelayCommand.cs (custom ICommand)
// Before
public ICommand ResizeCommand { get; } = new RelayCommand(Execute);
// After
[RelayCommand]
private void Resize() { /* ... */ }
// Source generator creates ResizeCommand property automatically
```
---
## Resource String Migration (.resx → .resw)
### ResourceLoaderInstance Helper
```csharp
internal static class ResourceLoaderInstance
{
internal static ResourceLoader ResourceLoader { get; private set; }
static ResourceLoaderInstance()
{
ResourceLoader = new ResourceLoader("PowerToys.ImageResizer.pri");
}
}
```
**Note**: Use the single-argument `ResourceLoader` constructor. The two-argument version (`ResourceLoader("file.pri", "path/Resources")`) may fail if the resource map path doesn't match the actual PRI structure.
### Usage
```csharp
// WPF
using ImageResizer.Properties;
string text = Resources.MyStringKey;
// WinUI 3
string text = ResourceLoaderInstance.ResourceLoader.GetString("MyStringKey");
```
### Lazy Initialization for Resource-Dependent Statics
`ResourceLoader` is not available at class-load time in all contexts (CLI mode, test harness). Use lazy initialization:
**Before (crashes at class load):**
```csharp
private static readonly CompositeFormat _format =
CompositeFormat.Parse(Resources.Error_Format);
private static readonly Dictionary<string, string> _tokens = new()
{
["$small$"] = Resources.Small,
["$medium$"] = Resources.Medium,
};
```
**After (lazy, safe):**
```csharp
private static CompositeFormat _format;
private static CompositeFormat Format => _format ??=
CompositeFormat.Parse(ResourceLoaderInstance.ResourceLoader.GetString("Error_Format"));
private static readonly Lazy<Dictionary<string, string>> _tokens = new(() =>
new Dictionary<string, string>
{
["$small$"] = ResourceLoaderInstance.ResourceLoader.GetString("Small"),
["$medium$"] = ResourceLoaderInstance.ResourceLoader.GetString("Medium"),
});
// Usage: _tokens.Value.TryGetValue(...)
```
### XAML: x:Static → x:Uid
```xml
<!-- WPF -->
<Button Content="{x:Static p:Resources.Cancel}" />
<!-- WinUI 3 -->
<Button x:Uid="Cancel" />
```
In `.resw`, use property-suffixed keys: `Cancel.Content`, `Header.Text`, etc.
---
## CLI Options Migration
`System.CommandLine.Option<T>` constructor signature changed:
```csharp
// WPF era — string[] aliases
public DestinationOption()
: base(_aliases, Properties.Resources.CLI_Option_Destination)
// WinUI 3 — single string name
public DestinationOption()
: base(_aliases[0], ResourceLoaderInstance.ResourceLoader.GetString("CLI_Option_Destination"))
```
---
## Installer Updates
### WiX Changes
#### 1. Remove Satellite Assembly References
Remove from `installer/PowerToysSetupVNext/Resources.wxs`:
- `<Component>` entries for `<Module>.resources.dll`
- `<RemoveFolder>` entries for locale directories
- Module from `WinUI3AppsInstallFolder` `ParentDirectory` loop
#### 2. Update File Component Generation
Run `generateAllFileComponents.ps1` after migration. For Exe→WinExe dependency issues, add cleanup logic:
```powershell
# Strip phantom ImageResizer files from BaseApplications.wxs
$content = $content -replace 'PowerToys\.ImageResizer\.exe', ''
$content = $content -replace 'PowerToys\.ImageResizer\.deps\.json', ''
$content = $content -replace 'PowerToys\.ImageResizer\.runtimeconfig\.json', ''
```
#### 3. Output Directory
WinUI 3 modules output to `WinUI3Apps/`:
```xml
<OutputPath>..\..\..\..\$(Platform)\$(Configuration)\WinUI3Apps\</OutputPath>
```
### ESRP Signing
Update `.pipelines/ESRPSigning_core.json` — all module binaries must use `WinUI3Apps\\` paths:
```json
{
"FileList": [
"WinUI3Apps\\PowerToys.ImageResizer.exe",
"WinUI3Apps\\PowerToys.ImageResizerExt.dll",
"WinUI3Apps\\PowerToys.ImageResizerContextMenu.dll"
]
}
```
---
## Build Pipeline Fixes
### $(SolutionDir) → $(MSBuildThisFileDirectory)
`$(SolutionDir)` is empty when building individual projects outside the solution. Replace with relative paths from the project file:
```xml
<!-- Before (breaks on standalone project build) -->
<Exec Command="powershell $(SolutionDir)tools\build\convert-resx-to-rc.ps1" />
<!-- After (works always) -->
<Exec Command="powershell $(MSBuildThisFileDirectory)..\..\..\..\tools\build\convert-resx-to-rc.ps1" />
```
### MSIX Packaging: PreBuild → PostBuild
MSIX packaging must happen AFTER the build (artifacts not ready at PreBuild):
```xml
<!-- Before -->
<PreBuildEvent>MakeAppx.exe pack /d . /p "$(OutDir)Package.msix" /o</PreBuildEvent>
<!-- After -->
<PostBuildEvent>
if exist "$(OutDir)Package.msix" del "$(OutDir)Package.msix"
MakeAppx.exe pack /d "$(MSBuildThisFileDirectory)." /p "$(OutDir)Package.msix" /o
</PostBuildEvent>
```
### RC File Icon Path Escaping
Windows Resource Compiler requires double-backslash paths:
```c
// Before (breaks)
IDI_ICON1 ICON "..\\ui\Assets\ImageResizer\ImageResizer.ico"
// After
IDI_ICON1 ICON "..\\ui\\Assets\\ImageResizer\\ImageResizer.ico"
```
### BOM/Encoding Normalization
Migration may strip UTF-8 BOM from C# files (`// Copyright``// Copyright`). This is cosmetic and safe, but be aware it will show as changes in diff.
---
## Test Adaptation
### Tests Requiring WPF Runtime
If tests still need WPF types (e.g., comparing old vs new output), temporarily add:
```xml
<UseWPF>true</UseWPF>
```
Remove this after fully migrating all test code to WinRT APIs.
### Tests Using ResourceLoader
Unit tests cannot easily initialize WinUI 3 `ResourceLoader`. Options:
- Hardcode expected strings in tests: `"Value must be between '{0}' and '{1}'."`
- Delete tests that only verify resource string lookup
- Avoid creating `App` instances in test harness (WinUI App cannot be instantiated in tests)
### Async Test Methods
All imaging tests become async:
```csharp
// Before
[TestMethod]
public void ResizesImage() { ... }
// After
[TestMethod]
public async Task ResizesImageAsync() { ... }
```
### uint Assertions
```csharp
// Before
Assert.AreEqual(96, image.Frames[0].PixelWidth);
// After
Assert.AreEqual(96u, decoder.PixelWidth);
```
### Pixel Data Access in Tests
```csharp
// Before (WPF)
public static Color GetFirstPixel(this BitmapSource source)
{
var pixel = new byte[4];
new FormatConvertedBitmap(
new CroppedBitmap(source, new Int32Rect(0, 0, 1, 1)),
PixelFormats.Bgra32, null, 0).CopyPixels(pixel, 4, 0);
return Color.FromArgb(pixel[3], pixel[2], pixel[1], pixel[0]);
}
// After (WinRT)
public static async Task<(byte R, byte G, byte B, byte A)> GetFirstPixelAsync(
this BitmapDecoder decoder)
{
using var bitmap = await decoder.GetSoftwareBitmapAsync(
BitmapPixelFormat.Bgra8, BitmapAlphaMode.Premultiplied);
var buffer = new Windows.Storage.Streams.Buffer(
(uint)(bitmap.PixelWidth * bitmap.PixelHeight * 4));
bitmap.CopyToBuffer(buffer);
using var reader = DataReader.FromBuffer(buffer);
byte b = reader.ReadByte(), g = reader.ReadByte(),
r = reader.ReadByte(), a = reader.ReadByte();
return (r, g, b, a);
}
```
### Metadata Assertions
```csharp
// Before
Assert.AreEqual("Test", ((BitmapMetadata)image.Frames[0].Metadata).Comment);
// After
var props = await decoder.BitmapProperties.GetPropertiesAsync(
new[] { "System.Photo.DateTaken" });
Assert.IsTrue(props.ContainsKey("System.Photo.DateTaken"),
"Metadata should be preserved during transcode");
```
### AllowUnsafeBlocks for SoftwareBitmap Tests
If tests access pixel data via `IMemoryBufferByteAccess`, add:
```xml
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
```
---
## Settings JSON Backward Compatibility
- Settings are stored in `%LOCALAPPDATA%\Microsoft\PowerToys\<ModuleName>\`
- Schema must remain backward-compatible across upgrades
- Add new fields with defaults; never remove or rename existing fields
- Create custom enums matching WPF enum integer values for deserialization (e.g., `ImagingEnums.cs`)
- See: `src/settings-ui/Settings.UI.Library/`
## IPC Contract
If the module communicates with the runner or settings UI:
1. Update BOTH sides of the IPC contract
2. Test settings changes are received by the module
3. Test module state changes are reflected in settings UI
4. Reference: `doc/devdocs/core/settings/runner-ipc.md`
---
## Checklist for PowerToys Module Migration
### Project & Dependencies
- [ ] Update `.csproj`: `UseWPF``UseWinUI`, TFM → `net8.0-windows10.0.19041.0`
- [ ] Add `WindowsPackageType=None`, `SelfContained=true`, `WindowsAppSDKSelfContained=true`
- [ ] Add `DISABLE_XAML_GENERATED_MAIN` if using custom `Program.cs`
- [ ] Replace NuGet packages (WPF-UI → remove, add WindowsAppSDK, etc.)
- [ ] Update project references (GPOWrapperProjection → GPOWrapper + CsWinRT)
- [ ] Move `InternalsVisibleTo` from code to `.csproj`
- [ ] Extract CLI shared logic to Library project (avoid Exe→WinExe dependency)
### MVVM & Resources
- [ ] Replace custom `Observable`/`RelayCommand` with CommunityToolkit.Mvvm source generators
- [ ] Migrate `.resx``.resw` (`Properties/Resources.resx``Strings/en-us/Resources.resw`)
- [ ] Create `ResourceLoaderInstance` helper
- [ ] Wrap resource-dependent statics in `Lazy<T>` or null-coalescing properties
- [ ] Delete `Properties/Resources.Designer.cs`, `Observable.cs`, `RelayCommand.cs`
### XAML
- [ ] Replace `clr-namespace:``using:` in all xmlns declarations
- [ ] Remove WPF-UI (Lepo) xmlns and controls — use native WinUI 3
- [ ] Replace `{x:Static p:Resources.Key}``x:Uid` with `.resw` keys
- [ ] Replace `{DynamicResource}``{ThemeResource}`
- [ ] Replace `DataType="{x:Type ...}"``x:DataType="..."`
- [ ] Replace `<Style.Triggers>``VisualStateManager`
- [ ] Add `<XamlControlsResources/>` to `App.xaml` merged dictionaries
- [ ] Move `Window.Resources` to root container's `Resources`
- [ ] Run XamlStyler: `.\.pipelines\applyXamlStyling.ps1 -Main`
### Code-Behind & APIs
- [ ] Replace all `System.Windows.*` namespaces with `Microsoft.UI.Xaml.*`
- [ ] Replace `Dispatcher` with `DispatcherQueue`
- [ ] Store `DispatcherQueue` reference explicitly (no `Application.Current.Dispatcher`)
- [ ] Implement `SizeToContent()` via AppWindow if needed
- [ ] Update `ContentDialog` calls to set `XamlRoot`
- [ ] Update `FilePicker` calls with HWND initialization
- [ ] Migrate imaging code to `Windows.Graphics.Imaging` (async, `SoftwareBitmap`)
- [ ] Create `CodecHelper` for legacy GUID → WinRT codec ID mapping (if imaging)
- [ ] Create custom imaging enums for JSON backward compatibility (if imaging)
- [ ] Update all `IValueConverter` signatures (`CultureInfo``string`)
### Build & Installer
- [ ] Update WiX installer: remove satellite assembly refs from `Resources.wxs`
- [ ] Run `generateAllFileComponents.ps1`; handle phantom artifacts
- [ ] Update ESRP signing paths to `WinUI3Apps\\`
- [ ] Fix `$(SolutionDir)``$(MSBuildThisFileDirectory)` in build events
- [ ] Move MSIX packaging from PreBuild to PostBuild
- [ ] Fix RC file path escaping (double-backslash)
- [ ] Verify output dir is `WinUI3Apps/`
### Testing & Validation
- [ ] Update test project: async methods, `uint` assertions
- [ ] Handle ResourceLoader unavailability in tests (hardcode strings or skip)
- [ ] Build clean: `cd` to project folder, `tools/build/build.cmd`, exit code 0
- [ ] Run tests for affected module
- [ ] Verify settings JSON backward compatibility
- [ ] Test IPC contracts (runner ↔ settings UI)

View File

@@ -1,314 +0,0 @@
# Threading and Window Management Migration
Based on patterns from the ImageResizer migration.
## Dispatcher → DispatcherQueue
### API Mapping
| WPF | WinUI 3 |
|-----|---------|
| `Dispatcher.Invoke(Action)` | `DispatcherQueue.TryEnqueue(Action)` |
| `Dispatcher.BeginInvoke(Action)` | `DispatcherQueue.TryEnqueue(Action)` |
| `Dispatcher.Invoke(DispatcherPriority, Action)` | `DispatcherQueue.TryEnqueue(DispatcherQueuePriority, Action)` |
| `Dispatcher.CheckAccess()` | `DispatcherQueue.HasThreadAccess` |
| `Dispatcher.VerifyAccess()` | Check `DispatcherQueue.HasThreadAccess` (no exception-throwing method) |
### Priority Mapping
WinUI 3 has only 3 levels: `High`, `Normal`, `Low`.
| WPF `DispatcherPriority` | WinUI 3 `DispatcherQueuePriority` |
|-------------------------|----------------------------------|
| `Send` | `High` |
| `Normal` / `Input` / `Loaded` / `Render` / `DataBind` | `Normal` |
| `Background` / `ContextIdle` / `ApplicationIdle` / `SystemIdle` | `Low` |
### Pattern: Global DispatcherQueue Access (from ImageResizer)
WPF provided `Application.Current.Dispatcher` globally. WinUI 3 requires explicit storage:
```csharp
// Store DispatcherQueue at app startup
private static DispatcherQueue _uiDispatcherQueue;
public static void InitializeDispatcher()
{
_uiDispatcherQueue = DispatcherQueue.GetForCurrentThread();
}
```
Usage with thread-check pattern (from `Settings.Reload()`):
```csharp
var currentDispatcher = DispatcherQueue.GetForCurrentThread();
if (currentDispatcher != null)
{
// Already on UI thread
ReloadCore(jsonSettings);
}
else if (_uiDispatcherQueue != null)
{
// Dispatch to UI thread
_uiDispatcherQueue.TryEnqueue(() => ReloadCore(jsonSettings));
}
else
{
// Fallback (e.g., CLI mode, no UI)
ReloadCore(jsonSettings);
}
```
### Pattern: DispatcherQueue in ViewModels (from ProgressViewModel)
```csharp
public class ProgressViewModel
{
private readonly DispatcherQueue _dispatcherQueue;
public ProgressViewModel()
{
_dispatcherQueue = DispatcherQueue.GetForCurrentThread();
}
private void OnProgressChanged(double progress)
{
_dispatcherQueue.TryEnqueue(() =>
{
Progress = progress;
// other UI updates...
});
}
}
```
### Pattern: Async Dispatch (await)
```csharp
// WPF
await this.Dispatcher.InvokeAsync(() => { /* UI work */ });
// WinUI 3 (using TaskCompletionSource)
var tcs = new TaskCompletionSource();
this.DispatcherQueue.TryEnqueue(() =>
{
try { /* UI work */ tcs.SetResult(); }
catch (Exception ex) { tcs.SetException(ex); }
});
await tcs.Task;
```
### C++/WinRT Threading
| Old API | New API |
|---------|---------|
| `winrt::resume_foreground(CoreDispatcher)` | `wil::resume_foreground(DispatcherQueue)` |
| `CoreDispatcher.RunAsync()` | `DispatcherQueue.TryEnqueue()` |
Add `Microsoft.Windows.ImplementationLibrary` NuGet for `wil::resume_foreground`.
---
## Window Management
### WPF Window vs WinUI 3 Window
| Feature | WPF `Window` | WinUI 3 `Window` |
|---------|-------------|------------------|
| Base class | `ContentControl``DependencyObject` | **NOT** a control, NOT a `DependencyObject` |
| `Resources` property | Yes | No — use root container's `Resources` |
| `DataContext` property | Yes | No — use root `Page`/`UserControl` |
| `VisualStateManager` | Yes | No — use inside child controls |
| `Load`/`Unload` events | Yes | No |
| `SizeToContent` | Yes (`Height`/`Width`/`WidthAndHeight`) | No — must implement manually |
| `WindowState` (min/max/normal) | Yes | No — use `AppWindow.Presenter` |
| `WindowStyle` | Yes | No — use `AppWindow` title bar APIs |
| `ResizeMode` | Yes | No — use `AppWindow.Presenter` |
| `WindowStartupLocation` | Yes | No — calculate manually |
| `Icon` | `Window.Icon` | `AppWindow.SetIcon()` |
| `Title` | `Window.Title` | `AppWindow.Title` (or `Window.Title`) |
| Size (Width/Height) | Yes | No — use `AppWindow.Resize()` |
| Position (Left/Top) | Yes | No — use `AppWindow.Move()` |
| `IsDefault`/`IsCancel` on buttons | Yes | No — handle Enter/Escape in code-behind |
### Getting AppWindow from Window
```csharp
using Microsoft.UI;
using Microsoft.UI.Windowing;
using WinRT.Interop;
IntPtr hwnd = WindowNative.GetWindowHandle(window);
WindowId windowId = Win32Interop.GetWindowIdFromWindow(hwnd);
AppWindow appWindow = AppWindow.GetFromWindowId(windowId);
```
### Pattern: SizeToContent Replacement (from ImageResizer)
WinUI 3 has no `SizeToContent`. ImageResizer implemented a manual equivalent:
```csharp
private void SizeToContent()
{
if (Content is not FrameworkElement content)
return;
// Measure desired content size
content.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
var desiredHeight = content.DesiredSize.Height + WindowChromeHeight + Padding;
// Account for DPI scaling
var scaleFactor = Content.XamlRoot.RasterizationScale;
var pixelHeight = (int)(desiredHeight * scaleFactor);
var pixelWidth = (int)(WindowWidth * scaleFactor);
// Resize via AppWindow
var hwnd = WindowNative.GetWindowHandle(this);
var windowId = Win32Interop.GetWindowIdFromWindow(hwnd);
var appWindow = AppWindow.GetFromWindowId(windowId);
appWindow.Resize(new Windows.Graphics.SizeInt32(pixelWidth, pixelHeight));
}
```
**Key details:**
- `WindowChromeHeight` ≈ 32px for the title bar
- Must multiply by `RasterizationScale` for DPI-aware sizing
- Call `SizeToContent()` after page navigation or content changes
- Unsubscribe previous event handlers before subscribing new ones to avoid memory leaks
### Window Positioning (Center Screen)
```csharp
var displayArea = DisplayArea.GetFromWindowId(windowId, DisplayAreaFallback.Nearest);
var centerX = (displayArea.WorkArea.Width - appWindow.Size.Width) / 2;
var centerY = (displayArea.WorkArea.Height - appWindow.Size.Height) / 2;
appWindow.Move(new Windows.Graphics.PointInt32(centerX, centerY));
```
### Window State (Minimize/Maximize)
```csharp
(appWindow.Presenter as OverlappedPresenter)?.Maximize();
(appWindow.Presenter as OverlappedPresenter)?.Minimize();
(appWindow.Presenter as OverlappedPresenter)?.Restore();
```
### Title Bar Customization
```csharp
// Extend content into title bar
this.ExtendsContentIntoTitleBar = true;
this.SetTitleBar(AppTitleBar); // AppTitleBar is a XAML element
// Or via AppWindow API
if (AppWindowTitleBar.IsCustomizationSupported())
{
var titleBar = appWindow.TitleBar;
titleBar.ExtendsContentIntoTitleBar = true;
titleBar.ButtonBackgroundColor = Colors.Transparent;
}
```
### Tracking the Main Window
```csharp
public partial class App : Application
{
public static Window MainWindow { get; private set; }
protected override void OnLaunched(LaunchActivatedEventArgs args)
{
MainWindow = new MainWindow();
MainWindow.Activate();
}
}
```
### ContentDialog Requires XamlRoot
```csharp
var dialog = new ContentDialog
{
Title = "Confirm",
Content = "Are you sure?",
PrimaryButtonText = "Yes",
CloseButtonText = "No",
XamlRoot = this.Content.XamlRoot // REQUIRED
};
var result = await dialog.ShowAsync();
```
### File Pickers Require HWND
```csharp
var picker = new FileOpenPicker();
picker.FileTypeFilter.Add(".jpg");
// REQUIRED for desktop apps
var hwnd = WindowNative.GetWindowHandle(App.MainWindow);
WinRT.Interop.InitializeWithWindow.Initialize(picker, hwnd);
var file = await picker.PickSingleFileAsync();
```
### Window Close Handling
```csharp
// WPF
protected override void OnClosing(CancelEventArgs e) { e.Cancel = true; this.Hide(); }
// WinUI 3
this.AppWindow.Closing += (s, e) => { e.Cancel = true; this.AppWindow.Hide(); };
```
---
## Custom Entry Point (DISABLE_XAML_GENERATED_MAIN)
ImageResizer uses a custom `Program.cs` entry point instead of the WinUI 3 auto-generated `Main`. This is needed for:
- CLI mode (process files without showing UI)
- Custom initialization before the WinUI 3 App starts
- Single-instance enforcement
### Setup
In `.csproj`:
```xml
<DefineConstants>DISABLE_XAML_GENERATED_MAIN,TRACE</DefineConstants>
```
Create `Program.cs`:
```csharp
public static class Program
{
[STAThread]
public static int Main(string[] args)
{
if (args.Length > 0)
{
// CLI mode — no UI
return RunCli(args);
}
// GUI mode
WinRT.ComWrappersSupport.InitializeComWrappers();
Application.Start((p) =>
{
var context = new DispatcherQueueSynchronizationContext(
DispatcherQueue.GetForCurrentThread());
SynchronizationContext.SetSynchronizationContext(context);
_ = new App();
});
return 0;
}
}
```
### WPF App Constructor Removal
WPF modules often created `new App()` to initialize the WPF `Application` and get `Application.Current.Dispatcher`. This is no longer needed — the WinUI 3 `Application.Start()` handles this.
```csharp
// DELETE (WPF pattern):
_imageResizerApp = new App();
// REPLACE with: Store DispatcherQueue explicitly (see Global DispatcherQueue Access above)
```

View File

@@ -1,365 +0,0 @@
# XAML Migration Guide
Detailed reference for migrating XAML from WPF to WinUI 3, based on the ImageResizer migration.
## XML Namespace Declaration Changes
### Before (WPF)
```xml
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MyApp"
xmlns:m="clr-namespace:ImageResizer.Models"
xmlns:p="clr-namespace:ImageResizer.Properties"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
x:Class="MyApp.MainWindow">
```
### After (WinUI 3)
```xml
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:MyApp"
xmlns:m="using:ImageResizer.Models"
xmlns:converters="using:ImageResizer.Converters"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
x:Class="MyApp.MainWindow">
```
### Key Changes
| WPF Syntax | WinUI 3 Syntax | Notes |
|------------|---------------|-------|
| `clr-namespace:Foo` | `using:Foo` | CLR namespace mapping |
| `clr-namespace:Foo;assembly=Bar` | `using:Foo` | Assembly qualification not needed |
| `xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"` | **Remove entirely** | WPF-UI namespace no longer needed |
| `xmlns:p="clr-namespace:...Properties"` | **Remove** | No more `.resx` string bindings |
| `sys:String` (from mscorlib) | `x:String` | XAML intrinsic types |
| `sys:Int32` | `x:Int32` | XAML intrinsic types |
| `sys:Boolean` | `x:Boolean` | XAML intrinsic types |
| `sys:Double` | `x:Double` | XAML intrinsic types |
## Unsupported Markup Extensions
| WPF Markup Extension | WinUI 3 Alternative |
|----------------------|---------------------|
| `{DynamicResource Key}` | `{ThemeResource Key}` (theme-reactive) or `{StaticResource Key}` |
| `{x:Static Type.Member}` | `{x:Bind}` to a static property, or code-behind |
| `{x:Type local:MyType}` | Not supported; use code-behind |
| `{x:Array}` | Not supported; create collections in code-behind |
| `{x:Code}` | Not supported |
### DynamicResource → ThemeResource
```xml
<!-- WPF -->
<TextBlock Foreground="{DynamicResource MyBrush}" />
<!-- WinUI 3 -->
<TextBlock Foreground="{ThemeResource MyBrush}" />
```
`ThemeResource` automatically updates when the app theme changes (Light/Dark/HighContrast). For truly dynamic non-theme resources, set values in code-behind or use data binding.
### x:Static Resource Strings → x:Uid
This is the most pervasive XAML change. WPF used `{x:Static}` to bind to strongly-typed `.resx` resource strings. WinUI 3 uses `x:Uid` with `.resw` files.
**WPF:**
```xml
<Button Content="{x:Static p:Resources.Cancel}" />
<TextBlock Text="{x:Static p:Resources.Input_Header}" />
```
**WinUI 3:**
```xml
<Button x:Uid="Cancel" />
<TextBlock x:Uid="Input_Header" />
```
In `Strings/en-us/Resources.resw`:
```xml
<data name="Cancel.Content" xml:space="preserve">
<value>Cancel</value>
</data>
<data name="Input_Header.Text" xml:space="preserve">
<value>Select a size</value>
</data>
```
The `x:Uid` suffix (`.Content`, `.Text`, `.Header`, `.PlaceholderText`, etc.) matches the target property name.
### DataType with x:Type → Remove
**WPF:**
```xml
<DataTemplate DataType="{x:Type m:ResizeSize}">
```
**WinUI 3:**
```xml
<DataTemplate x:DataType="m:ResizeSize">
```
## WPF-UI (Lepo) Controls Removal
If the module uses the `WPF-UI` library, replace all Lepo controls with native WinUI 3 equivalents.
### Window
```xml
<!-- WPF (WPF-UI) -->
<ui:FluentWindow
ExtendsContentIntoTitleBar="True"
WindowStartupLocation="CenterScreen">
<ui:TitleBar Title="Image Resizer" />
...
</ui:FluentWindow>
<!-- WinUI 3 (native) -->
<Window>
<!-- Title bar managed via code-behind: this.ExtendsContentIntoTitleBar = true; -->
...
</Window>
```
### App.xaml Resources
```xml
<!-- WPF (WPF-UI) -->
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ui:ThemesDictionary Theme="Dark" />
<ui:ControlsDictionary />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
<!-- WinUI 3 (native) -->
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
```
### Common Control Replacements
```xml
<!-- WPF-UI NumberBox -->
<ui:NumberBox Value="{Binding Width}" />
<!-- WinUI 3 -->
<NumberBox Value="{x:Bind ViewModel.Width, Mode=TwoWay}" />
<!-- WPF-UI InfoBar -->
<ui:InfoBar Title="Warning" Message="..." IsOpen="True" Severity="Warning" />
<!-- WinUI 3 -->
<InfoBar Title="Warning" Message="..." IsOpen="True" Severity="Warning" />
<!-- WPF-UI ProgressRing -->
<ui:ProgressRing IsIndeterminate="True" />
<!-- WinUI 3 -->
<ProgressRing IsActive="True" />
<!-- WPF-UI SymbolIcon -->
<ui:SymbolIcon Symbol="Add" />
<!-- WinUI 3 -->
<SymbolIcon Symbol="Add" />
```
### Button Patterns
```xml
<!-- WPF -->
<Button IsDefault="True" Content="OK" />
<Button IsCancel="True" Content="Cancel" />
<!-- WinUI 3 (no IsDefault/IsCancel) -->
<Button Style="{StaticResource AccentButtonStyle}" Content="OK" />
<Button Content="Cancel" />
<!-- Handle Enter/Escape keys in code-behind if needed -->
```
## Style and Template Changes
### Triggers → VisualStateManager
WPF `Triggers`, `DataTriggers`, and `EventTriggers` are not supported.
**WPF:**
```xml
<Style TargetType="Button">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="LightBlue"/>
</Trigger>
<DataTrigger Binding="{Binding IsEnabled}" Value="False">
<Setter Property="Opacity" Value="0.5"/>
</DataTrigger>
</Style.Triggers>
</Style>
```
**WinUI 3:**
```xml
<Style TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid x:Name="RootGrid" Background="{TemplateBinding Background}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="PointerOver">
<VisualState.Setters>
<Setter Target="RootGrid.Background" Value="LightBlue"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<ContentPresenter />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
```
### No Binding in Setter.Value
```xml
<!-- WPF (works) -->
<Setter Property="Foreground" Value="{Binding TextColor}"/>
<!-- WinUI 3 (does NOT work — use StaticResource) -->
<Setter Property="Foreground" Value="{StaticResource TextColorBrush}"/>
```
### Visual State Name Changes
| WPF | WinUI 3 |
|-----|---------|
| `MouseOver` | `PointerOver` |
| `Disabled` | `Disabled` |
| `Pressed` | `Pressed` |
## Resource Dictionary Changes
### Window.Resources → Grid.Resources
WinUI 3 `Window` is NOT a `DependencyObject` — no `Window.Resources`, `DataContext`, or `VisualStateManager`.
```xml
<!-- WPF -->
<Window>
<Window.Resources>
<SolidColorBrush x:Key="MyBrush" Color="Red"/>
</Window.Resources>
<Grid>...</Grid>
</Window>
<!-- WinUI 3 -->
<Window>
<Grid>
<Grid.Resources>
<SolidColorBrush x:Key="MyBrush" Color="Red"/>
</Grid.Resources>
...
</Grid>
</Window>
```
### Theme Dictionaries
```xml
<ResourceDictionary>
<ResourceDictionary.ThemeDictionaries>
<ResourceDictionary x:Key="Light">
<SolidColorBrush x:Key="MyBrush" Color="#FF000000"/>
</ResourceDictionary>
<ResourceDictionary x:Key="Dark">
<SolidColorBrush x:Key="MyBrush" Color="#FFFFFFFF"/>
</ResourceDictionary>
<ResourceDictionary x:Key="HighContrast">
<SolidColorBrush x:Key="MyBrush" Color="{ThemeResource SystemColorWindowTextColor}"/>
</ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>
</ResourceDictionary>
```
## URI Scheme Changes
| WPF | WinUI 3 |
|-----|---------|
| `pack://application:,,,/MyAssembly;component/image.png` | `ms-appx:///Assets/image.png` |
| `pack://application:,,,/image.png` | `ms-appx:///image.png` |
| Relative path `../image.png` | `ms-appx:///image.png` |
Assets directory convention: `Resources/``Assets/<Module>/`
## Data Binding Changes
### {Binding} vs {x:Bind}
Both are available. Prefer `{x:Bind}` for compile-time safety and performance.
| Feature | `{Binding}` | `{x:Bind}` |
|---------|------------|------------|
| Default mode | `OneWay` | **`OneTime`** (explicit `Mode=OneWay` required!) |
| Context | `DataContext` | Code-behind class |
| Resolution | Runtime | Compile-time |
| Performance | Reflection-based | Compiled |
| Function binding | No | Yes |
### WPF-Specific Binding Features to Remove
```xml
<!-- These WPF-only features must be removed or rewritten -->
<TextBox Text="{Binding Value, UpdateSourceTrigger=PropertyChanged}" />
<!-- WinUI 3: UpdateSourceTrigger not needed; TextBox uses PropertyChanged by default -->
<TextBox Text="{x:Bind ViewModel.Value, Mode=TwoWay}" />
{Binding RelativeSource={RelativeSource Self}, ...}
<!-- WinUI 3: Use x:Bind which binds to the page itself, or use ElementName -->
<ItemsControl ItemsSource="{Binding}" />
<!-- WinUI 3: Must specify explicit path -->
<ItemsControl ItemsSource="{x:Bind ViewModel.Items}" />
```
## WPF-Only Window Properties to Remove
These properties exist on WPF `Window` but not WinUI 3:
```xml
<!-- Remove from XAML — handle in code-behind via AppWindow API -->
SizeToContent="Height"
WindowStartupLocation="CenterScreen"
ResizeMode="NoResize"
ExtendsContentIntoTitleBar="True" <!-- Set in code-behind -->
```
## XAML Control Property Changes
| WPF Property | WinUI 3 Property | Notes |
|-------------|-----------------|-------|
| `Focusable` | `IsTabStop` | Different name |
| `SnapsToDevicePixels` | Not available | WinUI handles pixel snapping internally |
| `UseLayoutRounding` | `UseLayoutRounding` | Same |
| `IsHitTestVisible` | `IsHitTestVisible` | Same |
| `TextBox.VerticalScrollBarVisibility` | `ScrollViewer.VerticalScrollBarVisibility` (attached) | Attached property |
## XAML Formatting (XamlStyler)
After migration, run XamlStyler to normalize formatting:
- Alphabetize xmlns declarations and element attributes
- Add UTF-8 BOM to all XAML files
- Normalize comment spacing: `<!-- text -->``<!-- text -->`
PowerToys command: `.\.pipelines\applyXamlStyling.ps1 -Main`

View File

@@ -1,213 +0,0 @@
name: Automatic Triaging on Issue Creation
on:
issues:
types: [opened, reopened]
# Manual trigger: go to Actions → "Automatic Triaging on Issue Creation" → Run workflow.
# Enter one or more comma-separated issue numbers (e.g. "1234" or "1234,1235,1236")
# to apply AI-generated area labels to existing untriaged issues.
workflow_dispatch:
inputs:
issue_numbers:
description: 'Comma-separated issue number(s) to label (e.g. 1234 or 1234,1235)'
required: true
permissions:
models: read
issues: write
concurrency:
# Each workflow run gets its own concurrency group.
# For issue events, group by issue number so a rapid close+reopen only runs once.
# For manual dispatch (which may cover multiple issues), use the unique run ID.
group: ${{ github.event_name == 'issues' && format('{0}-issue-{1}', github.workflow, github.event.issue.number) || github.run_id }}
cancel-in-progress: true
jobs:
label:
runs-on: ubuntu-latest
steps:
- name: Apply area labels with AI
uses: actions/github-script@v7
env:
# actions/github-script does not propagate `github-token` to
# process.env. Expose it explicitly so the inline script can
# authenticate against the GitHub Models inference endpoint.
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
// When triggered manually, process each supplied issue number in turn.
// When triggered by an issue event, use the event's issue number.
let issueNumbers;
if (context.eventName === 'workflow_dispatch') {
issueNumbers = String(context.payload.inputs.issue_numbers)
.split(',')
.map(s => parseInt(s.trim(), 10))
.filter(n => Number.isFinite(n) && n > 0);
} else {
issueNumbers = [context.issue.number];
}
if (issueNumbers.length === 0) {
console.log('No valid issue numbers to process; skipping.');
return;
}
for (const issueNumber of issueNumbers) {
console.log(`\n--- Processing issue #${issueNumber} ---`);
await labelIssue(issueNumber);
}
async function labelIssue(issueNumber) {
// Fetch the issue so both the automatic and manual paths have the same data.
const { data: issue } = await github.rest.issues.get({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issueNumber,
});
const title = issue.title ?? '';
const body = issue.body ?? '';
if (!title && !body) {
console.log(`Issue #${issueNumber} has no title or body; skipping.`);
return;
}
// Truncation limit for issue body sent to the model. Keeps the
// prompt within the model's context window and avoids high token usage.
const MAX_BODY_LENGTH = 4000;
// Upper bound on model response tokens. A JSON array of label strings
// is compact; 200 tokens is more than enough for any realistic response.
const MAX_TOKENS = 200;
// All valid Product-* and Area-* labels the agent may choose from.
const VALID_LABELS = [
'Product-Advanced Paste',
'Product-Always On Top',
'Product-Awake',
'Product-Color Picker',
'Product-CommandNotFound',
'Product-Command Palette',
'Product-CropAndLock',
'Product-Environment Variables',
'Product-FancyZones',
'Product-File Explorer',
'Product-File Locksmith',
'Product-Find My Mouse',
'Product-Grab And Move',
'Product-Hosts File Editor',
'Product-Image Resizer',
'Product-Keyboard Manager',
'Product-LightSwitch',
'Product-Mouse Highlighter',
'Product-Mouse Jump',
'Product-Mouse Pointer Crosshairs',
'Product-Mouse Utilities',
'Product-Mouse Without Borders',
'Product-New+',
'Product-Peek',
'Product-PowerDisplay',
'Product-PowerRename',
'Product-PowerToys Run',
'Product-Quick Accent',
'Product-Registry Preview',
'Product-Screen Ruler',
'Product-Settings',
'Product-Shortcut Guide',
'Product-Text Extractor',
'Product-Workspaces',
'Product-ZoomIt',
'Area-Setup/Install',
'Area-Localization',
];
const systemPrompt = `You are a GitHub issue triage assistant for the microsoft/PowerToys repository.
Your job is to classify issues by assigning the correct area label(s).
Rules:
- Only return labels from the following list, exactly as written:
${VALID_LABELS.map(l => ` • ${l}`).join('\n')}
- Choose only the labels that clearly match the issue content.
- If the issue mentions multiple areas, include a label for each one.
- If no label fits, return an empty array.
- Respond with ONLY a JSON array of label strings, no explanation.
Example: ["Product-FancyZones","Product-Settings"]`;
const userPrompt = `Issue title: ${title}
Issue body:
${body.slice(0, MAX_BODY_LENGTH)}`;
// Validate that the token is available before making the API call.
const token = process.env.GITHUB_TOKEN;
if (!token) {
console.log('GITHUB_TOKEN is not set; skipping.');
return;
}
// Call the GitHub Models inference endpoint (OpenAI-compatible).
const response = await fetch(
'https://models.inference.ai.azure.com/chat/completions',
{
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
model: 'gpt-4o-mini',
messages: [
{ role: 'system', content: systemPrompt },
{ role: 'user', content: userPrompt },
],
max_tokens: MAX_TOKENS,
// temperature: 0 ensures deterministic, consistent label
// classification across similar issues.
temperature: 0,
}),
}
);
if (!response.ok) {
const errorBody = await response.text();
console.log(`GitHub Models API error: ${response.status} ${response.statusText} — ${errorBody}`);
return;
}
const data = await response.json();
const text = data.choices?.[0]?.message?.content?.trim() ?? '';
console.log(`Model response: ${text}`);
let suggested;
try {
suggested = JSON.parse(text);
} catch {
console.log('Could not parse model response as JSON; skipping.');
return;
}
if (!Array.isArray(suggested) || suggested.length === 0) {
console.log('No labels suggested by the model.');
return;
}
// Only apply labels that are in the allow-list.
const validSet = new Set(VALID_LABELS);
const toApply = [...new Set(suggested.filter(l => validSet.has(l)))];
if (toApply.length === 0) {
console.log('Model returned no valid labels.');
return;
}
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issueNumber,
labels: toApply,
});
console.log(`Issue #${issueNumber}: added labels: ${toApply.join(', ')}`);
}

View File

@@ -23,7 +23,7 @@ jobs:
export $(echo 'anypass_just_to_unlock' | gnome-keyring-daemon --start --components=gpg,pkcs11,secrets,ssh)
- name: Log in to Azure
uses: azure/login@v3
uses: azure/login@v2
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
@@ -47,7 +47,7 @@ jobs:
- uses: microsoft/setup-msstore-cli@v1
- name: Fetch Store Credential
uses: azure/cli@v3
uses: azure/cli@v2
with:
azcliversion: latest
inlineScript: |-

View File

@@ -55,7 +55,7 @@ name: Spell checking
# spelling:
# # remove `security-events: write` and `use_sarif: 1`
# # remove `experimental_apply_changes_via_bot: 1`
# ... otherwise, adjust the `with:` as you wish
# ... otherwise adjust the `with:` as you wish
on:
push:
@@ -74,8 +74,6 @@ on:
types:
- "created"
permissions: {}
jobs:
spelling:
name: Check Spelling
@@ -87,7 +85,7 @@ jobs:
outputs:
followup: ${{ steps.spelling.outputs.followup }}
runs-on: ubuntu-latest
if: ${{ (contains(github.event_name, 'pull_request') && github.event.pull_request.state == 'open') || github.event_name == 'push' }}
if: ${{ contains(github.event_name, 'pull_request') || github.event_name == 'push' }}
concurrency:
group: spelling-${{ github.event.pull_request.number || github.ref }}
# note: If you use only_check_changed_files, you do not want cancel-in-progress
@@ -95,7 +93,7 @@ jobs:
steps:
- name: check-spelling
id: spelling
uses: check-spelling/check-spelling@cfb6f7e75bbfc89c71eaa30366d0c166f1bd9c8c # v0.0.26
uses: check-spelling/check-spelling@c635c2f3f714eec2fcf27b643a1919b9a811ef2e # v0.0.25
with:
config: .github/actions/spell-check
suppress_push_for_open_pull_request: ${{ github.actor != 'dependabot[bot]' && 1 }}
@@ -137,12 +135,11 @@ jobs:
cspell:cpp/compiler-msvc.txt
cspell:python/common/extra.txt
cspell:scala/scala.txt
ignored: ignored-expect-variant
comment-push:
name: Report (Push)
# If your workflow isn't running on push, you can remove this job
runs-on: ubuntu-slim
runs-on: ubuntu-latest
needs: spelling
permissions:
actions: read
@@ -150,23 +147,30 @@ jobs:
if: (success() || failure()) && needs.spelling.outputs.followup && github.event_name == 'push'
steps:
- name: comment
uses: check-spelling/check-spelling@cfb6f7e75bbfc89c71eaa30366d0c166f1bd9c8c # v0.0.26
uses: check-spelling/check-spelling@c635c2f3f714eec2fcf27b643a1919b9a811ef2e # v0.0.25
with:
config: .github/actions/spell-check
checkout: true
spell_check_this: microsoft/PowerToys@main
task: ${{ needs.spelling.outputs.followup }}
comment-pr:
name: Report (PR)
# If you workflow isn't running on pull_request*, you can remove this job
runs-on: ubuntu-slim
runs-on: ubuntu-latest
needs: spelling
permissions:
actions: read
contents: read
pull-requests: write
if: (success() || failure()) && needs.spelling.outputs.followup && contains(github.event_name, 'pull_request')
steps:
- name: comment
uses: check-spelling/check-spelling@cfb6f7e75bbfc89c71eaa30366d0c166f1bd9c8c # v0.0.26
uses: check-spelling/check-spelling@c635c2f3f714eec2fcf27b643a1919b9a811ef2e # v0.0.25
with:
config: .github/actions/spell-check
checkout: true
spell_check_this: check-spelling/spell-check-this@prerelease
task: ${{ needs.spelling.outputs.followup }}
experimental_apply_changes_via_bot: ${{ github.repository_owner != 'microsoft' && 1 }}
@@ -176,13 +180,12 @@ jobs:
contents: write
pull-requests: write
actions: read
runs-on: ubuntu-slim
runs-on: ubuntu-latest
if: ${{
github.repository_owner != 'microsoft' &&
github.event_name == 'issue_comment' &&
github.event.issue.pull_request &&
contains(github.event.comment.body, '@check-spelling-bot') &&
contains(github.event.comment.body, 'apply') &&
contains(github.event.comment.body, '@check-spelling-bot apply') &&
contains(github.event.comment.body, 'https://')
}}
concurrency:
@@ -190,7 +193,7 @@ jobs:
cancel-in-progress: false
steps:
- name: apply spelling updates
uses: check-spelling/check-spelling@cfb6f7e75bbfc89c71eaa30366d0c166f1bd9c8c # v0.0.26
uses: check-spelling/check-spelling@c635c2f3f714eec2fcf27b643a1919b9a811ef2e # v0.0.25
with:
experimental_apply_changes_via_bot: ${{ github.repository_owner != 'microsoft' && 1 }}
checkout: true

View File

@@ -1,35 +0,0 @@
# NOTE: This workflow depends on .github/scripts/telemetry-pr-check.js for telemetry detection and PR comments.
# Keep this workflow and script behavior in sync when making changes.
name: Telemetry PR Check
on:
pull_request_target:
types: [opened, reopened, synchronize, ready_for_review]
workflow_dispatch:
inputs:
pr_number:
description: "Pull Request Number to test against"
required: true
type: string
permissions:
contents: read
pull-requests: write
concurrency:
group: telemetry-pr-check-${{ github.event.pull_request.number }}
cancel-in-progress: true
jobs:
detect-telemetry-events:
if: ${{ github.event.pull_request.draft == false }}
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v6
- name: Detect telemetry event changes and comment PR
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: node .github/scripts/telemetry-pr-check.js

15
.gitignore vendored
View File

@@ -360,18 +360,3 @@ src/common/Telemetry/*.etl
# PowerToysInstaller Build Temp Files
installer/*/*.wxs.bk
/src/modules/awake/.claude
# Claude AI local settings - local-only, not committed
**/.claude/settings.local.json
# Squad / Copilot agents — local-only, not committed
.copilot
.squad
.squad-workstream
.github/agents/**squad**.md
.github/workflows/**squad**.yml
# vcpkg manifest mode installed packages
vcpkg_installed/
deps/vcpkg/

6
.gitmodules vendored Normal file
View File

@@ -0,0 +1,6 @@
[submodule "deps/spdlog"]
path = deps/spdlog
url = https://github.com/gabime/spdlog.git
[submodule "deps/expected-lite"]
path = deps/expected-lite
url = https://github.com/martinmoene/expected-lite.git

View File

@@ -141,13 +141,13 @@
"WinUI3Apps\\PowerToys.EnvironmentVariables.dll",
"WinUI3Apps\\PowerToys.EnvironmentVariables.exe",
"WinUI3Apps\\PowerToys.ImageResizer.exe",
"WinUI3Apps\\PowerToys.ImageResizer.dll",
"PowerToys.ImageResizer.exe",
"PowerToys.ImageResizer.dll",
"WinUI3Apps\\PowerToys.ImageResizerCLI.exe",
"WinUI3Apps\\PowerToys.ImageResizerCLI.dll",
"WinUI3Apps\\PowerToys.ImageResizerExt.dll",
"WinUI3Apps\\PowerToys.ImageResizerContextMenu.dll",
"WinUI3Apps\\ImageResizerContextMenuPackage.msix",
"PowerToys.ImageResizerExt.dll",
"PowerToys.ImageResizerContextMenu.dll",
"ImageResizerContextMenuPackage.msix",
"PowerToys.LightSwitchModuleInterface.dll",
"LightSwitchService\\PowerToys.LightSwitchService.exe",
@@ -212,17 +212,12 @@
"WinUI3Apps\\PowerToys.NewPlus.ShellExtension.win10.dll",
"PowerAccent.Core.dll",
"PowerAccent.Common.dll",
"PowerToys.PowerAccent.dll",
"PowerToys.PowerAccent.exe",
"PowerToys.PowerAccentModuleInterface.dll",
"PowerToys.PowerAccentKeyboardService.dll",
"PowerToys.PowerDisplayModuleInterface.dll",
"WinUI3Apps\\PowerToys.PowerDisplay.dll",
"WinUI3Apps\\PowerToys.PowerDisplay.exe",
"PowerDisplay.Lib.dll",
"PowerDisplay.Models.dll",
"WinUI3Apps\\PowerToys.PowerRenameExt.dll",
"WinUI3Apps\\PowerToys.PowerRename.exe",
@@ -244,20 +239,13 @@
"WinUI3Apps\\PowerToys.RegistryPreview.dll",
"WinUI3Apps\\PowerToys.RegistryPreview.exe",
"WinUI3Apps\\PowerToys.ShortcutGuide.exe",
"WinUI3Apps\\PowerToys.ShortcutGuide.dll",
"WinUI3Apps\\PowerToys.ShortcutGuideModuleInterface.dll",
"WinUI3Apps\\PowerToys.ShortcutGuide.IndexYmlGenerator.dll",
"WinUI3Apps\\PowerToys.ShortcutGuide.IndexYmlGenerator.exe",
"WinUI3Apps\\ShortcutGuide.CPPProject.dll",
"PowerToys.ShortcutGuide.exe",
"PowerToys.ShortcutGuideModuleInterface.dll",
"PowerToys.ZoomIt.exe",
"PowerToys.ZoomItModuleInterface.dll",
"PowerToys.ZoomItSettingsInterop.dll",
"PowerToys.GrabAndMove.exe",
"PowerToys.GrabAndMoveModuleInterface.dll",
"WinUI3Apps\\PowerToys.Settings.dll",
"WinUI3Apps\\PowerToys.Settings.exe",
@@ -269,8 +257,8 @@
"Workspaces.ModuleServices.dll",
"Microsoft.CommandPalette.Extensions.dll",
"Microsoft.CommandPalette.Extensions.Toolkit.dll",
"WinUI3Apps\\Microsoft.CmdPal.Ext.PowerToys.dll",
"WinUI3Apps\\Microsoft.CmdPal.Ext.PowerToys.exe",
"Microsoft.CmdPal.Ext.PowerToys.dll",
"Microsoft.CmdPal.Ext.PowerToys.exe",
"*Microsoft.CmdPal.UI_*.msix",
"PowerToys.DSC.dll",
@@ -388,11 +376,6 @@
"ColorCode.Core.dll",
"Microsoft.SemanticKernel.Connectors.Ollama.dll",
"OllamaSharp.dll",
"WinUI3Apps\\Google.Apis.dll",
"WinUI3Apps\\Google.Apis.Auth.dll",
"WinUI3Apps\\Google.Apis.Core.dll",
"WinUI3Apps\\Google.GenAI.dll",
"WinUI3Apps\\YamlDotNet.dll",
"boost_regex-vc143-mt-gd-x32-1_87.dll",
"boost_regex-vc143-mt-gd-x64-1_87.dll",

View File

@@ -16,7 +16,6 @@ pr:
include:
- main
- stable
drafts: false
# paths:
# exclude:
# - '**.md'

View File

@@ -104,10 +104,6 @@ extends:
# Have msbuild use the release nuget config profile
additionalBuildOptions: /p:RestoreConfigFile="$(Build.SourcesDirectory)\.pipelines\release-nuget.config" /p:EnableCmdPalAOT=true
beforeBuildSteps:
# Install the Terrapin retrieval tool, which replaces vcpkg's download handler
# to redirect it to a safe Microsoft-controlled location
- template: .pipelines/v2/templates/steps-install-terrapin.yml@self
# Sets versions for all PowerToy created DLLs
- pwsh: |-
.pipelines/versionSetting.ps1 -versionNumber '${{ parameters.versionNumber }}' -DevEnvironment ''
@@ -144,10 +140,6 @@ extends:
signCertName: $(SigningSignCertName)
useManagedIdentity: $(SigningUseManagedIdentity)
clientId: $(SigningOriginalClientId)
beforeBuildSteps:
# Install the Terrapin retrieval tool, which replaces vcpkg's download handler
# to redirect it to a safe Microsoft-controlled location
- template: .pipelines/v2/templates/steps-install-terrapin.yml@self
- stage: Publish
displayName: Publish

View File

@@ -70,7 +70,7 @@ parameters:
default: false
- name: winAppSDKVersionNumber
type: string
default: '2.0'
default: 1.6
- name: useExperimentalVersion
type: boolean
default: false
@@ -200,7 +200,7 @@ jobs:
- template: steps-ensure-dotnet-version.yml
parameters:
sdk: true
version: '10.0'
version: '9.0'
- ${{ if eq(parameters.runTests, true) }}:
- task: VisualStudioTestPlatformInstaller@1
@@ -270,34 +270,6 @@ jobs:
parameters:
directory: $(build.sourcesdirectory)\src\modules\cmdpal
# --- vcpkg detection + binary cache --------------------------------------
# PowerToys consumes spdlog (and, over time, other native deps) via vcpkg in
# manifest mode. steps-install-vcpkg.yml prefers the vcpkg shipped with
# Visual Studio (Microsoft.VisualStudio.Component.Vcpkg) and falls back to a
# fresh clone of microsoft/vcpkg into deps/vcpkg if VS doesn't have it.
# Either way it sets the VCPKG_ROOT pipeline variable; MSBuild integration
# is wired globally from Cpp.Build.props (with vcpkg.targets in
# Cpp.Build.targets) using the three-tier VcpkgRoot fallback
# (env var > VS-shipped > deps/vcpkg runtime clone).
#
# Vcpkg's MSBuild integration runs `vcpkg install` once per project, so the
# binary cache below saves ~3-5 minutes per triplet on cache hits.
- template: .\steps-install-vcpkg.yml
parameters:
useVSPreview: ${{ parameters.useVSPreview }}
- ${{ if eq(parameters.enablePackageCaching, true) }}:
- task: Cache@2
displayName: 'Cache vcpkg binary archives'
inputs:
# Key on the inputs vcpkg uses to compute its package ABI: the manifest,
# configuration, every overlay-port file, and the agent OS.
key: '"vcpkg" | "$(Agent.OS)" | vcpkg.json | vcpkg-configuration.json | deps/vcpkg-overlays/**'
restoreKeys: |
"vcpkg" | "$(Agent.OS)"
"vcpkg"
path: $(LOCALAPPDATA)\vcpkg\archives
- ${{ parameters.beforeBuildSteps }}
@@ -446,7 +418,7 @@ jobs:
/p:VCRTForwarders-IncludeDebugCRT=false
/p:PowerToysRoot=$(Build.SourcesDirectory)
/p:PublishProfile=InstallationPublishProfile.pubxml
/p:TargetFramework=net10.0-windows10.0.26100.0
/p:TargetFramework=net9.0-windows10.0.26100.0
/bl:$(LogOutputDirectory)\publish-${{ join('_',split(project, '/')) }}.binlog
$(RestoreAdditionalProjectSourcesArg)
platform: $(BuildPlatform)

View File

@@ -15,9 +15,6 @@ parameters:
- name: signingIdentity
type: object
default: {}
- name: beforeBuildSteps
type: stepList
default: []
jobs:
- job: "BuildSDK"
@@ -48,8 +45,6 @@ jobs:
parameters:
directory: $(build.sourcesdirectory)\src\modules\cmdpal
- ${{ parameters.beforeBuildSteps }}
- pwsh: |-
& "$(build.sourcesdirectory)\src\modules\cmdpal\extensionsdk\nuget\BuildSDKHelper.ps1" -Configuration "Release" -BuildStep "build" -IsAzurePipelineBuild
displayName: Build SDK

View File

@@ -64,7 +64,7 @@ jobs:
- template: steps-ensure-dotnet-version.yml
parameters:
sdk: true
version: '10.0'
version: '9.0'
- template: .\steps-restore-nuget.yml

View File

@@ -30,7 +30,7 @@ parameters:
default: false
- name: winAppSDKVersionNumber
type: string
default: '2.0'
default: 1.6
- name: useExperimentalVersion
type: boolean
default: false

View File

@@ -27,7 +27,6 @@ stages:
name: SHINE-INT-L
${{ else }}:
name: SHINE-OSS-L
demands: ImageOverride -equals SHINE-VS18-Latest
buildPlatforms:
- ${{ parameters.platform }}
uiTestModules: ${{ parameters.uiTestModules }}

View File

@@ -1,7 +1,7 @@
parameters:
- name: version
type: string
default: "10.0"
default: "9.0"
- name: sdk
type: boolean
default: false

View File

@@ -1,6 +0,0 @@
steps:
- pwsh: |-
nuget install -source "https://microsoft.pkgs.visualstudio.com/Dart/_packaging/PowerToysDependencies/nuget/v3/index.json" TerrapinRetrievalTool -Prerelease -OutputDirectory _trt -Config "$(Build.SourcesDirectory)\.pipelines\release-nuget.config"
$TerrapinRetrievalToolPath = (Get-Item _trt\TerrapinRetrievalTool.*\win-x64\TerrapinRetrievalTool.exe).FullName
Write-Host "##vso[task.setvariable variable=X_VCPKG_ASSET_SOURCES]x-script,${TerrapinRetrievalToolPath} -b https://vcpkg.storage.devpackages.microsoft.io/artifacts/ -a true -u None -p {url} -s {sha512} -d {dst};x-block-origin"
displayName: Set up the Terrapin Retrieval Tool (vcpkg cache)

View File

@@ -1,41 +0,0 @@
# Adapted from microsoft/terminal build/pipelines/templates-v2/steps-install-vcpkg.yml.
#
# Detects vcpkg from (in order):
# 1. The Visual Studio installation (Microsoft.VisualStudio.Component.Vcpkg,
# declared in the repo-root .vsconfig).
# 2. A local clone at deps/vcpkg, cloned and bootstrapped on demand.
#
# Sets the pipeline-scoped VCPKG_ROOT variable; the rest of the build
# resolves vcpkg through it (see the three-tier VcpkgRoot fallback in
# Cpp.Build.props). No repo-level vcpkg submodule required.
parameters:
- name: useVSPreview
type: boolean
default: false
steps:
- pwsh: |-
# vswhere -prerelease is opt-in via the useVSPreview parameter so CI on
# stable VS doesn't accidentally pick up a Preview install when both
# are present. Matches the existing useVSPreview plumbing for
# verifyAndSetLatestVCToolsVersion.ps1.
$vswhereArgs = @('-latest', '-requires', 'Microsoft.VisualStudio.Component.Vcpkg', '-property', 'installationPath')
$useVSPreview = '${{ parameters.useVSPreview }}' -eq 'True'
if ($useVSPreview) { $vswhereArgs = @('-prerelease') + $vswhereArgs }
$VsInstallRoot = & 'C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe' @vswhereArgs
If ([String]::IsNullOrEmpty($VsInstallRoot)) {
Remove-Item -Recurse -Force deps/vcpkg -ErrorAction:Ignore
git clone https://github.com/microsoft/vcpkg deps/vcpkg
if ($LASTEXITCODE -ne 0) { throw "git clone vcpkg failed (exit $LASTEXITCODE)" }
Push-Location deps/vcpkg
& ./bootstrap-vcpkg.bat -disableMetrics
if ($LASTEXITCODE -ne 0) { Pop-Location; throw "bootstrap-vcpkg failed (exit $LASTEXITCODE)" }
$VcpkgRoot = $PWD
Pop-Location
Write-Host "Using vcpkg from local checkout ($VcpkgRoot)"
} Else {
$VcpkgRoot = Join-Path $VsInstallRoot 'VC\vcpkg'
Write-Host "Using vcpkg from Visual Studio installation ($VcpkgRoot)"
}
Write-Host "##vso[task.setvariable variable=VCPKG_ROOT]$VcpkgRoot"
displayName: Detect VS vcpkg or bootstrap locally

View File

@@ -1,7 +1,7 @@
parameters:
- name: versionNumber
type: string
default: '2.0'
default: 1.6
- name: useExperimentalVersion
type: boolean
default: false

View File

@@ -48,11 +48,6 @@ foreach ($csprojFile in $csprojFilesArray) {
continue
}
# The PowerAccent.Common project does not target WinRT, so skip it
if ($csprojFile -like '*PowerAccent.Common.csproj') {
continue
}
$importExists = Test-ImportSharedCsWinRTProps -filePath $csprojFile
if (!$importExists) {
Write-Output "$csprojFile need to import 'Common.Dotnet.CsWinRT.props'."

View File

@@ -22,7 +22,7 @@ $totalList = $projFiles | ForEach-Object -Parallel {
#Workaround for preventing exit code from dotnet process from reflecting exit code in PowerShell
$procInfo = New-Object System.Diagnostics.ProcessStartInfo -Property @{
FileName = "dotnet.exe";
Arguments = "list $csproj package --no-restore";
Arguments = "list $csproj package";
RedirectStandardOutput = $true;
RedirectStandardError = $true;
}

View File

@@ -13,6 +13,5 @@
{
"file": ".github/prompts/create-pr-summary.prompt.md"
}
],
"sarif-viewer.connectToGithubCodeScanning": "on"
]
}

View File

@@ -18,7 +18,6 @@
"Microsoft.VisualStudio.Component.VC.ATL.ARM64.Spectre",
"Microsoft.VisualStudio.Component.VC.ATL",
"Microsoft.VisualStudio.Component.VC.ATL.Spectre",
"Microsoft.VisualStudio.Component.Vcpkg",
"Microsoft.VisualStudio.ComponentGroup.WindowsAppSDK.Cs"
]
}

View File

@@ -3,7 +3,7 @@ description: 'Top-level AI contributor guidance for developing PowerToys - a col
applyTo: '**'
---
# PowerToys AI contributor guide
# PowerToys AI Contributor Guide
This is the top-level guidance for AI contributions to PowerToys. Keep changes atomic, follow existing patterns, and cite exact paths in PRs.
@@ -26,15 +26,13 @@ For architecture details and module types, see [Architecture Overview](doc/devdo
## Conventions
For detailed coding conventions, see:
- [Coding Guidelines](doc/devdocs/development/guidelines.md) Dependencies, testing, PR management
- [Coding Style](doc/devdocs/development/style.md) Formatting, C++/C#/XAML style rules
- [Logging](doc/devdocs/development/logging.md) C++ spdlog and C# Logger usage
### Component-specific instructions
### Component-Specific Instructions
These instruction files are automatically applied when working in their respective areas:
- [Runner & Settings UI](.github/instructions/runner-settings-ui.instructions.md) IPC contracts, schema migrations
- [Common Libraries](.github/instructions/common-libraries.instructions.md) ABI stability, shared code guidelines
@@ -46,7 +44,7 @@ These instruction files are automatically applied when working in their respecti
- Windows 10 1803+ (April 2018 Update or newer)
- Initialize submodules once: `git submodule update --init --recursive`
### Build commands
### Build Commands
| Task | Command |
|------|---------|
@@ -54,7 +52,7 @@ These instruction files are automatically applied when working in their respecti
| Build current folder | `tools\build\build.cmd` |
| Build with options | `build.ps1 -Platform x64 -Configuration Release` |
### Build discipline
### Build Discipline
1. One terminal per operation (build → test). Do not switch or open new ones mid-flow
2. After making changes, `cd` to the project folder that changed (`.csproj`/`.vcxproj`)
@@ -64,10 +62,9 @@ These instruction files are automatically applied when working in their respecti
6. On failure, read the errors log: `build.<config>.<platform>.errors.log`
7. Do not start tests or launch Runner until the build succeeds
### Build logs
### Build Logs
Located next to the solution/project being built:
- `build.<configuration>.<platform>.errors.log` errors only (check this first)
- `build.<configuration>.<platform>.all.log` full log
- `build.<configuration>.<platform>.trace.binlog` for MSBuild Structured Log Viewer
@@ -76,18 +73,18 @@ For complete details, see [Build Guidelines](tools/build/BUILD-GUIDELINES.md).
## Tests
### Test discovery
### Test Discovery
- Find test projects by product code prefix (e.g., `FancyZones`, `AdvancedPaste`)
- Look for sibling folders or 1-2 levels up named `<Product>*UnitTests` or `<Product>*UITests`
### Running tests
### Running Tests
1. **Build the test project first**, wait for exit code 0
2. Run via VS Test Explorer (`Ctrl+E, T`) or `vstest.console.exe` with filters
3. **Avoid `dotnet test`** in this repo use VS Test Explorer or vstest.console.exe
### Test types
### Test Types
| Type | Requirements | Setup |
|------|--------------|-------|
@@ -95,13 +92,13 @@ For complete details, see [Build Guidelines](tools/build/BUILD-GUIDELINES.md).
| UI Tests | WinAppDriver v1.2.1, Developer Mode | Install from [WinAppDriver releases](https://github.com/microsoft/WinAppDriver/releases/tag/v1.2.1) |
| Fuzz Tests | OneFuzz, .NET 8 | See [Fuzzing Tests](doc/devdocs/tools/fuzzingtesting.md) |
### Test discipline
### Test Discipline
1. Add or adjust tests when changing behavior
2. If tests skipped, state why (e.g., comment-only change, string rename)
3. New modules handling file I/O or user input **must** implement fuzzing tests
### Special requirements
### Special Requirements
- **Mouse Without Borders**: Requires 2+ physical computers (not VMs)
- **Multi-monitor utilities**: Test with 2+ monitors, different DPI settings
@@ -110,14 +107,14 @@ For UI test setup details, see [UI Tests](doc/devdocs/development/ui-tests.md).
## Boundaries
### Ask for clarification when
### Ask for Clarification When
- Ambiguous spec after scanning relevant docs
- Cross-module impact (shared enum/struct) is unclear
- Security, elevation, or installer changes involved
- GPO or policy handling modifications needed
### Areas requiring extra care
### Areas Requiring Extra Care
| Area | Concern | Reference |
|------|---------|-----------|
@@ -126,7 +123,7 @@ For UI test setup details, see [UI Tests](doc/devdocs/development/ui-tests.md).
| Installer files | Release impact | Careful review required |
| Elevation/GPO logic | Security | Confirm no regression in policy handling |
### What not to do
### What NOT to Do
- Don't merge incomplete features into main (use feature branches)
- Don't break IPC/JSON contracts without updating both runner and settings-ui
@@ -146,27 +143,23 @@ Before finishing, verify:
## Documentation Index
### Core architecture
### Core Architecture
- [Architecture Overview](doc/devdocs/core/architecture.md)
- [Runner](doc/devdocs/core/runner.md)
- [Settings System](doc/devdocs/core/settings/readme.md)
- [Module Interface](doc/devdocs/modules/interface.md)
### Development
- [Coding Guidelines](doc/devdocs/development/guidelines.md)
- [Coding Style](doc/devdocs/development/style.md)
- [Logging](doc/devdocs/development/logging.md)
- [UI Tests](doc/devdocs/development/ui-tests.md)
- [Fuzzing Tests](doc/devdocs/tools/fuzzingtesting.md)
### Build & tools
### Build & Tools
- [Build Guidelines](tools/build/BUILD-GUIDELINES.md)
- [Tools Overview](doc/devdocs/tools/readme.md)
### Instructions (auto-applied)
### Instructions (Auto-Applied)
- [Runner & Settings UI](.github/instructions/runner-settings-ui.instructions.md)
- [Common Libraries](.github/instructions/common-libraries.instructions.md)

View File

@@ -1,109 +1,84 @@
# Community
The PowerToys team is extremely grateful to have the support of an amazing active community. The work you do is incredibly important. PowerToys wouldn't be near what it is without your help filing bugs, updating documentation, guiding the design, or writing features. We want to say thanks and to recognize your work. This is a living document dedicated to highlighting the high impact community members and their contributions.
The PowerToys team is extremely grateful to have the support of an amazing active community. The work you do is incredibly important. PowerToys wouldnt be near what it is without your help filing bugs, updating documentation, guiding the design, or writing features. We want to say thanks and to recognize your work. This is a living document dedicated to highlighting the high impact community members and their contributions.
Names are in alphabetical order, based on first name.
Names are in alphabetical order based on first name.
## High impact community members
### [@cgaarden](https://github.com/cgaarden) - [Christian Gaarden Gaardmark](https://www.onegreatworld.com)
Christian contributed the New+ utility
### [@cgaarden](https://github.com/cgaarden) - [Christian Gaarden Gaardmark](https://www.onegreatworld.com)
Christian contributed New+ utility
### [@CleanCodeDeveloper](https://github.com/CleanCodeDeveloper)
CleanCodeDeveloper helped do massive amounts of code stability and image resizer work.
### [@plante-msft](https://github.com/plante-msft) - Connor Plante
Connor was the creator of Workspaces and helped create Command Palette (PowerToys Run v2)
### [@damienleroy](https://github.com/damienleroy) - [Damien Leroy](https://www.linkedin.com/in/Damien-Leroy-b2734416a/)
Damien has helped out by developing and contributing the Quick Accent utility.
### [@daverayment](https://github.com/daverayment) - [David Rayment](https://www.linkedin.com/in/david-rayment-168b5251/)
Dave has helped improve the experience inside of Peek by adding in new features and fixing bugs.
### [@davidegiacometti](https://github.com/davidegiacometti) - [Davide Giacometti](https://www.linkedin.com/in/davidegiacometti/)
Davide has helped fix multiple bugs, added new utilities, features, as well as help us with the ARM64 effort by porting applications to .NET Core.
### [@ethanfangg](https://github.com/ethanfangg) - Ethan Fang
Ethan helped run PowerToys and worked on improving and prototyping out next generation PowerToys
### [@franky920920](https://github.com/franky920920) - [Franky Chen](https://frankychen.net)
Franky has helped triaging, discussing, and creating a substantial number of issues and contributed features/fixes to PowerToys.
### [@htcfreek](https://github.com/htcfreek) - Heiko
Heiko has helped triaging, discussing, and creating a substantial number of issues and contributed features/fixes to PowerToys.
### [@Jay-o-Way](https://github.com/Jay-o-Way) - Jay
Jay has helped triaging, discussing, creating a substantial number of issues and PRs.
### [@jefflord](https://github.com/Jjefflord) - Jeff Lord
Jeff added multiple new features to Keyboard Manager, such as key chord support and launching apps. He also contributed multiple features/fixes to PowerToys.
Jeff added in multiple new features into Keyboard manager, such as key chord support and launching apps. He also contributed multiple features/fixes to PowerToys.
### [@snickler](https://github.com/snickler) - [Jeremy Sinclair](http://sinclairinat0r.com)
Jeremy has helped drive substantial ARM64 support within PowerToys.
Jeremy has helped drive large sums of the ARM64 support inside PowerToys
### [@jiripolasek](https://github.com/jiripolasek) - [Jiří Polášek](https://github.com/jiripolasek)
Jiří has contributed a massive number of features and improvements to Command Palette, including drag & drop support, custom themes, Web Search enhancements, Remote Desktop extension fixes, and many UX improvements.
### [@TheJoeFin](https://github.com/TheJoeFin) - [Joe Finney](https://joefinapps.com)
Joe has helped with triaging, discussing issues as well as fixing bugs and building features for Text Extractor.
Joe has helped triaging, discussing, issues as well as fixing bugs and building features for Text Extractor.
### [@joadoumie](https://github.com/joadoumie) - Jordi Adoumie
Jordi helped innovate amazing new features into Advanced Paste and helped create Command Palette (PowerToys Run v2)
### [@jsoref](https://github.com/jsoref) - [Josh Soref](https://check-spelling.dev/)
Helping keep our spelling correct :)
### [@martinchrzan](https://github.com/martinchrzan/) - Martin Chrzan
Color Picker is from Martin.
### [@mikeclayton](https://github.com/mikeclayton) - [Michael Clayton](https://michael-clayton.com)
Michael contributed the [initial version](https://github.com/microsoft/PowerToys/issues/23216) of the Mouse Jump tool and [a number of updates](https://github.com/microsoft/PowerToys/pulls?q=is%3Apr+author%3Amikeclayton) based on his FancyMouse utility.
### [@Noraa-Junker](https://github.com/Noraa-Junker) - [Noraa Junker](https://noraajunker.ch)
Noraa has helped triaging, discussing, and creating a substantial number of issues and contributed features/fixes. Noraa was the primary person for helping build the File Explorer preview pane handler for developer files.
### [@pedrolamas](https://github.com/pedrolamas/) - Pedro Lamas
Pedro helped create the thumbnail and File Explorer previewers for 3D files like STL and GCode. If you like 3D printing, these are very helpful.
Pedro helped create the thumbnail and File Explorer previewers for 3D files like STL and GCode. If you like 3D printing, these are very helpful.
### [@PesBandi](https://github.com/PesBandi/) - PesBandi
PesBandi has helped do massive amounts of Quick Accent and bug fixes.
### [@riverar](https://github.com/riverar) - [Rafael Rivera](https://withinrafael.com/)
Rafael has helped do the [upgrade from CppWinRT 1.x to 2.0](https://github.com/microsoft/PowerToys/issues/1907). He directly provided feedback to the CppWinRT team for bugs from this migration as well.
Rafael has helped do the [upgrade from CppWinRT 1.x to 2.0](https://github.com/microsoft/PowerToys/issues/1907). He directly provided feedback to the CppWinRT team for bugs from this migration as well.
### [@royvou](https://github.com/royvou)
Roy has helped out contributing multiple features to PowerToys Run
### [@ThiefZero](https://github.com/ThiefZero)
ThiefZero has helped contribute features to PowerToys Run, such as the unit converter plugin
ThiefZero has helped out contributing a features to PowerToys Run such as the unit converter plugin
### [@TobiasSekan](https://github.com/TobiasSekan) - Tobias Sekan
Tobias Sekan has helped out contributing features to PowerToys Run such as Settings plugin, Registry plugin
## Open source projects
@@ -119,8 +94,7 @@ Their fork of Wox was the base of PowerToys Run.
Initial base of jjw24's fork, which makes it the base of PowerToys Run.
### [Text-Grab](https://github.com/TheJoeFin/Text-Grab) - Joseph Finney
Joe helped develop and contribute to the Text Extractor utility. It is directly based on his Text Grab application.
Joe helped develop and contribute to the Text Extractor utility. It is directly based on his Text Grab application.
## Microsoft community members
@@ -128,7 +102,7 @@ We would like to also directly call out some extremely helpful Microsoft employe
### [@betsegaw](https://github.com/betsegaw/) - [Betsegaw Tadele](http://www.dreamsofameaningfullife.com/)
Window Walker, inside PowerToys Run, is from Beta.
Window Walker, inside PowerToys Run, is from Beta.
### [@TheMrJukes](https://github.com/TheMrJukes/) - Bret Anderson
@@ -151,7 +125,6 @@ PowerToys Awake is a tool to keep your computer awake.
Randy contributed Registry Preview and some very early conversations about keyboard remapping.
### [@cinnamon-msft](https://github.com/cinnamon-msft) - Kayla Cinnamon
Kayla was a former lead for PowerToys and helped create multiple utilities, maintained the GitHub repo, and collaborated with the community to improve the overall product
### [@oldnewthing](https://github.com/oldnewthing) - Raymond Chen
@@ -162,48 +135,46 @@ Find My Mouse is based on Raymond Chen's SuperSonar.
Crop And Lock is based on the original work of Robert Mikhayelyan, with Program Manager support from [@kevinguo305](https://github.com/kevinguo305) - Kevin Guo.
ZoomIt's Video Recording Session code is based on Robert Mikhayelyan's <https://github.com/robmikh/capturevideosample> code.
ZoomIt's Video Recording Session code is based on Robert Mikhayelyan's https://github.com/robmikh/capturevideosample code.
### Microsoft InVEST team
This amazing team helped PowerToys develop PowerToys Run and Keyboard manager as well as update our Settings to v2. @alekhyareddy28, @arjunbalgovind, @jyuwono @laviusmotileng-ms, @ryanbodrug-microsoft, @saahmedm, @somil55, @traies, @udit3333
This amazing team helped PowerToys develop PowerToys Run and Keyboard manager as well as update our Settings to v2. @alekhyareddy28, @arjunbalgovind, @jyuwono @laviusmotileng-ms, @ryanbodrug-microsoft, @saahmedm, @somil55, @traies, @udit3333
## Mouse Without Borders original contributors
Project creator: Truong Do (Đỗ Đức Trường)
*Project creator: Truong Do (Đỗ Đức Trường)*
Other contributors:
- Microsoft Garage: Quinn Hawkins, Michael Low, Joe Coplen, Nino Yuniardi, Gwyneth Marshall, David Andrews, Karen Luecking
- Peter Hauge - Visual Studio
- Bruce Dawson - Windows Fundamentals
- Alan Myrvold - Office Security
- Adrian Garside - WEX
- Scott Bradner - Surface
- Aleks Gershaft - Windows Azure
- Chinh Huynh - Windows Azure
- Long Nguyen - Data Center
- Triet Le - Cloud Engineering
- Luke Schoen - Excel
- Bao Nguyen - Bing
- Ross Nichols - Windows
- Ryan Baltazar - Windows
- Ed Essey - The Garage
- Mario Madden - The Garage
- Karthick Mahalingam - ACE
- Pooja Kamra - ACE
- Justin White - SA
- Chris Ransom - SA
- Mike Ricks - Red Team
- Randy Santossio - Surface
- Ashish Sen Jaswal - Device Health
- Zoltan Harmath - Security Tools
- Luciano Krigun - Security Products
- Jo Hemmerlein - Red Team
- Chris Johnson - Surface Hub
- Loren Ponten - Surface Hub
- Paul Schmitt - WWL
- And many other Users!
* Microsoft Garage: Quinn Hawkins, Michael Low, Joe Coplen, Nino Yuniardi, Gwyneth Marshall, David Andrews, Karen Luecking
* Peter Hauge - Visual Studio
* Bruce Dawson - Windows Fundamentals
* Alan Myrvold - Office Security
* Adrian Garside - WEX
* Scott Bradner - Surface
* Aleks Gershaft - Windows Azure
* Chinh Huynh - Windows Azure
* Long Nguyen - Data Center
* Triet Le - Cloud Engineering
* Luke Schoen - Excel
* Bao Nguyen - Bing
* Ross Nichols - Windows
* Ryan Baltazar - Windows
* Ed Essey - The Garage
* Mario Madden - The Garage
* Karthick Mahalingam - ACE
* Pooja Kamra - ACE
* Justin White - SA
* Chris Ransom - SA
* Mike Ricks - Red Team
* Randy Santossio - Surface
* Ashish Sen Jaswal - Device Health
* Zoltan Harmath - Security Tools
* Luciano Krigun - Security Products
* Jo Hemmerlein - Red Team
* Chris Johnson - Surface Hub
* Loren Ponten - Surface Hub
* Paul Schmitt - WWL
* And many other Users!
## ZoomIt original contributors

View File

@@ -1,4 +1,4 @@
# PowerToys contributor's guide
# PowerToys Contributor's Guide
Below is our guidance for reporting issues, proposing new features, and submitting contributions via Pull Requests (PRs). Our philosophy is to understand the problem and scenarios first, which is why we follow this pattern before work starts.
@@ -6,46 +6,46 @@ Below is our guidance for reporting issues, proposing new features, and submitti
2. There has been a conversation.
3. There is agreement on the problem, the fit for PowerToys, and the solution to the problem (implementation).
## Filing an issue
## Filing an Issue
**Importance of Filing an Issue First**
Please follow this rule to help eliminate wasted effort and frustration, and to ensure an efficient and effective use of everyone's time:
Please follow this rule to help eliminate wasted effort and frustration, and to ensure an efficient and effective use of everyones time:
> 👉 If you have a question, think you've discovered an issue, or would like to propose a new feature, please find/file an issue **BEFORE** starting work to fix/implement it.
When requesting new features or enhancements, providing additional evidence, data, tweets, blog posts, or research is extremely helpful. This information gives context to the scenario that may otherwise be lost.
- Unsure whether it's an issue or feature request? File an issue.
- Have a question that isn't answered in the docs, videos, etc.? File an issue.
- Want to know if we're planning a particular feature? File an issue.
- Got a great idea for a new utility or feature? File an issue/request/idea.
- Don't understand how to do something? File an issue/Community Guidance Request.
- Found an existing issue that describes yours? Great! Upvote and add additional commentary, info, or repro steps.
* Unsure whether its an issue or feature request? File an issue.
* Have a question that isn't answered in the docs, videos, etc.? File an issue.
* Want to know if were planning a particular feature? File an issue.
* Got a great idea for a new utility or feature? File an issue/request/idea.
* Dont understand how to do something? File an issue/Community Guidance Request.
* Found an existing issue that describes yours? Great! Upvote and add additional commentary, info, or repro steps.
A quick search before filing an issue could be helpful. It's likely someone else has found the same problem, and they may even be working on or have already contributed a fix!
A quick search before filing an issue could be helpful. Its likely someone else has found the same problem, and they may even be working on or have already contributed a fix!
### Indicating interest in issues
### Indicating Interest in Issues
To let the team know which issues are important, upvote by clicking the [+😊] button and the 👍 icon on the original issue post. Avoid comments like "+1" or "me too" as they clutter the discussion and make it harder to prioritize requests.
---
## Contributing fixes or features
## Contributing Fixes/Features
Please comment on our [Would you like to contribute to PowerToys?](https://github.com/microsoft/PowerToys/issues/28769) thread to let us know you're interested in working on something before you start. This helps avoid multiple people unexpectedly working on the same thing and ensures everyone is clear on what should be done. It's less work for everyone to establish this up front.
Please comment on our ["Would you like to contribute to PowerToys?"](https://github.com/microsoft/PowerToys/issues/28769) thread to let us know you're interested in working on something before you start. This helps avoid multiple people unexpectedly working on the same thing and ensures everyone is clear on what should be done. It's less work for everyone to establish this up front.
### Localization issues
### Localization Issues
For localization issues, please file an issue to notify our internal localization team, as community PRs for localization aren't accepted. Localization is handled exclusively by the internal Microsoft team.
### To spec or not to spec
### To Spec or Not to Spec
A key point is for everyone to understand the approach that will be taken. We want to be sure that any work done will be accepted. Larger-scope items will require a spec to outline the approach and allow for discussion. Specs help collaborators consider different solutions, describe feature behavior, and plan for errors. Achieving agreement in a spec before writing code often results in simpler code and less wasted effort.
Once a team member has agreed with your approach, proceed to the "Development" section below. Team members are happy to help review specs and guide them to completion.
### Help wanted
### Help Wanted
Once the team has approved an issue/spec approach, development can proceed. If no developers are immediately available, the spec may be parked and labeled "Help Wanted," ready for a developer to get started. For development opportunities, visit [Issues labeled Help Wanted](https://github.com/microsoft/PowerToys/labels/Help%20Wanted).
@@ -55,18 +55,18 @@ Once the team has approved an issue/spec approach, development can proceed. If n
Follow the [development guidelines](https://github.com/microsoft/PowerToys/blob/main/doc/devdocs/readme.md).
### Naming features and functionality
### Naming Features and Functionality
Names should be descriptive and straightforward, clearly reflecting functionality and usefulness.
### Becoming a collaborator on the PowerToys team
### Becoming a Collaborator on the PowerToys Team
Be an active community member! Make helpful contributions by filing bugs, offering suggestions, developing fixes and features, conducting code reviews, and updating documentation.
Be an active community member! Make helpful contributions by filing bugs, offering suggestions, developing fixes and features, conducting code reviews, and updating documentation.
When the time comes, Microsoft will reach out to you about becoming a formal team member. Just make sure they have a way to contact you. 😊
---
## Thank you
## Thank You
Thank you in advance for your contribution! We appreciate your help in making PowerToys a better tool for everyone.

View File

@@ -39,8 +39,7 @@
<PropertyGroup>
<PreferredToolArchitecture>x64</PreferredToolArchitecture>
<PreferredToolArchitecture Condition="'$(PROCESSOR_ARCHITECTURE)' == 'ARM64' or '$(PROCESSOR_ARCHITEW6432)' == 'ARM64'">arm64</PreferredToolArchitecture>
<!-- vcpkg.targets is imported via Cpp.Build.targets after Microsoft.Cpp.targets. -->
<ForceImportAfterCppTargets>$(MSBuildThisFileDirectory)Cpp.Build.targets</ForceImportAfterCppTargets>
<VcpkgEnabled>false</VcpkgEnabled>
<ReplaceWildcardsInProjectItems>true</ReplaceWildcardsInProjectItems>
<ExternalIncludePath>$(MSBuildThisFileDirectory)deps;$(MSBuildThisFileDirectory)packages;$(ExternalIncludePath)</ExternalIncludePath>
<!-- Enable control flow guard for C++ projects that don't consume any C++ files -->
@@ -122,48 +121,6 @@
<SpectreMitigation>Spectre</SpectreMitigation>
</PropertyGroup>
<!--
vcpkg integration. Set globally and loaded before Microsoft.Cpp.props (via
ForceImportBeforeCppProps) so that vcpkg.props' ClCompile hook is in place
before the C++ targets run. VcpkgRoot is resolved via the same three-tier
fallback used by microsoft/terminal (env var → VS-shipped → deps/vcpkg).
-->
<PropertyGroup Label="vcpkg">
<VcpkgEnabled>true</VcpkgEnabled>
<VcpkgEnableManifest>true</VcpkgEnableManifest>
<VcpkgManifestEnabled>true</VcpkgManifestEnabled>
<VcpkgManifestRoot>$(MSBuildThisFileDirectory)</VcpkgManifestRoot>
<VcpkgOSTarget>windows</VcpkgOSTarget>
<VcpkgUseStatic>true</VcpkgUseStatic>
<!--
Force VcpkgConfiguration to follow $(Configuration). Without this,
vcpkg.props infers VcpkgConfiguration from $(UseDebugLibraries), which
Microsoft.Cpp.Default.props has already defaulted to 'false' by the
time vcpkg.props is imported here (the PowerToys-wide Debug override
below runs LATER). That would silently link the Release-built spdlog
into Debug consumers and trigger LNK2038 (MT/MTd, _ITERATOR_DEBUG_LEVEL).
-->
<VcpkgConfiguration>$(Configuration)</VcpkgConfiguration>
<!-- vcpkg validates triplets case-sensitively; PowerToys uses ARM64 capital-case. -->
<VcpkgPlatformTarget Condition="'$(Platform)' == 'ARM64'">arm64</VcpkgPlatformTarget>
<VcpkgApplocalDeps>false</VcpkgApplocalDeps>
<VcpkgInstalledDir>$(MSBuildThisFileDirectory)vcpkg_installed\$(Platform)\</VcpkgInstalledDir>
<VcpkgRoot Condition="'$(VcpkgRoot)' == ''">$(VCPKG_ROOT)</VcpkgRoot>
<VcpkgRoot Condition="'$(VcpkgRoot)' == '' and '$(VsInstallRoot)' != ''">$(VsInstallRoot)\VC\vcpkg</VcpkgRoot>
<VcpkgRoot Condition="'$(VcpkgRoot)' == '' or !Exists('$(VcpkgRoot)\vcpkg.exe')">$(MSBuildThisFileDirectory)deps\vcpkg</VcpkgRoot>
<CAExcludePath>$(CAExcludePath);$(VcpkgInstalledDir)</CAExcludePath>
<VCPkgLocalAppDataDisabled>true</VCPkgLocalAppDataDisabled>
</PropertyGroup>
<!-- Fail fast with an actionable message instead of opaque C1083 spdlog/spdlog.h errors. -->
<Target Name="PowerToysEnsureVcpkgAvailable"
BeforeTargets="PrepareForBuild"
Condition="'$(MSBuildProjectExtension)' == '.vcxproj' and '$(VcpkgEnabled)' == 'true' and !Exists('$(VcpkgRoot)\scripts\buildsystems\msbuild\vcpkg.props')">
<Error Text="PowerToys requires the 'vcpkg' Visual Studio component, but it was not found.%0A%0AOpen the Visual Studio Installer, click Modify on your VS install, search for 'vcpkg', enable 'C++ vcpkg package manager', and click Modify. (Visual Studio will also prompt you to install missing .vsconfig components when you open PowerToys.slnx.)%0A%0AIf you have vcpkg installed elsewhere, set the VCPKG_ROOT environment variable to its root before building.%0A%0ASearched: '$(VcpkgRoot)\scripts\buildsystems\msbuild\vcpkg.props'" />
</Target>
<Import Project="$(VcpkgRoot)\scripts\buildsystems\msbuild\vcpkg.props"
Condition="'$(MSBuildProjectExtension)' == '.vcxproj' and Exists('$(VcpkgRoot)\scripts\buildsystems\msbuild\vcpkg.props')" />
<!-- Debug/Release props -->
<PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
<UseDebugLibraries>true</UseDebugLibraries>

View File

@@ -1,16 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project>
<!--
PowerToys global C++ post-targets. Wired in via
<ForceImportAfterCppTargets> in Cpp.Build.props so MSBuild loads this
file AFTER Microsoft.Cpp.targets for every .vcxproj.
Conditionally imports vcpkg.targets to hook ClCompile into vcpkg's
VcpkgInstallManifestDependencies target so spdlog headers are
auto-discovered on the include path and spdlog.lib is auto-linked.
vcpkg.props is imported in Cpp.Build.props (before Microsoft.Cpp.props);
vcpkg.targets needs the matching "after" hook here.
-->
<Import Project="$(VcpkgRoot)\scripts\buildsystems\msbuild\vcpkg.targets"
Condition="'$(MSBuildProjectExtension)' == '.vcxproj' and '$(VcpkgEnabled)' == 'true' and Exists('$(VcpkgRoot)\scripts\buildsystems\msbuild\vcpkg.targets')" />
</Project>

File diff suppressed because it is too large Load Diff

View File

@@ -171,12 +171,6 @@
$(USERPROFILE)\AppData\LocalLow\Microsoft\PowerToys\**;
</MSBuildCacheAllowFileAccessAfterProjectFinishFilePatterns>
<!-- dotnet.exe seems to access files after builds. Temporarily putting in this entry for testing if we get further. This looks to be related to a .NET Roslyn Analyzer in .NET 10-->
<MSBuildCacheAllowFileAccessAfterProjectFinishProcessPatterns>
$(MSBuildCacheAllowFileAccessAfterProjectFinishProcessPatterns);
\**\dotnet\dotnet.exe;
\**\vbcscompiler.exe;
</MSBuildCacheAllowFileAccessAfterProjectFinishProcessPatterns>
<!--
This repo uses a common output directory with many projects writing duplicate outputs. Allow everything, but note this costs some performance in the form of requiring
the cache to use copies instead of hardlinks when pulling from cache.

View File

@@ -65,20 +65,4 @@
<!-- Note: For C++ skipped test projects, build is effectively skipped by removing all compile items above.
We don't define empty Build/Rebuild/Clean targets here because MSBuild Target definitions with Condition
on the Target element still override the default targets even when condition is false. -->
<!-- Clean up unused VC++ runtime DLLs that CopyCppRuntimeToOutputDir copies from the full
VCRedist tree (MFC, C++ AMP, OpenMP). No PowerToys binary links against these — verified
with dumpbin /dependents across all installed binaries. -->
<Target Name="RemoveUnusedVCRuntimeDlls"
AfterTargets="Build"
Condition="'$(CopyCppRuntimeToOutputDir)' == 'true' and '$(MSBuildProjectExtension)' == '.vcxproj'">
<ItemGroup>
<_UnusedVCRuntimeDlls Include="$(OutDir)mfc140*.dll" />
<_UnusedVCRuntimeDlls Include="$(OutDir)mfcm140*.dll" />
<_UnusedVCRuntimeDlls Include="$(OutDir)vcamp140*.dll" />
<_UnusedVCRuntimeDlls Include="$(OutDir)vcomp140*.dll" />
</ItemGroup>
<Delete Files="@(_UnusedVCRuntimeDlls)" Condition="'@(_UnusedVCRuntimeDlls)' != ''" />
<Message Importance="normal" Text="Cleaned up unused VC runtime DLLs: @(_UnusedVCRuntimeDlls)" Condition="'@(_UnusedVCRuntimeDlls)' != ''" />
</Target>
</Project>

View File

@@ -1,4 +1,4 @@
<Project>
<Project>
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
<CentralPackageTransitivePinningEnabled>true</CentralPackageTransitivePinningEnabled>
@@ -18,14 +18,14 @@
<PackageVersion Include="SixLabors.ImageSharp" Version="2.1.12" />
<PackageVersion Include="CommunityToolkit.Common" Version="8.4.0" />
<PackageVersion Include="CommunityToolkit.Mvvm" Version="8.4.0" />
<PackageVersion Include="CommunityToolkit.WinUI.Animations" Version="8.2.251219" />
<PackageVersion Include="CommunityToolkit.WinUI.Collections" Version="8.2.251219" />
<PackageVersion Include="CommunityToolkit.WinUI.Controls.Primitives" Version="8.2.251219" />
<PackageVersion Include="CommunityToolkit.WinUI.Controls.SettingsControls" Version="8.2.251219" />
<PackageVersion Include="CommunityToolkit.WinUI.Controls.Segmented" Version="8.2.251219" />
<PackageVersion Include="CommunityToolkit.WinUI.Controls.Sizers" Version="8.2.251219" />
<PackageVersion Include="CommunityToolkit.WinUI.Converters" Version="8.2.251219" />
<PackageVersion Include="CommunityToolkit.WinUI.Extensions" Version="8.2.251219" />
<PackageVersion Include="CommunityToolkit.WinUI.Animations" Version="8.2.250402" />
<PackageVersion Include="CommunityToolkit.WinUI.Collections" Version="8.2.250402" />
<PackageVersion Include="CommunityToolkit.WinUI.Controls.Primitives" Version="8.2.250402" />
<PackageVersion Include="CommunityToolkit.WinUI.Controls.SettingsControls" Version="8.2.250402" />
<PackageVersion Include="CommunityToolkit.WinUI.Controls.Segmented" Version="8.2.250402" />
<PackageVersion Include="CommunityToolkit.WinUI.Controls.Sizers" Version="8.2.250402" />
<PackageVersion Include="CommunityToolkit.WinUI.Converters" Version="8.2.250402" />
<PackageVersion Include="CommunityToolkit.WinUI.Extensions" Version="8.2.250402" />
<PackageVersion Include="CommunityToolkit.WinUI.UI.Controls.DataGrid" Version="7.1.2" />
<PackageVersion Include="CommunityToolkit.Labs.WinUI.Controls.MarkdownTextBlock" Version="0.1.260116-build.2514" />
<PackageVersion Include="ControlzEx" Version="6.0.0" />
@@ -39,49 +39,49 @@
<PackageVersion Include="Markdig.Signed" Version="0.34.0" />
<!-- Including MessagePack to force version, since it's used by StreamJsonRpc but contains vulnerabilities. After StreamJsonRpc updates the version of MessagePack, we can upgrade StreamJsonRpc instead. -->
<PackageVersion Include="MessagePack" Version="3.1.3" />
<PackageVersion Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="10.0.102" />
<PackageVersion Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="9.0.0" />
<PackageVersion Include="Microsoft.CommandPalette.Extensions" Version="0.9.260303001" />
<PackageVersion Include="Microsoft.Data.Sqlite" Version="10.0.8" />
<PackageVersion Include="Microsoft.Data.Sqlite" Version="9.0.10" />
<!-- Including Microsoft.Bcl.AsyncInterfaces to force version, since it's used by Microsoft.SemanticKernel. -->
<PackageVersion Include="Microsoft.Bcl.AsyncInterfaces" Version="10.0.8" />
<PackageVersion Include="Microsoft.Bcl.AsyncInterfaces" Version="9.0.10" />
<PackageVersion Include="Microsoft.Graphics.Win2D" Version="1.3.2" />
<PackageVersion Include="Microsoft.Windows.CppWinRT" Version="2.0.250303.1" />
<PackageVersion Include="Microsoft.Diagnostics.Tracing.TraceEvent" Version="3.1.16" />
<PackageVersion Include="Microsoft.Extensions.AI" Version="10.2.0" />
<PackageVersion Include="Microsoft.Extensions.AI.OpenAI" Version="10.0.1-preview.1.25571.5" />
<PackageVersion Include="Microsoft.Extensions.Caching.Abstractions" Version="10.0.8" />
<PackageVersion Include="Microsoft.Extensions.Caching.Memory" Version="10.0.8" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="10.0.8" />
<PackageVersion Include="Microsoft.Extensions.Logging" Version="10.0.8" />
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.8" />
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="10.0.8" />
<PackageVersion Include="Microsoft.Extensions.Hosting.WindowsServices" Version="10.0.8" />
<PackageVersion Include="Microsoft.Extensions.AI" Version="9.9.1" />
<PackageVersion Include="Microsoft.Extensions.AI.OpenAI" Version="9.9.1-preview.1.25474.6" />
<PackageVersion Include="Microsoft.Extensions.Caching.Abstractions" Version="9.0.10" />
<PackageVersion Include="Microsoft.Extensions.Caching.Memory" Version="9.0.10" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="9.0.10" />
<PackageVersion Include="Microsoft.Extensions.Logging" Version="9.0.10" />
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="9.0.10" />
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="9.0.10" />
<PackageVersion Include="Microsoft.Extensions.Hosting.WindowsServices" Version="9.0.10" />
<PackageVersion Include="Microsoft.AI.Foundry.Local" Version="0.3.0" />
<PackageVersion Include="Microsoft.SemanticKernel" Version="1.71.0" />
<PackageVersion Include="Microsoft.SemanticKernel.Connectors.OpenAI" Version="1.71.0" />
<PackageVersion Include="Microsoft.SemanticKernel.Connectors.AzureAIInference" Version="1.71.0-beta" />
<PackageVersion Include="Microsoft.SemanticKernel.Connectors.Google" Version="1.71.0-alpha" />
<PackageVersion Include="Microsoft.SemanticKernel.Connectors.MistralAI" Version="1.71.0-alpha" />
<PackageVersion Include="Microsoft.SemanticKernel.Connectors.Ollama" Version="1.71.0-alpha" />
<PackageVersion Include="Microsoft.SemanticKernel" Version="1.66.0" />
<PackageVersion Include="Microsoft.SemanticKernel.Connectors.OpenAI" Version="1.66.0" />
<PackageVersion Include="Microsoft.SemanticKernel.Connectors.AzureAIInference" Version="1.66.0-beta" />
<PackageVersion Include="Microsoft.SemanticKernel.Connectors.Google" Version="1.66.0-alpha" />
<PackageVersion Include="Microsoft.SemanticKernel.Connectors.MistralAI" Version="1.66.0-alpha" />
<PackageVersion Include="Microsoft.SemanticKernel.Connectors.Ollama" Version="1.66.0-alpha" />
<PackageVersion Include="Microsoft.Toolkit.Uwp.Notifications" Version="7.1.2" />
<PackageVersion Include="Microsoft.Web.WebView2" Version="1.0.3719.77" />
<PackageVersion Include="Microsoft.Web.WebView2" Version="1.0.3179.45" />
<!-- Package Microsoft.Win32.SystemEvents added as a hack for being able to exclude the runtime assets so they don't conflict with 8.0.1. This is a dependency of System.Drawing.Common but the 8.0.1 version wasn't published to nuget. -->
<PackageVersion Include="Microsoft.Win32.SystemEvents" Version="10.0.8" />
<PackageVersion Include="Microsoft.Win32.SystemEvents" Version="9.0.10" />
<PackageVersion Include="Microsoft.WindowsPackageManager.ComInterop" Version="1.10.340" />
<PackageVersion Include="Microsoft.Windows.Compatibility" Version="10.0.8" />
<PackageVersion Include="Microsoft.Windows.CsWin32" Version="0.3.269" />
<PackageVersion Include="Microsoft.Windows.Compatibility" Version="9.0.10" />
<PackageVersion Include="Microsoft.Windows.CsWin32" Version="0.3.183" />
<!-- CsWinRT version needs to be set to have a WinRT.Runtime.dll at the same version contained inside the NET SDK we're currently building on CI. -->
<!--
TODO: in Common.Dotnet.CsWinRT.props, on upgrade, verify RemoveCsWinRTPackageAnalyzer is no longer needed.
This is present due to a bug in CsWinRT where WPF projects cause the analyzer to fail.
-->
<PackageVersion Include="Microsoft.Windows.CsWinRT" Version="2.2.0" />
<PackageVersion Include="Microsoft.Windows.ImplementationLibrary" Version="1.0.250325.1"/>
<PackageVersion Include="Microsoft.Windows.ImplementationLibrary" Version="1.0.231216.1"/>
<PackageVersion Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.26100.6901" />
<PackageVersion Include="Microsoft.WindowsAppSDK" Version="2.0.1" />
<PackageVersion Include="Microsoft.WindowsAppSDK.Foundation" Version="2.0.20" />
<PackageVersion Include="Microsoft.WindowsAppSDK.AI" Version="2.0.185" />
<PackageVersion Include="Microsoft.WindowsAppSDK.Runtime" Version="2.0.1" />
<PackageVersion Include="Microsoft.WindowsAppSDK" Version="1.8.260209005" />
<PackageVersion Include="Microsoft.WindowsAppSDK.Foundation" Version="1.8.260203002" />
<PackageVersion Include="Microsoft.WindowsAppSDK.AI" Version="1.8.47" />
<PackageVersion Include="Microsoft.WindowsAppSDK.Runtime" Version="1.8.260209005" />
<PackageVersion Include="Microsoft.Xaml.Behaviors.WinUI.Managed" Version="2.0.9" />
<PackageVersion Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.39" />
<PackageVersion Include="ModernWpfUI" Version="0.9.4" />
@@ -90,11 +90,11 @@
<PackageVersion Include="MSTest" Version="$(MSTestVersion)" />
<PackageVersion Include="MSTest.TestFramework" Version="$(MSTestVersion)" />
<PackageVersion Include="NJsonSchema" Version="11.4.0" />
<PackageVersion Include="Newtonsoft.Json" Version="13.0.4" />
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3" />
<PackageVersion Include="NLog" Version="5.2.8" />
<PackageVersion Include="NLog.Extensions.Logging" Version="5.3.8" />
<PackageVersion Include="NLog.Schema" Version="5.2.8" />
<PackageVersion Include="OpenAI" Version="2.7.0" />
<PackageVersion Include="OpenAI" Version="2.5.0" />
<PackageVersion Include="Polly.Core" Version="8.6.5" />
<PackageVersion Include="ReverseMarkdown" Version="4.1.0" />
<PackageVersion Include="RtfPipe" Version="2.0.7677.4303" />
@@ -106,28 +106,31 @@
<PackageVersion Include="StreamJsonRpc" Version="2.21.69" />
<PackageVersion Include="StyleCop.Analyzers" Version="1.2.0-beta.556" />
<!-- Package System.CodeDom added as a hack for being able to exclude the runtime assets so they don't conflict with 8.0.1. This is a dependency of System.Management but the 8.0.1 version wasn't published to nuget. -->
<PackageVersion Include="System.CodeDom" Version="10.0.8" />
<PackageVersion Include="System.CodeDom" Version="9.0.10" />
<PackageVersion Include="System.Collections.Immutable" Version="9.0.0" />
<PackageVersion Include="System.CommandLine" Version="2.0.0-beta4.22272.1" />
<PackageVersion Include="System.ComponentModel.Composition" Version="10.0.8" />
<PackageVersion Include="System.Configuration.ConfigurationManager" Version="10.0.8" />
<PackageVersion Include="System.Data.OleDb" Version="10.0.8" />
<PackageVersion Include="System.ComponentModel.Composition" Version="9.0.10" />
<PackageVersion Include="System.Configuration.ConfigurationManager" Version="9.0.10" />
<PackageVersion Include="System.Data.OleDb" Version="9.0.10" />
<!-- Package System.Data.SqlClient added to force it as a dependency of Microsoft.Windows.Compatibility to the latest version available at this time. -->
<PackageVersion Include="System.Data.SqlClient" Version="4.9.0" />
<!-- Package System.Diagnostics.EventLog added as a hack for being able to exclude the runtime assets so they don't conflict with 8.0.1. This is a dependency of System.Data.OleDb but the 8.0.1 version wasn't published to nuget. -->
<PackageVersion Include="System.Diagnostics.EventLog" Version="10.0.8" />
<PackageVersion Include="System.Diagnostics.EventLog" Version="9.0.10" />
<!-- Package System.Diagnostics.PerformanceCounter added as a hack for being able to exclude the runtime assets so they don't conflict with 8.0.11. -->
<PackageVersion Include="System.Diagnostics.PerformanceCounter" Version="10.0.8" />
<PackageVersion Include="System.ClientModel" Version="1.8.1" />
<PackageVersion Include="System.Drawing.Common" Version="10.0.8" />
<PackageVersion Include="System.Diagnostics.PerformanceCounter" Version="9.0.10" />
<PackageVersion Include="System.ClientModel" Version="1.7.0" />
<PackageVersion Include="System.Drawing.Common" Version="9.0.10" />
<PackageVersion Include="System.IO.Abstractions" Version="22.0.13" />
<PackageVersion Include="System.IO.Abstractions.TestingHelpers" Version="22.0.13" />
<PackageVersion Include="System.Management" Version="10.0.8" />
<PackageVersion Include="System.Management" Version="9.0.10" />
<PackageVersion Include="System.Net.Http" Version="4.3.4" />
<PackageVersion Include="System.Numerics.Tensors" Version="10.0.2" />
<PackageVersion Include="System.Numerics.Tensors" Version="9.0.11" />
<PackageVersion Include="System.Private.Uri" Version="4.3.2" />
<PackageVersion Include="System.Reactive" Version="6.0.1" />
<PackageVersion Include="System.Runtime.Caching" Version="10.0.8" />
<PackageVersion Include="System.ServiceProcess.ServiceController" Version="10.0.8" />
<PackageVersion Include="System.Text.Encoding.CodePages" Version="10.0.8" />
<PackageVersion Include="System.Text.Json" Version="10.0.8" />
<PackageVersion Include="System.Runtime.Caching" Version="9.0.10" />
<PackageVersion Include="System.ServiceProcess.ServiceController" Version="9.0.10" />
<PackageVersion Include="System.Text.Encoding.CodePages" Version="9.0.10" />
<PackageVersion Include="System.Text.Json" Version="9.0.10" />
<PackageVersion Include="System.Text.RegularExpressions" Version="4.3.1" />
<PackageVersion Include="ToolGood.Words.Pinyin" Version="3.1.0.3" />
<PackageVersion Include="UnicodeInformation" Version="2.6.0" />
@@ -135,8 +138,8 @@
<PackageVersion Include="UTF.Unknown" Version="2.6.0" />
<PackageVersion Include="WinUIEx" Version="2.8.0" />
<PackageVersion Include="WmiLight" Version="6.14.0" />
<PackageVersion Include="WPF-UI" Version="3.0.5" />
<PackageVersion Include="WyHash" Version="1.0.5" />
<PackageVersion Include="YamlDotNet" Version="16.3.0" />
<PackageVersion Include="WixToolset.Heat" Version="5.0.2" />
<PackageVersion Include="WixToolset.Firewall.wixext" Version="5.0.2" />
<PackageVersion Include="WixToolset.Util.wixext" Version="5.0.2" />

View File

@@ -17,7 +17,7 @@ This software incorporates material from third parties.
### Martin Chrzan's Color Picker
**Source**: <https://github.com/martinchrzan/ColorPicker>
**Source**: https://github.com/martinchrzan/ColorPicker
MIT License
@@ -49,7 +49,7 @@ We use the WyHash NuGet package for calculating stable hashes for strings.
**Source**: [https://github.com/wangyi-fudan/wyhash](https://github.com/wangyi-fudan/wyhash)
```text
```
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
@@ -82,7 +82,7 @@ We use the ToolGood.Words.Pinyin NuGet package for converting Chinese characters
**Source**: [https://github.com/toolgood/ToolGood.Words.Pinyin](https://github.com/toolgood/ToolGood.Words.Pinyin)
```text
```
MIT License
Copyright (c) 2020 ToolGood
@@ -106,7 +106,8 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
```
## Utility: Command palette built-in extensions
## Utility: Command Palette Built-in Extensions
### Calculator
@@ -116,7 +117,7 @@ We use the exprtk library (exprtk.hpp) to evaluate mathematical expressions.
**Source**: [https://github.com/ArashPartow/exprtk](https://github.com/ArashPartow/exprtk)
```text
```
MIT License
Copyright (c) 1999-2024 Arash Partow
@@ -143,7 +144,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
```
## Utility: PowerToys Run built-in extensions
## Utility: PowerToys Run Built-in Extensions
### Calculator
@@ -153,7 +154,7 @@ We use the Mages NuGet package for calculating the result of expression.
**Source**: [https://github.com/FlorianRappl/Mages](https://github.com/FlorianRappl/Mages)
```text
```
The MIT License (MIT)
Copyright (c) 2016 - 2025 Florian Rappl
@@ -177,13 +178,13 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
```
## Utility: File Explorer add-ins
## Utility: File Explorer Add-ins
### Monaco Editor
**Source**: <https://github.com/Microsoft/monaco-editor>
**Source**: https://github.com/Microsoft/monaco-editor
**Additional third party notifications:** <https://github.com/microsoft/monaco-editor/blob/main/ThirdPartyNotices.txt>
**Additional third party notifications:** https://github.com/microsoft/monaco-editor/blob/main/ThirdPartyNotices.txt
The MIT License (MIT)
@@ -207,9 +208,9 @@ 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.
### The Quite OK image format reference decoder
### The Quite OK Image Format reference decoder
**Source**: <https://github.com/phoboslab/qoi>
**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.
@@ -239,9 +240,9 @@ SOFTWARE.
We use the UTF.Unknown NuGet package for detecting encoding in text/code files.
**Source**: <https://github.com/CharsetDetector/UTF-unknown>
**Source**: https://github.com/CharsetDetector/UTF-unknown
```text
```
MOZILLA PUBLIC LICENSE
Version 1.1
@@ -715,9 +716,9 @@ EXHIBIT A -Mozilla Public License.
## Utility: ImageResizer
### Brice Lams's Image Resizer license
### Brice Lams's Image Resizer License
**Source**: <https://github.com/bricelam/ImageResizer/>
**Source**: https://github.com/bricelam/ImageResizer/
The MIT License (MIT)
@@ -743,10 +744,10 @@ THE SOFTWARE.
## Utility: PowerToys Run
### Wox license
### Wox License
**Fork project source**: <https://github.com/jjw24/Wox/>
**Base project source**: <https://github.com/Wox-launcher/Wox>
**Fork project source**: https://github.com/jjw24/Wox/
**Base project source**: https://github.com/Wox-launcher/Wox
The MIT License (MIT)
@@ -769,9 +770,9 @@ 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.
### Beta Tadele's Window Walker license
### Beta Tadele's Window Walker License
**Source**: <https://github.com/betsegaw/windowwalker>
**Source**: https://github.com/betsegaw/windowwalker
The MIT License (MIT)
@@ -785,9 +786,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
## Utility: PowerRename
### Chris Davis's SmartRename license
### Chris Davis's SmartRename License
**Source**: <https://github.com/chrdavis/SmartRename>
**Source**: https://github.com/chrdavis/SmartRename
MIT License
@@ -815,7 +816,7 @@ SOFTWARE.
### spdlog
**Source**: <https://github.com/gabime/spdlog>
**Source**: https://github.com/gabime/spdlog
The MIT License (MIT)
@@ -840,12 +841,12 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-- NOTE: Third party dependency used by this software --
This software depends on the fmt lib (MIT License), and users must comply to its license:
<https://github.com/fmtlib/fmt/blob/master/LICENSE.rst>
This software depends on the fmt lib (MIT License),
and users must comply to its license: https://github.com/fmtlib/fmt/blob/master/LICENSE.rst
### expected-lite
**Source**: <https://github.com/martinmoene/expected-lite>
**Source**: https://github.com/martinmoene/expected-lite
Boost Software License - Version 1.0 - August 17th, 2003
@@ -873,7 +874,7 @@ DEALINGS IN THE SOFTWARE.
### zip
**Source**: <https://github.com/kuba--/zip>
**Source**: https://github.com/kuba--/zip
All Rights Reserved.
@@ -901,7 +902,7 @@ THE SOFTWARE.
We adopted some functions from it.
**Source**: <https://github.com/DLTcollab/sse2neon>
**Source**: https://github.com/DLTcollab/sse2neon
sse2neon is freely redistributable under the MIT License.
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -924,9 +925,9 @@ SOFTWARE.
### Monaco Editor
**Source**: <https://github.com/Microsoft/monaco-editor>
**Source**: https://github.com/Microsoft/monaco-editor
**Additional third party notifications:** <https://github.com/microsoft/monaco-editor/blob/main/ThirdPartyNotices.txt>
**Additional third party notifications:** https://github.com/microsoft/monaco-editor/blob/main/ThirdPartyNotices.txt
The MIT License (MIT)
@@ -950,11 +951,11 @@ 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.
### The Quite OK image format reference decoder
### The Quite OK Image Format reference decoder
**Source**: <https://github.com/phoboslab/qoi>
**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.
**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
@@ -978,13 +979,13 @@ 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
### UTF Unknown
We use the UTF.Unknown NuGet package for detecting encoding in text/code files.
**Source**: <https://github.com/CharsetDetector/UTF-unknown>
**Source**: https://github.com/CharsetDetector/UTF-unknown
```text
```
MOZILLA PUBLIC LICENSE
Version 1.1
@@ -1462,9 +1463,9 @@ EXHIBIT A -Mozilla Public License.
We use HexBox.WinUI to show a preview of binary values.
**Source**: <https://github.com/hotkidfamily/HexBox.WinUI>
**Source**: https://github.com/hotkidfamily/HexBox.WinUI
```text
```
MIT License
Copyright (c) 2019 Filip Jeremic
@@ -1491,11 +1492,11 @@ SOFTWARE.
### Monaco Editor
**Source**: <https://github.com/Microsoft/monaco-editor>
**Source**: https://github.com/Microsoft/monaco-editor
**Additional third party notifications:** <https://github.com/microsoft/monaco-editor/blob/main/ThirdPartyNotices.txt>
**Additional third party notifications:** https://github.com/microsoft/monaco-editor/blob/main/ThirdPartyNotices.txt
```text
```
The MIT License (MIT)
Copyright (c) 2016 - present Microsoft Corporation
@@ -1525,7 +1526,7 @@ SOFTWARE.
PowerDisplay's DDC/CI implementation references techniques from Twinkle Tray.
**Source**: <https://github.com/xanderfrangos/twinkle-tray>
**Source**: https://github.com/xanderfrangos/twinkle-tray
MIT License
@@ -1587,6 +1588,7 @@ SOFTWARE.
- NLog.Extensions.Logging
- NLog.Schema
- OpenAI
- Polly.Core
- ReverseMarkdown
- ScipBe.Common.Office.OneNote
- SharpCompress
@@ -1600,5 +1602,5 @@ SOFTWARE.
- UTF.Unknown
- WinUIEx
- WmiLight
- WPF-UI
- WyHash
- YamlDotNet

View File

@@ -57,7 +57,6 @@
<Project Path="src/common/UnitTests-CommonLib/UnitTests-CommonLib.vcxproj" Id="1a066c63-64b3-45f8-92fe-664e1cce8077" />
<Project Path="src/common/UnitTests-CommonUtils/UnitTests-CommonUtils.vcxproj" Id="8b5cfb38-ccba-40a8-ad7a-89c57b070884" />
<Project Path="src/common/updating/updating.vcxproj" Id="17da04df-e393-4397-9cf0-84dabe11032e" />
<Project Path="src/common/updating/UnitTests/UpdatingUnitTests.vcxproj" Id="a1b2c3d4-e5f6-7890-abcd-ef1234567890" />
<Project Path="src/common/version/version.vcxproj" Id="cc6e41ac-8174-4e8a-8d22-85dd7f4851df" />
</Folder>
<Folder Name="/common/interop/">
@@ -68,7 +67,10 @@
<Project Path="src/common/interop/PowerToys.Interop.vcxproj" Id="f055103b-f80b-4d0c-bf48-057c55620033" />
</Folder>
<Folder Name="/common/log/">
<Project Path="src/common/logger/logger.vcxproj" Id="d9b8fc84-322a-4f9f-bbb9-20915c47ddfd" />
<Project Path="src/common/logger/logger.vcxproj" Id="d9b8fc84-322a-4f9f-bbb9-20915c47ddfd">
<BuildDependency Project="src/logging/logging.vcxproj" />
</Project>
<Project Path="src/logging/logging.vcxproj" Id="7e1e3f13-2bd6-3f75-a6a7-873a2b55c60f" />
</Folder>
<Folder Name="/common/notifications/">
<Project Path="src/common/notifications/BackgroundActivator/BackgroundActivator.vcxproj" Id="0b593a6c-4143-4337-860e-db5710fb87db" />
@@ -204,10 +206,6 @@
<Platform Solution="*|ARM64" Project="ARM64" />
<Platform Solution="*|x64" Project="x64" />
</Project>
<Project Path="src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Actions/Microsoft.CmdPal.Ext.Actions.csproj">
<Platform Solution="*|ARM64" Project="ARM64" />
<Platform Solution="*|x64" Project="x64" />
</Project>
<Project Path="src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Bookmark/Microsoft.CmdPal.Ext.Bookmarks.csproj">
<Platform Solution="*|ARM64" Project="ARM64" />
<Platform Solution="*|x64" Project="x64" />
@@ -321,10 +319,6 @@
<Platform Solution="*|ARM64" Project="ARM64" />
<Platform Solution="*|x64" Project="x64" />
</Project>
<Project Path="src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.Indexer.UnitTests/Microsoft.CmdPal.Ext.Indexer.UnitTests.csproj">
<Platform Solution="*|ARM64" Project="ARM64" />
<Platform Solution="*|x64" Project="x64" />
</Project>
<Project Path="src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.Registry.UnitTests/Microsoft.CmdPal.Ext.Registry.UnitTests.csproj">
<Platform Solution="*|ARM64" Project="ARM64" />
<Platform Solution="*|x64" Project="x64" />
@@ -433,7 +427,7 @@
</Project>
</Folder>
<Folder Name="/modules/FileLocksmith/">
<Project Path="src/modules/FileLocksmith/FileLocksmithCLI/FileLocksmithCLI.vcxproj" Id="49d456d3-f485-45af-8875-45b44f193ddc" />
<Project Path="src/modules/FileLocksmith/FileLocksmithCLI/FileLocksmithCLI.vcxproj" Id="49D456D3-F485-45AF-8875-45B44F193DDC" />
<Project Path="src/modules/FileLocksmith/FileLocksmithContextMenu/FileLocksmithContextMenu.vcxproj" Id="799a50d8-de89-4ed1-8ff8-ad5a9ed8c0ca" />
<Project Path="src/modules/FileLocksmith/FileLocksmithExt/FileLocksmithExt.vcxproj" Id="57175ec7-92a5-4c1e-8244-e3fbca2a81de" />
<Project Path="src/modules/FileLocksmith/FileLocksmithLib/FileLocksmithLib.vcxproj" Id="9d52fd25-ef90-4f9a-a015-91efc5daf54f" />
@@ -444,7 +438,7 @@
</Project>
</Folder>
<Folder Name="/modules/FileLocksmith/Tests/">
<Project Path="src/modules/FileLocksmith/FileLocksmithCLI/tests/FileLocksmithCLIUnitTests.vcxproj" Id="a1b2c3d4-e5f6-7890-1234-567890abcdef" />
<Project Path="src/modules/FileLocksmith/FileLocksmithCLI/tests/FileLocksmithCLIUnitTests.vcxproj" Id="A1B2C3D4-E5F6-7890-1234-567890ABCDEF" />
</Folder>
<Folder Name="/modules/Hosts/">
<Project Path="src/modules/Hosts/Hosts/Hosts.csproj">
@@ -470,16 +464,16 @@
</Folder>
<Folder Name="/modules/imageresizer/">
<Project Path="src/modules/imageresizer/dll/ImageResizerExt.vcxproj" Id="0b43679e-edfa-4da0-ad30-f4628b308b1b" />
<Project Path="src/modules/imageresizer/ImageResizerCLI/ImageResizerCLI.csproj">
<Platform Solution="*|ARM64" Project="ARM64" />
<Platform Solution="*|x64" Project="x64" />
</Project>
<Project Path="src/modules/imageresizer/ImageResizerContextMenu/ImageResizerContextMenu.vcxproj" Id="93b72a06-c8bd-484f-a6f7-c9f280b150bf" />
<Project Path="src/modules/imageresizer/ImageResizerLib/ImageResizerLib.vcxproj" Id="18b3db45-4ffe-4d01-97d6-5223feee1853" />
<Project Path="src/modules/imageresizer/ui/ImageResizerUI.csproj">
<Platform Solution="*|ARM64" Project="ARM64" />
<Platform Solution="*|x64" Project="x64" />
</Project>
<Project Path="src/modules/imageresizer/ImageResizerCLI/ImageResizerCLI.csproj">
<Platform Solution="*|ARM64" Project="ARM64" />
<Platform Solution="*|x64" Project="x64" />
</Project>
</Folder>
<Folder Name="/modules/imageresizer/Tests/">
<Project Path="src/modules/imageresizer/tests/ImageResizer.UnitTests.csproj">
@@ -715,19 +709,17 @@
</Project>
</Folder>
<Folder Name="/modules/PowerDisplay/">
<Project Path="src/modules/powerdisplay/PowerDisplay.Models/PowerDisplay.Models.csproj">
<Platform Solution="*|ARM64" Project="ARM64" />
<Platform Solution="*|x64" Project="x64" />
</Project>
<Project Path="src/modules/powerdisplay/PowerDisplay.Lib/PowerDisplay.Lib.csproj">
<Platform Solution="*|ARM64" Project="ARM64" />
<Platform Solution="*|x64" Project="x64" />
</Project>
<!-- TEMPORARILY_DISABLED: PowerDisplay
<Project Path="src/modules/powerdisplay/PowerDisplay/PowerDisplay.csproj">
<Platform Solution="*|ARM64" Project="ARM64" />
<Platform Solution="*|x64" Project="x64" />
</Project>
<Project Path="src/modules/powerdisplay/PowerDisplayModuleInterface/PowerDisplayModuleInterface.vcxproj" Id="d1234567-8901-2345-6789-abcdef012345" />
-->
</Folder>
<Folder Name="/modules/PowerDisplay/Tests/">
<Project Path="src/modules/powerdisplay/PowerDisplay.Lib.UnitTests/PowerDisplay.Lib.UnitTests.csproj">
@@ -799,14 +791,6 @@
<Project Path="src/modules/peek/peek/peek.vcxproj" Id="a1425b53-3d61-4679-8623-e64a0d3d0a48" />
</Folder>
<Folder Name="/modules/PowerAccent/">
<Project Path="src/modules/poweraccent/PowerAccent.Common.UnitTests/PowerAccent.Common.UnitTests.csproj">
<Platform Solution="*|ARM64" Project="ARM64" />
<Platform Solution="*|x64" Project="x64" />
</Project>
<Project Path="src/modules/poweraccent/PowerAccent.Common/PowerAccent.Common.csproj">
<Platform Solution="*|ARM64" Project="ARM64" />
<Platform Solution="*|x64" Project="x64" />
</Project>
<Project Path="src/modules/poweraccent/PowerAccent.Core/PowerAccent.Core.csproj">
<Platform Solution="*|ARM64" Project="ARM64" />
<Platform Solution="*|x64" Project="x64" />
@@ -995,20 +979,9 @@
<Platform Solution="*|x64" Project="x64" />
</Project>
</Folder>
<Folder Name="/modules/ShortcutGuide/">
<Project Path="src/modules/ShortcutGuide/ShortcutGuide.IndexYmlGenerator/ShortcutGuide.IndexYmlGenerator.csproj">
<Platform Solution="*|ARM64" Project="ARM64" />
<Platform Solution="*|x64" Project="x64" />
</Project>
<Project Path="src/modules/ShortcutGuide/ShortcutGuide.Ui/ShortcutGuide.Ui.csproj">
<Platform Solution="*|ARM64" Project="ARM64" />
<Platform Solution="*|x64" Project="x64" />
</Project>
<Project Path="src/modules/ShortcutGuide/ShortcutGuide.UnitTests/ShortcutGuide.UnitTests.csproj">
<Platform Solution="*|ARM64" Project="ARM64" />
<Platform Solution="*|x64" Project="x64" />
</Project>
<Project Path="src/modules/ShortcutGuide/ShortcutGuideModuleInterface/ShortcutGuideModuleInterface.vcxproj" Id="e487304a-b1fb-4e6b-8e70-014051af5b99" />
<Folder Name="/modules/shortcutguide/">
<Project Path="src/modules/ShortcutGuide/ShortcutGuide/ShortcutGuide.vcxproj" Id="2edb3eb4-fa92-4bff-b2d8-566584837231" />
<Project Path="src/modules/ShortcutGuide/ShortcutGuideModuleInterface/ShortcutGuideModuleInterface.vcxproj" Id="2d604c07-51fc-46bb-9eb7-75aecc7f5e81" />
</Folder>
<Folder Name="/modules/Workspaces/">
<Project Path="src/modules/Workspaces/Workspaces.ModuleServices/Workspaces.ModuleServices.csproj">
@@ -1054,17 +1027,10 @@
<File Path="src/modules/Workspaces/workspaces-common/WindowUtils.h" />
</Folder>
<Folder Name="/modules/ZoomIt/">
<Project Path="src/modules/ZoomIt/ZoomIt/ZoomIt.vcxproj" Id="0a84f764-3a88-44cd-aa96-41bdbd48627b">
<BuildDependency Project="src/modules/ZoomIt/ZoomItBreak/ZoomItBreak.vcxproj" />
</Project>
<Project Path="src/modules/ZoomIt/ZoomItBreak/ZoomItBreak.vcxproj" Id="94ba3051-c8d7-454a-9d46-1a7c78e228a3" />
<Project Path="src/modules/ZoomIt/ZoomIt/ZoomIt.vcxproj" Id="0a84f764-3a88-44cd-aa96-41bdbd48627b" />
<Project Path="src/modules/ZoomIt/ZoomItModuleInterface/ZoomItModuleInterface.vcxproj" Id="e4585179-2ac1-4d5f-a3ff-cfc5392f694c" />
<Project Path="src/modules/ZoomIt/ZoomItSettingsInterop/ZoomItSettingsInterop.vcxproj" Id="ca7d8106-30b9-4aec-9d05-b69b31b8c461" />
</Folder>
<Folder Name="/modules/GrabAndMove/">
<Project Path="src/modules/GrabAndMove/GrabAndMove/GrabAndMove.vcxproj" Id="568c4c30-2e3c-4c2c-a691-007362073765" />
<Project Path="src/modules/GrabAndMove/GrabAndMoveModuleInterface/GrabAndMoveModuleInterface.vcxproj" Id="2c3f7770-4e57-46b7-8dc1-7428a383d0db" />
</Folder>
<Folder Name="/settings-ui/">
<Project Path="src/settings-ui/QuickAccess.UI/PowerToys.QuickAccess.csproj">
<Platform Solution="*|ARM64" Project="ARM64" />
@@ -1129,8 +1095,6 @@
<BuildDependency Project="src/modules/launcher/Microsoft.Launcher/Microsoft.Launcher.vcxproj" />
<BuildDependency Project="src/modules/LightSwitch/LightSwitchModuleInterface/LightSwitchModuleInterface.vcxproj" />
<BuildDependency Project="src/modules/LightSwitch/LightSwitchService/LightSwitchService.vcxproj" />
<BuildDependency Project="src/modules/GrabAndMove/GrabAndMoveModuleInterface/GrabAndMoveModuleInterface.vcxproj" />
<BuildDependency Project="src/modules/GrabAndMove/GrabAndMove/GrabAndMove.vcxproj" />
<BuildDependency Project="src/modules/powerrename/dll/PowerRenameExt.vcxproj" />
<BuildDependency Project="src/modules/powerrename/lib/PowerRenameLib.vcxproj" />
<BuildDependency Project="src/modules/previewpane/Common/PreviewHandlerCommon.csproj" />
@@ -1143,5 +1107,3 @@
<Project Path="src/Update/PowerToys.Update.vcxproj" Id="44ce9ae1-4390-42c5-bacc-0fd6b40aa203" />
<Project Path="tools/project_template/ModuleTemplate/ModuleTemplateCompileTest.vcxproj" Id="64a80062-4d8b-4229-8a38-dfa1d7497749" />
</Solution>

319
README.md
View File

@@ -19,35 +19,51 @@
<span> · </span>
<a href="#-whats-new">Release notes</a>
</h3>
<br/><br/>
## 🔨 Utilities
PowerToys includes over 30 utilities to help you customize and optimize your Windows experience:
PowerToys includes over 25 utilities to help you customize and optimize your Windows experience:
| | | |
| --- | --- | --- |
|---|---|---|
| [<img src="doc/images/icons/AdvancedPaste.png" alt="Advanced Paste icon" height="16"> Advanced Paste](https://aka.ms/PowerToysOverview_AdvancedPaste) | [<img src="doc/images/icons/Always%20On%20Top.png" alt="Always on Top icon" height="16"> Always on Top](https://aka.ms/PowerToysOverview_AoT) | [<img src="doc/images/icons/Awake.png" alt="Awake icon" height="16"> Awake](https://aka.ms/PowerToysOverview_Awake) |
| [<img src="doc/images/icons/Color%20Picker.png" alt="Color Picker icon" height="16"> Color Picker](https://aka.ms/PowerToysOverview_ColorPicker) | [<img src="doc/images/icons/Command%20Not%20Found.png" alt="Command Not Found icon" height="16"> Command Not Found](https://aka.ms/PowerToysOverview_CmdNotFound) | [<img src="doc/images/icons/Command Palette.png" alt="Command Palette icon" height="16"> Command Palette](https://aka.ms/PowerToysOverview_CmdPal) |
| [<img src="doc/images/icons/Crop%20And%20Lock.png" alt="Crop and Lock icon" height="16"> Crop And Lock](https://aka.ms/PowerToysOverview_CropAndLock) | [<img src="doc/images/icons/Environment%20Manager.png" alt="Environment Variables icon" height="16"> Environment Variables](https://aka.ms/PowerToysOverview_EnvironmentVariables) | [<img src="doc/images/icons/FancyZones.png" alt="FancyZones icon" height="16"> FancyZones](https://aka.ms/PowerToysOverview_FancyZones) |
| [<img src="doc/images/icons/File%20Explorer%20Preview.png" alt="File Explorer Add-ons icon" height="16"> File Explorer Add-ons](https://aka.ms/PowerToysOverview_FileExplorerAddOns) | [<img src="doc/images/icons/File%20Locksmith.png" alt="File Locksmith icon" height="16"> File Locksmith](https://aka.ms/PowerToysOverview_FileLocksmith) | [<img src="doc/images/icons/GrabAndMove.png" alt="Grab And Move icon" height="16"> Grab And Move](https://aka.ms/PowerToysOverview_GrabAndMove) |
| [<img src="doc/images/icons/Host%20File%20Editor.png" alt="Hosts File Editor icon" height="16"> Hosts File Editor](https://aka.ms/PowerToysOverview_HostsFileEditor) | [<img src="doc/images/icons/Image%20Resizer.png" alt="Image Resizer icon" height="16"> Image Resizer](https://aka.ms/PowerToysOverview_ImageResizer) | [<img src="doc/images/icons/Keyboard%20Manager.png" alt="Keyboard Manager icon" height="16"> Keyboard Manager](https://aka.ms/PowerToysOverview_KeyboardManager) |
| [<img src="doc/images/icons/Light Switch.png" alt="Light Switch icon" height="16"> Light Switch](https://aka.ms/PowerToysOverview_LightSwitch) | [<img src="doc/images/icons/Find My Mouse.png" alt="Mouse Utilities icon" height="16"> Mouse Utilities](https://aka.ms/PowerToysOverview_MouseUtilities) | [<img src="doc/images/icons/MouseWithoutBorders.png" alt="Mouse Without Borders icon" height="16"> Mouse Without Borders](https://aka.ms/PowerToysOverview_MouseWithoutBorders) |
| [<img src="doc/images/icons/NewPlus.png" alt="New+ icon" height="16"> New+](https://aka.ms/PowerToysOverview_NewPlus) | [<img src="doc/images/icons/Peek.png" alt="Peek icon" height="16"> Peek](https://aka.ms/PowerToysOverview_Peek) | [<img src="doc/images/icons/PowerDisplay.png" alt="PowerDisplay icon" height="16"> PowerDisplay](https://aka.ms/PowerToysOverview_PowerDisplay) |
| [<img src="doc/images/icons/PowerRename.png" alt="PowerRename icon" height="16"> PowerRename](https://aka.ms/PowerToysOverview_PowerRename) | [<img src="doc/images/icons/PowerToys%20Run.png" alt="PowerToys Run icon" height="16"> PowerToys Run](https://aka.ms/PowerToysOverview_PowerToysRun) | [<img src="doc/images/icons/PowerAccent.png" alt="Quick Accent icon" height="16"> Quick Accent](https://aka.ms/PowerToysOverview_QuickAccent) |
| [<img src="doc/images/icons/Registry%20Preview.png" alt="Registry Preview icon" height="16"> Registry Preview](https://aka.ms/PowerToysOverview_RegistryPreview) | [<img src="doc/images/icons/MeasureTool.png" alt="Screen Ruler icon" height="16"> Screen Ruler](https://aka.ms/PowerToysOverview_ScreenRuler) | [<img src="doc/images/icons/Shortcut%20Guide.png" alt="Shortcut Guide icon" height="16"> Shortcut Guide](https://aka.ms/PowerToysOverview_ShortcutGuide) |
| [<img src="doc/images/icons/PowerOCR.png" alt="Text Extractor icon" height="16"> Text Extractor](https://aka.ms/PowerToysOverview_TextExtractor) | [<img src="doc/images/icons/Workspaces.png" alt="Workspaces icon" height="16"> Workspaces](https://aka.ms/PowerToysOverview_Workspaces) | [<img src="doc/images/icons/ZoomIt.png" alt="ZoomIt icon" height="16"> ZoomIt](https://aka.ms/PowerToysOverview_ZoomIt) |
| [<img src="doc/images/icons/File%20Explorer%20Preview.png" alt="File Explorer Add-ons icon" height="16"> File Explorer Add-ons](https://aka.ms/PowerToysOverview_FileExplorerAddOns) | [<img src="doc/images/icons/File%20Locksmith.png" alt="File Locksmith icon" height="16"> File Locksmith](https://aka.ms/PowerToysOverview_FileLocksmith) | [<img src="doc/images/icons/Host%20File%20Editor.png" alt="Hosts File Editor icon" height="16"> Hosts File Editor](https://aka.ms/PowerToysOverview_HostsFileEditor) |
| [<img src="doc/images/icons/Image%20Resizer.png" alt="Image Resizer icon" height="16"> Image Resizer](https://aka.ms/PowerToysOverview_ImageResizer) | [<img src="doc/images/icons/Keyboard%20Manager.png" alt="Keyboard Manager icon" height="16"> Keyboard Manager](https://aka.ms/PowerToysOverview_KeyboardManager) | [<img src="doc/images/icons/Light Switch.png" alt="Light Switch icon" height="16"> Light Switch](https://aka.ms/PowerToysOverview_LightSwitch) |
| [<img src="doc/images/icons/Find My Mouse.png" alt="Mouse Utilities icon" height="16"> Mouse Utilities](https://aka.ms/PowerToysOverview_MouseUtilities) | [<img src="doc/images/icons/MouseWithoutBorders.png" alt="Mouse Without Borders icon" height="16"> Mouse Without Borders](https://aka.ms/PowerToysOverview_MouseWithoutBorders) | [<img src="doc/images/icons/NewPlus.png" alt="New+ icon" height="16"> New+](https://aka.ms/PowerToysOverview_NewPlus) |
| [<img src="doc/images/icons/Peek.png" alt="Peek icon" height="16"> Peek](https://aka.ms/PowerToysOverview_Peek) | [<img src="doc/images/icons/PowerRename.png" alt="PowerRename icon" height="16"> PowerRename](https://aka.ms/PowerToysOverview_PowerRename) | [<img src="doc/images/icons/PowerToys%20Run.png" alt="PowerToys Run icon" height="16"> PowerToys Run](https://aka.ms/PowerToysOverview_PowerToysRun) |
| [<img src="doc/images/icons/PowerAccent.png" alt="Quick Accent icon" height="16"> Quick Accent](https://aka.ms/PowerToysOverview_QuickAccent) | [<img src="doc/images/icons/Registry%20Preview.png" alt="Registry Preview icon" height="16"> Registry Preview](https://aka.ms/PowerToysOverview_RegistryPreview) | [<img src="doc/images/icons/MeasureTool.png" alt="Screen Ruler icon" height="16"> Screen Ruler](https://aka.ms/PowerToysOverview_ScreenRuler) |
| [<img src="doc/images/icons/Shortcut%20Guide.png" alt="Shortcut Guide icon" height="16"> Shortcut Guide](https://aka.ms/PowerToysOverview_ShortcutGuide) | [<img src="doc/images/icons/PowerOCR.png" alt="Text Extractor icon" height="16"> Text Extractor](https://aka.ms/PowerToysOverview_TextExtractor) | [<img src="doc/images/icons/Workspaces.png" alt="Workspaces icon" height="16"> Workspaces](https://aka.ms/PowerToysOverview_Workspaces) |
| [<img src="doc/images/icons/ZoomIt.png" alt="ZoomIt icon" height="16"> ZoomIt](https://aka.ms/PowerToysOverview_ZoomIt) | | |
## 📦 Installation
For detailed installation instructions and system requirements, visit the [installation docs](https://learn.microsoft.com/windows/powertoys/install).
## 📋 Installation
For detailed installation instructions and system requirements, visit the [installation docs](https://learn.microsoft.com/windows/powertoys/install).
But to get started quickly, choose one of the installation methods below:
<br/><br/>
<details open>
<summary><strong>Download the .exe file from GitHub</strong></summary>
<summary><strong>Download .exe from GitHub</strong></summary>
<br/>
Go to the <a href="https://aka.ms/installPowerToys">PowerToys GitHub releases</a>, click Assets to reveal the downloads, and choose the installer that matches your architecture and install scope. For most devices, that's the x64 per-user installer.
Go to the [PowerToys GitHub releases](https://aka.ms/installPowerToys), scroll down and select **Assets** to reveal the installation files, and choose the one that matches your architecture and install scope. For most devices, that would be _x64 per-user_.
<!-- items that need to be updated release to release -->
[github-next-release-work]: https://github.com/microsoft/PowerToys/issues?q=is%3Aissue+milestone%3A%22PowerToys+0.98%22
[github-current-release-work]: https://github.com/microsoft/PowerToys/issues?q=is%3Aissue+milestone%3A%22PowerToys+0.97%22
[ptUserX64]: https://github.com/microsoft/PowerToys/releases/download/v0.97.1/PowerToysUserSetup-0.97.1-x64.exe
[ptUserArm64]: https://github.com/microsoft/PowerToys/releases/download/v0.97.1/PowerToysUserSetup-0.97.1-arm64.exe
[ptMachineX64]: https://github.com/microsoft/PowerToys/releases/download/v0.97.1/PowerToysSetup-0.97.1-x64.exe
[ptMachineArm64]: https://github.com/microsoft/PowerToys/releases/download/v0.97.1/PowerToysSetup-0.97.1-arm64.exe
| Description | Filename |
|----------------|----------|
| Per user - x64 | [PowerToysUserSetup-0.97.1-x64.exe][ptUserX64] |
| Per user - ARM64 | [PowerToysUserSetup-0.97.1-arm64.exe][ptUserArm64] |
| Machine wide - x64 | [PowerToysSetup-0.97.1-x64.exe][ptMachineX64] |
| Machine wide - ARM64 | [PowerToysSetup-0.97.1-arm64.exe][ptMachineArm64] |
</details>
@@ -67,16 +83,14 @@ You can easily install PowerToys from the Microsoft Store:
<details>
<summary><strong>WinGet</strong></summary>
<br/>
Download PowerToys from [WinGet](https://github.com/microsoft/winget-cli#installing-the-client). Updating PowerToys via winget will respect the current PowerToys installation scope. To install PowerToys, run the following command from the command line / PowerShell:
- User scope installer (default)
Download PowerToys from <a href="https://github.com/microsoft/winget-cli#installing-the-client">WinGet</a>. Updating PowerToys via winget will respect the current PowerToys installation scope. To install PowerToys, run the following command from the command line / PowerShell:
*User scope installer [default]*
```powershell
winget install Microsoft.PowerToys -s winget
```
- Machine-wide scope installer
*Machine-wide scope installer*
```powershell
winget install --scope machine Microsoft.PowerToys -s winget
```
@@ -85,36 +99,265 @@ winget install --scope machine Microsoft.PowerToys -s winget
<details>
<summary><strong>Other methods</strong></summary>
<br/>
There are [community driven install methods](https://learn.microsoft.com/windows/powertoys/install#community-driven-install-tools) such as Chocolatey and Scoop. If these are your preferred install solutions, you can find the install instructions there.
There are <a href="https://learn.microsoft.com/windows/powertoys/install#community-driven-install-tools">community driven install methods</a> such as Chocolatey and Scoop. If these are your preferred install solutions, you can find the install instructions there.
</details>
## ✨ What's new?
## ✨ What's new
[![What's new image](doc/images/readme/Release-Banner.png)](https://github.com/microsoft/PowerToys/releases)
**Version 0.97.2 (Feb 2026)**
To see what's new, check out the [release notes](https://github.com/microsoft/PowerToys/releases/).
This patch release fixes several important stability issues identified in v0.97.0 based on incoming reports. Check out the [v0.97.0](https://github.com/microsoft/PowerToys/releases/tag/v0.97.0) notes for the full list of changes.
## 🛣️ Roadmap
## Advanced Paste
- #45207 Fixed a crash in the Advanced Paste settings page caused by null values during JSON deserialization.
We are planning some nice new features and improvements for the next releases a brand-new Shortcut Guide experience, ensuring it's easier to find and install Command Palette extensions and so much more! Stay tuned for [v0.100][github-next-release-work]!
## Color Picker
- #45367 Fixed contrast issue in Color picker UI.
## ❤️ PowerToys Community
## Command Palette
- #45194 Fixed an issue where some Command Palette PowerToys Extension strings were not localised.
## Cursor Wrap
- #45210 Fixed "Automatically activate on utility startup" setting not persisting when disabled. Thanks [@ThanhNguyxn](https://github.com/ThanhNguyxn)!
- #45303 Added option to disable Cursor Wrapping when only a single monitor is connected. Thanks [@mikehall-ms](https://github.com/mikehall-ms)!
## Image Resizer
- #45184 Fixed Image Resizer not working after upgrading PowerToys on Windows 10 by properly cleaning up legacy sparse app packages.
## LightSwitch
- #45304 Fixed Light Switch startup logic to correctly apply the appropriate theme on launch.
## Workspaces
- #45183 Fixed overlay positioning issue in workspace snapshot draw caused by DPI-aware coordinate mismatch.
## Quick Access and Measure Tool
- #45443 Fixed crash related to `IsShownInSwitchers` property when Explorer is not running.
**Version 0.97.1 (January 2026)**
**Highlights**
### Advanced Paste
- #44862: Fixed Settings UI advanced paste page crash by using correct settings repository for null checking.
### Command Palette
- #44886: Fixed personalization section not appearing by using latest MSIX for installation.
- #44938: Fixed loading of icons from internet shortcuts. Thanks [@jiripolasek](https://github.com/jiripolasek)!
- #45076: Fixed potential deadlock from lazy-loading AppListItem details. Thanks [@jiripolasek](https://github.com/jiripolasek)!
### Cursor Wrap
- #44936: Added improved multi-monitor support; Added laptop lid close detection for dynamic monitor topology updates. Thanks [@mikehall-ms](https://github.com/mikehall-ms)!
- #44936: Added new settings dropdown to constrain wrapping to horizontal-only, vertical-only, or both directions. Thanks [@mikehall-ms](https://github.com/mikehall-ms)!
### Peek
- #44995: Fixed Space key triggering Peek during file rename, search, or address bar typing.
### PowerRename
- #44944: Fixed regex `$` not working, preventing users from adding text at the end of filenames.
### Runner
- #44931: Monochrome tray icon now adapts to Windows system theme instead of app theme.
- #44982: Fixed right-click menu to dynamically update based on Quick Access enabled/disabled state.
### GPO / Enterprise
- #45028: Added CursorWrap policy definition to ADMX templates. Thanks [@htcfreek](https://github.com/htcfreek)!
For the full list of v0.97 changes, visit the [Windows Command Line blog](https://aka.ms/powertoys-releaseblog).
## Advanced Paste
- Added hex color previews in clipboard history. Thanks [@crramirez](https://github.com/crramirez)!
- Added automatic placeholder endpoints when required fields are left empty.
- Fixed a grammar issue in the AI settings description. Thanks [@erik-anderson](https://github.com/erik-anderson)!
- Fixed loading order so custom action hotkeys are read correctly.
- Updated Advanced Paste descriptions to reflect support for online and local models.
- Fixed clipboard history item selection so it doesnt duplicate entries.
- Prevented placeholder endpoints from being saved for providers that dont need them.
- Added image input support for AI transforms and improved clipboard change tracking.
## Awake
- Fixed Awake CLI so help, errors, and logs appear correctly in the console. Thanks [@daverayment](https://github.com/daverayment)!
## Command Palette
- Fixed background image loading in BlurImageControl. Thanks [@jiripolasek](https://github.com/jiripolasek)!
- Fixed SDK packaging paths and added a CI SDK build stage.
- Aligned naming and spell-checking with .NET conventions. Thanks [@jiripolasek](https://github.com/jiripolasek)!
- Added drag-and-drop support for Command Palette items. Thanks [@jiripolasek](https://github.com/jiripolasek)!
- Added a PowerToys Command Palette extension to discover and launch PowerToys utilities.
- Fixed grid view bindings and layout issues. Thanks [@jiripolasek](https://github.com/jiripolasek)!
- Fixed a line-break issue in RDC extension toast messages. Thanks [@jiripolasek](https://github.com/jiripolasek)!
- Made the Settings button text localizable. Thanks [@jiripolasek](https://github.com/jiripolasek)!
- Hid the RDC fallback on the home page and fixed MSTSC working directory handling. Thanks [@jiripolasek](https://github.com/jiripolasek)!
- Optimized result list merging for better performance. Thanks [@daverayment](https://github.com/daverayment)!
- Added Small/Medium/Large detail sizes in the extensions API. Thanks [@DevLGuilherme](https://github.com/DevLGuilherme)!
- Hid fallback commands on the home page when no query is entered. Thanks [@jiripolasek](https://github.com/jiripolasek)!
- Added back navigation support in the Settings window. Thanks [@jiripolasek](https://github.com/jiripolasek)!
- Added a Command Palette solution filter. Thanks [@jiripolasek](https://github.com/jiripolasek)!
- Updated Extension SDK documentation links to Microsoft Learn. Thanks [@RubenFricke](https://github.com/RubenFricke)!
- Added a custom search engine URL setting for Web Search. Thanks [@jiripolasek](https://github.com/jiripolasek)!
- Added pinyin matching for Chinese input. Thanks [@frg2089](https://github.com/frg2089)!
- Bumped Command Palette version to 0.8.
- Removed subtitles from built-in top-level commands. Thanks [@jiripolasek](https://github.com/jiripolasek)!
- Refined separator styling in the details pane. Thanks [@jiripolasek](https://github.com/jiripolasek)!
- Added a built-in Remote Desktop extension.
- Added a Peek command to the Indexer extension.
- Improved default browser detection using the Windows Shell API. Thanks [@jiripolasek](https://github.com/jiripolasek)!
- Added Escape key behavior options. Thanks [@jiripolasek](https://github.com/jiripolasek)!
- Added theme and background customization options. Thanks [@jiripolasek](https://github.com/jiripolasek)!
- Improved WinGet package app matching. Thanks [@jiripolasek](https://github.com/jiripolasek)!
- Added an auto-return-home delay setting. Thanks [@jiripolasek](https://github.com/jiripolasek)!
- Added fallback ranking and global results settings.
- Removed the selection indicator in the context menu list. Thanks [@jiripolasek](https://github.com/jiripolasek)!
- Added a developer ribbon with build and log info. Thanks [@jiripolasek](https://github.com/jiripolasek)!
- Updated the “Learn more” string for Command Palette. Thanks [@pratnala](https://github.com/pratnala)!
- Added arrow-key navigation for grid views. Thanks [@samrueby](https://github.com/samrueby)!
- Fixed version display when running unpackaged. Thanks [@jiripolasek](https://github.com/jiripolasek)!
- Added a native debugging launch profile. Thanks [@jiripolasek](https://github.com/jiripolasek)!
- Reduced redundant property change notifications in the SDK. Thanks [@jiripolasek](https://github.com/jiripolasek)!
- Improved section readability and accessibility. Thanks [@jiripolasek](https://github.com/jiripolasek)!
- Made gallery spacing uniform. Thanks [@jiripolasek](https://github.com/jiripolasek)!
- Added sections and separators for list and grid pages. Thanks [@DevLGuilherme](https://github.com/DevLGuilherme)!
## Crop & Lock
- Added a screenshot mode that freezes a cropped region into its own window. Thanks [@fm-sys](https://github.com/fm-sys)!
## Cursor Wrap
- Improved Cursor Wrap behavior on multi-monitor setups by wrapping only at outer edges. Thanks [@mikehall-ms](https://github.com/mikehall-ms)!
## FancyZones
- Fixed editor overlay positioning on mixed-DPI multi-monitor setups. Thanks [@Memphizzz](https://github.com/Memphizzz)!
- Added a FancyZones CLI for command-line layout management.
## File Locksmith
- Added a File Locksmith CLI for querying, waiting on, or killing file locks.
## Find My Mouse
- Improved spotlight edge rendering for clearer Find My Mouse visuals.
- Added telemetry to track how Find My Mouse is triggered.
## Image Resizer
- Fixed Fill mode cropping when Shrink Only is enabled. Thanks [@daverayment](https://github.com/daverayment)!
- Added a dedicated Image Resizer CLI for scripted resizing.
## Light Switch
- Added telemetry events for Light Switch usage and settings changes.
- Added a Follow Night Light mode to sync theme changes with Night Light.
- Clarified LightSwitchService and LightSwitchStateManager roles in docs.
- Added a Quick Access dashboard button to toggle Light Switch quickly.
- Ensured Light Switch honors GPO policy states with clear status messaging.
## Mouse Without Borders
- Continued refactoring Mouse Without Borders by splitting the large Common class into focused components. Thanks [@mikeclayton](https://github.com/mikeclayton)!
- Completed the Common class refactor with Core and IPC helper extraction. Thanks [@mikeclayton](https://github.com/mikeclayton)!
## Peek
- Hardened Peek previews with strict resource filtering and safer external link warnings.
- Improved SVG preview compatibility by rendering via WebView2.
## PowerRename
- Added HEIF/AVIF EXIF metadata extraction and extension status guidance for related previews.
- Fixed undefined behavior in file time handling. Thanks [@safocl](https://github.com/safocl)!
- Optimized memory allocation for depth-based rename processing.
- Fixed Unicode normalization and nonbreaking space matching. Thanks [@daverayment](https://github.com/daverayment)!
- Fixed date token replacements followed by capital letters. Thanks [@daverayment](https://github.com/daverayment)!
## PowerToys Run Plugins
- Fixed a plugin name typo and added Project Launcher to the thirdparty list. Thanks [@artickc](https://github.com/artickc)!
- Added the Open With Antigravity plugin to the thirdparty list. Thanks [@artickc](https://github.com/artickc)!
## PowerToys Run
- Avoided unnecessary hotkey conflict checks when settings change.
- Added QuickAI to the third-party PowerToys Run plugin list. Thanks [@ruslanlap](https://github.com/ruslanlap)!
## Quick Accent
- Added localized quotation marks to Quick Accent. Thanks [@warquys](https://github.com/warquys)!
- Fixed duplicate and redundant characters in Quick Accent sets. Thanks [@noraa-junker](https://github.com/noraa-junker)!
- Fixed DPI positioning issues for Quick Accent on mixed-DPI setups. Thanks [@noraa-junker](https://github.com/noraa-junker)!
## Settings
- Added a new tray icon that adapts to theme changes. Thanks [@HO-COOH](https://github.com/HO-COOH)!
- Centralized module enable/disable logic for cleaner Settings UI updates.
- Simplified Settings utilities by removing ISettingsUtils/ISettingsPath interfaces. Thanks [@noraa-junker](https://github.com/noraa-junker)!
- Improved Settings UI consistency and disabled-state visuals.
- Added semantic headings to the Dashboard for better accessibility.
- Introduced Quick Access as a standalone host with updated Settings integration.
- Fixed Dashboard toggle flicker and sort menu checkmarks. Thanks [@daverayment](https://github.com/daverayment)!
- Added Native AOT-compatible settings serialization.
- Standardized mouse tool description text. Thanks [@daverayment](https://github.com/daverayment)!
- Added a global SettingsUtils singleton to reduce repeated initialization.
## Development
- Fixed broken devdocs links to the coding style guide. Thanks [@RubenFricke](https://github.com/RubenFricke)!
- Migrated main and installer solutions to .slnx for improved build tooling.
- Restored local installer builds after the WiX v5 upgrade with signing and versioning fixes.
- Added incremental review tooling and structured AI prompts for PR/issue reviews.
- Documented bot commands and cleaned up devdocs structure. Thanks [@noraa-junker](https://github.com/noraa-junker)!
- Updated WinAppSDK pipeline defaults to 1.8 and fixed restore handling.
- Updated the COMMUNITY list to reflect current roles.
- Maintained community member ordering and added a new entry.
- Re-enabled centralized PackageReference for native projects with VS auto-restore.
- Disabled MSBuild caching by default in CI to avoid build instability.
- Updated the latest WinAppSDK daily pipeline for split-dependency restores.
- Suppressed experimental build warnings and aligned WrapPanel stretch handling.
- Reordered the spell-check expect list for consistent automation.
- Migrated native projects to centralized PackageReference management.
- Cleaned spell-check dictionary entries and capitalization.
- Synced commit/PR prompts and wired VS Code to repo prompt files.
- Added VS Code build tasks and improved build script path handling.
- Updated Windows App SDK package versions in central package management.
- Migrated cmdpal extension native project to PackageReference and fixed outputs.
- Reverted PackageReference changes back to packages.config where needed.
- Bypassed a release version check for a failing DLL to keep pipelines green.
- Consolidated Copilot instructions and fixed prompt frontmatter.
- Added signing entries for new Quick Access binaries and CLI version metadata.
- Fixed install scope detection to avoid mixed per-user/per-machine installs.
- Added a Module Loader tool to quickly test PowerToys modules without full builds. Thanks [@mikehall-ms](https://github.com/mikehall-ms)!
- Added update telemetry to understand auto-update checks and downloads.
- Updated the telemetry package for new compliance requirements. Thanks [@carlos-zamora](https://github.com/carlos-zamora)!
- Documented missing telemetry events in DATA_AND_PRIVACY.
- Fixed UI test pipeline restores for .slnx solutions.
- Added UI automation coverage for Advanced Paste clipboard history flows.
- Stabilized FancyZones UI tests with more reliable selectors and screen recordings.
## 🛣️ Roadmap
We are planning some nice new features and improvements for the next releases PowerDisplay, Command Palette improvements and a brand-new Shortcut Guide experience! Stay tuned for [v0.98][github-next-release-work]!
## ❤️ PowerToys Community
The PowerToys team is extremely grateful to have the [support of an amazing active community][community-link]. The work you do is incredibly important. PowerToys wouldn't be nearly what it is today without your help filing bugs, updating documentation, guiding the design, or writing features. We want to say thank you and take time to recognize your work. Your contributions and feedback improve PowerToys month after month!
## Contributing
## Contributing
This project welcomes contributions of all types. Besides coding features / bug fixes, other ways to assist include spec writing, design, documentation, and finding bugs. We are excited to work with the power user community to build a set of tools for helping you get the most out of Windows. We ask that **before you start work on a feature that you would like to contribute**, please read our [Contributor's Guide](CONTRIBUTING.md). We would be happy to work with you to figure out the best approach, provide guidance and mentorship throughout feature development, and help avoid any wasted or duplicate effort. Most contributions require you to agree to a [Contributor License Agreement (CLA)][oss-CLA] declaring that you grant us the rights to use your contribution and that you have permission to do so. For guidance on developing for PowerToys, please read the [developer docs](./doc/devdocs) for a detailed breakdown. This includes how to setup your computer to compile.
This project welcomes contributions of all types. Besides coding features / bug fixes, other ways to assist include spec writing, design, documentation, and finding bugs. We are excited to work with the power user community to build a set of tools for helping you get the most out of Windows. We ask that **before you start work on a feature that you would like to contribute**, please read our [Contributor's Guide](CONTRIBUTING.md). We would be happy to work with you to figure out the best approach, provide guidance and mentorship throughout feature development, and help avoid any wasted or duplicate effort. Most contributions require you to agree to a [Contributor License Agreement (CLA)][oss-CLA] declaring that you grant us the rights to use your contribution and that you have permission to do so. For guidance on developing for PowerToys, please read the [developer docs](./doc/devdocs) for a detailed breakdown. This includes how to setup your computer to compile.
## Code of Conduct
This project has adopted the [Microsoft Open Source Code of Conduct][oss-conduct-code].
## Code of conduct
## Privacy Statement
The application logs basic diagnostic data (telemetry). For more privacy information and what we collect, see our [PowerToys Data and Privacy documentation](https://aka.ms/powertoys-data-and-privacy-documentation).
This project has adopted the [Microsoft Open Source Code of Conduct][oss-conduct-code].
## Privacy statement
The application logs basic diagnostic data (telemetry). For more privacy information and what we collect, see our [PowerToys Data and Privacy documentation](https://aka.ms/powertoys-data-and-privacy-documentation).
[oss-CLA]: https://cla.opensource.microsoft.com
[oss-conduct-code]: CODE_OF_CONDUCT.md
[community-link]: COMMUNITY.md
[github-next-release-work]: https://github.com/microsoft/PowerToys/issues?q=is%3Aissue+milestone%3A%22PowerToys+0.100%22
[oss-CLA]: https://cla.opensource.microsoft.com
[oss-conduct-code]: CODE_OF_CONDUCT.md
[community-link]: COMMUNITY.md
[github-release-link]: https://aka.ms/installPowerToys
[microsoft-store-link]: https://aka.ms/getPowertoys
[winget-link]: https://github.com/microsoft/winget-cli#installing-the-client
[roadmap]: https://github.com/microsoft/PowerToys/wiki/Roadmap
[privacy-link]: http://go.microsoft.com/fwlink/?LinkId=521839
[loc-bug]: https://github.com/microsoft/PowerToys/issues/new?assignees=&labels=&template=translation_issue.md&title=
[usingPowerToys-docs-link]: https://aka.ms/powertoys-docs

View File

@@ -1,36 +1,36 @@
<!-- BEGIN MICROSOFT SECURITY.MD V0.0.9 BLOCK -->
# Security
## Security
Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet) and [Xamarin](https://github.com/xamarin).
If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/security.md/definition), please report it to us as described below.
## Reporting security issues
## Reporting Security Issues
**Please do not report security vulnerabilities through public GitHub issues.**
Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/security.md/msrc/create-report).
If you prefer to submit without logging in, send an email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/security.md/msrc/pgp).
If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/security.md/msrc/pgp).
You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://www.microsoft.com/msrc).
You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://www.microsoft.com/msrc).
Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue:
- Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.)
- Full paths of source file(s) related to the manifestation of the issue
- The location of the affected source code (tag/branch/commit or direct URL)
- Any special configuration required to reproduce the issue
- Step-by-step instructions to reproduce the issue
- Proof-of-concept or exploit code (if possible)
- Impact of the issue, including how an attacker might exploit the issue
* Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.)
* Full paths of source file(s) related to the manifestation of the issue
* The location of the affected source code (tag/branch/commit or direct URL)
* Any special configuration required to reproduce the issue
* Step-by-step instructions to reproduce the issue
* Proof-of-concept or exploit code (if possible)
* Impact of the issue, including how an attacker might exploit the issue
This information will help us triage your report more quickly.
If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/security.md/msrc/bounty) page for more details about our active programs.
## Preferred languages
## Preferred Languages
We prefer all communications to be in English.

View File

@@ -1,21 +1,24 @@
# Support
## How to use Microsoft PowerToys
For more information about PowerToys overviews, how to use the utilities, and other tools and resources for [Windows development environments](https://learn.microsoft.com/windows/dev-environment/overview), visit [learn.microsoft.com][usingPowerToys-docs-link].
## How to use Microsoft PowerToys
For more info on [PowerToys overviews and how to use the utilities][usingPowerToys-docs-link], or any other tools and resources for [Windows development environments](https://learn.microsoft.com/windows/dev-environment/overview), head over to [learn.microsoft.com][usingPowerToys-docs-link]!
## How to file issues and get help
This project uses [GitHub Issues][gh-issue] to [track bugs][gh-bug] and [feature requests][gh-feature]. Please search the existing issues before filing new issues to avoid duplicates. For new issues, file your bug or feature request as a new issue.
This project uses [GitHub Issues][gh-issue] to [track bugs][gh-bug] and [feature requests][gh-feature]. Please search the existing issues before filing new issues to avoid duplicates. For new issues, file your bug or
feature request as a new Issue.
For help and questions about using this project, please visit our documentation and [Contributor's Guide][contributor] if you want to contribute to PowerToys.
For help and questions about using this project, please look at our Wiki for using PowerToys and our [Contributor's Guide][contributor] if you want to work on PowerToys.
## Microsoft support policy
## Microsoft Support Policy
Support for PowerToys is limited to the resources listed above.
[gh-issue]: https://github.com/microsoft/PowerToys/issues/new/choose
[gh-bug]: https://github.com/microsoft/PowerToys/issues/new?assignees=&labels=Issue-Bug&template=bug_report.md
[gh-feature]: https://github.com/microsoft/PowerToys/issues/new?assignees=&labels=&template=feature_request.md
[gh-bug]: https://github.com/microsoft/PowerToys/issues/new?assignees=&labels=Issue-Bug&template=bug_report.md&title=
[gh-feature]: https://github.com/microsoft/PowerToys/issues/new?assignees=&labels=&template=feature_request.md&title=
[wiki]: https://github.com/microsoft/PowerToys/wiki
[contributor]: https://github.com/microsoft/PowerToys/blob/main/CONTRIBUTING.md
[usingPowerToys-docs-link]: https://aka.ms/powertoys-docs

View File

@@ -1,54 +0,0 @@
# Auto-resolve cherry-pick conflicts
param([int]$MaxAttempts = 100)
$attempts = 0
while ($attempts -lt $MaxAttempts) {
$attempts++
# Check if cherry-pick is in progress
$status = git status --porcelain
if (-not $status) {
Write-Host "Cherry-pick complete!" -ForegroundColor Green
break
}
# Get conflicted files
$conflicts = git diff --name-only --diff-filter=U
if ($conflicts) {
Write-Host "Attempt $attempts`: Resolving conflicts..." -ForegroundColor Yellow
foreach ($file in $conflicts) {
Write-Host " Resolving: $file"
git checkout --ours $file 2>$null
}
# Handle deleted files
git status --short | Where-Object { $_ -match '^DU' } | ForEach-Object {
$file = ($_ -split '\s+', 2)[1]
Write-Host " Removing deleted: $file"
git rm $file 2>$null
}
git add . 2>$null
}
# Try to continue
$result = git cherry-pick --continue 2>&1
if ($LASTEXITCODE -eq 0) {
Write-Host " Continued successfully" -ForegroundColor Green
}
elseif ($result -match 'empty') {
Write-Host " Skipping empty commit" -ForegroundColor Cyan
git cherry-pick --skip 2>&1 | Out-Null
}
else {
Write-Host " Error: $result" -ForegroundColor Red
Start-Sleep -Seconds 1
}
}
if ($attempts -ge $MaxAttempts) {
Write-Host "Max attempts reached. Check status manually." -ForegroundColor Red
}

1
deps/expected-lite vendored Submodule

Submodule deps/expected-lite added at 95b9cb015f

7
deps/expected.props vendored Normal file
View File

@@ -0,0 +1,7 @@
<Project>
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>$(MSBuildThisFileDirectory)expected-lite\include\nonstd\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
</ItemDefinitionGroup>
</Project>

1
deps/spdlog vendored Submodule

Submodule deps/spdlog added at 616866fcf4

18
deps/spdlog.props vendored
View File

@@ -1,14 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<Project>
<!--
SPDLOG_* preprocessor defines for spdlog consumers. The actual vcpkg
integration (VcpkgEnabled, VcpkgRoot, triplet, manifest install) lives
in Cpp.Build.props; this file just carries the defines that match how
the pre-vcpkg in-tree build was configured.
-->
<ItemDefinitionGroup>
<ClCompile>
<PreprocessorDefinitions>SPDLOG_WCHAR_TO_UTF8_SUPPORT;SPDLOG_COMPILED_LIB;SPDLOG_WCHAR_FILENAMES;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>$(MSBuildThisFileDirectory)spdlog\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>SPDLOG_WCHAR_TO_UTF8_SUPPORT;SPDLOG_COMPILED_LIB;SPDLOG_WCHAR_FILENAMES;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
</ItemDefinitionGroup>
</Project>

View File

@@ -1,16 +0,0 @@
--- a/include/spdlog/fmt/bundled/format.h
+++ b/include/spdlog/fmt/bundled/format.h
@@ -354,7 +354,12 @@ inline typename Container::value_type* get_data(Container& c) {
return c.data();
}
-#if defined(_SECURE_SCL) && _SECURE_SCL
+// PowerToys: stdext::checked_array_iterator was deprecated in VS 2019 16.10
+// and removed entirely in MSVC 14.51 (compiler 19.51, _MSC_VER >= 1951;
+// see microsoft/STL STL4043). Skip the broken branch on those toolsets so the
+// pointer-based fallback below is used instead. Drop this guard once
+// deps/spdlog is bumped past v1.14 (which ships fmt 10.2 and removes this code).
+#if defined(_SECURE_SCL) && _SECURE_SCL && (!defined(_MSC_VER) || _MSC_VER < 1951)
// Make a checked iterator to avoid MSVC warnings.
template <typename T> using checked_ptr = stdext::checked_array_iterator<T*>;
template <typename T> checked_ptr<T> make_checked(T* p, size_t size) {

View File

@@ -1,43 +0,0 @@
# PowerToys overlay port for spdlog.
#
# Pinned to the same git commit that the deleted deps/spdlog submodule pointed
# at, so this is a 1:1 submodule->vcpkg migration with no version change
# (per the maintainer guidance: convert one submodule at a time, atomic
# commit, don't also bump the version).
#
# A single hunk patch works around MSVC 14.51 STL4043 (removal of
# stdext::checked_array_iterator) in spdlog's bundled fmt 7. Drop this overlay
# (and switch to upstream vcpkg's spdlog port) once PowerToys bumps spdlog
# past v1.14, which ships fmt 10.2 and removes the affected code path.
vcpkg_from_github(
OUT_SOURCE_PATH SOURCE_PATH
REPO gabime/spdlog
REF 616866fcf40340ea25a8f218369bad810ef58e72
SHA512 2076c527c7768627e6856b2f7ef663b185fd6251894cffd9299203d00f3d2de5696461060442dd72b96c9d3f0fd27f7f63ad2edfdf295e9b06c5fac6d6212faf
HEAD_REF v1.x
PATCHES
msvc-14.51-stdext-checked-array-iterator.patch
)
vcpkg_cmake_configure(
SOURCE_PATH "${SOURCE_PATH}"
OPTIONS
-DSPDLOG_BUILD_EXAMPLE=OFF
-DSPDLOG_BUILD_TESTS=OFF
-DSPDLOG_BUILD_BENCH=OFF
-DSPDLOG_FMT_EXTERNAL=OFF
-DSPDLOG_WCHAR_SUPPORT=ON
-DSPDLOG_WCHAR_FILENAMES=ON
-DSPDLOG_NO_EXCEPTIONS=OFF
-DSPDLOG_BUILD_SHARED=OFF
)
vcpkg_cmake_install()
vcpkg_cmake_config_fixup(PACKAGE_NAME spdlog CONFIG_PATH lib/cmake/spdlog)
vcpkg_fixup_pkgconfig()
vcpkg_copy_pdbs()
file(REMOVE_RECURSE "${CURRENT_PACKAGES_DIR}/debug/include")
vcpkg_install_copyright(FILE_LIST "${SOURCE_PATH}/LICENSE")

View File

@@ -1,18 +0,0 @@
{
"name": "spdlog",
"version-string": "1.8.5-pt-616866fc",
"port-version": 0,
"description": "Very fast, header-only/compiled, C++ logging library. PowerToys overlay pinned to gabime/spdlog@616866fc (the exact submodule commit before this migration), with a single-hunk patch that works around MSVC 14.51 removing stdext::checked_array_iterator (STL4043).",
"homepage": "https://github.com/gabime/spdlog",
"license": "MIT",
"dependencies": [
{
"name": "vcpkg-cmake",
"host": true
},
{
"name": "vcpkg-cmake-config",
"host": true
}
]
}

View File

@@ -97,10 +97,6 @@ The Shell Process Debugging Tool is a Visual Studio extension that helps debug m
- Check Event Viewer for application crashes related to `PowerToys.Settings.exe`
- Crash dumps can be obtained from Event Viewer
### Debugging Command Palette
Command Palette can be easily debugged using the solution filter in `src/modules/cmdpal/Command Palette.slnf`. This will open Command Palette as its own Visual Studio solution that can be run and debugged directly in Visual Studio without the need for the Shell Process Debugging Tool.
## Troubleshooting Build Errors
### Missing Image Files or Corrupted Build State

View File

@@ -56,7 +56,7 @@ After generating the resx file, rename the existing rc and h files to ProjName.b
</Target>
```
This event runs a script which generates a resource.h and ProjName.rc in the `Generated Files` folder using the strings in all the resx files along with the existing information in resource.base.h and ProjName.base.rc. The script is [convert-resx-to-rc.ps1](https://github.com/microsoft/PowerToys/blob/main/tools/build/convert-resx-to-rc.ps1). The script uses [`resgen`](https://learn.microsoft.com/dotnet/framework/tools/resgen-exe-resource-file-generator#Convert) to convert the resx file to a string table expected in the .rc file format. When the resources are added to the rc file the `IDS_` prefix is added and resource names are in uppercase (as it was originally). Any occurrences of `"` in the string resource is escaped as `""` to prevent build errors. The string tables are added to the rc file in the following format:
This event runs a script which generates a resource.h and ProjName.rc in the `Generated Files` folder using the strings in all the resx files along with the existing information in resource.base.h and ProjName.base.rc. The script is [convert-resx-to-rc.ps1](https://github.com/microsoft/PowerToys/blob/main/tools/build/convert-resx-to-rc.ps1). The script uses [`resgen`](https://learn.microsoft.com/dotnet/framework/tools/resgen-exe-resource-file-generator#Convert) to convert the resx file to a string table expected in the .rc file format. When the resources are added to the rc file the `IDS_` prefix is added and resource names are in upper case (as it was originally). Any occurrences of `"` in the string resource is escaped as `""` to prevent build errors. The string tables are added to the rc file in the following format:
```
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

View File

@@ -461,7 +461,7 @@ Editor read/write config data handler is in FancyZonesEditorCommon project.
FancyZones cpp project read/write config data handler is in FancyZonesLib project.
![Debug Step Image](../images/fancyzones/19.png)
However, the files read from and written to are those in `C:\Users\“xxxxxx”\AppData\Local\Microsoft\PowerToys\FancyZones`
However, the files write and read those are C:\Users\“xxxxxx”\AppData\Local\Microsoft\PowerToys\FancyZones
You can think of the editor as a visual config editor, which is most of its functionality. Another feature is used to set the layout for the monitor displays.

View File

@@ -0,0 +1,308 @@
# Keyboard Manager CmdPal Integration
## Goal
Expose Keyboard Manager mappings in Command Palette (`cmdpal`) through `ext.powertoys` with two separate user experiences:
- quick actions for executable mappings
- an inspection list for all current mappings
This should be done without introducing a new settings schema or a CmdPal-specific Keyboard Manager settings file.
The first scope should cover:
- Expose `Run Program` remaps as invokable CmdPal actions
- Expose `Open URI` remaps as invokable CmdPal actions
- Add one Keyboard Manager `List all mappings` command item
- List all current mappings on a dedicated Keyboard Manager page
- Make the primary interaction for a mapping item be inspection of what that mapping does
## Current State
The repository already contains most of the plumbing needed for this integration:
1. Keyboard Manager publishes actions through the module action surface in `src/modules/keyboardmanager/dll/dllmain.cpp`.
2. Runner aggregates module actions through `src/runner/action_registry.cpp` and exposes them over the existing named pipe consumed by `RunnerActionClient`.
3. The PowerToys CmdPal extension enumerates module commands through `src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.PowerToys/Helpers/ModuleCommandCatalog.cs`.
4. Keyboard Manager already has a provider in `src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.PowerToys/Modules/KeyboardManagerModuleCommandProvider.cs` that:
- shows the active-state toggle
- opens the new editor
- enumerates Runner actions with the `powertoys.keyboardManager.mapping.` prefix
- invokes them through `src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.PowerToys/Commands/KeyboardManager/InvokeKeyboardManagerCustomActionCommand.cs`
At the Keyboard Manager layer, only remappings backed by executable actions are currently turned into invokable actions:
- `Shortcut::IsRunProgram()`
- `Shortcut::IsOpenURI()`
This is implemented in `is_keyboard_manager_custom_action`, `append_mapping_actions`, and `invoke_keyboard_manager_custom_action` in `src/modules/keyboardmanager/dll/dllmain.cpp`.
The repository also already has read-side Keyboard Manager mapping logic in `src/modules/keyboardmanager/KeyboardManagerEditorUI/Interop/KeyboardMappingService.cs`, but that code lives inside the editor UI project and is not an appropriate dependency for `ext.powertoys`.
## Lightweight Design
### Design Decision
Split the design into two surfaces:
1. Executable mapping actions
2. Mapping inspection
Executable mapping actions stay centered on the existing Runner action registry.
Mapping inspection should use a dedicated read-only Keyboard Manager query service shared with CmdPal, following the existing `*.ModuleServices` pattern used by other modules.
Do not add:
- a new CmdPal-only data file
- a direct JSON parse of Keyboard Manager settings in `ext.powertoys`
- a UI-project dependency from `ext.powertoys` to `KeyboardManagerEditorUI`
- CmdPal-specific logic in the Keyboard Manager editor
### Why This Is The Right Shape
This matches the way other PowerToys modules integrate with CmdPal:
- module owns its state and execution semantics
- executable actions are published through a small action surface
- richer read-only data can be exposed through a shared service layer when the module needs inspection or navigation
This keeps the startup path lean and avoids duplicating Keyboard Manager parsing logic in `ext.powertoys`.
## Proposed Functional Model
### Surface A: Executable Actions
Keyboard Manager remains the source of truth for which mappings are eligible for direct invocation in CmdPal.
When `get_actions()` is called:
1. Load the current `MappingConfiguration`
2. Enumerate OS-level shortcut remaps
3. Enumerate app-specific shortcut remaps
4. Keep only remaps whose target operation is:
- `Run Program`
- `Open URI`
5. Emit one Runner action descriptor per eligible remap
### Identity For Executable Actions
Each action id remains derived from the remap identity:
- source shortcut
- exact-match flag
- app scope
- target operation type
- target payload fields
The current implementation uses a hashed identity under the prefix `powertoys.keyboardManager.mapping.`. That is acceptable for a lightweight design because:
- CmdPal does not need stable ids across edits beyond the current session
- the action id is regenerated from source-of-truth settings
- action invocation already re-resolves the action against current config and fails safely if the mapping no longer exists
### Invocation Of Executable Actions
CmdPal invokes the selected item through `RunnerActionClient.InvokeAction(actionId)`.
Keyboard Manager stays responsible for:
- launching programs
- open-existing-instance behavior
- elevation mode
- start-in directory
- window visibility
- URI/path normalization and shell execution
This is important because CmdPal should not duplicate Keyboard Manager's execution semantics.
### Surface B: All Mappings Inspection
CmdPal also needs one dedicated Keyboard Manager entry for inspecting every current mapping, not just executable ones.
That entry should be a top-level module item such as:
- `List Keyboard Manager mappings`
Its command should open a dedicated `KeyboardManagerMappingsPage`.
### Data Source For All Mappings
The `KeyboardManagerMappingsPage` should not be backed by Runner actions because Runner actions currently model invokable operations only.
Instead, add a small shared Keyboard Manager query layer, ideally as a module service project, for example:
- `src/modules/keyboardmanager/KeyboardManager.ModuleServices`
That shared service should reuse the existing native mapping query path already used by the editor and expose normalized read-only DTOs for CmdPal consumption.
The service should cover all current mapping categories:
- single key to key
- single key to shortcut
- single key to text
- shortcut to shortcut
- shortcut to program
- shortcut to URI
- app-specific shortcut mappings
### Interaction Model For The Mappings Page
The mappings page should behave like an inspection page first, not an execution page first.
Recommended interaction:
1. `KeyboardManagerMappingsPage` is a `DynamicListPage` or `ListPage` with `ShowDetails = true`
2. Each mapping is rendered as a `ListItem` with rich `Details`
3. Selecting a mapping shows what it maps to
4. Invoking the item opens a small `KeyboardManagerMappingDetailsPage` or equivalent detail-focused page
5. Executable mappings may expose an extra command such as `Run now` or `Open now`, but that should not be the primary action on the inspection page
This satisfies the requirement that the primary action for a mapping entry is to show what the mapping is, while still leaving room for execution when the mapping type supports it.
### Presentation In CmdPal
Within `ext.powertoys`, the Keyboard Manager provider should emit these command groups:
1. Keyboard Manager state commands
- toggle active state
- open editor
2. Keyboard Manager inspection commands
- `List Keyboard Manager mappings`
3. Keyboard Manager quick actions
- `Run Program` entries
- `Open URI` entries
4. Keyboard Manager settings
- open settings
## UX Guidance
The minimum viable experience is:
- searchable by trigger or target
- clearly labeled as Keyboard Manager actions or mappings
- capable of both inspection and direct execution for supported mapping types
Recommended presentation rules:
1. The `List Keyboard Manager mappings` item should use the Keyboard Manager icon and clearly signal it opens a list, not an action.
2. Mapping list titles should prioritize the trigger:
- `Ctrl+Alt+N`
- `Caps Lock`
3. Mapping list subtitles should say what the trigger maps to:
- `Opens notepad.exe`
- `Maps to Ctrl+C`
- `Types Hello world`
4. Mapping details should carry the rest of the context:
- global vs app-specific
- mapping kind
- target payload
- execution-specific options when relevant
5. Quick-action titles can continue to prioritize the executable action:
- `Run notepad.exe`
- `Open https://contoso.com`
6. Keyboard Manager module icon is sufficient for the first version
The current implementation already covers the quick-action portion. The new work is primarily the all-mappings inspection surface.
## Non-Goals For The First Version
Do not add these in the initial pass:
- editing Keyboard Manager mappings from CmdPal
- enabling or disabling individual mappings from CmdPal
- live push notifications when mappings change
- custom icons per program or URI
- a new `kbm:` command syntax or dedicated parser
These all increase complexity without being necessary to validate the feature.
## Integration Pattern Compared To Other Modules
This feature now combines two existing CmdPal integration styles.
- `Workspaces` loads module-owned data and emits one command per data item
- `FancyZones` uses dedicated pages and details for richer inspection
Keyboard Manager quick actions should follow the lighter `Workspaces` pattern:
- one provider
- one flat list of dynamic items
- generic command invocation
Keyboard Manager all-mappings inspection should follow the `list page with details` pattern already supported by CmdPal:
- one top-level entry that opens a page
- one list item per mapping
- rich `Details` on every row
- optional secondary commands for invokable mappings
The main constraint is the same in both paths: `ext.powertoys` should not duplicate Keyboard Manager's mapping schema by parsing the settings file directly.
## Error Handling
The existing executable-action behavior is the correct baseline:
- hidden or deleted mappings simply disappear from `list_actions`
- stale CmdPal entries fail through `action_not_found`
- disabled Keyboard Manager returns `module_unavailable`
- launch failures return module-defined error messages
CmdPal only needs to surface the returned message as toast text for quick actions.
For the all-mappings inspection page:
- malformed or unreadable mapping snapshots should yield an empty page or an inline error item
- missing targets should still render as mappings, but be tagged as invalid or unavailable
- details rendering should degrade gracefully when optional fields are absent
## Risks
### Two Data Paths
This design intentionally uses two integration paths:
- Runner actions for invokable mappings
- a shared read-only query service for all mappings
That is acceptable because the two paths serve different UX needs. The risk is manageable as long as both paths derive from the same Keyboard Manager mapping model rather than separate ad hoc parsers.
### Duplicate Or Ambiguous Entries
Different mappings may produce similar titles, especially on the quick-action side. This is acceptable in the first iteration because the subtitle already carries scope and trigger details.
### Action Id Churn After Edits
Editing a mapping changes the derived id. This is acceptable because action ids are not a persisted public contract.
### Large Mapping Sets
Very large mapping sets could make the inspection page noisy. This is manageable for the first version if the page supports search and details, but sectioning or filters may be needed later.
## Minimal Implementation Plan
1. Keep Keyboard Manager as the producer of invokable mapping actions.
2. Keep Runner action registry as the discovery path for executable quick actions.
3. Add a small shared read-only Keyboard Manager module service for enumerating all mappings.
4. Add `List Keyboard Manager mappings` to `KeyboardManagerModuleCommandProvider`.
5. Add a `KeyboardManagerMappingsPage` with `ShowDetails = true`.
6. Represent each mapping as an inspection-first `ListItem` with rich `Details`.
7. Add optional secondary execution commands only for mappings that are invokable.
8. Add focused tests around:
- Keyboard Manager action enumeration for `Run Program` and `Open URI`
- mapping snapshot enumeration across all mapping kinds
- CmdPal rendering of the mappings page
- graceful handling of stale, invalid, or missing mappings
## Future Extensions
If the first version lands well, the next step should still preserve the same split architecture:
- enrich action descriptors with more metadata if Runner actions grow argument or icon support
- add sections or filters to the mappings page when the list becomes large
- optionally expose app-specific filtering in CmdPal UI
The extension points should remain:
- Runner actions for execution
- a shared Keyboard Manager query service for inspection

View File

@@ -3,9 +3,9 @@
- [ ] The plugin is a project under `modules\launcher\Plugins`
- [ ] Microsoft plugin project name pattern: `Microsoft.PowerToys.Run.Plugin.{PluginName}`
- [ ] Community plugin project name pattern: `Community.PowerToys.Run.Plugin.{PluginName}`
- [ ] The plugin target framework should be `net10.0-windows10.0.22621.0`
- [ ] The plugin target framework should be `net9.0-windows10.0.22621.0`
- [ ] If the plugin uses any 3rd party dependencies the project file should import `DynamicPlugin.props`
- [ ] 3rd party dependencies must be compatible with .NET 10
- [ ] 3rd party dependencies must be compatible with .NET 9
- [ ] The plugin has to contain a `plugin.json` file of the following format in its root folder:
```json

View File

@@ -75,7 +75,7 @@ There are three different score types with different start values.
| Medium score | 5000 |
| Low score | 1000 |
Each score will be decreased by one when a condition match.
Each score will decreased by one when a condition match.
| Priority | Condition | Score type |
| -------- | ----------------------------------------------------------------- | ------------ |
@@ -134,7 +134,7 @@ The plugin use only these interfaces (all inside the `Main.cs`):
| `plugin.json` | All meta-data for this plugin |
1. We need this extra wrapper class to make it possible that the JSON file can have and use a JSON schema file.
Because the JSON file must have an object as root type, instead of an array.
Because the JSON file must have a object as root type, instead of a array.
### Important project values (*.csproj)

View File

@@ -9,14 +9,12 @@
[Pull Requests](https://github.com/microsoft/PowerToys/pulls?q=is%3Apr+is%3Aopen+label%3A%22Product-Shortcut+Guide%22+)
## Overview
Shortcut Guide is a PowerToy that displays an overlay of available keyboard shortcuts when a user-set keyboard shortcut is pressed. It helps users discover and remember keyboard shortcuts for Windows and apps.
> [!NOTE]
> The spec for the manifest files is in development and will be linked here once available.
Shortcut Guide is a PowerToy that displays an overlay of available keyboard shortcuts when the Windows key is pressed and held. It provides a visual reference for Windows key combinations, helping users discover and utilize built-in Windows shortcuts.
## Usage
- Press the user-defined hotkey to display the overlay
- Press the hotkey again or press ESC to dismiss the overlay
- Press and hold the Windows key to display the overlay of available shortcuts
- Press the hotkey again to dismiss the overlay
- The overlay displays Windows shortcuts with their corresponding actions
## Build and Debug Instructions
@@ -27,89 +25,67 @@ Shortcut Guide is a PowerToy that displays an overlay of available keyboard shor
4. The executable is named PowerToys.ShortcutGuide.exe
### Debug
1. Right-click the ShortcutGuide.Ui project and select 'Set as Startup Project'
1. Right-click the ShortcutGuide project and select 'Set as Startup Project'
2. Right-click the project again and select 'Debug'
> [!NOTE]
> When run in debug mode, the window behaves differently than in release mode. It will not automatically close when loosing focus, it will be displayed on top of all other windows, and it is not hidden from the taskbar.
## Code Structure
## Project Structure
![Diagram](../images/shortcutguide/diagram.png)
The Shortcut Guide module consists of the following 4 projects:
### Core Files
### [`ShortcutGuide.Ui`](/src/modules/ShortcutGuide/ShortcutGuide.Ui/ShortcutGuide.Ui.csproj
#### [`dllmain.cpp`](/src/modules/shortcut_guide/dllmain.cpp)
Contains DLL boilerplate code. Implements the PowertoyModuleIface, including enable/disable functionality and GPO policy handling. Captures hotkey events and starts the PowerToys.ShortcutGuide.exe process to display the shortcut guide window.
This is the main UI project for the Shortcut Guide module. Upon startup it does the following tasks:
#### [`shortcut_guide.cpp`](/src/modules/shortcut_guide/shortcut_guide.cpp)
Contains the module interface code. It initializes the settings values and the keyboard event listener. Defines the OverlayWindow class, which manages the overall logic and event handling for the PowerToys Shortcut Guide.
1. Copies the built-in manifest files to the users manifest directory (overwriting existing files).
2. Generate the `index.yml` manifest file.
3. Populate the PowerToys shortcut manifest with the user-defined shortcuts.
4. Starts the UI.
#### [`overlay_window.cpp`](/src/modules/shortcut_guide/overlay_window.cpp)
Contains the code for loading the SVGs, creating and rendering of the overlay window. Manages and displays overlay windows with SVG graphics through two main classes:
- D2DOverlaySVG: Handles loading, resizing, and manipulation of SVG graphics
- D2DOverlayWindow: Manages the display and behavior of the overlay window
### Related files in PowerToys.Interop
#### [`keyboard_state.cpp`](/src/modules/shortcut_guide/keyboard_state.cpp)
Contains helper methods for checking the current state of the keyboard.
#### [`excluded_app.cpp`](/src/modules/ShortcutGuide/ShortcutGuide.CPPProject/excluded_app.cpp)
#### [`target_state.cpp`](/src/modules/shortcut_guide/target_state.cpp)
State machine that handles the keyboard events. It's responsible for deciding when to show the overlay, when to suppress the Start menu (if the overlay is displayed long enough), etc. Handles state transitions and synchronization to ensure the overlay is shown or hidden appropriately based on user interactions.
This file contains one function with the following signature:
#### [`trace.cpp`](/src/modules/shortcut_guide/trace.cpp)
Contains code for telemetry.
```cpp
__declspec(dllexport) bool IsCurrentWindowExcludedFromShortcutGuide()
```
### Supporting Files
This function checks if the current window is excluded from the Shortcut Guide overlay. It returns `true` if the current window is excluded otherwise it returns `false`.
#### [`animation.cpp`](/src/modules/shortcut_guide/animation.cpp)
Handles the timing and interpolation of animations. Calculates the current value of an animation based on elapsed time and a specified easing function.
#### [`tasklist_positions.cpp`](/src/modules/ShortcutGuide/ShortcutGuide.CPPProject/tasklist_positions.cpp)
#### [`d2d_svg.cpp`](/src/modules/shortcut_guide/d2d_svg.cpp)
Provides functionality for loading, resizing, recoloring, rendering, and manipulating SVG images using Direct2D.
This file contains helper functions to retrieve the positions of the taskbar buttons. It exports the following function:
#### [`d2d_text.cpp`](/src/modules/shortcut_guide/d2d_text.cpp)
Handles creation, resizing, alignment, and rendering of text using Direct2D and DirectWrite.
```cpp
__declspec(dllexport) TasklistButton* get_buttons(HMONITOR monitor, int* size)
```
#### [`d2d_window.cpp`](/src/modules/shortcut_guide/d2d_window.cpp)
Manages a window using Direct2D and Direct3D for rendering. Handles window creation, resizing, rendering, and destruction.
This function retrieves the positions of the taskbar buttons for a given monitor. It returns an array of `TasklistButton` structures (max 10), which contain the position and size of each button.
#### [`native_event_waiter.cpp`](/src/modules/shortcut_guide/native_event_waiter.cpp)
Waits for a named event and executes a specified action when the event is triggered. Uses a separate thread to handle event waiting and action execution.
`monitor` must be the monitor handle of the monitor containing the taskbar instance of which the buttons should be retrieved.
#### [`tasklist_positions.cpp`](/src/modules/shortcut_guide/tasklist_positions.cpp)
Handles retrieving and updating the positions and information of taskbar buttons in Windows.
`size` will contain the resulting array size.
It determines the positions through Windows `FindWindowEx` function.
For the primary taskbar it searches for:
* A window called "Shell_TrayWnd"
* that contains a window called "ReBarWindow32"
* that contains a window called "MSTaskSwWClass"
* that contains a window called "MSTaskListWClass"
For any secondary taskbar it searches for:
* A window called "Shell_SecondaryTrayWnd"
* that contains a window called "WorkerW"
* that contains a window called "MSTaskListWClass"
It then enumerates all the button elements inside "MSTaskListWClass" while skipping such with a same name (which implies the user does not use combining taskbar buttons)
If this method fails, which it will for newer versions of Windows, it falls back to searching for:
* A window called "Shell_TrayWnd" or "Shell_SecondaryTrayWnd"
* that contains a window called "Windows.UI.Composition.DesktopWindowContentBridge"
* that contains a window called "Windows.UI.Input.InputSite.WindowClass"
* the first child element
It then enumerates all the button elements inside the selected while skipping such with a same name (which implies the user does not use combining taskbar buttons) and such that do not start with "Appid:" (which are not actual taskbar buttons related to apps, but others like the widgets or the search button).
### [`ShortcutGuide.IndexYmlGenerator`](/src/modules/ShortcutGuide/ShortcutGuide.IndexYmlGenerator/)
This application generates the `index.yml` manifest file.
It is a separate project so that its code can be easier ported to WinGet in the future.
### [`ShortcutGuideModuleInterface`](/src/modules/ShortcutGuide/ShortcutGuideModuleInterface/ShortcutGuideModuleInterface.vcxproj)
The module interface that handles opening and closing the user interface.
#### [`main.cpp`](/src/modules/shortcut_guide/main.cpp)
The entry point for the PowerToys Shortcut Guide application. Handles initialization, ensures single instance execution, manages parent process termination, creates and displays the overlay window, and runs the main event loop.
## Features and Limitations
- Currently the displayed shortcuts (Except the ones from PowerToys) are not localized.
- The overlay displays Windows shortcuts (Windows key combinations)
- The module supports localization, but only for the Windows controls on the left side of the overlay
- It's currently rated as a P3 (lower priority) module
## Future Development
- Implementing with WinGet to get new shortcut manifest files
- Adding localization support for the built-in manifest files
A community-contributed version 2 is in development that will support:
- Application-specific shortcuts based on the active application
- Additional shortcuts beyond Windows key combinations
- PowerToys shortcuts

View File

@@ -1,93 +0,0 @@
# PowerToys Installer & Update Diagnostics
A step-by-step guide for diagnosing installer and update issues reported by users.
## Quick Reference: Key Files
| File/Folder | Path | Contains |
|---|---|---|
| UpdateState.json | `%LOCALAPPDATA%\Microsoft\PowerToys\UpdateState.json` | Persisted update state machine |
| Runner logs | `%LOCALAPPDATA%\Microsoft\PowerToys\RunnerLogs\runner-log_*.log` | Startup, update checks, cleanup |
| Update logs | `%LOCALAPPDATA%\Microsoft\PowerToys\UpdateLogs\update-log_*.log` | PowerToys.Update.exe activity |
| Updates folder | `%LOCALAPPDATA%\Microsoft\PowerToys\Updates\` | Downloaded installer files |
> **Note:** These paths use `%LOCALAPPDATA%` (per-user AppData) regardless of whether PowerToys was installed per-user or per-machine. The data/settings location is always per-user.
## Update State Values
From `src/common/updating/updateState.h` (`UpdateState::State` enum):
| Value | Name | Meaning |
|---|---|---|
| 0 | upToDate | No update needed |
| 1 | errorDownloading | Download or install failed, will retry |
| 2 | readyToDownload | New version found, not yet downloaded |
| 3 | readyToInstall | Installer downloaded, waiting for user action |
| 4 | networkError | GitHub API call failed |
---
## Symptom: Old update installers accumulating on disk
### What to ask the user for
1. Contents of `UpdateState.json`
2. Runner logs (last few days from `RunnerLogs\`)
3. Update logs (from `UpdateLogs\`, if they exist)
4. List of files in `Updates\` folder (names + sizes)
### Step 1: Check the running version
In runner logs, look for the startup line:
```
[info] Scoobe: product_version=v0.XX.X last_version_run=v0.XX.X
```
- **If version < v0.73.0**: The pre-download cleanup (PR #27908) is missing. Each downloaded installer accumulates because cleanup only runs at startup when state is `upToDate`. Ask the user to manually upgrade to the latest version.
- **If version >= v0.73.0**: The pre-download cleanup exists. Accumulation should not happen under normal conditions. Continue to Step 2.
### Step 2: Check UpdateState.json
```jsonc
{"state": 3, "downloadedInstallerFilename": "powertoyssetup-0.98.1-x64.exe" /* additional fields may be present */}
```
- **state = 0 (upToDate)**: Cleanup should run at startup. If files are accumulating, check runner logs for "Failed to delete" warnings (Step 4).
- **state = 3 (readyToInstall)**: An installer is downloaded but never installed. Cleanup at startup is skipped (by design, to preserve the pending installer). On v0.73+, cleanup can still occur when a future update check triggers a new download (pre-download cleanup path).
- **state = 1 (errorDownloading)**: A previous download or install failed. Startup cleanup is skipped (state is not `upToDate`). On v0.73+, cleanup runs before the next installer download is attempted.
- **state = 2 or 4**: Startup cleanup is skipped. On v0.73+, cleanup runs before the next installer download is attempted.
### Step 3: Check if PowerToys.Update.exe has ever run
- **UpdateLogs directory missing**: This suggests `PowerToys.Update.exe` may never have been launched, or it did not progress far enough to create logs. The user may never have triggered an install, or Stage 1 may have failed before Stage 2 could run.
- **UpdateLogs exist but show only "logger is initialized"**: The exe launched but the command-line argument didn't match any action (possible argument parsing issue).
- **UpdateLogs show install activity**: The update process ran. Check for success/failure.
### Step 4: Check runner logs for cleanup evidence
Search for these patterns:
| Log pattern | Meaning |
|---|---|
| `Failed to delete installer file ... Access is denied` | File locked by AV, another process, or permissions issue |
| `Failed to delete log file ...` | Same, for old log files |
| `Discovered new version` | Periodic update check ran |
| `New version is already downloaded` | State is `readyToInstall` and filename matches — no re-download, no cleanup |
| No cleanup-related entries at all | Inconclusive by itself — `cleanup_updates()` is silent on success. Corroborate with the Updates folder contents (Step 5) and the running version (Step 1). |
### Step 5: Check the Updates folder contents
- **All different versions**: Cleanup likely did not run across multiple update cycles. Confirm with the running version (Step 1) and update state before concluding a state gate issue.
- **Duplicate filenames**: Unusual — would suggest repeated download without cleanup.
- **Single file matching `downloadedInstallerFilename`**: Normal for `readyToInstall` state.
### Common root causes
| Root cause | Evidence | Fix |
|---|---|---|
| Running pre-v0.73.0 binary | `product_version` < v0.73.0 in runner log | Manually upgrade to latest |
| State stuck at `readyToInstall` (pre-v0.73) | `"state": 3` in UpdateState.json, no UpdateLogs | Manually upgrade to latest |
| File lock preventing deletion | "Failed to delete ... Access is denied" in runner logs | Check AV software, reboot and retry |
| Update installer never launched | No UpdateLogs directory | Check if update notifications are disabled by GPO or setting |
| Install fails silently | UpdateLogs show init but no install activity | Check related issues: #46966, #46967, #46969 |

83
doc/dsc/Settings.md Normal file
View File

@@ -0,0 +1,83 @@
# Settings resource
Manage the settings for PowerToys modules
## Commands
### ✨ Modules
List all the modules supported by the settings resource.
```shell
PS C:\> PowerToys.DSC.exe modules --resource 'settings'
AdvancedPaste
AlwaysOnTop
App
Awake
ColorPicker
CropAndLock
EnvironmentVariables
FancyZones
FileLocksmith
FindMyMouse
Hosts
ImageResizer
KeyboardManager
MeasureTool
MouseHighlighter
MouseJump
MousePointerCrosshairs
Peek
PowerAccent
PowerOCR
PowerRename
RegistryPreview
ShortcutGuide
Workspaces
ZoomIt
```
### 📄 Get
Get the settings for a specific module.
```shell
PS C:\> PowerToys.DSC.exe get --resource 'settings' --module EnvironmentVariables
{"settings":{"properties":{"LaunchAdministrator":{"value":true}},"name":"EnvironmentVariables","version":"1.0"}}
```
### 🖨️ Export
Export the settings for a specific module.
Settings resource Get and Export operation output states are identical.
```shell
PS C:\> PowerToys.DSC.exe get --resource 'settings' --module EnvironmentVariables
{"settings":{"properties":{"LaunchAdministrator":{"value":true}},"name":"EnvironmentVariables","version":"1.0"}}
```
### 📝 Set
Set the settings for a specific module. This command will update the settings to the specified values.
```shell
PS C:\> PowerToys.DSC.exe set --resource 'settings' --module Awake --input '{"settings":{"properties":{"keepDisplayOn":false,"mode":0,"intervalHours":0,"intervalMinutes":1,"expirationDateTime":"2025-08-13T10:10:00.000001-07:00","customTrayTimes":{}},"name":"Awake","version":"0.0.1"}}'
{"settings":{"properties":{"keepDisplayOn":false,"mode":0,"intervalHours":0,"intervalMinutes":1,"expirationDateTime":"2025-08-13T10:10:00.000001-07:00","customTrayTimes":{}},"name":"Awake","version":"0.0.1"}}
["settings"]
```
### 🧪 Test
Test the settings for a specific module. This command will check if the current settings match the desired state.
```shell
PS C:\> PowerToys.DSC.exe test --resource 'settings' --module Awake --input '{"settings":{"properties":{"keepDisplayOn":false,"mode":0,"intervalHours":0,"intervalMinutes":1,"expirationDateTime":"2025-08-13T10:10:00.000002-07:00","customTrayTimes":{}},"name":"Awake","version":"0.0.1"}}'
{"settings":{"properties":{"keepDisplayOn":false,"mode":0,"intervalHours":0,"intervalMinutes":1,"expirationDateTime":"2025-08-13T10:10:00.000001-07:00","customTrayTimes":{}},"name":"Awake","version":"0.0.1"},"_inDesiredState":false}
["settings"]
```
### 🛠️ Schema
Generates the JSON schema for the settings resource of a specific module.
```shell
PS C:\> PowerToys.DSC.exe schema --resource 'settings' --module Awake
{"$schema":"http://json-schema.org/draft-04/schema#","title":"SettingsResourceObjectOfAwakeSettings","type":"object","additionalProperties":false,"required":["settings"],"properties":{"_inDesiredState":{"type":["boolean","null"],"description":"Indicates whether an instance is in the desired state"},"settings":{"description":"The settings content for the module."}}}
PS E:\src\powertoys> PowerToys.DSC.exe schema --resource 'settings' --module Awake | Format-Json
```
### 📦 Manifest
Generates a manifest dsc resource JSON file for the specified module.
- If the module is not specified, it will generate a manifest for all modules.
- If the output directory is not specified, it will print the manifest to the console.
```shell
PS C:\> PowerToys.DSC.exe manifest --resource settings --module 'Awake' --outputDir "C:\manifests"
```

View File

@@ -1,263 +0,0 @@
---
description: DSC configuration reference for PowerToys AdvancedPaste module
ms.date: 10/18/2025
ms.topic: reference
title: AdvancedPaste Module
---
# AdvancedPaste Module
## Synopsis
Manages configuration for the Advanced Paste utility, which provides advanced clipboard operations and custom paste formats.
## Description
The `AdvancedPaste` module configures PowerToys Advanced Paste, a utility
that extends clipboard functionality with AI-powered transformations, custom
formats, and advanced paste options. It allows you to paste clipboard content
with transformations like plain text conversion, markdown formatting, JSON
formatting, and AI-based text processing.
## Properties
The AdvancedPaste module supports the following configurable properties:
### IsAdvancedAIEnabled
Controls whether AI-powered paste transformations are enabled.
**Type:** boolean
**Default:** `false`
**Description:** Enables AI-based clipboard transformations such as
summarization, translation, and content reformatting.
### PasteAsPlainTextHotkey
Sets the keyboard shortcut for pasting as plain text.
**Type:** object
**Properties:**
- `win` (boolean) - Windows key modifier.
- `ctrl` (boolean) - Ctrl key modifier.
- `alt` (boolean) - Alt key modifier.
- `shift` (boolean) - Shift key modifier.
- `code` (integer) - Virtual key code.
- `key` (string) - Key name.
**Default:** `Ctrl+Win+V`
### PasteAsMarkdownHotkey
Sets the keyboard shortcut for pasting as markdown.
**Type:** object (same structure as PasteAsPlainTextHotkey)
**Default:** `Ctrl+Win+Shift+V`
### PasteAsJsonHotkey
Sets the keyboard shortcut for pasting as JSON.
**Type:** object (same structure as PasteAsPlainTextHotkey)
### ShowCustomPreview
Controls whether a preview window is shown before pasting custom formats.
**Type:** boolean
**Default:** `true`
### CloseAfterLosingFocus
Controls whether the Advanced Paste window closes when it loses focus.
**Type:** boolean
**Default:** `false`
## Examples
### Example 1 - Enable AI features with direct execution
This example enables AI-powered paste transformations.
```powershell
$config = @{
settings = @{
properties = @{
IsAdvancedAIEnabled = $true
}
name = "AdvancedPaste"
version = "1.0"
}
} | ConvertTo-Json -Depth 10 -Compress
PowerToys.DSC.exe set --resource 'settings' --module AdvancedPaste `
--input $config
```
### Example 2 - Configure paste hotkeys with DSC
This example customizes keyboard shortcuts for different paste formats.
```bash
dsc config set --file advancedpaste-hotkeys.dsc.yaml
```
```yaml
# advancedpaste-hotkeys.dsc.yaml
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
resources:
- name: Configure Advanced Paste hotkeys
type: Microsoft.PowerToys/AdvancedPasteSettings
properties:
settings:
properties:
PasteAsPlainTextHotkey:
win: true
ctrl: true
alt: false
shift: false
code: 86
key: V
PasteAsMarkdownHotkey:
win: true
ctrl: true
alt: false
shift: true
code: 86
key: V
name: AdvancedPaste
version: 1.0
```
### Example 3 - Install and configure with WinGet
This example installs PowerToys and configures Advanced Paste with AI
enabled.
```bash
winget configure winget-advancedpaste.yaml
```
```yaml
# winget-advancedpaste.yaml
$schema: https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2023/08/config/document.json
metadata:
winget:
processor: dscv3
resources:
- name: Install PowerToys
type: Microsoft.WinGet.DSC/WinGetPackage
properties:
id: Microsoft.PowerToys
source: winget
- name: Configure Advanced Paste
type: Microsoft.PowerToys/AdvancedPasteSettings
properties:
settings:
properties:
IsAdvancedAIEnabled: true
ShowCustomPreview: true
CloseAfterLosingFocus: true
name: AdvancedPaste
version: 1.0
```
### Example 4 - Enable with custom preview settings
This example configures preview behavior for custom paste formats.
```bash
dsc config set --file advancedpaste-preview.dsc.yaml
```
```yaml
# advancedpaste-preview.dsc.yaml
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
resources:
- name: Configure preview settings
type: Microsoft.PowerToys/AdvancedPasteSettings
properties:
settings:
properties:
ShowCustomPreview: true
CloseAfterLosingFocus: false
name: AdvancedPaste
version: 1.0
```
### Example 5 - Test AI enablement
This example tests whether AI features are enabled.
```powershell
$desired = @{
settings = @{
properties = @{
IsAdvancedAIEnabled = $true
}
name = "AdvancedPaste"
version = "1.0"
}
} | ConvertTo-Json -Depth 10 -Compress
$result = PowerToys.DSC.exe test --resource 'settings' `
--module AdvancedPaste --input $desired | ConvertFrom-Json
if ($result._inDesiredState) {
Write-Host "AI features are enabled"
} else {
Write-Host "AI features need to be enabled"
}
```
## Use cases
### Development workflow
Enable AI transformations for code snippets and documentation:
```yaml
resources:
- name: Developer paste settings
type: Microsoft.PowerToys/AdvancedPasteSettings
properties:
settings:
properties:
IsAdvancedAIEnabled: true
ShowCustomPreview: true
name: AdvancedPaste
version: 1.0
```
### Content creation
Configure for markdown and formatted text operations:
```yaml
resources:
- name: Content creator settings
type: Microsoft.PowerToys/AdvancedPasteSettings
properties:
settings:
properties:
ShowCustomPreview: true
CloseAfterLosingFocus: false
name: AdvancedPaste
version: 1.0
```
## See also
- [Settings Resource][01]
- [PowerToys DSC Overview][02]
- [ColorPicker Module][03] - System-wide color picker utility
- [PowerToys Advanced Paste Documentation][04]
<!-- Link reference definitions -->
[01]: ../settings-resource.md
[02]: ../overview.md
[03]: ./ColorPicker.md
[04]: https://learn.microsoft.com/windows/powertoys/advanced-paste

View File

@@ -1,299 +0,0 @@
---
description: DSC configuration reference for PowerToys AlwaysOnTop module
ms.date: 10/18/2025
ms.topic: reference
title: AlwaysOnTop Module
---
# AlwaysOnTop Module
## Synopsis
Manages configuration for the Always On Top utility, which pins windows to stay on top of other windows.
## Description
The `AlwaysOnTop` module configures PowerToys Always On Top, a utility that
allows you to pin any window to remain visible above all other windows. This
is useful for keeping reference materials, chat windows, or monitoring tools
visible while working with other applications.
## Properties
The AlwaysOnTop module supports the following configurable properties:
### Hotkey
Sets the keyboard shortcut to toggle Always On Top for the active window.
**Type:** object
**Properties:**
- `win` (boolean) - Windows key modifier.
- `ctrl` (boolean) - Ctrl key modifier.
- `alt` (boolean) - Alt key modifier.
- `shift` (boolean) - Shift key modifier.
- `code` (integer) - Virtual key code.
- `key` (string) - Key name.
**Default:** `Win+Ctrl+T`
### FrameEnabled
Controls whether a colored border is displayed around pinned windows.
**Type:** boolean
**Default:** `true`
### FrameThickness
Sets the thickness of the border around pinned windows (in pixels).
**Type:** integer
**Range:** `1` to `100`
**Default:** `5`
### FrameColor
Sets the color of the border around pinned windows.
**Type:** string (hex color)
**Format:** `"#RRGGBB"`
**Default:** `"#FF0000"` (red)
### FrameOpacity
Sets the opacity of the border (0-100).
**Type:** integer
**Range:** `0` to `100`
**Default:** `100`
### FrameAccentColor
Controls whether to use the Windows accent color for the frame.
**Type:** boolean
**Default:** `false`
### SoundEnabled
Controls whether a sound plays when toggling Always On Top.
**Type:** boolean
**Default:** `false`
### DoNotActivateOnGameMode
Controls whether Always On Top is automatically disabled during game mode.
**Type:** boolean
**Default:** `true`
### RoundCornersEnabled
Controls whether the frame has rounded corners.
**Type:** boolean
**Default:** `true`
### ExcludedApps
List of applications excluded from Always On Top functionality.
**Type:** string (newline-separated list of executable names)
## Examples
### Example 1 - Enable with default settings using direct execution
This example enables Always On Top with default border appearance.
```powershell
$config = @{
settings = @{
properties = @{
FrameEnabled = $true
FrameThickness = 5
FrameColor = "#FF0000"
FrameOpacity = 100
}
name = "AlwaysOnTop"
version = "1.0"
}
} | ConvertTo-Json -Depth 10 -Compress
PowerToys.DSC.exe set --resource 'settings' --module AlwaysOnTop `
--input $config
```
### Example 2 - Customize frame appearance with DSC
This example configures a custom border color and thickness.
```bash
dsc config set --file alwaysontop-appearance.dsc.yaml
```
```yaml
# alwaysontop-appearance.dsc.yaml
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
resources:
- name: Customize Always On Top frame
type: Microsoft.PowerToys/AlwaysOnTopSettings
properties:
settings:
properties:
FrameEnabled: true
FrameThickness: 8
FrameColor: "#0078D7"
FrameOpacity: 80
RoundCornersEnabled: true
name: AlwaysOnTop
version: 1.0
```
### Example 3 - Configure with accent color using WinGet
This example installs PowerToys and configures Always On Top to use the
Windows accent color.
```bash
winget configure winget-alwaysontop.yaml
```
```yaml
# winget-alwaysontop.yaml
$schema: https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2023/08/config/document.json
metadata:
winget:
processor: dscv3
resources:
- name: Install PowerToys
type: Microsoft.WinGet.DSC/WinGetPackage
properties:
id: Microsoft.PowerToys
source: winget
- name: Configure Always On Top
type: Microsoft.PowerToys/AlwaysOnTopSettings
properties:
settings:
properties:
FrameEnabled: true
FrameAccentColor: true
FrameThickness: 6
SoundEnabled: true
name: AlwaysOnTop
version: 1.0
```
### Example 4 - Disable for gaming
This example ensures Always On Top is disabled during game mode.
```yaml
# alwaysontop-gaming.dsc.yaml
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
resources:
- name: Configure for gaming
type: Microsoft.PowerToys/AlwaysOnTopSettings
properties:
settings:
properties:
DoNotActivateOnGameMode: true
name: AlwaysOnTop
version: 1.0
```
### Example 5 - Minimal border configuration
This example configures a subtle, thin border.
```powershell
$config = @{
settings = @{
properties = @{
FrameEnabled = $true
FrameThickness = 2
FrameOpacity = 50
RoundCornersEnabled = true
}
name = "AlwaysOnTop"
version = "1.0"
}
} | ConvertTo-Json -Depth 10 -Compress
PowerToys.DSC.exe set --resource 'settings' --module AlwaysOnTop --input $config
```
### Example 6 - Exclude specific applications
This example excludes certain applications from Always On Top.
```yaml
# alwaysontop-exclusions.dsc.yaml
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
resources:
- name: Exclude apps from Always On Top
type: Microsoft.PowerToys/AlwaysOnTopSettings
properties:
settings:
properties:
ExcludedApps: |
Game.exe
FullScreenApp.exe
name: AlwaysOnTop
version: 1.0
```
## Use cases
### Reference material
Keep documentation or reference windows visible:
```yaml
resources:
- name: Reference window settings
type: Microsoft.PowerToys/AlwaysOnTopSettings
properties:
settings:
properties:
FrameEnabled: true
FrameColor: "#00FF00"
FrameOpacity: 60
name: AlwaysOnTop
version: 1.0
```
### Monitoring dashboards
Pin monitoring tools and dashboards:
```yaml
resources:
- name: Monitoring settings
type: Microsoft.PowerToys/AlwaysOnTopSettings
properties:
settings:
properties:
FrameEnabled: true
FrameAccentColor: true
SoundEnabled: false
name: AlwaysOnTop
version: 1.0
```
## See also
- [Settings Resource][01]
- [PowerToys DSC Overview][02]
- [FancyZones Module][03] - Window layout manager
- [PowerToys Always On Top Documentation][04]
<!-- Link reference definitions -->
[01]: ../settings-resource.md
[02]: ../overview.md
[03]: ./FancyZones.md
[04]: https://learn.microsoft.com/windows/powertoys/always-on-top

View File

@@ -1,279 +0,0 @@
---
description: DSC configuration reference for PowerToys App module (general settings)
ms.date: 10/18/2025
ms.topic: reference
title: App module
---
# App Module
## Synopsis
Manages general PowerToys application settings, including utility enable/disable states, startup behavior, and theme preferences.
## Description
The `App` module controls global PowerToys settings that affect the entire
application. This includes which utilities are enabled, whether PowerToys
runs at startup, the application theme, and other general preferences.
Unlike other modules that configure specific utilities, the App module
manages PowerToys-wide settings and the enabled state of all utilities.
## Properties
The App module supports the following configurable properties:
### Enabled
Controls which PowerToys utilities are enabled or disabled.
**Type:** Object
**Properties:**
- `AdvancedPaste` (boolean) - Enable/disable Advanced Paste utility.
- `AlwaysOnTop` (boolean) - Enable/disable Always On Top utility.
- `Awake` (boolean) - Enable/disable Awake utility.
- `ColorPicker` (boolean) - Enable/disable Color Picker utility.
- `CropAndLock` (boolean) - Enable/disable Crop And Lock utility.
- `EnvironmentVariables` (boolean) - Enable/disable Environment Variables
utility.
- `FancyZones` (boolean) - Enable/disable FancyZones utility.
- `FileLocksmith` (boolean) - Enable/disable File Locksmith utility.
- `FindMyMouse` (boolean) - Enable/disable Find My Mouse utility.
- `Hosts` (boolean) - Enable/disable Hosts File Editor utility.
- `ImageResizer` (boolean) - Enable/disable Image Resizer utility.
- `KeyboardManager` (boolean) - Enable/disable Keyboard Manager utility.
- `MeasureTool` (boolean) - Enable/disable Measure Tool utility.
- `MouseHighlighter` (boolean) - Enable/disable Mouse Highlighter utility.
- `MouseJump` (boolean) - Enable/disable Mouse Jump utility.
- `MousePointerCrosshairs` (boolean) - Enable/disable Mouse Pointer
Crosshairs utility.
- `Peek` (boolean) - Enable/disable Peek utility.
- `PowerAccent` (boolean) - Enable/disable Power Accent utility.
- `PowerOCR` (boolean) - Enable/disable Power OCR utility.
- `PowerRename` (boolean) - Enable/disable Power Rename utility.
- `RegistryPreview` (boolean) - Enable/disable Registry Preview utility.
- `ShortcutGuide` (boolean) - Enable/disable Shortcut Guide utility.
- `Workspaces` (boolean) - Enable/disable Workspaces utility.
- `ZoomIt` (boolean) - Enable/disable ZoomIt utility.
### startup
Controls whether PowerToys starts automatically when you sign in.
**Type:** boolean
**Default:** `true`
### run_elevated
Controls whether PowerToys runs with administrator privileges.
**Type:** boolean
**Default:** `false`
### theme
Sets the application theme.
**Type:** string
**Allowed values:** `"light"`, `"dark"`, `"system"`
**Default:** `"system"`
## Examples
### Example 1 - Enable specific utilities with direct execution
This example enables only FancyZones, PowerRename, and ColorPicker while
disabling all others.
```powershell
$config = @{
settings = @{
properties = @{
Enabled = @{
AdvancedPaste = $false
AlwaysOnTop = $false
Awake = $false
ColorPicker = $true
CropAndLock = $false
EnvironmentVariables = $false
FancyZones = $true
FileLocksmith = $false
FindMyMouse = $false
Hosts = $false
ImageResizer = $false
KeyboardManager = $false
MeasureTool = $false
MouseHighlighter = $false
MouseJump = $false
MousePointerCrosshairs = $false
Peek = $false
PowerAccent = $false
PowerOCR = $false
PowerRename = $true
RegistryPreview = $false
ShortcutGuide = $false
Workspaces = $false
ZoomIt = $false
}
}
name = "App"
version = "1.0"
}
} | ConvertTo-Json -Depth 10 -Compress
PowerToys.DSC.exe set --resource 'settings' --module App --input $config
```
### Example 2 - Configure startup and theme with DSC
This example configures PowerToys to run at startup with elevated privileges
and use dark theme.
```bash
dsc config set --file app-config.dsc.yaml
```
```yaml
# app-config.dsc.yaml
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
resources:
- name: Configure PowerToys general settings
type: Microsoft.PowerToys/AppSettings
properties:
settings:
properties:
startup: true
run_elevated: true
theme: dark
name: App
version: 1.0
```
### Example 3 - Enable all utilities with WinGet
This example installs PowerToys and enables all available utilities.
```bash
winget configure winget-enable-all.yaml
```
```yaml
# winget-enable-all.yaml
$schema: https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2023/08/config/document.json
metadata:
winget:
processor: dscv3
resources:
- name: Install PowerToys
type: Microsoft.WinGet.DSC/WinGetPackage
properties:
id: Microsoft.PowerToys
source: winget
- name: Enable all utilities
type: Microsoft.PowerToys/AppSettings
properties:
settings:
properties:
Enabled:
AdvancedPaste: true
AlwaysOnTop: true
Awake: true
ColorPicker: true
CropAndLock: true
EnvironmentVariables: true
FancyZones: true
FileLocksmith: true
FindMyMouse: true
Hosts: true
ImageResizer: true
KeyboardManager: true
MeasureTool: true
MouseHighlighter: true
MouseJump: true
MousePointerCrosshairs: true
Peek: true
PowerAccent: true
PowerOCR: true
PowerRename: true
RegistryPreview: true
ShortcutGuide: true
Workspaces: true
ZoomIt: true
name: App
version: 1.0
```
### Example 4 - Test if specific utilities are enabled
This example tests whether FancyZones and PowerRename are enabled.
```powershell
$desired = @{
settings = @{
properties = @{
Enabled = @{
FancyZones = $true
PowerRename = $true
}
}
name = "App"
version = "1.0"
}
} | ConvertTo-Json -Depth 10 -Compress
$result = PowerToys.DSC.exe test --resource 'settings' --module App `
--input $desired | ConvertFrom-Json
if ($result._inDesiredState) {
Write-Host "FancyZones and PowerRename are enabled"
} else {
Write-Host "Configuration needs to be updated"
}
```
### Example 5 - Individual resource for each utility
This example shows enabling utilities individually, which provides better granularity for complex configurations.
```powershell
# Get current state
PowerToys.DSC.exe get --resource 'settings' --module App
# Enable individual utilities
$config = @{
settings = @{
properties = @{
Enabled = @{
FancyZones = $true
}
}
name = "App"
version = "1.0"
}
} | ConvertTo-Json -Depth 10 -Compress
PowerToys.DSC.exe set --resource 'settings' --module App --input $config
```
### Example 6 - Get schema for App module
This example retrieves the complete JSON schema for the App module.
```powershell
PowerToys.DSC.exe schema --resource 'settings' --module App | `
ConvertFrom-Json | ConvertTo-Json -Depth 10
```
## See also
- [Settings Resource][01]
- [PowerToys DSC Overview][02]
- [Awake][03]
<!-- Link reference definitions -->
[01]: ../settings-resource.md
[02]: ../overview.md
[03]: ./Awake.md

View File

@@ -1,342 +0,0 @@
---
description: DSC configuration reference for PowerToys Awake module
ms.date: 10/18/2025
ms.topic: reference
title: Awake Module
---
# Awake Module
## Synopsis
Manages configuration for the Awake utility, which keeps your computer awake without changing power settings.
## Description
The `Awake` module configures PowerToys Awake, a utility that prevents your
computer from going to sleep or turning off the display. This is useful
during installations, presentations, or any scenario where you need to
temporarily override power settings without permanently changing them.
Awake supports multiple modes including indefinite keep-awake, timed
intervals, and scheduled expiration. The display can be kept on or allowed
to turn off independently of the system sleep state.
## Properties
The Awake module supports the following configurable properties:
### keepDisplayOn
Controls whether the display remains on while Awake is active.
**Type:** boolean
**Default:** `true`
**Description:** When `true`, prevents the display from turning off. When
`false`, only prevents system sleep while allowing the display to turn off
according to power settings.
### mode
Specifies the Awake operating mode.
**Type:** integer
**Allowed values:**
- `0` - Off (Awake is disabled).
- `1` - Keep awake indefinitely.
- `2` - Keep awake for a timed interval.
- `3` - Keep awake until a specific date/time.
**Default:** `0`
### intervalHours
Number of hours to keep the system awake (used when mode is `2`).
**Type:** integer
**Range:** `0` to `999`
**Default:** `0`
### intervalMinutes
Number of minutes to keep the system awake (used when mode is `2`).
**Type:** integer
**Range:** `0` to `59`
**Default:** `1`
### expirationDateTime
The date and time when Awake should automatically disable (used when mode is `3`).
**Type:** string (ISO 8601 datetime format)
**Format:** `"YYYY-MM-DDTHH:mm:ss.fffffffzzz"`
**Example:** `"2025-12-31T23:59:59.0000000-08:00"`
### customTrayTimes
Custom time intervals displayed in the system tray context menu for quick activation.
**Type:** object
**Description:** A dictionary of custom time presets for quick access. Keys
are display names, values are time specifications.
## Examples
### Example 1 - Keep awake indefinitely with display on
This example configures Awake to keep the system and display awake
indefinitely using direct execution.
```powershell
$config = @{
settings = @{
properties = @{
keepDisplayOn = $true
mode = 1
}
name = "Awake"
version = "0.0.1"
}
} | ConvertTo-Json -Depth 10 -Compress
PowerToys.DSC.exe set --resource 'settings' --module Awake --input $config
```
### Example 2 - Keep awake for 2 hours with DSC
This example configures a timed keep-awake period.
```bash
dsc config set --file awake-timed.dsc.yaml
```
```yaml
# awake-timed.dsc.yaml
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
resources:
- name: Configure Awake for 2 hours
type: Microsoft.PowerToys/AwakeSettings
properties:
settings:
properties:
keepDisplayOn: true
mode: 2
intervalHours: 2
intervalMinutes: 0
name: Awake
version: 0.0.1
```
### Example 3 - Keep awake until specific time with WinGet
This example configures Awake to stay active until a specific date and time.
```bash
winget configure winget-awake-scheduled.yaml
```
```yaml
# winget-awake-scheduled.yaml
$schema: https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2023/08/config/document.json
metadata:
winget:
processor: dscv3
resources:
- name: Install PowerToys
type: Microsoft.WinGet.DSC/WinGetPackage
properties:
id: Microsoft.PowerToys
source: winget
- name: Keep awake until end of workday
type: Microsoft.PowerToys/AwakeSettings
properties:
settings:
properties:
keepDisplayOn: true
mode: 3
expirationDateTime: "2025-10-18T17:00:00.0000000-07:00"
name: Awake
version: 0.0.1
```
### Example 4 - Disable Awake
This example disables Awake using direct execution.
```powershell
$config = @{
settings = @{
properties = @{
mode = 0
}
name = "Awake"
version = "0.0.1"
}
} | ConvertTo-Json -Depth 10 -Compress
PowerToys.DSC.exe set --resource 'settings' --module Awake --input $config
```
### Example 5 - Keep system awake but allow display to sleep
This example keeps the system awake while allowing the display to turn off.
```bash
dsc config set --file awake-system-only.dsc.yaml
```
```yaml
# awake-system-only.dsc.yaml
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
resources:
- name: Keep system awake only
type: Microsoft.PowerToys/AwakeSettings
properties:
settings:
properties:
keepDisplayOn: false
mode: 1
name: Awake
version: 0.0.1
```
### Example 6 - Configure for presentation (4 hours)
This example configures Awake for a presentation scenario using WinGet.
```bash
winget configure presentation-mode.yaml
```
```yaml
# presentation-mode.yaml
$schema: https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2023/08/config/document.json
metadata:
winget:
processor: dscv3
resources:
- name: Enable Awake for presentation
type: Microsoft.PowerToys/AwakeSettings
properties:
settings:
properties:
keepDisplayOn: true
mode: 2
intervalHours: 4
intervalMinutes: 0
name: Awake
version: 0.0.1
```
### Example 7 - Test current configuration
This example tests whether Awake is configured for indefinite keep-awake.
```powershell
$desired = @{
settings = @{
properties = @{
keepDisplayOn = $true
mode = 1
}
name = "Awake"
version = "0.0.1"
}
} | ConvertTo-Json -Depth 10 -Compress
$result = PowerToys.DSC.exe test --resource 'settings' --module Awake --input $desired | ConvertFrom-Json
if ($result._inDesiredState) {
Write-Host "Awake is configured for indefinite keep-awake"
} else {
Write-Host "Awake configuration differs from desired state"
}
```
### Example 8 - Get current Awake configuration
This example retrieves the current Awake settings.
```powershell
PowerToys.DSC.exe get --resource 'settings' --module Awake | ConvertFrom-Json | ConvertTo-Json -Depth 10
```
### Example 9 - Get Awake schema
This example retrieves the JSON schema for Awake module properties.
```powershell
PowerToys.DSC.exe schema --resource 'settings' --module Awake | ConvertFrom-Json | ConvertTo-Json -Depth 10
```
## Use cases
### Development and builds
Keep the system awake during long-running builds or installations:
```yaml
resources:
- name: Keep awake during build
type: Microsoft.PowerToys/AwakeSettings
properties:
settings:
properties:
mode: 2
intervalHours: 8
intervalMinutes: 0
keepDisplayOn: false
name: Awake
version: 0.0.1
```
### Presentations and demos
Ensure the system stays awake during presentations:
```yaml
resources:
- name: Presentation mode
type: Microsoft.PowerToys/AwakeSettings
properties:
settings:
properties:
mode: 1
keepDisplayOn: true
name: Awake
version: 0.0.1
```
### Scheduled maintenance
Keep the system awake until a specific time for scheduled tasks:
```yaml
resources:
- name: Maintenance window
type: Microsoft.PowerToys/AwakeSettings
properties:
settings:
properties:
mode: 3
expirationDateTime: "2025-10-19T02:00:00.0000000-07:00"
keepDisplayOn: false
name: Awake
version: 0.0.1
```
## See also
- [Settings Resource][01]
- [PowerToys DSC Overview][02]
- [PowerRename][03]
- [PowerToys Awake Documentation][04]
<!-- Link reference definitions -->
[01]: ../settings-resource.md
[02]: ../overview.md
[03]: ./PowerRename.md
[04]: https://learn.microsoft.com/windows/powertoys/awake

View File

@@ -1,307 +0,0 @@
---
description: DSC configuration reference for PowerToys ColorPicker module
ms.date: 10/18/2025
ms.topic: reference
title: ColorPicker Module
---
# ColorPicker Module
## Synopsis
Manages configuration for the Color Picker utility, a system-wide color selection and identification tool.
## Description
The `ColorPicker` module configures PowerToys Color Picker, a utility that allows you to pick colors from anywhere on your screen and copy them to the clipboard in various formats. It's useful for designers, developers, and anyone working with colors.
## Properties
The ColorPicker module supports the following configurable properties:
### ActivationShortcut
Sets the keyboard shortcut to activate the color picker.
**Type:** object
**Properties:**
- `win` (boolean) - Windows key modifier.
- `ctrl` (boolean) - Ctrl key modifier.
- `alt` (boolean) - Alt key modifier.
- `shift` (boolean) - Shift key modifier.
- `code` (integer) - Virtual key code.
- `key` (string) - Key name.
**Default:** `Win+Shift+C`
### changecursor
Controls whether the cursor changes when the color picker is activated.
**Type:** boolean
**Default:** `true`
### copiedcolorrepresentation
Sets the default color format copied to the clipboard.
**Type:** string
**Allowed values:** `"HEX"`, `"RGB"`, `"HSL"`, `"HSV"`, `"CMYK"`, `"HSB"`,
`"HSI"`, `"HWB"`, `"NCol"`
**Default:** `"HEX"`
### activationaction
Controls the action when the color picker activation shortcut is pressed.
**Type:** integer
**Allowed values:**
- `0` - Open color picker and show editor
- `1` - Open color picker only
- `2` - Open editor only
**Default:** `0`
### showColorName
Controls whether color names are displayed in the color picker.
**Type:** boolean
**Default:** `false`
### VisibleColorFormats
Defines which color formats are visible in the picker interface.
**Type:** object with boolean properties for each format:
- `HEX` (boolean)
- `RGB` (boolean)
- `HSL` (boolean)
- `HSV` (boolean)
- `CMYK` (boolean)
- `HSB` (boolean)
- `HSI` (boolean)
- `HWB` (boolean)
- `NCol` (boolean)
- `Decimal` (boolean)
## Examples
### Example 1 - Configure default color format with direct execution
This example sets the default copied color format to RGB.
```powershell
$config = @{
settings = @{
properties = @{
copiedcolorrepresentation = "RGB"
}
name = "ColorPicker"
version = "1.0"
}
} | ConvertTo-Json -Depth 10 -Compress
PowerToys.DSC.exe set --resource 'settings' --module ColorPicker --input $config
```
### Example 2 - Configure activation behavior with DSC
This example configures the color picker to open directly without the
editor.
```bash
dsc config set --file colorpicker-activation.dsc.yaml
```
```yaml
# colorpicker-activation.dsc.yaml
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
resources:
- name: Configure Color Picker activation
type: Microsoft.PowerToys/ColorPickerSettings
properties:
settings:
properties:
activationaction: 1
changecursor: true
copiedcolorrepresentation: HEX
name: ColorPicker
version: 1.0
```
### Example 3 - Install and configure for web development with WinGet
This example installs PowerToys and configures Color Picker for web
developers.
```bash
winget configure winget-colorpicker-webdev.yaml
```
```yaml
# winget-colorpicker-webdev.yaml
$schema: https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2023/08/config/document.json
metadata:
winget:
processor: dscv3
resources:
- name: Install PowerToys
type: Microsoft.WinGet.DSC/WinGetPackage
properties:
id: Microsoft.PowerToys
source: winget
- name: Configure Color Picker for web development
type: Microsoft.PowerToys/ColorPickerSettings
properties:
settings:
properties:
copiedcolorrepresentation: HEX
showColorName: true
changecursor: true
VisibleColorFormats:
HEX: true
RGB: true
HSL: true
HSV: false
CMYK: false
name: ColorPicker
version: 1.0
```
### Example 4 - Configure visible formats
This example enables only HEX, RGB, and HSL formats.
```bash
dsc config set --file colorpicker-formats.dsc.yaml
```
```yaml
# colorpicker-formats.dsc.yaml
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
resources:
- name: Configure visible color formats
type: Microsoft.PowerToys/ColorPickerSettings
properties:
settings:
properties:
VisibleColorFormats:
HEX: true
RGB: true
HSL: true
HSV: false
CMYK: false
HSB: false
HSI: false
HWB: false
NCol: false
Decimal: false
name: ColorPicker
version: 1.0
```
### Example 5 - Configure for graphic design
This example configures Color Picker for graphic designers with CMYK support.
```powershell
$config = @{
settings = @{
properties = @{
copiedcolorrepresentation = "CMYK"
showColorName = $true
VisibleColorFormats = @{
HEX = $true
RGB = $true
CMYK = $true
HSL = $true
HSV = $true
}
}
name = "ColorPicker"
version = "1.0"
}
} | ConvertTo-Json -Depth 10 -Compress
PowerToys.DSC.exe set --resource 'settings' --module ColorPicker --input $config
```
### Example 6 - Test configuration
This example tests whether HEX is the default format.
```powershell
$desired = @{
settings = @{
properties = @{
copiedcolorrepresentation = "HEX"
}
name = "ColorPicker"
version = "1.0"
}
} | ConvertTo-Json -Depth 10 -Compress
$result = PowerToys.DSC.exe test --resource 'settings' --module ColorPicker `
--input $desired | ConvertFrom-Json
if ($result._inDesiredState) {
Write-Host "HEX is the default format"
}
```
## Use cases
### Web development
Configure for HTML/CSS color codes:
```yaml
resources:
- name: Web developer settings
type: Microsoft.PowerToys/ColorPickerSettings
properties:
settings:
properties:
copiedcolorrepresentation: HEX
VisibleColorFormats:
HEX: true
RGB: true
HSL: true
name: ColorPicker
version: 1.0
```
### Print design
Configure for CMYK color space:
```yaml
resources:
- name: Print designer settings
type: Microsoft.PowerToys/ColorPickerSettings
properties:
settings:
properties:
copiedcolorrepresentation: CMYK
showColorName: true
name: ColorPicker
version: 1.0
```
## See also
- [Settings Resource][01]
- [PowerToys DSC Overview][02]
- [ImageResizer][03]
- [PowerToys Color Picker Documentation][04]
<!-- Link reference definitions -->
[01]: ../settings-resource.md
[02]: ../overview.md
[03]: ./ImageResizer.md
[04]: https://learn.microsoft.com/windows/powertoys/color-picker

View File

@@ -1,195 +0,0 @@
---
description: DSC configuration reference for PowerToys CropAndLock module
ms.date: 10/18/2025
ms.topic: reference
title: CropAndLock Module
---
# CropAndLock Module
## Synopsis
Manages configuration for the Crop And Lock utility, which crops and locks portions of windows.
## Description
The `CropAndLock` module configures PowerToys Crop And Lock, a utility that allows you to crop a portion of any window and keep it visible as a thumbnail. This is useful for monitoring specific parts of applications, keeping reference information visible, or focusing on particular UI elements.
## Properties
The CropAndLock module supports the following configurable properties:
### Hotkey
Sets the keyboard shortcut to activate Crop And Lock for the active window.
**Type:** object
**Properties:**
- `win` (boolean) - Windows key modifier.
- `ctrl` (boolean) - Ctrl key modifier.
- `alt` (boolean) - Alt key modifier.
- `shift` (boolean) - Shift key modifier.
- `code` (integer) - Virtual key code.
- `key` (string) - Key name.
**Default:** `Win+Ctrl+Shift+T`
### ReparentHotkey
Sets the keyboard shortcut to change the parent window of a cropped thumbnail.
**Type:** object (same structure as Hotkey)
### ThumbnailOpacity
Sets the opacity of cropped thumbnails (0-100).
**Type:** integer
**Range:** `0` to `100`
**Default:** `100`
## Examples
### Example 1 - Configure basic settings with direct execution
This example sets the Crop And Lock hotkey and thumbnail opacity.
```powershell
$config = @{
settings = @{
properties = @{
ThumbnailOpacity = 90
}
name = "CropAndLock"
version = "1.0"
}
} | ConvertTo-Json -Depth 10 -Compress
PowerToys.DSC.exe set --resource 'settings' --module CropAndLock --input $config
```
### Example 2 - Configure hotkeys with DSC
This example configures custom hotkeys for cropping and reparenting.
```bash
dsc config set --file cropandlock-hotkeys.dsc.yaml
```
```yaml
# cropandlock-hotkeys.dsc.yaml
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
resources:
- name: Configure Crop And Lock hotkeys
type: Microsoft.PowerToys/CropAndLockSettings
properties:
settings:
properties:
Hotkey:
win: true
ctrl: true
shift: true
alt: false
code: 84
key: T
ThumbnailOpacity: 85
name: CropAndLock
version: 1.0
```
### Example 3 - Install and configure with WinGet
This example installs PowerToys and configures Crop And Lock.
```bash
winget configure winget-cropandlock.yaml
```
```yaml
# winget-cropandlock.yaml
$schema: https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2023/08/config/document.json
metadata:
winget:
processor: dscv3
resources:
- name: Install PowerToys
type: Microsoft.WinGet.DSC/WinGetPackage
properties:
id: Microsoft.PowerToys
source: winget
- name: Configure Crop And Lock
type: Microsoft.PowerToys/CropAndLockSettings
properties:
settings:
properties:
ThumbnailOpacity: 75
name: CropAndLock
version: 1.0
```
### Example 4 - Semi-transparent thumbnails
This example configures thumbnails to be semi-transparent for overlay use.
```yaml
# cropandlock-transparent.dsc.yaml
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
resources:
- name: Semi-transparent thumbnails
type: Microsoft.PowerToys/CropAndLockSettings
properties:
settings:
properties:
ThumbnailOpacity: 60
name: CropAndLock
version: 1.0
```
## Use cases
### Monitoring dashboards
Keep portions of monitoring tools visible:
```yaml
resources:
- name: Monitoring configuration
type: Microsoft.PowerToys/CropAndLockSettings
properties:
settings:
properties:
ThumbnailOpacity: 80
name: CropAndLock
version: 1.0
```
### Reference material
Crop and display reference information:
```yaml
resources:
- name: Reference display
type: Microsoft.PowerToys/CropAndLockSettings
properties:
settings:
properties:
ThumbnailOpacity: 95
name: CropAndLock
version: 1.0
```
## See also
- [Settings Resource][01]
- [PowerToys DSC Overview][02]
- [MouseJump][03]
- [PowerToys Crop And Lock Documentation][04]
<!-- Link reference definitions -->
[01]: ../settings-resource.md
[02]: ../overview.md
[03]: ./MouseJump.md
[04]: https://learn.microsoft.com/windows/powertoys/crop-and-lock

View File

@@ -1,193 +0,0 @@
---
description: DSC configuration reference for PowerToys EnvironmentVariables module
ms.date: 10/18/2025
ms.topic: reference
title: EnvironmentVariables Module
---
# EnvironmentVariables Module
## Synopsis
Manages configuration for the Environment Variables utility, a quick editor for system and user environment variables.
## Description
The `EnvironmentVariables` module configures PowerToys Environment Variables, a utility that provides an enhanced interface for viewing and editing Windows environment variables. It offers a more user-friendly alternative to the standard Windows environment variable editor.
## Properties
The EnvironmentVariables module supports the following configurable properties:
### LaunchAdministrator
Controls whether the Environment Variables editor launches with administrator privileges by default.
**Type:** boolean
**Default:** `false`
**Description:** When enabled, the editor will always attempt to launch with elevated permissions, allowing editing of system-wide environment variables.
## Examples
### Example 1 - Enable admin launch with direct execution
This example configures the Environment Variables editor to always launch with admin rights.
```powershell
$config = @{
settings = @{
properties = @{
LaunchAdministrator = $true
}
name = "EnvironmentVariables"
version = "1.0"
}
} | ConvertTo-Json -Depth 10 -Compress
PowerToys.DSC.exe set --resource 'settings' --module EnvironmentVariables --input $config
```
### Example 2 - Configure with DSC
This example enables administrator launch through DSC configuration.
```bash
dsc config set --file environmentvariables-config.dsc.yaml
```
```yaml
# environmentvariables-config.dsc.yaml
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
resources:
- name: Configure Environment Variables editor
type: Microsoft.PowerToys/EnvironmentVariablesSettings
properties:
settings:
properties:
LaunchAdministrator: true
name: EnvironmentVariables
version: 1.0
```
### Example 3 - Install and configure with WinGet
This example installs PowerToys and configures Environment Variables for
admin launch.
```bash
winget configure winget-envvars.yaml
```
```yaml
# winget-envvars.yaml
$schema: https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2023/08/config/document.json
metadata:
winget:
processor: dscv3
resources:
- name: Install PowerToys
type: Microsoft.WinGet.DSC/WinGetPackage
properties:
id: Microsoft.PowerToys
source: winget
- name: Configure Environment Variables
type: Microsoft.PowerToys/EnvironmentVariablesSettings
properties:
settings:
properties:
LaunchAdministrator: true
name: EnvironmentVariables
version: 1.0
```
### Example 4 - Standard user mode
This example configures for standard user access (no elevation).
```bash
dsc config set --file envvars-user.dsc.yaml
```
```yaml
# envvars-user.dsc.yaml
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
resources:
- name: User-level Environment Variables
type: Microsoft.PowerToys/EnvironmentVariablesSettings
properties:
settings:
properties:
LaunchAdministrator: false
name: EnvironmentVariables
version: 1.0
```
### Example 5 - Test admin launch configuration
This example tests whether admin launch is enabled.
```powershell
$desired = @{
settings = @{
properties = @{
LaunchAdministrator = $true
}
name = "EnvironmentVariables"
version = "1.0"
}
} | ConvertTo-Json -Depth 10 -Compress
$result = PowerToys.DSC.exe test --resource 'settings' --module EnvironmentVariables --input $desired | ConvertFrom-Json
if ($result._inDesiredState) {
Write-Host "Admin launch is enabled"
}
```
## Use cases
### System administration
Configure for system-wide environment variable management:
```yaml
resources:
- name: Admin configuration
type: Microsoft.PowerToys/EnvironmentVariablesSettings
properties:
settings:
properties:
LaunchAdministrator: true
name: EnvironmentVariables
version: 1.0
```
### Development workstations
Configure for user-level variable management:
```yaml
resources:
- name: Developer configuration
type: Microsoft.PowerToys/EnvironmentVariablesSettings
properties:
settings:
properties:
LaunchAdministrator: false
name: EnvironmentVariables
version: 1.0
```
## See also
- [Settings Resource][01]
- [PowerToys DSC Overview][02]
- [Hosts][03]
- [PowerToys Environment Variables Documentation][04]
<!-- Link reference definitions -->
[01]: ../settings-resource.md
[02]: ../overview.md
[03]: ./Hosts.md
[04]: https://learn.microsoft.com/windows/powertoys/environment-variables

View File

@@ -1,545 +0,0 @@
---
description: DSC configuration reference for PowerToys FancyZones module
ms.date: 10/18/2025
ms.topic: reference
title: FancyZones Module
---
# FancyZones Module
## Synopsis
Manages configuration for the FancyZones utility, a window layout manager that arranges and snaps windows into efficient layouts.
## Description
The `FancyZones` module configures PowerToys FancyZones, a window manager
utility that helps organize windows into custom layouts called zones.
FancyZones allows you to create multiple zone layouts for different displays
and quickly snap windows into position using keyboard shortcuts or mouse
actions.
This module controls activation methods, window behavior, zone appearance, editor settings, and other FancyZones preferences.
## Properties
The FancyZones module supports the following configurable properties:
### fancyzones_shiftDrag
Controls whether holding Shift while dragging a window activates zone snapping.
**Type:** boolean
**Default:** `true`
### fancyzones_mouseSwitch
Controls whether moving a window across monitors triggers zone selection.
**Type:** boolean
**Default:** `false`
### fancyzones_overrideSnapHotkeys
Controls whether FancyZones overrides the Windows Snap hotkeys (Win+Arrow keys).
**Type:** boolean
**Default:** `false`
### fancyzones_moveWindowsAcrossMonitors
Controls whether moving windows between monitors is enabled.
**Type:** boolean
**Default:** `false`
### fancyzones_moveWindowsBasedOnPosition
Controls whether windows move to zones based on cursor position rather than window position.
**Type:** boolean
**Default:** `false`
### fancyzones_overlappingZonesAlgorithm
Determines the algorithm used when multiple zones overlap.
**Type:** integer
**Allowed values:**
- `0` - Smallest zone
- `1` - Largest zone
- `2` - Positional (based on cursor/window position)
**Default:** `0`
### fancyzones_displayOrWorkAreaChange_moveWindows
Controls whether windows are moved to fit when display or work area changes.
**Type:** boolean
**Default:** `false`
### fancyzones_zoneSetChange_flashZones
Controls whether zones flash briefly when the zone set changes.
**Type:** boolean
**Default:** `false`
### fancyzones_zoneSetChange_moveWindows
Controls whether windows are automatically moved when the zone set changes.
**Type:** boolean
**Default:** `false`
### fancyzones_appLastZone_moveWindows
Controls whether windows are moved to their last known zone when reopened.
**Type:** boolean
**Default:** `true`
### fancyzones_openWindowOnActiveMonitor
Controls whether newly opened windows appear on the currently active monitor.
**Type:** boolean
**Default:** `false`
### fancyzones_spanZonesAcrossMonitors
Controls whether zones can span across multiple monitors.
**Type:** boolean
**Default:** `false`
### fancyzones_makeDraggedWindowTransparent
Controls whether dragged windows become transparent to show zones underneath.
**Type:** boolean
**Default:** `true`
### fancyzones_zoneColor
Sets the color of zone areas.
**Type:** string (hex color)
**Format:** `"#RRGGBB"`
**Example:** `"#0078D7"`
**Default:** `"#0078D7"`
### fancyzones_zoneBorderColor
Sets the color of zone borders.
**Type:** string (hex color)
**Format:** `"#RRGGBB"`
**Example:** `"#FFFFFF"`
**Default:** `"#FFFFFF"`
### fancyzones_zoneHighlightColor
Sets the highlight color when a zone is activated.
**Type:** string (hex color)
**Format:** `"#RRGGBB"`
**Example:** `"#0078D7"`
**Default:** `"#0078D7"`
### fancyzones_highlightOpacity
Sets the opacity of zone highlights (0-100).
**Type:** integer
**Range:** `0` to `100`
**Default:** `50`
### fancyzones_editorHotkey
Sets the keyboard shortcut to open the FancyZones editor.
**Type:** object
**Properties:**
- `win` (boolean) - Windows key modifier
- `ctrl` (boolean) - Ctrl key modifier
- `alt` (boolean) - Alt key modifier
- `shift` (boolean) - Shift key modifier
- `code` (integer) - Virtual key code
- `key` (string) - Key name
**Default:** `Win+Shift+~`
### fancyzones_windowSwitching
Controls whether window switching with arrow keys is enabled.
**Type:** boolean
**Default:** `true`
### fancyzones_nextTabHotkey
Sets the keyboard shortcut to switch to the next tab/window in a zone.
**Type:** object (same structure as fancyzones_editorHotkey)
### fancyzones_prevTabHotkey
Sets the keyboard shortcut to switch to the previous tab/window in a zone.
**Type:** object (same structure as fancyzones_editorHotkey)
### fancyzones_excludedApps
List of applications excluded from FancyZones snapping.
**Type:** string (newline-separated list of executable names)
**Example:** `"Notepad.exe\nCalc.exe"`
## Examples
### Example 1 - Enable basic zone snapping with direct execution
This example enables Shift-drag zone snapping and mouse-based monitor switching.
```powershell
$config = @{
settings = @{
properties = @{
fancyzones_shiftDrag = $true
fancyzones_mouseSwitch = $true
}
name = "FancyZones"
version = "1.0"
}
} | ConvertTo-Json -Depth 10 -Compress
PowerToys.DSC.exe set --resource 'settings' --module FancyZones --input $config
```
### Example 2 - Configure window movement behavior with DSC
This example configures how windows behave when displays or zones change.
```bash
dsc config set --file fancyzones-window-behavior.dsc.yaml
```
```yaml
# fancyzones-window-behavior.dsc.yaml
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
resources:
- name: Configure FancyZones window behavior
type: Microsoft.PowerToys/FancyZonesSettings
properties:
settings:
properties:
fancyzones_displayOrWorkAreaChange_moveWindows: true
fancyzones_zoneSetChange_moveWindows: true
fancyzones_appLastZone_moveWindows: true
fancyzones_moveWindowsAcrossMonitors: true
name: FancyZones
version: 1.0
```
### Example 3 - Customize zone appearance with WinGet
This example installs PowerToys and configures custom zone colors and
opacity.
```bash
winget configure winget-fancyzones-appearance.yaml
```
```yaml
# winget-fancyzones-appearance.yaml
$schema: https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2023/08/config/document.json
metadata:
winget:
processor: dscv3
resources:
- name: Install PowerToys
type: Microsoft.WinGet.DSC/WinGetPackage
properties:
id: Microsoft.PowerToys
source: winget
- name: Customize FancyZones appearance
type: Microsoft.PowerToys/FancyZonesSettings
properties:
settings:
properties:
fancyzones_zoneColor: "#2D2D30"
fancyzones_zoneBorderColor: "#007ACC"
fancyzones_zoneHighlightColor: "#007ACC"
fancyzones_highlightOpacity: 75
fancyzones_makeDraggedWindowTransparent: true
name: FancyZones
version: 1.0
```
### Example 4 - Override Windows Snap hotkeys
This example configures FancyZones to replace Windows default snap
functionality.
```bash
dsc config set --file fancyzones-snap-override.dsc.yaml
```
```yaml
# fancyzones-snap-override.dsc.yaml
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
resources:
- name: Override Windows Snap
type: Microsoft.PowerToys/FancyZonesSettings
properties:
settings:
properties:
fancyzones_overrideSnapHotkeys: true
fancyzones_moveWindowsBasedOnPosition: true
name: FancyZones
version: 1.0
```
### Example 5 - Configure editor hotkey
This example changes the FancyZones editor hotkey to Ctrl+Shift+Alt+F.
```powershell
$config = @{
settings = @{
properties = @{
fancyzones_editorHotkey = @{
win = $false
ctrl = $true
alt = $true
shift = $true
code = 70 # F key
key = "F"
}
}
name = "FancyZones"
version = "1.0"
}
} | ConvertTo-Json -Depth 10 -Compress
PowerToys.DSC.exe set --resource 'settings' --module FancyZones --input $config
```
### Example 6 - Exclude applications from zone snapping
This example configures FancyZones to ignore specific applications.
```yaml
# fancyzones-exclusions.dsc.yaml
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
resources:
- name: Exclude apps from FancyZones
type: Microsoft.PowerToys/FancyZonesSettings
properties:
settings:
properties:
fancyzones_excludedApps: |
Notepad.exe
Calculator.exe
mspaint.exe
name: FancyZones
version: 1.0
```
### Example 7 - Multi-monitor configuration
This example configures FancyZones for optimal multi-monitor workflow.
```bash
dsc config set --file fancyzones-multimonitor.dsc.yaml
```
```yaml
# fancyzones-multimonitor.dsc.yaml
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
resources:
- name: Multi-monitor FancyZones setup
type: Microsoft.PowerToys/FancyZonesSettings
properties:
settings:
properties:
fancyzones_shiftDrag: true
fancyzones_mouseSwitch: true
fancyzones_moveWindowsAcrossMonitors: true
fancyzones_spanZonesAcrossMonitors: false
fancyzones_openWindowOnActiveMonitor: true
fancyzones_displayOrWorkAreaChange_moveWindows: true
name: FancyZones
version: 1.0
```
### Example 8 - Complete FancyZones configuration with WinGet
This example shows a comprehensive FancyZones setup with installation.
```bash
winget configure winget-fancyzones-complete.yaml
```
```yaml
# winget-fancyzones-complete.yaml
$schema: https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2023/08/config/document.json
metadata:
winget:
processor: dscv3
resources:
- name: Install PowerToys
type: Microsoft.WinGet.DSC/WinGetPackage
properties:
id: Microsoft.PowerToys
source: winget
- name: Enable FancyZones
type: Microsoft.PowerToys/AppSettings
properties:
settings:
properties:
Enabled:
FancyZones: true
name: App
version: 1.0
- name: Configure FancyZones
type: Microsoft.PowerToys/FancyZonesSettings
properties:
settings:
properties:
# Activation
fancyzones_shiftDrag: true
fancyzones_mouseSwitch: true
fancyzones_overrideSnapHotkeys: false
# Window behavior
fancyzones_moveWindowsAcrossMonitors: true
fancyzones_moveWindowsBasedOnPosition: false
fancyzones_displayOrWorkAreaChange_moveWindows: true
fancyzones_zoneSetChange_moveWindows: false
fancyzones_appLastZone_moveWindows: true
# Appearance
fancyzones_makeDraggedWindowTransparent: true
fancyzones_zoneColor: "#0078D7"
fancyzones_zoneBorderColor: "#FFFFFF"
fancyzones_zoneHighlightColor: "#0078D7"
fancyzones_highlightOpacity: 50
# Multi-monitor
fancyzones_openWindowOnActiveMonitor: true
fancyzones_spanZonesAcrossMonitors: false
name: FancyZones
version: 1.0
```
### Example 9 - Test FancyZones configuration
This example tests whether FancyZones is configured for multi-monitor use.
```powershell
$desired = @{
settings = @{
properties = @{
fancyzones_moveWindowsAcrossMonitors = $true
fancyzones_openWindowOnActiveMonitor = $true
}
name = "FancyZones"
version = "1.0"
}
} | ConvertTo-Json -Depth 10 -Compress
$result = PowerToys.DSC.exe test --resource 'settings' --module FancyZones `
--input $desired | ConvertFrom-Json
if ($result._inDesiredState) {
Write-Host "FancyZones is configured for multi-monitor"
} else {
Write-Host "FancyZones configuration needs updating"
}
```
### Example 10 - Get FancyZones schema
This example retrieves the complete JSON schema for FancyZones properties.
```powershell
PowerToys.DSC.exe schema --resource 'settings' --module FancyZones | `
ConvertFrom-Json | ConvertTo-Json -Depth 10
```
## Use cases
### Development workflow
Configure FancyZones for efficient development with IDE, browser, and terminal windows:
```yaml
resources:
- name: Developer layout
type: Microsoft.PowerToys/FancyZonesSettings
properties:
settings:
properties:
fancyzones_shiftDrag: true
fancyzones_overrideSnapHotkeys: true
fancyzones_appLastZone_moveWindows: true
name: FancyZones
version: 1.0
```
### Presentation mode
Optimize window management for presentations and screen sharing:
```yaml
resources:
- name: Presentation layout
type: Microsoft.PowerToys/FancyZonesSettings
properties:
settings:
properties:
fancyzones_openWindowOnActiveMonitor: true
fancyzones_highlightOpacity: 30
fancyzones_makeDraggedWindowTransparent: false
name: FancyZones
version: 1.0
```
### Home office setup
Configure for docking/undocking laptop scenarios:
```yaml
resources:
- name: Home office configuration
type: Microsoft.PowerToys/FancyZonesSettings
properties:
settings:
properties:
fancyzones_displayOrWorkAreaChange_moveWindows: true
fancyzones_moveWindowsAcrossMonitors: true
fancyzones_appLastZone_moveWindows: true
name: FancyZones
version: 1.0
```
## See also
- [Settings Resource][01]
- [PowerToys DSC Overview][02]
- [Peek][03]
- [PowerToys FancyZones Documentation][04]
<!-- Link reference definitions -->
[01]: ../settings-resource.md
[02]: ../overview.md
[03]: ./Peek.md
[04]: https://learn.microsoft.com/windows/powertoys/fancyzones

View File

@@ -1,179 +0,0 @@
---
description: DSC configuration reference for PowerToys FileLocksmith module
ms.date: 10/18/2025
ms.topic: reference
title: FileLocksmith Module
---
# FileLocksmith Module
## Synopsis
Manages configuration for the File Locksmith utility, which identifies
processes that are locking files or folders.
## Description
The `FileLocksmith` module configures PowerToys File Locksmith, a Windows
shell extension that helps identify which processes are using (locking)
specific files or folders. It integrates with the Windows Explorer context
menu for easy access.
## Properties
The FileLocksmith module supports the following configurable properties:
### ExtendedContextMenuOnly
Controls whether File Locksmith appears only in the extended context menu.
**Type:** boolean
**Default:** `false`
**Description:** When `true`, File Locksmith only appears in the context menu
when you hold Shift while right-clicking. When `false`, it appears in the
standard context menu.
## Examples
### Example 1 - Show in standard context menu with direct execution
This example configures File Locksmith to appear in the standard context menu.
```powershell
$config = @{
settings = @{
properties = @{
ExtendedContextMenuOnly = $false
}
name = "FileLocksmith"
version = "1.0"
}
} | ConvertTo-Json -Depth 10 -Compress
PowerToys.DSC.exe set --resource 'settings' --module FileLocksmith `
--input $config
```
### Example 2 - Extended menu only with DSC
This example configures File Locksmith to appear only in the extended
context menu.
```bash
dsc config set --file filelocksmith-extended.dsc.yaml
```
```yaml
# filelocksmith-extended.dsc.yaml
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
resources:
- name: Configure File Locksmith for extended menu
type: Microsoft.PowerToys/FileLocksmithSettings
properties:
settings:
properties:
ExtendedContextMenuOnly: true
name: FileLocksmith
version: 1.0
```
### Example 3 - Install and configure with WinGet
This example installs PowerToys and configures File Locksmith for standard
menu access.
```bash
winget configure winget-filelocksmith.yaml
```
```yaml
# winget-filelocksmith.yaml
$schema: https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2023/08/config/document.json
metadata:
winget:
processor: dscv3
resources:
- name: Install PowerToys
type: Microsoft.WinGet.DSC/WinGetPackage
properties:
id: Microsoft.PowerToys
source: winget
- name: Configure File Locksmith
type: Microsoft.PowerToys/FileLocksmithSettings
properties:
settings:
properties:
ExtendedContextMenuOnly: false
name: FileLocksmith
version: 1.0
```
### Example 4 - Minimize context menu clutter
This example configures for extended menu to reduce clutter.
```bash
dsc config set --file filelocksmith-minimal.dsc.yaml
```
```yaml
# filelocksmith-minimal.dsc.yaml
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
resources:
- name: Minimal context menu
type: Microsoft.PowerToys/FileLocksmithSettings
properties:
settings:
properties:
ExtendedContextMenuOnly: true
name: FileLocksmith
version: 1.0
```
## Use cases
### System administration
Quick access for troubleshooting file locks:
```yaml
resources:
- name: Admin quick access
type: Microsoft.PowerToys/FileLocksmithSettings
properties:
settings:
properties:
ExtendedContextMenuOnly: false
name: FileLocksmith
version: 1.0
```
### Clean context menu
Reduce menu clutter for casual users:
```yaml
resources:
- name: Clean menu
type: Microsoft.PowerToys/FileLocksmithSettings
properties:
settings:
properties:
ExtendedContextMenuOnly: true
name: FileLocksmith
version: 1.0
```
## See also
- [Settings Resource][01]
- [PowerToys DSC Overview][02]
- [RegistryPreview][03]
- [PowerToys File Locksmith Documentation][04]
<!-- Link reference definitions -->
[01]: ../settings-resource.md
[02]: ../overview.md
[03]: ./RegistryPreview.md
[04]: https://learn.microsoft.com/windows/powertoys/file-locksmith

View File

@@ -1,288 +0,0 @@
---
description: DSC configuration reference for PowerToys FindMyMouse module
ms.date: 10/18/2025
ms.topic: reference
title: FindMyMouse Module
---
# FindMyMouse Module
## Synopsis
Manages configuration for the Find My Mouse utility, which helps locate your
mouse cursor on the screen.
## Description
The `FindMyMouse` module configures PowerToys Find My Mouse, a utility that
highlights your mouse cursor location when you press the Ctrl key. This is
particularly useful on large or multiple displays where the cursor can be
difficult to locate.
## Properties
The FindMyMouse module supports the following configurable properties:
### DoNotActivateOnGameMode
Controls whether Find My Mouse is disabled during game mode.
**Type:** boolean
**Default:** `true`
**Description:** When enabled, Find My Mouse will not activate when Windows
game mode is active.
### BackgroundColor
Sets the background color of the spotlight effect.
**Type:** string (hex color)
**Format:** `"#RRGGBB"`
**Default:** `"#000000"` (black)
### SpotlightColor
Sets the color of the spotlight circle around the cursor.
**Type:** string (hex color)
**Format:** `"#RRGGBB"`
**Default:** `"#FFFFFF"` (white)
### OverlayOpacity
Sets the opacity of the background overlay (0-100).
**Type:** integer
**Range:** `0` to `100`
**Default:** `50`
### SpotlightRadius
Sets the radius of the spotlight in pixels.
**Type:** integer
**Range:** `50` to `500`
**Default:** `100`
### AnimationDurationMs
Sets the duration of the spotlight animation in milliseconds.
**Type:** integer
**Range:** `0` to `5000`
**Default:** `500`
### SpotlightInitialZoom
Sets the initial zoom level of the spotlight effect.
**Type:** integer
**Range:** `100` to `1000`
**Default:** `200`
### ExcludedApps
List of applications where Find My Mouse is disabled.
**Type:** string (newline-separated list of executable names)
## Examples
### Example 1 - Configure spotlight appearance with direct execution
This example customizes the spotlight colors and radius.
```powershell
$config = @{
settings = @{
properties = @{
BackgroundColor = "#000000"
SpotlightColor = "#00FF00"
SpotlightRadius = 150
OverlayOpacity = 60
}
name = "FindMyMouse"
version = "1.0"
}
} | ConvertTo-Json -Depth 10 -Compress
PowerToys.DSC.exe set --resource 'settings' --module FindMyMouse --input $config
```
### Example 2 - Configure animation with DSC
This example customizes the spotlight animation behavior.
```bash
dsc config set --file findmymouse-animation.dsc.yaml
```
```yaml
# findmymouse-animation.dsc.yaml
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
resources:
- name: Configure Find My Mouse animation
type: Microsoft.PowerToys/FindMyMouseSettings
properties:
settings:
properties:
AnimationDurationMs: 750
SpotlightInitialZoom: 300
SpotlightRadius: 120
name: FindMyMouse
version: 1.0
```
### Example 3 - Install and configure with WinGet
This example installs PowerToys and configures Find My Mouse with custom
colors.
```bash
winget configure winget-findmymouse.yaml
```
```yaml
# winget-findmymouse.yaml
$schema: https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2023/08/config/document.json
metadata:
winget:
processor: dscv3
resources:
- name: Install PowerToys
type: Microsoft.WinGet.DSC/WinGetPackage
properties:
id: Microsoft.PowerToys
source: winget
- name: Configure Find My Mouse
type: Microsoft.PowerToys/FindMyMouseSettings
properties:
settings:
properties:
BackgroundColor: "#000000"
SpotlightColor: "#0078D7"
OverlayOpacity: 70
SpotlightRadius: 140
DoNotActivateOnGameMode: true
name: FindMyMouse
version: 1.0
```
### Example 4 - Subtle configuration
This example creates a subtle, less intrusive spotlight effect.
```bash
dsc config set --file findmymouse-subtle.dsc.yaml
```
```yaml
# findmymouse-subtle.dsc.yaml
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
resources:
- name: Subtle spotlight
type: Microsoft.PowerToys/FindMyMouseSettings
properties:
settings:
properties:
OverlayOpacity: 30
SpotlightRadius: 100
AnimationDurationMs: 300
name: FindMyMouse
version: 1.0
```
### Example 5 - High visibility configuration
This example creates a high-visibility spotlight for accessibility.
```powershell
$config = @{
settings = @{
properties = @{
BackgroundColor = "#000000"
SpotlightColor = "#FFFF00"
OverlayOpacity = 80
SpotlightRadius = 200
SpotlightInitialZoom = 400
}
name = "FindMyMouse"
version = "1.0"
}
} | ConvertTo-Json -Depth 10 -Compress
PowerToys.DSC.exe set --resource 'settings' --module FindMyMouse --input $config
```
### Example 6 - Disable during gaming
This example ensures Find My Mouse doesn't interfere with games.
```bash
dsc config set --file findmymouse-gaming.dsc.yaml
```
```yaml
# findmymouse-gaming.dsc.yaml
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
resources:
- name: Gaming configuration
type: Microsoft.PowerToys/FindMyMouseSettings
properties:
settings:
properties:
DoNotActivateOnGameMode: true
name: FindMyMouse
version: 1.0
```
## Use cases
### Large displays
Configure for high visibility on large screens:
```yaml
resources:
- name: Large display configuration
type: Microsoft.PowerToys/FindMyMouseSettings
properties:
settings:
properties:
SpotlightRadius: 180
OverlayOpacity: 70
SpotlightColor: "#FFFFFF"
name: FindMyMouse
version: 1.0
```
### Accessibility
Configure for maximum visibility:
```yaml
resources:
- name: Accessibility configuration
type: Microsoft.PowerToys/FindMyMouseSettings
properties:
settings:
properties:
SpotlightColor: "#FFFF00"
OverlayOpacity: 80
SpotlightRadius: 200
AnimationDurationMs: 1000
name: FindMyMouse
version: 1.0
```
## See also
- [Settings Resource][01]
- [PowerToys DSC Overview][02]
- [MouseHighlighter][03]
<!-- Link reference definitions -->
[01]: ../settings-resource.md
[02]: ../overview.md
[03]: ./MouseHighlighter.md

View File

@@ -1,200 +0,0 @@
---
description: DSC configuration reference for PowerToys Hosts module
ms.date: 10/18/2025
ms.topic: reference
title: Hosts Module
---
# Hosts Module
## Synopsis
Manages configuration for the Hosts File Editor utility, a quick editor for
the Windows hosts file.
## Description
The `Hosts` module configures PowerToys Hosts File Editor, a utility that
provides a user-friendly interface for viewing and editing the Windows hosts
file. It simplifies the process of adding, modifying, and managing DNS
entries in the hosts file.
## Properties
The Hosts module supports the following configurable properties:
### LaunchAdministrator
Controls whether the Hosts File Editor launches with administrator privileges
by default.
**Type:** boolean
**Default:** `false`
**Description:** When enabled, the editor will always attempt to launch with
elevated permissions, which is required to edit the hosts file.
### LoopbackDuplicates
Controls how duplicate loopback addresses are handled.
**Type:** boolean
**Default:** `false`
### AdditionalLinesPosition
Controls where additional lines are positioned when editing entries.
**Type:** integer
**Allowed values:**
- `0` - Top
- `1` - Bottom
**Default:** `0`
## Examples
### Example 1 - Enable admin launch with direct execution
This example configures the Hosts editor to always launch with admin rights.
```powershell
$config = @{
settings = @{
properties = @{
LaunchAdministrator = $true
}
name = "Hosts"
version = "1.0"
}
} | ConvertTo-Json -Depth 10 -Compress
PowerToys.DSC.exe set --resource 'settings' --module Hosts --input $config
```
### Example 2 - Configure with DSC
This example enables administrator launch and configures line positioning.
```bash
dsc config set --file hosts-config.dsc.yaml
```
```yaml
# hosts-config.dsc.yaml
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
resources:
- name: Configure Hosts File Editor
type: Microsoft.PowerToys/HostsSettings
properties:
settings:
properties:
LaunchAdministrator: true
AdditionalLinesPosition: 1
name: Hosts
version: 1.0
```
### Example 3 - Install and configure with WinGet
This example installs PowerToys and configures the Hosts editor for admin
launch.
```bash
winget configure winget-hosts.yaml
```
```yaml
# winget-hosts.yaml
$schema: https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2023/08/config/document.json
metadata:
winget:
processor: dscv3
resources:
- name: Install PowerToys
type: Microsoft.WinGet.DSC/WinGetPackage
properties:
id: Microsoft.PowerToys
source: winget
- name: Configure Hosts File Editor
type: Microsoft.PowerToys/HostsSettings
properties:
settings:
properties:
LaunchAdministrator: true
LoopbackDuplicates: false
name: Hosts
version: 1.0
```
### Example 4 - Development configuration
This example configures for development use with new entries at the bottom.
```bash
dsc config set --file hosts-development.dsc.yaml
```
```yaml
# hosts-development.dsc.yaml
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
resources:
- name: Development hosts configuration
type: Microsoft.PowerToys/HostsSettings
properties:
settings:
properties:
LaunchAdministrator: true
AdditionalLinesPosition: 1
name: Hosts
version: 1.0
```
## Use cases
### System administration
Configure for frequent hosts file editing:
```yaml
resources:
- name: Admin configuration
type: Microsoft.PowerToys/HostsSettings
properties:
settings:
properties:
LaunchAdministrator: true
name: Hosts
version: 1.0
```
### Web development
Configure for development environment management:
```yaml
resources:
- name: Developer configuration
type: Microsoft.PowerToys/HostsSettings
properties:
settings:
properties:
LaunchAdministrator: true
AdditionalLinesPosition: 1
name: Hosts
version: 1.0
```
## See also
- [Settings Resource][01]
- [PowerToys DSC Overview][02]
- [KeyboardManager][03]
- [PowerToys Hosts File Editor Documentation][04]
<!-- Link reference definitions -->
[01]: ../settings-resource.md
[02]: ../overview.md
[03]: ./KeyboardManager.md
[04]: https://learn.microsoft.com/windows/powertoys/hosts-file-editor

View File

@@ -1,349 +0,0 @@
---
description: DSC configuration reference for PowerToys ImageResizer module
ms.date: 10/18/2025
ms.topic: reference
title: ImageResizer Module
---
# ImageResizer Module
## Synopsis
Manages configuration for the Image Resizer utility, which provides quick
image resizing from the Windows Explorer context menu.
## Description
The `ImageResizer` module configures PowerToys Image Resizer, a Windows shell
extension that allows you to resize one or multiple images directly from the
File Explorer context menu. It supports custom size presets and various
resize options.
## Properties
The ImageResizer module supports the following configurable properties:
### ImageResizerSizes
Defines the preset sizes available in the Image Resizer interface.
**Type:** array of objects
**Object properties:**
- `Name` (string) - Display name for the preset
- `Width` (integer) - Width value
- `Height` (integer) - Height value
- `Unit` (string) - Unit of measurement: `"Pixel"`, `"Percent"`, `"Centimeter"`, `"Inch"`
- `Fit` (string) - Resize mode: `"Fit"`, `"Fill"`, `"Stretch"`
### ImageresizerSelectedSizeIndex
Sets the default selected size preset (0-based index).
**Type:** integer
**Default:** `0`
### ImageresizerShrinkOnly
Controls whether images are only resized if they're larger than the target size.
**Type:** boolean
**Default:** `false`
### ImageresizerReplace
Controls whether resized images replace the original files.
**Type:** boolean
**Default:** `false`
### ImageresizerIgnoreOrientation
Controls whether EXIF orientation data is ignored.
**Type:** boolean
**Default:** `true`
### ImageresizerJpegQualityLevel
Sets the JPEG quality level for resized images (1-100).
**Type:** integer
**Range:** `1` to `100`
**Default:** `90`
### ImageresizerPngInterlaceOption
Sets the PNG interlace option.
**Type:** integer
**Allowed values:**
- `0` - No interlacing
- `1` - Interlaced
**Default:** `0`
### ImageresizerTiffCompressOption
Sets the TIFF compression option.
**Type:** integer
**Allowed values:**
- `0` - No compression
- `1` - LZW compression
- `2` - ZIP compression
**Default:** `0`
### ImageresizerFileName
Sets the naming pattern for resized images.
**Type:** string
**Default:** `"%1 (%2)"`
**Placeholders:**
- `%1` - Original filename
- `%2` - Size name
- `%3` - Selected width
- `%4` - Selected height
- `%5` - Actual width
- `%6` - Actual height
### ImageresizerKeepDateModified
Controls whether the original file's modified date is preserved.
**Type:** boolean
**Default:** `false`
### ImageresizerFallbackEncoder
Sets the fallback encoder for unsupported formats.
**Type:** string
**Allowed values:** `"png"`, `"jpg"`, `"bmp"`, `"tiff"`, `"gif"`
**Default:** `"png"`
## Examples
### Example 1 - Configure custom size presets with direct execution
This example defines custom image resize presets.
```powershell
$config = @{
settings = @{
properties = @{
ImageResizerSizes = @(
@{
Name = "Small"
Width = 640
Height = 480
Unit = "Pixel"
Fit = "Fit"
},
@{
Name = "Medium"
Width = 1280
Height = 720
Unit = "Pixel"
Fit = "Fit"
},
@{
Name = "Large"
Width = 1920
Height = 1080
Unit = "Pixel"
Fit = "Fit"
}
)
}
name = "ImageResizer"
version = "1.0"
}
} | ConvertTo-Json -Depth 10 -Compress
PowerToys.DSC.exe set --resource 'settings' --module ImageResizer `
--input $config
```
### Example 2 - Configure quality settings with DSC
This example configures image quality and format options.
```bash
dsc config set --file imageresizer-quality.dsc.yaml
```
```yaml
# imageresizer-quality.dsc.yaml
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
resources:
- name: Configure Image Resizer quality
type: Microsoft.PowerToys/ImageResizerSettings
properties:
settings:
properties:
ImageresizerJpegQualityLevel: 95
ImageresizerShrinkOnly: true
ImageresizerKeepDateModified: true
name: ImageResizer
version: 1.0
```
### Example 3 - Install and configure with WinGet
This example installs PowerToys and configures Image Resizer with
web-optimized presets.
```bash
winget configure winget-imageresizer.yaml
```
```yaml
# winget-imageresizer.yaml
$schema: https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2023/08/config/document.json
metadata:
winget:
processor: dscv3
resources:
- name: Install PowerToys
type: Microsoft.WinGet.DSC/WinGetPackage
properties:
id: Microsoft.PowerToys
source: winget
- name: Configure Image Resizer
type: Microsoft.PowerToys/ImageResizerSettings
properties:
settings:
properties:
ImageResizerSizes:
- Name: Thumbnail
Width: 320
Height: 240
Unit: Pixel
Fit: Fit
- Name: Web Small
Width: 800
Height: 600
Unit: Pixel
Fit: Fit
- Name: Web Large
Width: 1920
Height: 1080
Unit: Pixel
Fit: Fit
ImageresizerJpegQualityLevel: 85
ImageresizerFileName: "%1_resized_%2"
name: ImageResizer
version: 1.0
```
### Example 4 - Photography workflow
This example configures for photography with high quality and metadata
preservation.
```bash
dsc config set --file imageresizer-photo.dsc.yaml
```
```yaml
# imageresizer-photography.dsc.yaml
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
resources:
- name: Photography configuration
type: Microsoft.PowerToys/ImageResizerSettings
properties:
settings:
properties:
ImageresizerJpegQualityLevel: 100
ImageresizerKeepDateModified: true
ImageresizerIgnoreOrientation: false
ImageresizerShrinkOnly: true
name: ImageResizer
version: 1.0
```
### Example 5 - Social media presets
This example defines presets for social media platforms.
```powershell
$config = @{
settings = @{
properties = @{
ImageResizerSizes = @(
@{ Name = "Instagram Square"; Width = 1080; Height = 1080; Unit = "Pixel"; Fit = "Fill" },
@{ Name = "Instagram Portrait"; Width = 1080; Height = 1350; Unit = "Pixel"; Fit = "Fill" },
@{ Name = "Facebook Cover"; Width = 820; Height = 312; Unit = "Pixel"; Fit = "Fill" },
@{ Name = "Twitter Header"; Width = 1500; Height = 500; Unit = "Pixel"; Fit = "Fill" }
)
ImageresizerJpegQualityLevel = 90
}
name = "ImageResizer"
version = "1.0"
}
} | ConvertTo-Json -Depth 10 -Compress
PowerToys.DSC.exe set --resource 'settings' --module ImageResizer `
--input $config
```
## Use cases
### Web development
Configure for web-optimized images:
```yaml
resources:
- name: Web optimization
type: Microsoft.PowerToys/ImageResizerSettings
properties:
settings:
properties:
ImageresizerJpegQualityLevel: 85
ImageresizerShrinkOnly: true
name: ImageResizer
version: 1.0
```
### Content creation
Configure for social media and content platforms:
```yaml
resources:
- name: Content creation
type: Microsoft.PowerToys/ImageResizerSettings
properties:
settings:
properties:
ImageResizerSizes:
- Name: HD
Width: 1920
Height: 1080
Unit: Pixel
Fit: Fit
ImageresizerJpegQualityLevel: 90
name: ImageResizer
version: 1.0
```
## See also
- [Settings Resource][01]
- [PowerToys DSC Overview][02]
- [MeasureTool][03]
- [PowerToys Image Resizer Documentation][04]
<!-- Link reference definitions -->
[01]: ../settings-resource.md
[02]: ../overview.md
[03]: ./MeasureTool.md
[04]: https://learn.microsoft.com/windows/powertoys/image-resizer

View File

@@ -1,145 +0,0 @@
---
description: DSC configuration reference for PowerToys KeyboardManager module
ms.date: 10/18/2025
ms.topic: reference
title: KeyboardManager Module
---
# KeyboardManager Module
## Synopsis
Manages configuration for the Keyboard Manager utility, which allows key
remapping and custom keyboard shortcuts.
## Description
The `KeyboardManager` module configures PowerToys Keyboard Manager, a utility
that enables you to remap keys and create custom keyboard shortcuts. It
allows reassigning keys, creating application-specific remappings, and
defining shortcuts that run programs or commands.
## Properties
The KeyboardManager module supports the following configurable properties:
### Enabled
Controls whether Keyboard Manager is enabled.
**Type:** boolean
**Default:** `true`
## Examples
### Example 1 - Enable Keyboard Manager with direct execution
This example enables the Keyboard Manager utility.
```powershell
$config = @{
settings = @{
properties = @{
Enabled = $true
}
name = "KeyboardManager"
version = "1.0"
}
} | ConvertTo-Json -Depth 10 -Compress
PowerToys.DSC.exe set --resource 'settings' --module KeyboardManager --input $config
```
### Example 2 - Configure with DSC
This example enables Keyboard Manager through DSC configuration.
```bash
dsc config set --file keyboardmanager-config.dsc.yaml
```
```yaml
# keyboardmanager-config.dsc.yaml
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
resources:
- name: Enable Keyboard Manager
type: Microsoft.PowerToys/KeyboardManagerSettings
properties:
settings:
properties:
Enabled: true
name: KeyboardManager
version: 1.0
```
### Example 3 - Install and configure with WinGet
This example installs PowerToys and enables Keyboard Manager.
```bash
winget configure winget-keyboardmanager.yaml
```
```yaml
# winget-keyboardmanager.yaml
$schema: https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2023/08/config/document.json
metadata:
winget:
processor: dscv3
resources:
- name: Install PowerToys
type: Microsoft.WinGet.DSC/WinGetPackage
properties:
id: Microsoft.PowerToys
source: winget
- name: Enable Keyboard Manager
type: Microsoft.PowerToys/KeyboardManagerSettings
properties:
settings:
properties:
Enabled: true
name: KeyboardManager
version: 1.0
```
## Important notes
> **Note:** The Keyboard Manager module DSC configuration controls the enabled state only. Key remappings and shortcut definitions are managed through the Keyboard Manager UI and stored separately. This design ensures that complex remapping configurations are not accidentally overwritten by DSC operations.
To configure key remappings:
1. Enable Keyboard Manager using DSC
2. Open PowerToys Settings
3. Navigate to Keyboard Manager
4. Use "Remap a key" or "Remap a shortcut" to configure specific mappings
## Use cases
### Enable for deployment
Enable Keyboard Manager on new workstations:
```yaml
resources:
- name: Enable Keyboard Manager
type: Microsoft.PowerToys/KeyboardManagerSettings
properties:
settings:
properties:
Enabled: true
name: KeyboardManager
version: 1.0
```
## See also
- [Settings Resource][01]
- [PowerToys DSC Overview][02]
- [PowerOCR][03]
- [PowerToys Keyboard Manager Documentation][04]
<!-- Link reference definitions -->
[01]: ../settings-resource.md
[02]: ../overview.md
[03]: ./PowerOCR.md
[04]: https://learn.microsoft.com/windows/powertoys/keyboard-manager

View File

@@ -1,254 +0,0 @@
---
description: DSC configuration reference for PowerToys MeasureTool module
ms.date: 10/18/2025
ms.topic: reference
title: MeasureTool Module
---
# MeasureTool Module
## Synopsis
Manages configuration for the Measure Tool (Screen Ruler) utility, which
measures pixels on your screen.
## Description
The `MeasureTool` module configures PowerToys Measure Tool (also known as
Screen Ruler), a utility that allows you to measure the distance between two
points on your screen in pixels. It's useful for designers, developers, and
anyone who needs to measure UI elements or screen distances.
## Properties
The MeasureTool module supports the following configurable properties:
### ActivationShortcut
Sets the keyboard shortcut to activate the measure tool.
**Type:** object
**Properties:**
- `win` (boolean) - Windows key modifier
- `ctrl` (boolean) - Ctrl key modifier
- `alt` (boolean) - Alt key modifier
- `shift` (boolean) - Shift key modifier
- `code` (integer) - Virtual key code
- `key` (string) - Key name
**Default:** `Win+Shift+M`
### ContinuousCapture
Controls whether continuous capture mode is enabled.
**Type:** boolean
**Default:** `false`
### DrawFeetOnCross
Controls whether measurement lines extend to screen edges.
**Type:** boolean
**Default:** `true`
### PerColorChannelEdgeDetection
Controls whether edge detection is per-color-channel or luminosity-based.
**Type:** boolean
**Default:** `false`
### PixelTolerance
Sets the pixel tolerance for edge detection (0-255).
**Type:** integer
**Range:** `0` to `255`
**Default:** `30`
### MeasureCrossColor
Sets the color of the measurement crosshair.
**Type:** string (hex color)
**Format:** `"#RRGGBBAA"` (with alpha)
**Default:** `"#FF4500FF"`
## Examples
### Example 1 - Configure activation shortcut with direct execution
This example customizes the measure tool activation shortcut.
```powershell
$config = @{
settings = @{
properties = @{
ActivationShortcut = @{
win = $true
ctrl = $false
alt = $false
shift = $true
code = 77
key = "M"
}
}
name = "MeasureTool"
version = "1.0"
}
} | ConvertTo-Json -Depth 10 -Compress
PowerToys.DSC.exe set --resource 'settings' --module MeasureTool `
--input $config
```
### Example 2 - Configure measurement appearance with DSC
This example customizes the crosshair color and measurement behavior.
```bash
dsc config set --file measuretool-appearance.dsc.yaml
```
```yaml
# measuretool-appearance.dsc.yaml
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
resources:
- name: Configure Measure Tool appearance
type: Microsoft.PowerToys/MeasureToolSettings
properties:
settings:
properties:
MeasureCrossColor: "#00FF00FF"
DrawFeetOnCross: true
ContinuousCapture: false
name: MeasureTool
version: 1.0
```
### Example 3 - Install and configure with WinGet
This example installs PowerToys and configures Measure Tool with edge
detection.
```bash
winget configure winget-measuretool.yaml
```
```yaml
# winget-measuretool.yaml
$schema: https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2023/08/config/document.json
metadata:
winget:
processor: dscv3
resources:
- name: Install PowerToys
type: Microsoft.WinGet.DSC/WinGetPackage
properties:
id: Microsoft.PowerToys
source: winget
- name: Configure Measure Tool
type: Microsoft.PowerToys/MeasureToolSettings
properties:
settings:
properties:
PixelTolerance: 20
PerColorChannelEdgeDetection: true
DrawFeetOnCross: true
name: MeasureTool
version: 1.0
```
### Example 4 - High contrast configuration
This example configures for high visibility measurements.
```bash
dsc config set --file measuretool-highcontrast.dsc.yaml
```
```yaml
# measuretool-highcontrast.dsc.yaml
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
resources:
- name: High contrast Measure Tool
type: Microsoft.PowerToys/MeasureToolSettings
properties:
settings:
properties:
MeasureCrossColor: "#FFFF00FF"
DrawFeetOnCross: true
name: MeasureTool
version: 1.0
```
### Example 5 - Continuous capture mode
This example enables continuous capture for repeated measurements.
```powershell
$config = @{
settings = @{
properties = @{
ContinuousCapture = $true
PixelTolerance = 25
}
name = "MeasureTool"
version = "1.0"
}
} | ConvertTo-Json -Depth 10 -Compress
PowerToys.DSC.exe set --resource 'settings' --module MeasureTool --input $config
```
## Use cases
### UI/UX design
Configure for design work with precise measurements:
```yaml
resources:
- name: Design configuration
type: Microsoft.PowerToys/MeasureToolSettings
properties:
settings:
properties:
PixelTolerance: 15
DrawFeetOnCross: true
name: MeasureTool
version: 1.0
```
### Web development
Configure for layout debugging:
```yaml
resources:
- name: Developer configuration
type: Microsoft.PowerToys/MeasureToolSettings
properties:
settings:
properties:
ContinuousCapture: true
MeasureCrossColor: "#0078D7FF"
name: MeasureTool
version: 1.0
```
## See also
- [Settings Resource][01]
- [PowerToys DSC Overview][02]
- [PowerAccent][03]
- [PowerToys Screen Ruler Documentation][04]
<!-- Link reference definitions -->
[01]: ../settings-resource.md
[02]: ../overview.md
[03]: ./PowerAccent.md
[04]: https://learn.microsoft.com/windows/powertoys/screen-ruler

View File

@@ -1,276 +0,0 @@
---
description: DSC configuration reference for PowerToys MouseHighlighter module
ms.date: 10/18/2025
ms.topic: reference
title: MouseHighlighter Module
---
# MouseHighlighter Module
## Synopsis
Manages configuration for the Mouse Highlighter utility, which highlights
your mouse cursor and clicks.
## Description
The `MouseHighlighter` module configures PowerToys Mouse Highlighter, a
utility that adds visual highlights to your mouse cursor and click locations.
This is useful for presentations, tutorials, screen recordings, or
accessibility purposes.
## Properties
The MouseHighlighter module supports the following configurable properties:
### ActivationShortcut
Sets the keyboard shortcut to toggle mouse highlighting.
**Type:** object
**Properties:**
- `win` (boolean) - Windows key modifier
- `ctrl` (boolean) - Ctrl key modifier
- `alt` (boolean) - Alt key modifier
- `shift` (boolean) - Shift key modifier
- `code` (integer) - Virtual key code
- `key` (string) - Key name
**Default:** `Win+Shift+H`
### LeftButtonClickColor
Sets the color for left mouse button clicks.
**Type:** string (hex color)
**Format:** `"#RRGGBB"`
**Default:** `"#FFFF00"` (yellow)
### RightButtonClickColor
Sets the color for right mouse button clicks.
**Type:** string (hex color)
**Format:** `"#RRGGBB"`
**Default:** `"#0000FF"` (blue)
### HighlightOpacity
Sets the opacity of click highlights (0-100).
**Type:** integer
**Range:** `0` to `100`
**Default:** `160`
### HighlightRadius
Sets the radius of click highlights in pixels.
**Type:** integer
**Range:** `1` to `500`
**Default:** `20`
### HighlightFadeDelayMs
Sets how long highlights remain visible in milliseconds.
**Type:** integer
**Range:** `0` to `10000`
**Default:** `500`
### HighlightFadeDurationMs
Sets the duration of the highlight fade animation in milliseconds.
**Type:** integer
**Range:** `0` to `10000`
**Default:** `250`
### AutoActivate
Controls whether Mouse Highlighter activates automatically during presentations.
**Type:** boolean
**Default:** `false`
## Examples
### Example 1 - Configure highlight colors with direct execution
This example customizes the click highlight colors.
```powershell
$config = @{
settings = @{
properties = @{
LeftButtonClickColor = "#00FF00"
RightButtonClickColor = "#FF0000"
HighlightOpacity = 200
}
name = "MouseHighlighter"
version = "1.0"
}
} | ConvertTo-Json -Depth 10 -Compress
PowerToys.DSC.exe set --resource 'settings' --module MouseHighlighter `
--input $config
```
### Example 2 - Configure highlight animation with DSC
This example customizes the animation timing and appearance.
```bash
dsc config set --file mousehighlighter-animation.dsc.yaml
```
```yaml
# mousehighlighter-animation.dsc.yaml
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
resources:
- name: Configure Mouse Highlighter animation
type: Microsoft.PowerToys/MouseHighlighterSettings
properties:
settings:
properties:
HighlightRadius: 30
HighlightFadeDelayMs: 750
HighlightFadeDurationMs: 400
name: MouseHighlighter
version: 1.0
```
### Example 3 - Install and configure for presentations with WinGet
This example installs PowerToys and configures Mouse Highlighter for
presentations.
```bash
winget configure winget-mousehighlighter.yaml
```
```yaml
# winget-mousehighlighter.yaml
$schema: https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2023/08/config/document.json
metadata:
winget:
processor: dscv3
resources:
- name: Install PowerToys
type: Microsoft.WinGet.DSC/WinGetPackage
properties:
id: Microsoft.PowerToys
source: winget
- name: Configure Mouse Highlighter for presentations
type: Microsoft.PowerToys/MouseHighlighterSettings
properties:
settings:
properties:
LeftButtonClickColor: "#FFD700"
RightButtonClickColor: "#FF4500"
HighlightOpacity: 220
HighlightRadius: 25
AutoActivate: true
name: MouseHighlighter
version: 1.0
```
### Example 4 - Subtle highlighting
This example configures subtle, less distracting highlights.
```bash
dsc config set --file mousehighlighter-subtle.dsc.yaml
```
```yaml
# mousehighlighter-subtle.dsc.yaml
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
resources:
- name: Subtle mouse highlighting
type: Microsoft.PowerToys/MouseHighlighterSettings
properties:
settings:
properties:
HighlightOpacity: 100
HighlightRadius: 15
HighlightFadeDelayMs: 300
name: MouseHighlighter
version: 1.0
```
### Example 5 - High visibility for accessibility
This example configures high-contrast, long-lasting highlights.
```powershell
$config = @{
settings = @{
properties = @{
LeftButtonClickColor = "#FFFFFF"
RightButtonClickColor = "#FF0000"
HighlightOpacity = 255
HighlightRadius = 40
HighlightFadeDelayMs = 1500
HighlightFadeDurationMs = 500
}
name = "MouseHighlighter"
version = "1.0"
}
} | ConvertTo-Json -Depth 10 -Compress
PowerToys.DSC.exe set --resource 'settings' --module MouseHighlighter --input $config
```
## Use cases
### Presentations and demos
Configure for clear visibility during presentations:
```yaml
resources:
- name: Presentation highlighting
type: Microsoft.PowerToys/MouseHighlighterSettings
properties:
settings:
properties:
LeftButtonClickColor: "#FFD700"
HighlightOpacity: 200
HighlightRadius: 25
AutoActivate: true
name: MouseHighlighter
version: 1.0
```
### Screen recording
Configure for video tutorials and recordings:
```yaml
resources:
- name: Recording configuration
type: Microsoft.PowerToys/MouseHighlighterSettings
properties:
settings:
properties:
HighlightOpacity: 180
HighlightFadeDelayMs: 600
name: MouseHighlighter
version: 1.0
```
## See also
- [Settings Resource][01]
- [PowerToys DSC Overview][02]
- [MousePointerCrosshairs][03]
- [PowerToys Mouse Utilities Documentation][04]
<!-- Link reference definitions -->
[01]: ../settings-resource.md
[02]: ../overview.md
[03]: ./MousePointerCrosshairs.md
[04]: https://learn.microsoft.com/windows/powertoys/mouse-utilities

View File

@@ -1,220 +0,0 @@
---
description: DSC configuration reference for PowerToys MouseJump module
ms.date: 10/18/2025
ms.topic: reference
title: MouseJump Module
---
# MouseJump Module
## Synopsis
Manages configuration for the Mouse Jump utility, which enables quick
navigation across large or multiple displays.
## Description
The `MouseJump` module configures PowerToys Mouse Jump, a utility that
provides a miniature preview of all your displays, allowing you to quickly
jump your mouse cursor to any location. This is particularly useful with
large monitors or multi-monitor setups.
## Properties
The MouseJump module supports the following configurable properties:
### ActivationShortcut
Sets the keyboard shortcut to activate Mouse Jump.
**Type:** object
**Properties:**
- `win` (boolean) - Windows key modifier
- `ctrl` (boolean) - Ctrl key modifier
- `alt` (boolean) - Alt key modifier
- `shift` (boolean) - Shift key modifier
- `code` (integer) - Virtual key code
- `key` (string) - Key name
**Default:** `Win+Shift+D`
### ThumbnailSize
Sets the size of the screen thumbnail preview.
**Type:** string
**Allowed values:**
- `"small"` - Smaller thumbnail for faster performance
- `"medium"` - Balanced size and performance
- `"large"` - Larger thumbnail for better visibility
**Default:** `"medium"`
## Examples
### Example 1 - Configure activation shortcut with direct execution
This example customizes the Mouse Jump activation shortcut.
```powershell
$config = @{
settings = @{
properties = @{
ActivationShortcut = @{
win = $true
ctrl = $false
alt = $false
shift = $true
code = 68
key = "D"
}
}
name = "MouseJump"
version = "1.0"
}
} | ConvertTo-Json -Depth 10 -Compress
PowerToys.DSC.exe set --resource 'settings' --module MouseJump `
--input $config
```
### Example 2 - Configure thumbnail size with DSC
This example sets a larger thumbnail for better visibility.
```bash
dsc config set --file mousejump-size.dsc.yaml
```
```yaml
# mousejump-size.dsc.yaml
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
resources:
- name: Configure Mouse Jump thumbnail
type: Microsoft.PowerToys/MouseJumpSettings
properties:
settings:
properties:
ThumbnailSize: large
name: MouseJump
version: 1.0
```
### Example 3 - Install and configure with WinGet
This example installs PowerToys and configures Mouse Jump for multi-monitor
setups.
```bash
winget configure winget-mousejump.yaml
```
```yaml
# winget-mousejump.yaml
$schema: https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2023/08/config/document.json
metadata:
winget:
processor: dscv3
resources:
- name: Install PowerToys
type: Microsoft.WinGet.DSC/WinGetPackage
properties:
id: Microsoft.PowerToys
source: winget
- name: Configure Mouse Jump
type: Microsoft.PowerToys/MouseJumpSettings
properties:
settings:
properties:
ThumbnailSize: medium
name: MouseJump
version: 1.0
```
### Example 4 - Performance-optimized configuration
This example uses a smaller thumbnail for better performance.
```bash
dsc config set --file mousejump-performance.dsc.yaml
```
```yaml
# mousejump-performance.dsc.yaml
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
resources:
- name: Performance-optimized Mouse Jump
type: Microsoft.PowerToys/MouseJumpSettings
properties:
settings:
properties:
ThumbnailSize: small
name: MouseJump
version: 1.0
```
### Example 5 - Large display configuration
This example configures for large or high-DPI displays.
```powershell
$config = @{
settings = @{
properties = @{
ThumbnailSize = "large"
}
name = "MouseJump"
version = "1.0"
}
} | ConvertTo-Json -Depth 10 -Compress
PowerToys.DSC.exe set --resource 'settings' --module MouseJump --input $config
```
## Use cases
### Multi-monitor workstations
Configure for efficient navigation across multiple displays:
```yaml
resources:
- name: Multi-monitor configuration
type: Microsoft.PowerToys/MouseJumpSettings
properties:
settings:
properties:
ThumbnailSize: medium
name: MouseJump
version: 1.0
```
### Large displays
Configure for ultra-wide or 4K+ displays:
```yaml
resources:
- name: Large display configuration
type: Microsoft.PowerToys/MouseJumpSettings
properties:
settings:
properties:
ThumbnailSize: large
name: MouseJump
version: 1.0
```
## See also
- [Settings Resource][01]
- [PowerToys DSC Overview][02]
- [FindMyMouse][03]
<!-- Link reference definitions -->
[01]: ../settings-resource.md
[02]: ../overview.md
[03]: ./FindMyMouse.md

View File

@@ -1,290 +0,0 @@
---
description: DSC configuration reference for PowerToys MousePointerCrosshairs module
ms.date: 10/18/2025
ms.topic: reference
title: MousePointerCrosshairs Module
---
# MousePointerCrosshairs Module
## Synopsis
Manages configuration for the Mouse Pointer Crosshairs utility, which
displays crosshairs centered on your mouse pointer.
## Description
The `MousePointerCrosshairs` module configures PowerToys Mouse Pointer
Crosshairs, a utility that displays customizable crosshairs overlaid on your
screen, centered on the mouse cursor. This is useful for presentations,
design work, or improving cursor visibility.
## Properties
The MousePointerCrosshairs module supports the following configurable properties:
### ActivationShortcut
Sets the keyboard shortcut to toggle crosshairs display.
**Type:** object
**Properties:**
- `win` (boolean) - Windows key modifier
- `ctrl` (boolean) - Ctrl key modifier
- `alt` (boolean) - Alt key modifier
- `shift` (boolean) - Shift key modifier
- `code` (integer) - Virtual key code
- `key` (string) - Key name
**Default:** `Win+Alt+P`
### CrosshairsColor
Sets the color of the crosshairs.
**Type:** string (hex color)
**Format:** `"#RRGGBB"`
**Default:** `"#FF0000"` (red)
### CrosshairsOpacity
Sets the opacity of the crosshairs (0-100).
**Type:** integer
**Range:** `0` to `100`
**Default:** `75`
### CrosshairsRadius
Sets the length of the crosshair lines in pixels.
**Type:** integer
**Range:** `0` to `9999`
**Default:** `100`
### CrosshairsThickness
Sets the thickness of the crosshair lines in pixels.
**Type:** integer
**Range:** `1` to `50`
**Default:** `5`
### CrosshairsBorderColor
Sets the border color of the crosshairs.
**Type:** string (hex color)
**Format:** `"#RRGGBB"`
**Default:** `"#FFFFFF"` (white)
### CrosshairsBorderSize
Sets the width of the crosshair border in pixels.
**Type:** integer
**Range:** `0` to `50`
**Default:** `1`
### CrosshairsAutoHide
Controls whether crosshairs automatically hide when the mouse is not moving.
**Type:** boolean
**Default:** `false`
### CrosshairsIsFixedLengthEnabled
Controls whether crosshairs have a fixed length or extend to screen edges.
**Type:** boolean
**Default:** `true`
### CrosshairsFixedLength
Sets the fixed length of crosshairs when fixed length mode is enabled.
**Type:** integer
**Range:** `0` to `9999`
**Default:** `100`
## Examples
### Example 1 - Configure crosshair appearance with direct execution
This example customizes the crosshair color and size.
```powershell
$config = @{
settings = @{
properties = @{
CrosshairsColor = "#00FF00"
CrosshairsOpacity = 85
CrosshairsThickness = 3
CrosshairsRadius = 150
}
name = "MousePointerCrosshairs"
version = "1.0"
}
} | ConvertTo-Json -Depth 10 -Compress
PowerToys.DSC.exe set --resource 'settings' --module MousePointerCrosshairs `
--input $config
```
### Example 2 - Configure with border with DSC
This example adds a border to the crosshairs for better visibility.
```bash
dsc config set --file mousecrosshairs-border.dsc.yaml
```
```yaml
# mousecrosshairs-border.dsc.yaml
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
resources:
- name: Configure crosshairs with border
type: Microsoft.PowerToys/MousePointerCrosshairsSettings
properties:
settings:
properties:
CrosshairsColor: "#FF0000"
CrosshairsBorderColor: "#FFFFFF"
CrosshairsBorderSize: 2
CrosshairsThickness: 4
name: MousePointerCrosshairs
version: 1.0
```
### Example 3 - Install and configure with WinGet
This example installs PowerToys and configures crosshairs for presentations.
```bash
winget configure winget-mousecrosshairs.yaml
```
```yaml
# winget-mousecrosshairs.yaml
$schema: https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2023/08/config/document.json
metadata:
winget:
processor: dscv3
resources:
- name: Install PowerToys
type: Microsoft.WinGet.DSC/WinGetPackage
properties:
id: Microsoft.PowerToys
source: winget
- name: Configure Mouse Crosshairs
type: Microsoft.PowerToys/MousePointerCrosshairsSettings
properties:
settings:
properties:
CrosshairsColor: "#FFFF00"
CrosshairsOpacity: 90
CrosshairsRadius: 120
CrosshairsThickness: 5
CrosshairsBorderSize: 2
name: MousePointerCrosshairs
version: 1.0
```
### Example 4 - Full-screen crosshairs
This example configures crosshairs that extend to screen edges.
```bash
dsc config set --file mousecrosshairs-fullscreen.dsc.yaml
```
```yaml
# mousecrosshairs-fullscreen.dsc.yaml
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
resources:
- name: Full-screen crosshairs
type: Microsoft.PowerToys/MousePointerCrosshairsSettings
properties:
settings:
properties:
CrosshairsIsFixedLengthEnabled: false
CrosshairsOpacity: 60
name: MousePointerCrosshairs
version: 1.0
```
### Example 5 - Subtle crosshairs with auto-hide
This example creates subtle crosshairs that hide when idle.
```powershell
$config = @{
settings = @{
properties = @{
CrosshairsColor = "#FFFFFF"
CrosshairsOpacity = 50
CrosshairsThickness = 2
CrosshairsRadius = 80
CrosshairsAutoHide = $true
}
name = "MousePointerCrosshairs"
version = "1.0"
}
} | ConvertTo-Json -Depth 10 -Compress
PowerToys.DSC.exe set --resource 'settings' --module MousePointerCrosshairs --input $config
```
## Use cases
### Presentations and demos
Configure for clear cursor tracking during presentations:
```yaml
resources:
- name: Presentation crosshairs
type: Microsoft.PowerToys/MousePointerCrosshairsSettings
properties:
settings:
properties:
CrosshairsColor: "#FFFF00"
CrosshairsOpacity: 85
CrosshairsRadius: 150
name: MousePointerCrosshairs
version: 1.0
```
### Design and alignment
Configure for precise alignment work:
```yaml
resources:
- name: Design crosshairs
type: Microsoft.PowerToys/MousePointerCrosshairsSettings
properties:
settings:
properties:
CrosshairsIsFixedLengthEnabled: false
CrosshairsThickness: 1
CrosshairsOpacity: 70
name: MousePointerCrosshairs
version: 1.0
```
## See also
- [Settings Resource][01]
- [PowerToys DSC Overview][02]
- [MouseHighlighter][03]
- [PowerToys Mouse Utilities Documentation][04]
<!-- Link reference definitions -->
[01]: ../settings-resource.md
[02]: ../overview.md
[03]: ./MouseHighlighter.md
[04]: https://learn.microsoft.com/windows/powertoys/mouse-utilities

View File

@@ -1,200 +0,0 @@
---
description: DSC configuration reference for PowerToys Peek module
ms.date: 10/18/2025
ms.topic: reference
title: Peek Module
---
# Peek Module
## Synopsis
Manages configuration for the Peek utility, a quick file preview tool.
## Description
The `Peek` module configures PowerToys Peek, a utility that provides quick
file previews without opening files. Activate it with a keyboard shortcut to
preview documents, images, videos, and more in a popup window.
## Properties
The Peek module supports the following configurable properties:
### ActivationShortcut
Sets the keyboard shortcut to activate Peek for the selected file.
**Type:** object
**Properties:**
- `win` (boolean) - Windows key modifier
- `ctrl` (boolean) - Ctrl key modifier
- `alt` (boolean) - Alt key modifier
- `shift` (boolean) - Shift key modifier
- `code` (integer) - Virtual key code
- `key` (string) - Key name
**Default:** `Ctrl+Space`
### CloseAfterLosingFocus
Controls whether Peek window closes when it loses focus.
**Type:** boolean
**Default:** `true`
## Examples
### Example 1 - Configure activation shortcut with direct execution
This example customizes the Peek activation shortcut.
```powershell
$config = @{
settings = @{
properties = @{
ActivationShortcut = @{
win = $false
ctrl = $true
alt = $false
shift = $false
code = 32
key = "Space"
}
}
name = "Peek"
version = "1.0"
}
} | ConvertTo-Json -Depth 10 -Compress
PowerToys.DSC.exe set --resource 'settings' --module Peek --input $config
```
### Example 2 - Configure focus behavior with DSC
This example configures Peek to remain open after losing focus.
```bash
dsc config set --file peek-focus.dsc.yaml
```
```yaml
# peek-focus.dsc.yaml
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
resources:
- name: Configure Peek focus behavior
type: Microsoft.PowerToys/PeekSettings
properties:
settings:
properties:
CloseAfterLosingFocus: false
name: Peek
version: 1.0
```
### Example 3 - Install and configure with WinGet
This example installs PowerToys and configures Peek.
```bash
winget configure winget-peek.yaml
```
```yaml
# winget-peek.yaml
$schema: https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2023/08/config/document.json
metadata:
winget:
processor: dscv3
resources:
- name: Install PowerToys
type: Microsoft.WinGet.DSC/WinGetPackage
properties:
id: Microsoft.PowerToys
source: winget
- name: Configure Peek
type: Microsoft.PowerToys/PeekSettings
properties:
settings:
properties:
CloseAfterLosingFocus: true
name: Peek
version: 1.0
```
### Example 4 - Alternative activation shortcut
This example uses Ctrl+Shift+Space as the activation shortcut.
```bash
dsc config set --file peek-altkey.dsc.yaml
```
```yaml
# peek-altkey.dsc.yaml
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
resources:
- name: Alternative Peek shortcut
type: Microsoft.PowerToys/PeekSettings
properties:
settings:
properties:
ActivationShortcut:
win: false
ctrl: true
alt: false
shift: true
code: 32
key: Space
name: Peek
version: 1.0
```
## Use cases
### File browsing
Configure for quick file preview during browsing:
```yaml
resources:
- name: File browsing configuration
type: Microsoft.PowerToys/PeekSettings
properties:
settings:
properties:
CloseAfterLosingFocus: true
name: Peek
version: 1.0
```
### Content review
Configure for extended content review:
```yaml
resources:
- name: Review configuration
type: Microsoft.PowerToys/PeekSettings
properties:
settings:
properties:
CloseAfterLosingFocus: false
name: Peek
version: 1.0
```
## See also
- [Settings Resource][01]
- [PowerToys DSC Overview][02]
- [ShortcutGuide][03]
- [PowerToys Peek Documentation][04]
<!-- Link reference definitions -->
[01]: ../settings-resource.md
[02]: ../overview.md
[03]: ./ShortcutGuide.md
[04]: https://learn.microsoft.com/windows/powertoys/peek

View File

@@ -1,257 +0,0 @@
---
description: DSC configuration reference for PowerToys PowerAccent module
ms.date: 10/18/2025
ms.topic: reference
title: PowerAccent Module
---
# PowerAccent Module
## Synopsis
Manages configuration for the Power Accent utility, a quick accent character selector.
## Description
The `PowerAccent` module configures PowerToys Power Accent (Quick Accent), a
utility that provides quick access to accented characters. Hold down a key
and use arrow keys or numbers to select from available accent variations.
## Properties
The PowerAccent module supports the following configurable properties:
### ActivationKey
Sets which key triggers the accent selection.
**Type:** string
**Allowed values:**
- `"LeftRightArrow"` - Hold left or right arrow keys
- `"Space"` - Hold spacebar
- `"Both"` - Hold either left/right arrows or spacebar
**Default:** `"Both"`
### InputTime
Sets how long the activation key must be held (in milliseconds) before showing accents.
**Type:** integer
**Range:** `100` to `1000`
**Default:** `300`
### ExcludedApps
List of applications where Power Accent is disabled.
**Type:** string (newline-separated list of executable names)
### ToolbarPosition
Sets the position of the accent selection toolbar.
**Type:** string
**Allowed values:**
- `"Top"` - Above the cursor
- `"Bottom"` - Below the cursor
- `"Left"` - To the left of cursor
- `"Right"` - To the right of cursor
- `"Center"` - Centered on screen
**Default:** `"Top"`
### ShowUnicodeDescription
Controls whether Unicode descriptions are shown for each accent character.
**Type:** boolean
**Default:** `false`
### SortByUsageFrequency
Controls whether accent characters are sorted by usage frequency.
**Type:** boolean
**Default:** `false`
### StartSelectionFromTheLeft
Controls whether selection starts from the left side.
**Type:** boolean
**Default:** `false`
## Examples
### Example 1 - Configure activation method with direct execution
This example sets spacebar as the activation key.
```powershell
$config = @{
settings = @{
properties = @{
ActivationKey = "Space"
InputTime = 250
}
name = "PowerAccent"
version = "1.0"
}
} | ConvertTo-Json -Depth 10 -Compress
PowerToys.DSC.exe set --resource 'settings' --module PowerAccent `
--input $config
```
### Example 2 - Configure toolbar appearance with DSC
This example customizes the toolbar position and display options.
```bash
dsc config set --file poweraccent-toolbar.dsc.yaml
```
```yaml
# poweraccent-toolbar.dsc.yaml
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
resources:
- name: Configure Power Accent toolbar
type: Microsoft.PowerToys/PowerAccentSettings
properties:
settings:
properties:
ToolbarPosition: Bottom
ShowUnicodeDescription: true
SortByUsageFrequency: true
name: PowerAccent
version: 1.0
```
### Example 3 - Install and configure with WinGet
This example installs PowerToys and configures Power Accent for multilingual
typing.
```bash
winget configure winget-poweraccent.yaml
```
```yaml
# winget-poweraccent.yaml
$schema: https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2023/08/config/document.json
metadata:
winget:
processor: dscv3
resources:
- name: Install PowerToys
type: Microsoft.WinGet.DSC/WinGetPackage
properties:
id: Microsoft.PowerToys
source: winget
- name: Configure Power Accent
type: Microsoft.PowerToys/PowerAccentSettings
properties:
settings:
properties:
ActivationKey: Space
InputTime: 300
ToolbarPosition: Top
SortByUsageFrequency: true
name: PowerAccent
version: 1.0
```
### Example 4 - Fast activation configuration
This example configures for quick accent selection.
```bash
dsc config set --file poweraccent-fast.dsc.yaml
```
```yaml
# poweraccent-fast.dsc.yaml
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
resources:
- name: Fast accent activation
type: Microsoft.PowerToys/PowerAccentSettings
properties:
settings:
properties:
InputTime: 150
SortByUsageFrequency: true
name: PowerAccent
version: 1.0
```
### Example 5 - Exclude applications
This example excludes specific applications from Power Accent.
```powershell
$config = @{
settings = @{
properties = @{
ExcludedApps = "notepad.exe`nWordPad.exe"
}
name = "PowerAccent"
version = "1.0"
}
} | ConvertTo-Json -Depth 10 -Compress
PowerToys.DSC.exe set --resource 'settings' --module PowerAccent --input $config
```
## Use cases
### Multilingual content creation
Configure for efficient multilingual typing:
```yaml
resources:
- name: Multilingual configuration
type: Microsoft.PowerToys/PowerAccentSettings
properties:
settings:
properties:
ActivationKey: Space
SortByUsageFrequency: true
ShowUnicodeDescription: false
name: PowerAccent
version: 1.0
```
### Language learning
Configure for language learning with Unicode descriptions:
```yaml
resources:
- name: Learning configuration
type: Microsoft.PowerToys/PowerAccentSettings
properties:
settings:
properties:
ShowUnicodeDescription: true
InputTime: 400
name: PowerAccent
version: 1.0
```
## See also
- [Settings Resource][01]
- [PowerToys DSC Overview][02]
- [Workspaces][03]
- [PowerToys Quick Accent Documentation][04]
<!-- Link reference definitions -->
[01]: ../settings-resource.md
[02]: ../overview.md
[03]: ./Workspaces.md
[04]: https://learn.microsoft.com/windows/powertoys/quick-accent

View File

@@ -1,197 +0,0 @@
---
description: DSC configuration reference for PowerToys PowerOCR module
ms.date: 10/18/2025
ms.topic: reference
title: PowerOCR Module
---
# PowerOCR Module
## Synopsis
Manages configuration for the Power OCR (Text Extractor) utility, which
extracts text from images and screen regions.
## Description
The `PowerOCR` module configures PowerToys Power OCR (Text Extractor), a
utility that uses optical character recognition (OCR) to extract text from
any screen region and copy it to the clipboard. It's useful for capturing
text from images, videos, PDFs, or any on-screen content.
## Properties
The PowerOCR module supports the following configurable properties:
### ActivationShortcut
Sets the keyboard shortcut to activate text extraction.
**Type:** object
**Properties:**
- `win` (boolean) - Windows key modifier
- `ctrl` (boolean) - Ctrl key modifier
- `alt` (boolean) - Alt key modifier
- `shift` (boolean) - Shift key modifier
- `code` (integer) - Virtual key code
- `key` (string) - Key name
**Default:** `Win+Shift+T`
### PreferredLanguage
Sets the preferred language for OCR recognition.
**Type:** string
**Default:** System language
## Examples
### Example 1 - Configure activation shortcut with direct execution
This example customizes the OCR activation shortcut.
```powershell
$config = @{
settings = @{
properties = @{
ActivationShortcut = @{
win = $true
ctrl = $false
alt = $false
shift = $true
code = 84
key = "T"
}
}
name = "PowerOCR"
version = "1.0"
}
} | ConvertTo-Json -Depth 10 -Compress
PowerToys.DSC.exe set --resource 'settings' --module PowerOCR `
--input $config
```
### Example 2 - Configure language with DSC
This example sets the preferred OCR language.
```bash
dsc config set --file powerocr-language.dsc.yaml
```
```yaml
# powerocr-language.dsc.yaml
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
resources:
- name: Configure Power OCR language
type: Microsoft.PowerToys/PowerOCRSettings
properties:
settings:
properties:
PreferredLanguage: en-US
name: PowerOCR
version: 1.0
```
### Example 3 - Install and configure with WinGet
This example installs PowerToys and configures Power OCR.
```bash
winget configure winget-powerocr.yaml
```
```yaml
# winget-powerocr.yaml
$schema: https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2023/08/config/document.json
metadata:
winget:
processor: dscv3
resources:
- name: Install PowerToys
type: Microsoft.WinGet.DSC/WinGetPackage
properties:
id: Microsoft.PowerToys
source: winget
- name: Configure Power OCR
type: Microsoft.PowerToys/PowerOCRSettings
properties:
settings:
properties:
PreferredLanguage: en-US
name: PowerOCR
version: 1.0
```
### Example 4 - Multilingual configuration
This example configures for multilingual text extraction.
```bash
dsc config set --file powerocr-multilingual.dsc.yaml
```
```yaml
# powerocr-multilingual.dsc.yaml
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
resources:
- name: Multilingual OCR
type: Microsoft.PowerToys/PowerOCRSettings
properties:
settings:
properties:
PreferredLanguage: fr-FR
name: PowerOCR
version: 1.0
```
## Use cases
### Document digitization
Configure for extracting text from documents:
```yaml
resources:
- name: Document OCR
type: Microsoft.PowerToys/PowerOCRSettings
properties:
settings:
properties:
PreferredLanguage: en-US
name: PowerOCR
version: 1.0
```
### International content
Configure for multilingual content extraction:
```yaml
resources:
- name: Multilingual OCR
type: Microsoft.PowerToys/PowerOCRSettings
properties:
settings:
properties:
PreferredLanguage: es-ES
name: PowerOCR
version: 1.0
```
## See also
- [Settings Resource][01]
- [PowerToys DSC Overview][02]
- [ZoomIt][03]
- [PowerToys Text Extractor Documentation][04]
<!-- Link reference definitions -->
[01]: ../settings-resource.md
[02]: ../overview.md
[03]: ./ZoomIt.md
[04]: https://learn.microsoft.com/windows/powertoys/text-extractor

View File

@@ -1,230 +0,0 @@
---
description: DSC configuration reference for PowerToys PowerRename module
ms.date: 10/18/2025
ms.topic: reference
title: PowerRename Module
---
# PowerRename Module
## Synopsis
Manages configuration for the Power Rename utility, a bulk file and folder renaming tool.
## Description
The `PowerRename` module configures PowerToys Power Rename, a Windows shell
extension that enables bulk renaming of files and folders with advanced
features like regular expressions, preview, and undo functionality. It
integrates with the Windows Explorer context menu.
## Properties
The PowerRename module supports the following configurable properties:
### MRUEnabled
Controls whether the most recently used (MRU) search and replace terms are saved.
**Type:** boolean
**Default:** `true`
### MaxMRUSize
Sets the maximum number of MRU entries to remember.
**Type:** integer
**Range:** `0` to `20`
**Default:** `10`
### ShowIcon
Controls whether the Power Rename icon appears in the Explorer context menu.
**Type:** boolean
**Default:** `true`
### ExtendedContextMenuOnly
Controls whether Power Rename appears only in the extended context menu (Shift+right-click).
**Type:** boolean
**Default:** `false`
### UseBoostLib
Controls whether the Boost library is used for regular expression processing.
**Type:** boolean
**Default:** `false`
## Examples
### Example 1 - Configure MRU settings with direct execution
This example configures the most recently used list behavior.
```powershell
$config = @{
settings = @{
properties = @{
MRUEnabled = $true
MaxMRUSize = 15
}
name = "PowerRename"
version = "1.0"
}
} | ConvertTo-Json -Depth 10 -Compress
PowerToys.DSC.exe set --resource 'settings' --module PowerRename --input $config
```
### Example 2 - Configure context menu with DSC
This example configures Power Rename to appear in the extended context menu
only.
```bash
dsc config set --file powerrename-context.dsc.yaml
```
```yaml
# powerrename-context.dsc.yaml
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
resources:
- name: Configure Power Rename context menu
type: Microsoft.PowerToys/PowerRenameSettings
properties:
settings:
properties:
ExtendedContextMenuOnly: true
ShowIcon: true
name: PowerRename
version: 1.0
```
### Example 3 - Install and configure with WinGet
This example installs PowerToys and configures Power Rename.
```bash
winget configure winget-powerrename.yaml
```
```yaml
# winget-powerrename.yaml
$schema: https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2023/08/config/document.json
metadata:
winget:
processor: dscv3
resources:
- name: Install PowerToys
type: Microsoft.WinGet.DSC/WinGetPackage
properties:
id: Microsoft.PowerToys
source: winget
- name: Configure Power Rename
type: Microsoft.PowerToys/PowerRenameSettings
properties:
settings:
properties:
MRUEnabled: true
MaxMRUSize: 20
ShowIcon: true
UseBoostLib: true
name: PowerRename
version: 1.0
```
### Example 4 - Clean context menu configuration
This example minimizes context menu clutter.
```bash
dsc config set --file powerrename-minimal.dsc.yaml
```
```yaml
# powerrename-minimal.dsc.yaml
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
resources:
- name: Minimal context menu
type: Microsoft.PowerToys/PowerRenameSettings
properties:
settings:
properties:
ExtendedContextMenuOnly: true
ShowIcon: false
name: PowerRename
version: 1.0
```
### Example 5 - Advanced regex configuration
This example enables the Boost library for advanced regex features.
```powershell
$config = @{
settings = @{
properties = @{
UseBoostLib = $true
MRUEnabled = $true
MaxMRUSize = 15
}
name = "PowerRename"
version = "1.0"
}
} | ConvertTo-Json -Depth 10 -Compress
PowerToys.DSC.exe set --resource 'settings' --module PowerRename --input $config
```
## Use cases
### Content management
Configure for frequent file renaming tasks:
```yaml
resources:
- name: Content management
type: Microsoft.PowerToys/PowerRenameSettings
properties:
settings:
properties:
MRUEnabled: true
MaxMRUSize: 20
ShowIcon: true
name: PowerRename
version: 1.0
```
### Clean interface
Configure for minimal context menu presence:
```yaml
resources:
- name: Clean interface
type: Microsoft.PowerToys/PowerRenameSettings
properties:
settings:
properties:
ExtendedContextMenuOnly: true
name: PowerRename
version: 1.0
```
## See also
- [Settings Resource][01]
- [PowerToys DSC Overview][02]
- [AdvancedPaste][03]
- [PowerToys PowerRename Documentation][04]
<!-- Link reference definitions -->
[01]: ../settings-resource.md
[02]: ../overview.md
[03]: ./AdvancedPaste.md
[04]: https://learn.microsoft.com/windows/powertoys/powerrename

View File

@@ -1,173 +0,0 @@
---
description: DSC configuration reference for PowerToys RegistryPreview module
ms.date: 10/18/2025
ms.topic: reference
title: RegistryPreview Module
---
# RegistryPreview Module
## Synopsis
Manages configuration for the Registry Preview utility, which visualizes and edits Windows registry files (.reg).
## Description
The `RegistryPreview` module configures PowerToys Registry Preview, a utility
that provides a visual preview and editing interface for Windows registry
(.reg) files. It helps you understand and safely edit registry files before
applying them to your system.
## Properties
The RegistryPreview module supports the following configurable properties:
### DefaultRegApp
Controls whether Registry Preview is set as the default application for .reg files.
**Type:** boolean
**Default:** `false`
## Examples
### Example 1 - Set as default .reg handler with direct execution
This example sets Registry Preview as the default application for .reg files.
```powershell
$config = @{
settings = @{
properties = @{
DefaultRegApp = $true
}
name = "RegistryPreview"
version = "1.0"
}
} | ConvertTo-Json -Depth 10 -Compress
PowerToys.DSC.exe set --resource 'settings' --module RegistryPreview --input $config
```
### Example 2 - Configure with DSC
This example configures Registry Preview as the default handler.
```bash
dsc config set --file registrypreview-default.dsc.yaml
```
```yaml
# registrypreview-default.dsc.yaml
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
resources:
- name: Set Registry Preview as default
type: Microsoft.PowerToys/RegistryPreviewSettings
properties:
settings:
properties:
DefaultRegApp: true
name: RegistryPreview
version: 1.0
```
### Example 3 - Install and configure with WinGet
This example installs PowerToys and sets Registry Preview as the default .reg
handler.
```bash
winget configure winget-registrypreview.yaml
```
```yaml
# winget-registrypreview.yaml
$schema: https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2023/08/config/document.json
metadata:
winget:
processor: dscv3
resources:
- name: Install PowerToys
type: Microsoft.WinGet.DSC/WinGetPackage
properties:
id: Microsoft.PowerToys
source: winget
- name: Configure Registry Preview
type: Microsoft.PowerToys/RegistryPreviewSettings
properties:
settings:
properties:
DefaultRegApp: true
name: RegistryPreview
version: 1.0
```
### Example 4 - Disable as default handler
This example ensures Registry Preview is not the default .reg handler.
```bash
dsc config set --file registrypreview-notdefault.dsc.yaml
```
```yaml
# registrypreview-notdefault.dsc.yaml
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
resources:
- name: Do not use as default
type: Microsoft.PowerToys/RegistryPreviewSettings
properties:
settings:
properties:
DefaultRegApp: false
name: RegistryPreview
version: 1.0
```
## Use cases
### System administration
Configure as default for safe registry file handling:
```yaml
resources:
- name: Admin configuration
type: Microsoft.PowerToys/RegistryPreviewSettings
properties:
settings:
properties:
DefaultRegApp: true
name: RegistryPreview
version: 1.0
```
### Optional tool
Keep as optional tool without default file association:
```yaml
resources:
- name: Optional tool
type: Microsoft.PowerToys/RegistryPreviewSettings
properties:
settings:
properties:
DefaultRegApp: false
name: RegistryPreview
version: 1.0
```
## See also
- [Settings Resource][01]
- [PowerToys DSC Overview][02]
- [FileLocksmith][03]
- [PowerToys Registry Preview Documentation][04]
<!-- Link reference definitions -->
[01]: ../settings-resource.md
[02]: ../overview.md
[03]: ./FileLocksmith.md
[04]: https://learn.microsoft.com/windows/powertoys/registry-preview

View File

@@ -1,259 +0,0 @@
---
description: DSC configuration reference for PowerToys ShortcutGuide module
ms.date: 10/18/2025
ms.topic: reference
title: ShortcutGuide Module
---
# ShortcutGuide Module
## Synopsis
Manages configuration for the Shortcut Guide utility, which displays available keyboard shortcuts.
## Description
The `ShortcutGuide` module configures PowerToys Shortcut Guide, a utility that
displays an overlay showing available Windows keyboard shortcuts when you hold
the Windows key. It helps users discover and learn keyboard shortcuts.
## Properties
The ShortcutGuide module supports the following configurable properties:
### OpenShortcutGuide
Sets the keyboard shortcut or method to open the shortcut guide.
**Type:** object
**Properties:**
- `win` (boolean) - Windows key modifier
- `ctrl` (boolean) - Ctrl key modifier
- `alt` (boolean) - Alt key modifier
- `shift` (boolean) - Shift key modifier
- `code` (integer) - Virtual key code
- `key` (string) - Key name
**Default:** Hold Windows key for 900ms
### OverlayOpacity
Sets the opacity of the shortcut guide overlay (0-100).
**Type:** integer
**Range:** `0` to `100`
**Default:** `90`
### Theme
Sets the theme for the shortcut guide.
**Type:** string
**Allowed values:** `"light"`, `"dark"`, `"system"`
**Default:** `"dark"`
### PressTime
Sets how long the Windows key must be held before showing the guide (in milliseconds).
**Type:** integer
**Range:** `100` to `10000`
**Default:** `900`
### ExcludedApps
List of applications where Shortcut Guide is disabled.
**Type:** string (newline-separated list of executable names)
## Examples
### Example 1 - Configure activation time with direct execution
This example sets a faster activation time for the shortcut guide.
```powershell
$config = @{
settings = @{
properties = @{
PressTime = 600
}
name = "ShortcutGuide"
version = "1.0"
}
} | ConvertTo-Json -Depth 10 -Compress
PowerToys.DSC.exe set --resource 'settings' --module ShortcutGuide `
--input $config
```
### Example 2 - Configure appearance with DSC
This example customizes the overlay appearance.
```bash
dsc config set --file shortcutguide-appearance.dsc.yaml
```
```yaml
# shortcutguide-appearance.dsc.yaml
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
resources:
- name: Configure Shortcut Guide appearance
type: Microsoft.PowerToys/ShortcutGuideSettings
properties:
settings:
properties:
OverlayOpacity: 95
Theme: light
name: ShortcutGuide
version: 1.0
```
### Example 3 - Install and configure with WinGet
This example installs PowerToys and configures Shortcut Guide.
```bash
winget configure winget-shortcutguide.yaml
```
```yaml
# winget-shortcutguide.yaml
$schema: https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2023/08/config/document.json
metadata:
winget:
processor: dscv3
resources:
- name: Install PowerToys
type: Microsoft.WinGet.DSC/WinGetPackage
properties:
id: Microsoft.PowerToys
source: winget
- name: Configure Shortcut Guide
type: Microsoft.PowerToys/ShortcutGuideSettings
properties:
settings:
properties:
PressTime: 700
OverlayOpacity: 90
Theme: dark
name: ShortcutGuide
version: 1.0
```
### Example 4 - Quick activation
This example configures for quick activation with a short press time.
```bash
dsc config set --file shortcutguide-quick.dsc.yaml
```
```yaml
# shortcutguide-quick.dsc.yaml
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
resources:
- name: Quick activation
type: Microsoft.PowerToys/ShortcutGuideSettings
properties:
settings:
properties:
PressTime: 400
name: ShortcutGuide
version: 1.0
```
### Example 5 - High opacity for visibility
This example maximizes opacity for better visibility.
```powershell
$config = @{
settings = @{
properties = @{
OverlayOpacity = 100
Theme = "dark"
}
name = "ShortcutGuide"
version = "1.0"
}
} | ConvertTo-Json -Depth 10 -Compress
PowerToys.DSC.exe set --resource 'settings' --module ShortcutGuide --input $config
```
### Example 6 - Exclude applications
This example excludes Shortcut Guide from specific applications.
```bash
dsc config set --file shortcutguide-exclusions.dsc.yaml
```
```yaml
# shortcutguide-exclusions.dsc.yaml
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
resources:
- name: Exclude apps
type: Microsoft.PowerToys/ShortcutGuideSettings
properties:
settings:
properties:
ExcludedApps: |
Game.exe
FullScreenApp.exe
name: ShortcutGuide
version: 1.0
```
## Use cases
### New users
Configure for easy keyboard shortcut discovery:
```yaml
resources:
- name: New user configuration
type: Microsoft.PowerToys/ShortcutGuideSettings
properties:
settings:
properties:
PressTime: 800
OverlayOpacity: 95
name: ShortcutGuide
version: 1.0
```
### Power users
Configure for quick access without accidental activation:
```yaml
resources:
- name: Power user configuration
type: Microsoft.PowerToys/ShortcutGuideSettings
properties:
settings:
properties:
PressTime: 1200
OverlayOpacity: 85
name: ShortcutGuide
version: 1.0
```
## See also
- [Settings Resource][01]
- [PowerToys DSC Overview][02]
- [Peek][03]
- [PowerToys Keyboard Shortcut Guide Documentation][04]
<!-- Link reference definitions -->
[01]: ../settings-resource.md
[02]: ../overview.md
[03]: ./Peek.md
[04]: https://learn.microsoft.com/windows/powertoys/shortcut-guide

View File

@@ -1,238 +0,0 @@
---
description: DSC configuration reference for PowerToys Workspaces module
ms.date: 10/18/2025
ms.topic: reference
title: Workspaces Module
---
# Workspaces Module
## Synopsis
Manages configuration for the Workspaces utility, which launches application sets and arranges windows.
## Description
The `Workspaces` module configures PowerToys Workspaces, a utility that allows
you to save and restore sets of applications with their window positions. It
enables you to quickly switch between different work contexts by launching and
arranging multiple applications at once.
## Properties
The Workspaces module supports the following configurable properties:
### LaunchHotkey
Sets the keyboard shortcut to launch the Workspaces editor.
**Type:** object
**Properties:**
- `win` (boolean) - Windows key modifier
- `ctrl` (boolean) - Ctrl key modifier
- `alt` (boolean) - Alt key modifier
- `shift` (boolean) - Shift key modifier
- `code` (integer) - Virtual key code
- `key` (string) - Key name
**Default:** `Win+Shift+;` (VK code 186)
### MoveExistingWindows
Controls whether existing application windows are moved when launching a workspace.
**Type:** boolean
**Default:** `false`
### SpanZonesAcrossMonitors
Controls whether workspace zones can span across multiple monitors.
**Type:** boolean
**Default:** `false`
## Examples
### Example 1 - Configure launch hotkey with direct execution
This example sets a custom hotkey to launch the Workspaces editor.
```powershell
$config = @{
settings = @{
properties = @{
LaunchHotkey = @{
win = $true
ctrl = $true
alt = $false
shift = $false
code = 87
key = "W"
}
}
name = "Workspaces"
version = "1.0"
}
} | ConvertTo-Json -Depth 10 -Compress
PowerToys.DSC.exe set --resource 'settings' --module Workspaces --input $config
```
### Example 2 - Configure window behavior with DSC
This example enables moving existing windows when launching workspaces.
```bash
dsc config set --file workspaces-behavior.dsc.yaml
```
```yaml
# workspaces-behavior.dsc.yaml
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
resources:
- name: Configure Workspaces window behavior
type: Microsoft.PowerToys/WorkspacesSettings
properties:
settings:
properties:
MoveExistingWindows: true
SpanZonesAcrossMonitors: false
name: Workspaces
version: 1.0
```
### Example 3 - Install and configure with WinGet
This example installs PowerToys and configures Workspaces.
```bash
winget configure winget-workspaces.yaml
```
```yaml
# winget-workspaces.yaml
$schema: https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2023/08/config/document.json
metadata:
winget:
processor: dscv3
resources:
- name: Install PowerToys
type: Microsoft.WinGet.DSC/WinGetPackage
properties:
id: Microsoft.PowerToys
source: winget
- name: Configure Workspaces
type: Microsoft.PowerToys/WorkspacesSettings
properties:
settings:
properties:
LaunchHotkey:
win: true
ctrl: false
alt: false
shift: true
code: 186
key: ";"
MoveExistingWindows: true
name: Workspaces
version: 1.0
```
### Example 4 - Multi-monitor setup
This example configures for multi-monitor workspace management.
```bash
dsc config set --file workspaces-multimonitor.dsc.yaml
```
```yaml
# workspaces-multimonitor.dsc.yaml
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
resources:
- name: Multi-monitor configuration
type: Microsoft.PowerToys/WorkspacesSettings
properties:
settings:
properties:
SpanZonesAcrossMonitors: true
MoveExistingWindows: true
name: Workspaces
version: 1.0
```
### Example 5 - Simple hotkey
This example sets a simple single-key hotkey combination.
```powershell
$config = @{
settings = @{
properties = @{
LaunchHotkey = @{
win = $true
ctrl = $false
alt = $true
shift = $false
code = 192
key = "~"
}
}
name = "Workspaces"
version = "1.0"
}
} | ConvertTo-Json -Depth 10 -Compress
PowerToys.DSC.exe set --resource 'settings' --module Workspaces --input $config
```
## Use cases
### Development environments
Configure for quick switching between development workspaces:
```yaml
resources:
- name: Development workspace
type: Microsoft.PowerToys/WorkspacesSettings
properties:
settings:
properties:
MoveExistingWindows: true
SpanZonesAcrossMonitors: true
name: Workspaces
version: 1.0
```
### Single monitor usage
Configure for single-monitor workflow:
```yaml
resources:
- name: Single monitor setup
type: Microsoft.PowerToys/WorkspacesSettings
properties:
settings:
properties:
SpanZonesAcrossMonitors: false
MoveExistingWindows: false
name: Workspaces
version: 1.0
```
## See also
- [Settings Resource][01]
- [PowerToys DSC Overview][02]
- [ColorPicker Module][03] - For additional PowerToys configuration
- [PowerToys Workspaces Documentation][04]
<!-- Link reference definitions -->
[01]: ../settings-resource.md
[02]: ../overview.md
[03]: ./ColorPicker.md
[04]: https://learn.microsoft.com/windows/powertoys/workspaces

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