mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-16 11:48:06 +01:00
Merge branch 'main' into niels9001/assistive-tools-settings
This commit is contained in:
7
.github/actions/spell-check/allow/code.txt
vendored
7
.github/actions/spell-check/allow/code.txt
vendored
@@ -95,6 +95,7 @@ OTP
|
||||
Yubi
|
||||
Yubico
|
||||
Perplexity
|
||||
Groq
|
||||
svgl
|
||||
|
||||
# KEYS
|
||||
@@ -328,3 +329,9 @@ FFF
|
||||
HHH
|
||||
riday
|
||||
YYY
|
||||
|
||||
# GitHub issue/PR commands
|
||||
azp
|
||||
feedbackhub
|
||||
needinfo
|
||||
reportbug
|
||||
|
||||
121
.github/actions/spell-check/expect.txt
vendored
121
.github/actions/spell-check/expect.txt
vendored
@@ -2,8 +2,8 @@ AAAAs
|
||||
abcdefghjkmnpqrstuvxyz
|
||||
abgr
|
||||
ABlocked
|
||||
ABOUTBOX
|
||||
ABORTIFHUNG
|
||||
ABOUTBOX
|
||||
Abug
|
||||
Acceleratorkeys
|
||||
ACCEPTFILES
|
||||
@@ -56,6 +56,7 @@ ANull
|
||||
AOC
|
||||
aocfnapldcnfbofgmbbllojgocaelgdd
|
||||
AOklab
|
||||
aot
|
||||
APARTMENTTHREADED
|
||||
APeriod
|
||||
apicontract
|
||||
@@ -97,8 +98,8 @@ ASSOCSTR
|
||||
ASYNCWINDOWPLACEMENT
|
||||
ASYNCWINDOWPOS
|
||||
atl
|
||||
ATX
|
||||
ATRIOX
|
||||
ATX
|
||||
aumid
|
||||
authenticode
|
||||
AUTOBUDDY
|
||||
@@ -117,10 +118,10 @@ azman
|
||||
azureaiinference
|
||||
azureinference
|
||||
azureopenai
|
||||
backticks
|
||||
bbwe
|
||||
BCIE
|
||||
bck
|
||||
backticks
|
||||
BESTEFFORT
|
||||
bezelled
|
||||
bhid
|
||||
@@ -148,8 +149,8 @@ bmi
|
||||
BNumber
|
||||
BODGY
|
||||
BOklab
|
||||
Bootstrappers
|
||||
BOOTSTRAPPERINSTALLFOLDER
|
||||
Bootstrappers
|
||||
BOTTOMALIGN
|
||||
boxmodel
|
||||
BPBF
|
||||
@@ -176,17 +177,16 @@ BYPOSITION
|
||||
CALCRECT
|
||||
CALG
|
||||
callbackptr
|
||||
cabstr
|
||||
calpwstr
|
||||
caub
|
||||
Cangjie
|
||||
CANRENAME
|
||||
Carlseibert
|
||||
Canvascustomlayout
|
||||
CAPTUREBLT
|
||||
CAPTURECHANGED
|
||||
CARETBLINKING
|
||||
Carlseibert
|
||||
CAtl
|
||||
caub
|
||||
CBN
|
||||
cch
|
||||
CCHDEVICENAME
|
||||
@@ -206,11 +206,9 @@ changecursor
|
||||
CHILDACTIVATE
|
||||
CHILDWINDOW
|
||||
CHOOSEFONT
|
||||
CIBUILD
|
||||
cidl
|
||||
CIELCh
|
||||
cim
|
||||
claude
|
||||
CImage
|
||||
cla
|
||||
CLASSDC
|
||||
@@ -223,6 +221,7 @@ clientside
|
||||
CLIPBOARDUPDATE
|
||||
CLIPCHILDREN
|
||||
CLIPSIBLINGS
|
||||
CLITo
|
||||
closesocket
|
||||
clp
|
||||
CLSCTX
|
||||
@@ -264,7 +263,6 @@ CONFIGW
|
||||
CONFLICTINGMODIFIERKEY
|
||||
CONFLICTINGMODIFIERSHORTCUT
|
||||
CONOUT
|
||||
coreclr
|
||||
constexpr
|
||||
contentdialog
|
||||
contentfiles
|
||||
@@ -276,6 +274,7 @@ copiedcolorrepresentation
|
||||
coppied
|
||||
copyable
|
||||
COPYPEN
|
||||
coreclr
|
||||
COREWINDOW
|
||||
Corpor
|
||||
cotaskmem
|
||||
@@ -284,18 +283,18 @@ countof
|
||||
covrun
|
||||
cpcontrols
|
||||
cph
|
||||
cppcoreguidelines
|
||||
cplusplus
|
||||
CPower
|
||||
cppcoreguidelines
|
||||
cpptools
|
||||
cppvsdbg
|
||||
cppwinrt
|
||||
createdump
|
||||
creativecommons
|
||||
CREATEPROCESS
|
||||
CREATESCHEDULEDTASK
|
||||
CREATESTRUCT
|
||||
CREATEWINDOWFAILED
|
||||
creativecommons
|
||||
CRECT
|
||||
CRH
|
||||
critsec
|
||||
@@ -331,7 +330,6 @@ CYSCREEN
|
||||
CYSMICON
|
||||
CYVIRTUALSCREEN
|
||||
Czechia
|
||||
cziplib
|
||||
Dac
|
||||
dacl
|
||||
DAffine
|
||||
@@ -355,9 +353,7 @@ Deact
|
||||
debugbreak
|
||||
decryptor
|
||||
Dedup
|
||||
dfx
|
||||
Deduplicator
|
||||
Deeplink
|
||||
DEFAULTBOOTSTRAPPERINSTALLFOLDER
|
||||
DEFAULTCOLOR
|
||||
DEFAULTFLAGS
|
||||
@@ -404,7 +400,6 @@ DISPLAYFREQUENCY
|
||||
displayname
|
||||
DISPLAYORIENTATION
|
||||
divyan
|
||||
djwsxzxb
|
||||
Dlg
|
||||
DLGFRAME
|
||||
DLGMODALFRAME
|
||||
@@ -417,7 +412,6 @@ DONTVALIDATEPATH
|
||||
dotnet
|
||||
downsampled
|
||||
downsampling
|
||||
Downsampled
|
||||
downscale
|
||||
DPICHANGED
|
||||
DPIs
|
||||
@@ -531,7 +525,6 @@ EXTRINSICPROPERTIES
|
||||
eyetracker
|
||||
FANCYZONESDRAWLAYOUTTEST
|
||||
FANCYZONESEDITOR
|
||||
FNumber
|
||||
FARPROC
|
||||
fdx
|
||||
fesf
|
||||
@@ -563,8 +556,8 @@ FIXEDSYS
|
||||
flac
|
||||
flyouts
|
||||
FMask
|
||||
foundrylocal
|
||||
fmtid
|
||||
FNumber
|
||||
FOF
|
||||
FOFX
|
||||
FOLDERID
|
||||
@@ -575,6 +568,7 @@ FORCEMINIMIZE
|
||||
FORMATDLGORD
|
||||
formatetc
|
||||
FORPARSING
|
||||
foundrylocal
|
||||
FRAMECHANGED
|
||||
frm
|
||||
FROMTOUCH
|
||||
@@ -593,13 +587,13 @@ gdi
|
||||
gdiplus
|
||||
GDIPVER
|
||||
GDISCALED
|
||||
geolocator
|
||||
GETCLIENTAREAANIMATION
|
||||
GETCURSEL
|
||||
GETDESKWALLPAPER
|
||||
GETDLGCODE
|
||||
GETDPISCALEDSIZE
|
||||
getfilesiginforedist
|
||||
geolocator
|
||||
GETHOTKEY
|
||||
GETICON
|
||||
GETLBTEXT
|
||||
@@ -610,11 +604,12 @@ GETSCREENSAVERRUNNING
|
||||
GETSECKEY
|
||||
GETSTICKYKEYS
|
||||
GETTEXTLENGTH
|
||||
GIFs
|
||||
gitmodules
|
||||
GHND
|
||||
gitmodules
|
||||
GMEM
|
||||
GNumber
|
||||
googleai
|
||||
googlegemini
|
||||
gpedit
|
||||
gpo
|
||||
GPOCA
|
||||
@@ -631,8 +626,6 @@ GValue
|
||||
gwl
|
||||
GWLP
|
||||
GWLSTYLE
|
||||
googleai
|
||||
googlegemini
|
||||
hangeul
|
||||
Hanzi
|
||||
Hardlines
|
||||
@@ -736,16 +729,14 @@ HWNDPARENT
|
||||
HWNDPREV
|
||||
hyjiacan
|
||||
IAI
|
||||
icf
|
||||
ICONERROR
|
||||
ICONLOCATION
|
||||
icf
|
||||
IDCANCEL
|
||||
IDD
|
||||
idk
|
||||
idl
|
||||
IIM
|
||||
idlist
|
||||
ifd
|
||||
IDOK
|
||||
IDOn
|
||||
IDR
|
||||
@@ -754,15 +745,16 @@ ietf
|
||||
IEXPLORE
|
||||
IFACEMETHOD
|
||||
IFACEMETHODIMP
|
||||
ifd
|
||||
IGNOREUNKNOWN
|
||||
IGo
|
||||
iid
|
||||
IIM
|
||||
Iindex
|
||||
Ijwhost
|
||||
ILD
|
||||
IMAGEHLP
|
||||
IMAGERESIZERCONTEXTMENU
|
||||
IPTC
|
||||
IMAGERESIZEREXT
|
||||
imageresizerinput
|
||||
imageresizersettings
|
||||
@@ -782,6 +774,7 @@ INITGUID
|
||||
INITTOLOGFONTSTRUCT
|
||||
INLINEPREFIX
|
||||
inlines
|
||||
Inno
|
||||
INPC
|
||||
inproc
|
||||
INPUTHARDWARE
|
||||
@@ -798,7 +791,6 @@ INSTALLFOLDERTOPREVIOUSINSTALLFOLDER
|
||||
INSTALLLOCATION
|
||||
INSTALLMESSAGE
|
||||
INSTALLPROPERTY
|
||||
installscopeperuser
|
||||
INSTALLSTARTMENUSHORTCUT
|
||||
INSTALLSTATE
|
||||
Inste
|
||||
@@ -811,6 +803,7 @@ invokecommand
|
||||
ipcmanager
|
||||
IPREVIEW
|
||||
ipreviewhandlervisualssetfont
|
||||
IPTC
|
||||
irow
|
||||
irprops
|
||||
isbi
|
||||
@@ -854,15 +847,14 @@ keyvault
|
||||
KILLFOCUS
|
||||
killrunner
|
||||
kmph
|
||||
ksa
|
||||
kvp
|
||||
Kybd
|
||||
LARGEICON
|
||||
lastcodeanalysissucceeded
|
||||
LASTEXITCODE
|
||||
LAYOUTRTL
|
||||
LCh
|
||||
lbl
|
||||
LCh
|
||||
lcid
|
||||
LCIDTo
|
||||
lcl
|
||||
@@ -878,10 +870,10 @@ LExit
|
||||
lhwnd
|
||||
LIBFUZZER
|
||||
LIBID
|
||||
lightswitch
|
||||
LIMITSIZE
|
||||
LIMITTEXT
|
||||
lindex
|
||||
lightswitch
|
||||
linkid
|
||||
LINKOVERLAY
|
||||
LINQTo
|
||||
@@ -892,6 +884,7 @@ LLKH
|
||||
llkhf
|
||||
LMEM
|
||||
LMENU
|
||||
lng
|
||||
LOADFROMFILE
|
||||
LOBYTE
|
||||
localappdata
|
||||
@@ -901,17 +894,14 @@ LOCATIONCHANGE
|
||||
LOCKTYPE
|
||||
LOGFONT
|
||||
LOGFONTW
|
||||
logon
|
||||
lon
|
||||
LOGMSG
|
||||
logon
|
||||
LOGPIXELSX
|
||||
LOGPIXELSY
|
||||
lng
|
||||
lon
|
||||
longdate
|
||||
LONGNAMES
|
||||
lowlevel
|
||||
lquadrant
|
||||
LOWORD
|
||||
lparam
|
||||
LPBITMAPINFOHEADER
|
||||
@@ -945,6 +935,7 @@ lpv
|
||||
LPW
|
||||
lpwcx
|
||||
lpwndpl
|
||||
lquadrant
|
||||
LReader
|
||||
LRESULT
|
||||
LSTATUS
|
||||
@@ -971,6 +962,7 @@ MAKELONG
|
||||
MAKELPARAM
|
||||
makepri
|
||||
MAKEWPARAM
|
||||
Malware
|
||||
manifestdependency
|
||||
MAPPEDTOSAMEKEY
|
||||
MAPTOSAMESHORTCUT
|
||||
@@ -993,8 +985,8 @@ MENUITEMINFO
|
||||
MENUITEMINFOW
|
||||
MERGECOPY
|
||||
MERGEPAINT
|
||||
Metadatas
|
||||
metadatamatters
|
||||
Metadatas
|
||||
metafile
|
||||
mfc
|
||||
Mgmt
|
||||
@@ -1040,9 +1032,6 @@ mousepointer
|
||||
mouseutils
|
||||
MOVESIZEEND
|
||||
MOVESIZESTART
|
||||
muxx
|
||||
muxxc
|
||||
muxxh
|
||||
MRM
|
||||
MRT
|
||||
mru
|
||||
@@ -1071,16 +1060,21 @@ msrc
|
||||
msstore
|
||||
msvcp
|
||||
MT
|
||||
mstsc
|
||||
MTND
|
||||
MULTIPLEUSE
|
||||
multizone
|
||||
muxc
|
||||
muxx
|
||||
muxxc
|
||||
muxxh
|
||||
MVPs
|
||||
mvvm
|
||||
MVVMTK
|
||||
MWBEx
|
||||
MYICON
|
||||
NAMECHANGE
|
||||
Notavailable
|
||||
namespaceanddescendants
|
||||
nao
|
||||
NCACTIVATE
|
||||
@@ -1157,7 +1151,6 @@ nonstd
|
||||
NOOWNERZORDER
|
||||
NOPARENTNOTIFY
|
||||
NOPREFIX
|
||||
NPU
|
||||
NOREDIRECTIONBITMAP
|
||||
NOREDRAW
|
||||
NOREMOVE
|
||||
@@ -1186,6 +1179,7 @@ nowarn
|
||||
NOZORDER
|
||||
NPH
|
||||
npmjs
|
||||
NPU
|
||||
NResize
|
||||
NTAPI
|
||||
ntdll
|
||||
@@ -1210,15 +1204,17 @@ oldpath
|
||||
oldtheme
|
||||
oleaut
|
||||
OLECHAR
|
||||
ollama
|
||||
onebranch
|
||||
onnx
|
||||
OOBEUI
|
||||
openas
|
||||
opencode
|
||||
OPENFILENAME
|
||||
openrdp
|
||||
opensource
|
||||
openxmlformats
|
||||
ollama
|
||||
Olllama
|
||||
onnx
|
||||
OPTIMIZEFORINVOKE
|
||||
ORPHANEDDIALOGTITLE
|
||||
@@ -1292,6 +1288,7 @@ pguid
|
||||
phbm
|
||||
phbmp
|
||||
phicon
|
||||
Photoshop
|
||||
phwnd
|
||||
pici
|
||||
pidl
|
||||
@@ -1314,7 +1311,6 @@ pnid
|
||||
PNMLINK
|
||||
Poc
|
||||
Podcasts
|
||||
Photoshop
|
||||
POINTERID
|
||||
POINTERUPDATE
|
||||
Pokedex
|
||||
@@ -1409,10 +1405,9 @@ pwsz
|
||||
pwtd
|
||||
QDC
|
||||
qit
|
||||
QNN
|
||||
Qualcomm
|
||||
QITAB
|
||||
QITABENT
|
||||
QNN
|
||||
qoi
|
||||
Quarternary
|
||||
QUERYENDSESSION
|
||||
@@ -1422,8 +1417,8 @@ quickaccent
|
||||
QUNS
|
||||
RAII
|
||||
RAlt
|
||||
RAquadrant
|
||||
randi
|
||||
RAquadrant
|
||||
rasterization
|
||||
Rasterize
|
||||
RAWINPUTDEVICE
|
||||
@@ -1433,6 +1428,8 @@ RAWPATH
|
||||
rbhid
|
||||
rclsid
|
||||
RCZOOMIT
|
||||
remotedesktop
|
||||
rdp
|
||||
RDW
|
||||
READMODE
|
||||
READOBJECTS
|
||||
@@ -1450,9 +1447,7 @@ regfile
|
||||
REGISTERCLASSFAILED
|
||||
REGISTRYHEADER
|
||||
REGISTRYPREVIEWEXT
|
||||
registryroot
|
||||
regkey
|
||||
regroot
|
||||
regsvr
|
||||
REINSTALLMODE
|
||||
releaseblog
|
||||
@@ -1488,6 +1483,7 @@ rgh
|
||||
rgn
|
||||
rgs
|
||||
rguid
|
||||
rhk
|
||||
RIDEV
|
||||
RIGHTSCROLLBAR
|
||||
riid
|
||||
@@ -1505,7 +1501,6 @@ rstringalpha
|
||||
rstringdigit
|
||||
rtb
|
||||
RTLREADING
|
||||
rtm
|
||||
runas
|
||||
rundll
|
||||
rungameid
|
||||
@@ -1562,8 +1557,8 @@ SETRULES
|
||||
SETSCREENSAVEACTIVE
|
||||
SETSTICKYKEYS
|
||||
SETTEXT
|
||||
settingscard
|
||||
SETTINGCHANGE
|
||||
settingscard
|
||||
SETTINGSCHANGED
|
||||
settingsheader
|
||||
settingshotkeycontrol
|
||||
@@ -1594,6 +1589,7 @@ SHGDNF
|
||||
SHGFI
|
||||
SHIL
|
||||
shinfo
|
||||
shk
|
||||
shlwapi
|
||||
shobjidl
|
||||
SHORTCUTATLEAST
|
||||
@@ -1638,6 +1634,7 @@ SKIPOWNPROCESS
|
||||
sku
|
||||
SLGP
|
||||
sln
|
||||
slnx
|
||||
SMALLICON
|
||||
smartphone
|
||||
smileys
|
||||
@@ -1708,6 +1705,7 @@ stringtable
|
||||
stringval
|
||||
Strm
|
||||
strret
|
||||
STRSAFE
|
||||
stscanf
|
||||
sttngs
|
||||
Stubless
|
||||
@@ -1719,7 +1717,6 @@ sublang
|
||||
SUBMODULEUPDATE
|
||||
subresource
|
||||
Superbar
|
||||
suntimes
|
||||
sut
|
||||
svchost
|
||||
SVGIn
|
||||
@@ -1753,7 +1750,6 @@ SYSTEMMODAL
|
||||
SYSTEMTIME
|
||||
TARG
|
||||
TARGETAPPHEADER
|
||||
TARGETDIR
|
||||
targetentrypoint
|
||||
TARGETHEADER
|
||||
targetver
|
||||
@@ -1783,10 +1779,10 @@ textextractor
|
||||
TEXTINCLUDE
|
||||
tfopen
|
||||
tgz
|
||||
THEMECHANGED
|
||||
themeresources
|
||||
THH
|
||||
THICKFRAME
|
||||
THEMECHANGED
|
||||
THISCOMPONENT
|
||||
throughs
|
||||
TILEDWINDOW
|
||||
@@ -1804,6 +1800,7 @@ tlbimp
|
||||
tlc
|
||||
tmain
|
||||
TNP
|
||||
toolgood
|
||||
Toolhelp
|
||||
toolwindow
|
||||
TOPDOWNDIB
|
||||
@@ -1857,6 +1854,7 @@ UNCPRIORITY
|
||||
UNDNAME
|
||||
UNICODETEXT
|
||||
unins
|
||||
Uninstaller
|
||||
uninstalls
|
||||
Uniquifies
|
||||
unitconverter
|
||||
@@ -1883,7 +1881,6 @@ USEINSTALLERFORTEST
|
||||
USESHOWWINDOW
|
||||
USESTDHANDLES
|
||||
USRDLL
|
||||
utm
|
||||
UType
|
||||
uuidv
|
||||
uwp
|
||||
@@ -1956,11 +1953,11 @@ Wca
|
||||
WCE
|
||||
wcex
|
||||
WClass
|
||||
WCRAPI
|
||||
wcsicmp
|
||||
wcsncpy
|
||||
wcsnicmp
|
||||
WCT
|
||||
WCRAPI
|
||||
WDA
|
||||
wdm
|
||||
wdp
|
||||
@@ -1988,6 +1985,7 @@ WINDOWPLACEMENT
|
||||
WINDOWPOSCHANGED
|
||||
WINDOWPOSCHANGING
|
||||
WINDOWSBUILDNUMBER
|
||||
windowsml
|
||||
windowssearch
|
||||
windowssettings
|
||||
WINDOWSTYLES
|
||||
@@ -2003,9 +2001,8 @@ Winhook
|
||||
WINL
|
||||
winlogon
|
||||
winmd
|
||||
WINNT
|
||||
windowsml
|
||||
winml
|
||||
WINNT
|
||||
winres
|
||||
winrt
|
||||
winsdk
|
||||
@@ -2067,20 +2064,21 @@ WTSAT
|
||||
Wubi
|
||||
WUX
|
||||
Wwanpp
|
||||
xap
|
||||
XAxis
|
||||
XButton
|
||||
xclip
|
||||
xcopy
|
||||
xap
|
||||
XDeployment
|
||||
XDimension
|
||||
xdf
|
||||
XDimension
|
||||
XDocument
|
||||
XElement
|
||||
xfd
|
||||
XFile
|
||||
XIncrement
|
||||
XLoc
|
||||
xmp
|
||||
XNamespace
|
||||
Xoshiro
|
||||
XPels
|
||||
@@ -2091,23 +2089,22 @@ xsi
|
||||
XSpeed
|
||||
XStr
|
||||
xstyler
|
||||
xmp
|
||||
XTimer
|
||||
XUP
|
||||
XVIRTUALSCREEN
|
||||
xxxxxx
|
||||
YAxis
|
||||
ycombinator
|
||||
YIncrement
|
||||
YDimension
|
||||
YIncrement
|
||||
yinle
|
||||
yinyue
|
||||
YPels
|
||||
YPos
|
||||
YResolution
|
||||
YSpeed
|
||||
YTimer
|
||||
YStr
|
||||
YTimer
|
||||
YVIRTUALSCREEN
|
||||
ZEROINIT
|
||||
zonability
|
||||
|
||||
2
.github/workflows/dependency-review.yml
vendored
2
.github/workflows/dependency-review.yml
vendored
@@ -21,6 +21,6 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: 'Checkout Repository'
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
- name: 'Dependency Review'
|
||||
uses: actions/dependency-review-action@v4
|
||||
@@ -27,7 +27,7 @@ jobs:
|
||||
issue: ${{ fromJson(github.event.inputs.issue_numbers) }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Run GenAI Issue Deduplicator
|
||||
uses: pelikhan/action-genai-issue-dedup@v0
|
||||
|
||||
@@ -60,6 +60,8 @@
|
||||
"PowerToys.FancyZonesEditorCommon.dll",
|
||||
"PowerToys.FancyZonesModuleInterface.dll",
|
||||
"PowerToys.FancyZones.exe",
|
||||
"FancyZonesCLI.exe",
|
||||
"FancyZonesCLI.dll",
|
||||
|
||||
"PowerToys.GcodePreviewHandler.dll",
|
||||
"PowerToys.GcodePreviewHandler.exe",
|
||||
@@ -351,6 +353,11 @@
|
||||
"Microsoft.SemanticKernel.Connectors.Ollama.dll",
|
||||
"OllamaSharp.dll",
|
||||
|
||||
"boost_regex-vc143-mt-gd-x32-1_87.dll",
|
||||
"boost_regex-vc143-mt-gd-x64-1_87.dll",
|
||||
"boost_regex-vc143-mt-x32-1_87.dll",
|
||||
"boost_regex-vc143-mt-x64-1_87.dll",
|
||||
|
||||
"UnitsNet.dll",
|
||||
"UtfUnknown.dll",
|
||||
"Wpf.Ui.dll"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.PowerToys.Telemetry" version="2.0.3" />
|
||||
<package id="Microsoft.PowerToys.Telemetry" version="2.0.4" />
|
||||
</packages>
|
||||
|
||||
@@ -192,14 +192,14 @@ jobs:
|
||||
displayName: Verify XAML formatting
|
||||
|
||||
- pwsh: |-
|
||||
& '.pipelines/verifyNugetPackages.ps1' -solution '$(build.sourcesdirectory)\PowerToys.sln'
|
||||
displayName: Verify Nuget package versions for PowerToys.sln
|
||||
& '.pipelines/verifyNugetPackages.ps1' -solution '$(build.sourcesdirectory)\PowerToys.slnx'
|
||||
displayName: Verify Nuget package versions for PowerToys.slnx
|
||||
|
||||
- pwsh: |-
|
||||
& '.pipelines/verifyArm64Configuration.ps1' -solution '$(build.sourcesdirectory)\PowerToys.sln'
|
||||
& '.pipelines/verifyArm64Configuration.ps1' -solution '$(build.sourcesdirectory)\PowerToys.slnx'
|
||||
& '.pipelines/verifyArm64Configuration.ps1' -solution '$(build.sourcesdirectory)\tools\BugReportTool\BugReportTool.sln'
|
||||
& '.pipelines/verifyArm64Configuration.ps1' -solution '$(build.sourcesdirectory)\tools\StylesReportTool\StylesReportTool.sln'
|
||||
& '.pipelines/verifyArm64Configuration.ps1' -solution '$(build.sourcesdirectory)\installer\PowerToysSetup.sln'
|
||||
& '.pipelines/verifyArm64Configuration.ps1' -solution '$(build.sourcesdirectory)\installer\PowerToysSetup.slnx'
|
||||
displayName: Verify ARM64 configurations
|
||||
|
||||
- ${{ if eq(parameters.enablePackageCaching, true) }}:
|
||||
@@ -252,7 +252,7 @@ jobs:
|
||||
${{ else }}:
|
||||
displayName: Build PowerToys main project
|
||||
inputs:
|
||||
solution: 'PowerToys.sln'
|
||||
solution: 'PowerToys.slnx'
|
||||
vsVersion: 17.0
|
||||
msbuildArgs: >-
|
||||
-restore -graph
|
||||
@@ -275,7 +275,7 @@ jobs:
|
||||
displayName: Generate DSC artifacts for ARM64
|
||||
condition: and(succeeded(), eq(variables['BuildPlatform'], 'arm64'))
|
||||
inputs:
|
||||
solution: PowerToys.sln
|
||||
solution: PowerToys.slnx
|
||||
vsVersion: 17.0
|
||||
msbuildArgs: >-
|
||||
-restore
|
||||
|
||||
@@ -74,7 +74,7 @@ jobs:
|
||||
command: restore
|
||||
feedsToUse: config
|
||||
configPath: nuget.config
|
||||
restoreSolution: PowerToys.sln
|
||||
restoreSolution: PowerToys.slnx
|
||||
restoreDirectory: '$(Build.SourcesDirectory)\packages'
|
||||
|
||||
# Build all UI test projects if no specific modules are specified
|
||||
|
||||
@@ -35,7 +35,7 @@ steps:
|
||||
- task: VSBuild@1
|
||||
displayName: Build Shared Support DLLs
|
||||
inputs:
|
||||
solution: "**/installer/PowerToysSetup.sln"
|
||||
solution: "**/installer/PowerToysSetup.slnx"
|
||||
vsVersion: 17.0
|
||||
msbuildArgs: >-
|
||||
/t:PowerToysSetupCustomActionsVNext;SilentFilesInUseBAFunction
|
||||
@@ -74,7 +74,7 @@ steps:
|
||||
- task: VSBuild@1
|
||||
displayName: 💻 Build VNext MSI
|
||||
inputs:
|
||||
solution: "**/installer/PowerToysSetup.sln"
|
||||
solution: "**/installer/PowerToysSetup.slnx"
|
||||
vsVersion: 17.0
|
||||
msbuildArgs: >-
|
||||
-restore
|
||||
@@ -91,7 +91,7 @@ steps:
|
||||
- task: VSBuild@1
|
||||
displayName: 👤 Build VNext MSI
|
||||
inputs:
|
||||
solution: "**/installer/PowerToysSetup.sln"
|
||||
solution: "**/installer/PowerToysSetup.slnx"
|
||||
vsVersion: 17.0
|
||||
msbuildArgs: >-
|
||||
/t:PowerToysInstallerVNext
|
||||
@@ -142,7 +142,7 @@ steps:
|
||||
- task: VSBuild@1
|
||||
displayName: 💻 Build VNext Bootstrapper
|
||||
inputs:
|
||||
solution: "**/installer/PowerToysSetup.sln"
|
||||
solution: "**/installer/PowerToysSetup.slnx"
|
||||
vsVersion: 17.0
|
||||
msbuildArgs: >-
|
||||
-restore
|
||||
@@ -159,7 +159,7 @@ steps:
|
||||
- task: VSBuild@1
|
||||
displayName: 👤 Build VNext Bootstrapper
|
||||
inputs:
|
||||
solution: "**/installer/PowerToysSetup.sln"
|
||||
solution: "**/installer/PowerToysSetup.slnx"
|
||||
vsVersion: 17.0
|
||||
msbuildArgs: >-
|
||||
/t:PowerToysBootstrapperVNext
|
||||
|
||||
@@ -55,3 +55,12 @@ steps:
|
||||
nugetConfigPath: '$(build.sourcesdirectory)\nuget.config'
|
||||
restoreSolution: '$(build.sourcesdirectory)\**\*.sln'
|
||||
includeNuGetOrg: false
|
||||
|
||||
- task: NuGetCommand@2
|
||||
displayName: 'Restore NuGet packages (slnx)'
|
||||
inputs:
|
||||
command: 'restore'
|
||||
feedsToUse: 'config'
|
||||
nugetConfigPath: '$(build.sourcesdirectory)\nuget.config'
|
||||
restoreSolution: '$(build.sourcesdirectory)\**\*.slnx'
|
||||
includeNuGetOrg: false
|
||||
|
||||
@@ -52,7 +52,12 @@ $nullVersionExceptions = @(
|
||||
"System.Diagnostics.EventLog.Messages.dll",
|
||||
"Microsoft.Windows.Widgets.dll",
|
||||
"AdaptiveCards.ObjectModel.WinUI3.dll",
|
||||
"AdaptiveCards.Rendering.WinUI3.dll") -join '|';
|
||||
"AdaptiveCards.Rendering.WinUI3.dll",
|
||||
"boost_regex_vc143_mt_gd_x32_1_87.dll",
|
||||
"boost_regex_vc143_mt_gd_x64_1_87.dll",
|
||||
"boost_regex_vc143_mt_x32_1_87.dll",
|
||||
"boost_regex_vc143_mt_x64_1_87.dll"
|
||||
) -join '|';
|
||||
$totalFailure = 0;
|
||||
|
||||
Write-Host $DirPath;
|
||||
|
||||
@@ -42,6 +42,11 @@
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<!-- Make angle-bracket includes external and turn off code analysis for them -->
|
||||
<TreatAngleIncludeAsExternal>true</TreatAngleIncludeAsExternal>
|
||||
<ExternalWarningLevel>TurnOffAllWarnings</ExternalWarningLevel>
|
||||
<DisableAnalyzeExternal>true</DisableAnalyzeExternal>
|
||||
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<PrecompiledHeader Condition="'$(UsePrecompiledHeaders)' != 'false'">Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
@@ -111,13 +116,11 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Debug/Release props -->
|
||||
<PropertyGroup Condition="'$(Configuration)'=='Debug'"
|
||||
Label="Configuration">
|
||||
<PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)'=='Release'"
|
||||
Label="Configuration">
|
||||
<PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
|
||||
@@ -243,6 +243,10 @@ _If you want to find diagnostic data events in the source code, these two links
|
||||
<th>Event Name</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Microsoft.PowerToys.CmdNotFound_EnableCmdNotFound</td>
|
||||
<td>Triggered when Command Not Found is enabled or disabled.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Microsoft.PowerToys.CmdNotFoundInstallEvent</td>
|
||||
<td>Triggered when a Command Not Found is installed.</td>
|
||||
@@ -257,6 +261,62 @@ _If you want to find diagnostic data events in the source code, these two links
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
### Command Palette
|
||||
<table style="width:100%">
|
||||
<tr>
|
||||
<th>Event Name</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Microsoft.PowerToys.CmdPal_BeginInvoke</td>
|
||||
<td>Triggered when the Command Palette is launched by the user.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Microsoft.PowerToys.CmdPal_ColdLaunch</td>
|
||||
<td>Occurs when Command Palette starts for the first time (cold start).</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Microsoft.PowerToys.CmdPal_OpenPage</td>
|
||||
<td>Triggered when a page is opened within the Command Palette, tracking navigation depth.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Microsoft.PowerToys.CmdPal_OpenUri</td>
|
||||
<td>Occurs when a URI is opened through the Command Palette, including whether it's a web URL.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Microsoft.PowerToys.CmdPal_ReactivateInstance</td>
|
||||
<td>Triggered when an existing Command Palette instance is reactivated.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Microsoft.PowerToys.CmdPal_RunCommand</td>
|
||||
<td>Logs when a command is executed through the Command Palette, including admin elevation status.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Microsoft.PowerToys.CmdPal_RunQuery</td>
|
||||
<td>Triggered when a search query is performed, including result count and duration.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Microsoft.PowerToys.CmdPalDismissedOnEsc</td>
|
||||
<td>Occurs when the Command Palette is dismissed by pressing the Escape key.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Microsoft.PowerToys.CmdPalDismissedOnLostFocus</td>
|
||||
<td>Triggered when the Command Palette is dismissed due to losing focus.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Microsoft.PowerToys.CmdPalHotkeySummoned</td>
|
||||
<td>Logs when the Command Palette is summoned via hotkey, distinguishing between global and context-specific hotkeys.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Microsoft.PowerToys.CmdPalInvokeResult</td>
|
||||
<td>Records the result type of a Command Palette invocation.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Microsoft.PowerToys.CmdPalProcessStarted</td>
|
||||
<td>Triggered when the Command Palette process is started.</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
### Crop And Lock
|
||||
<table style="width:100%">
|
||||
<tr>
|
||||
@@ -735,6 +795,10 @@ _If you want to find diagnostic data events in the source code, these two links
|
||||
<th>Event Name</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Microsoft.PowerToys.NewPlus_ChangedTemplateLocation</td>
|
||||
<td>Triggered when the template folder location is changed.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Microsoft.PowerToys.NewPlus_EventCopyTemplate</td>
|
||||
<td>Triggered when an item from New+ is created (copied to the current directory).</td>
|
||||
@@ -743,6 +807,10 @@ _If you want to find diagnostic data events in the source code, these two links
|
||||
<td>Microsoft.PowerToys.NewPlus_EventCopyTemplateResult</td>
|
||||
<td>Logs the success of item creation (copying).</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Microsoft.PowerToys.NewPlus_EventOpenTemplates</td>
|
||||
<td>Triggered when the templates folder is opened.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Microsoft.PowerToys.NewPlus_EventShowTemplateItems</td>
|
||||
<td>Triggered when the New+ context menu flyout is displayed.</td>
|
||||
@@ -928,12 +996,8 @@ _If you want to find diagnostic data events in the source code, these two links
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Microsoft.PowerToys.ShortcutGuide_EnableGuide</td>
|
||||
<td>Triggered when Shortcut Guide is enabled.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Microsoft.PowerToys.ShortcutGuide_HideGuide</td>
|
||||
<td>Occurs when Shortcut Guide is hidden from view.</td>
|
||||
<td>Microsoft.PowerToys.ShortcutGuide_GuideSession</td>
|
||||
<td>Logs a Shortcut Guide session including duration and how it was closed.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Microsoft.PowerToys.ShortcutGuide_Settings</td>
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
<PackageVersion Include="AdaptiveCards.ObjectModel.WinUI3" Version="2.0.0-beta" />
|
||||
<PackageVersion Include="AdaptiveCards.Rendering.WinUI3" Version="2.1.0-beta" />
|
||||
<PackageVersion Include="AdaptiveCards.Templating" Version="2.0.5" />
|
||||
<PackageVersion Include="boost" Version="1.87.0" TargetFramework="native" />
|
||||
<PackageVersion Include="boost_regex-vc143" Version="1.87.0" TargetFramework="native" />
|
||||
<PackageVersion Include="CommunityToolkit.Labs.WinUI.Controls.OpacityMaskView" Version="0.1.251101-build.2372" />
|
||||
<PackageVersion Include="Microsoft.Bot.AdaptiveExpressions.Core" Version="4.23.0" />
|
||||
<PackageVersion Include="Appium.WebDriver" Version="4.4.5" />
|
||||
@@ -69,10 +71,12 @@
|
||||
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.SDK.BuildTools" Version="10.0.26100.4948" />
|
||||
<PackageVersion Include="Microsoft.WindowsAppSDK" Version="1.8.250907003" />
|
||||
<PackageVersion Include="Microsoft.WindowsAppSDK.AI" Version="1.8.37" />
|
||||
<PackageVersion Include="Microsoft.WindowsAppSDK.Runtime" Version="1.8.250907003" />
|
||||
<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="1.8.251106002" />
|
||||
<PackageVersion Include="Microsoft.WindowsAppSDK.Foundation" Version="1.8.251104000" />
|
||||
<PackageVersion Include="Microsoft.WindowsAppSDK.AI" Version="1.8.39" />
|
||||
<PackageVersion Include="Microsoft.WindowsAppSDK.Runtime" Version="1.8.251106002" />
|
||||
<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" />
|
||||
@@ -111,6 +115,7 @@
|
||||
<PackageVersion Include="System.IO.Abstractions.TestingHelpers" Version="22.0.13" />
|
||||
<PackageVersion Include="System.Management" Version="9.0.10" />
|
||||
<PackageVersion Include="System.Net.Http" Version="4.3.4" />
|
||||
<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="9.0.10" />
|
||||
@@ -118,6 +123,7 @@
|
||||
<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" />
|
||||
<PackageVersion Include="UnitsNet" Version="5.56.0" />
|
||||
<PackageVersion Include="UTF.Unknown" Version="2.6.0" />
|
||||
|
||||
32
NOTICE.md
32
NOTICE.md
@@ -75,6 +75,37 @@ OTHER DEALINGS IN THE SOFTWARE.
|
||||
For more information, please refer to <http://unlicense.org/>
|
||||
```
|
||||
|
||||
### ToolGood.Words.Pinyin
|
||||
|
||||
We use the ToolGood.Words.Pinyin NuGet package for converting Chinese characters to pinyin.
|
||||
|
||||
**Source**: [https://github.com/toolgood/ToolGood.Words.Pinyin](https://github.com/toolgood/ToolGood.Words.Pinyin)
|
||||
|
||||
```
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 ToolGood
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
```
|
||||
|
||||
|
||||
## Utility: Command Palette Built-in Extensions
|
||||
|
||||
### Calculator
|
||||
@@ -1532,6 +1563,7 @@ SOFTWARE.
|
||||
- SkiaSharp.Views.WinUI
|
||||
- StreamJsonRpc
|
||||
- StyleCop.Analyzers
|
||||
- ToolGood.Words.Pinyin
|
||||
- UnicodeInformation
|
||||
- UnitsNet
|
||||
- UTF.Unknown
|
||||
|
||||
3374
PowerToys.sln
3374
PowerToys.sln
File diff suppressed because it is too large
Load Diff
1045
PowerToys.slnx
Normal file
1045
PowerToys.slnx
Normal file
File diff suppressed because it is too large
Load Diff
16
README.md
16
README.md
@@ -53,17 +53,17 @@ Go to the [PowerToys GitHub releases][github-release-link], click Assets to reve
|
||||
<!-- 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.97%22
|
||||
[github-current-release-work]: https://github.com/microsoft/PowerToys/issues?q=is%3Aissue+milestone%3A%22PowerToys+0.96%22
|
||||
[ptUserX64]: https://github.com/microsoft/PowerToys/releases/download/v0.96.0/PowerToysUserSetup-0.96.0-x64.exe
|
||||
[ptUserArm64]: https://github.com/microsoft/PowerToys/releases/download/v0.96.0/PowerToysUserSetup-0.96.0-arm64.exe
|
||||
[ptMachineX64]: https://github.com/microsoft/PowerToys/releases/download/v0.96.0/PowerToysSetup-0.96.0-x64.exe
|
||||
[ptMachineArm64]: https://github.com/microsoft/PowerToys/releases/download/v0.96.0/PowerToysSetup-0.96.0-arm64.exe
|
||||
[ptUserX64]: https://github.com/microsoft/PowerToys/releases/download/v0.96.1/PowerToysUserSetup-0.96.1-x64.exe
|
||||
[ptUserArm64]: https://github.com/microsoft/PowerToys/releases/download/v0.96.1/PowerToysUserSetup-0.96.1-arm64.exe
|
||||
[ptMachineX64]: https://github.com/microsoft/PowerToys/releases/download/v0.96.1/PowerToysSetup-0.96.1-x64.exe
|
||||
[ptMachineArm64]: https://github.com/microsoft/PowerToys/releases/download/v0.96.1/PowerToysSetup-0.96.1-arm64.exe
|
||||
|
||||
| Description | Filename |
|
||||
|----------------|----------|
|
||||
| Per user - x64 | [PowerToysUserSetup-0.96.0-x64.exe][ptUserX64] |
|
||||
| Per user - ARM64 | [PowerToysUserSetup-0.96.0-arm64.exe][ptUserArm64] |
|
||||
| Machine wide - x64 | [PowerToysSetup-0.96.0-x64.exe][ptMachineX64] |
|
||||
| Machine wide - ARM64 | [PowerToysSetup-0.96.0-arm64.exe][ptMachineArm64] |
|
||||
| Per user - x64 | [PowerToysUserSetup-0.96.1-x64.exe][ptUserX64] |
|
||||
| Per user - ARM64 | [PowerToysUserSetup-0.96.1-arm64.exe][ptUserArm64] |
|
||||
| Machine wide - x64 | [PowerToysSetup-0.96.1-x64.exe][ptMachineX64] |
|
||||
| Machine wide - ARM64 | [PowerToysSetup-0.96.1-arm64.exe][ptMachineArm64] |
|
||||
|
||||
</details>
|
||||
|
||||
|
||||
34
doc/devdocs/commands.md
Normal file
34
doc/devdocs/commands.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# Issue/PR commands
|
||||
|
||||
The PowerToys repository uses some special keywords to help manage issues and pull requests. Here is a list of the most important commands you can use in issue and PR descriptions or comments.
|
||||
|
||||
| Command | Description |
|
||||
|---------|-------------|
|
||||
| `/azp run` | Triggers the Azure Pipelines CI build for the current PR. Useful if you want to re-run the build without creating a new commit. |
|
||||
| `/bugreport` / `/reportbug` | Adds a comment with a manual for the Bug Report Tool, which helps users collect logs and system information for debugging purposes. It requests to upload this file and adds the `Needs-Author-Feedback` label. |
|
||||
| `/feedbackhub` | Adds a comment with a link to the Feedback Hub app on Windows, where users can submit feedback about PowerToys. Closes the issue and adds the `Resolution-Please File on Feedback Hub` label. |
|
||||
| `/dup #...` / `/duplicate #...` / `/dup https://...` / `/duplicate https://...` | Marks the current issue as a duplicate of another issue. It closes the current issue and applies the `Resolution-Duplicate` label. Replace `#...` with the issue number or a link to the issue. |
|
||||
| `/needinfo` | Adds the `Needs-Author-Feedback` label to the issue or PR, indicating that more information is needed from the author. |
|
||||
| `/helped` | Closes the issue and adds the `Resolution-Helped User` label. Furthermore a comment is added with a link to the PowerToys user documentation. |
|
||||
| `/loc` | Adds a comment informing the user that the issue was forwarded to the localization team and will soon be fixed. It adds the `Loc-Sent To Team` label. |
|
||||
|
||||
## Defining new commands
|
||||
|
||||
Most of these commands are using the [Microsoft GitHub Policy Service](https://github.com/apps/microsoft-github-policy-service) bot. Its commands are defined in the [PowerToys policy configuration file](/.github/policies/resourceManagement.yml).
|
||||
|
||||
## Other automated tasks
|
||||
|
||||
### Automatic labeling
|
||||
|
||||
The bot can automatically apply the correct `product-...` label for any opened issue.
|
||||
|
||||
> [!NOTE]
|
||||
> This feature is currently only available for the Workspaces module as a test.
|
||||
|
||||
### The `Needs-Author-Feedback` label
|
||||
|
||||
If an issue has this label and had no activity for 5 days, the bot will post a comment reminding the author to provide the needed information. It also adds the `Status-No recent activity` label. If no further activity occurs for another 5 days, the bot will close the issue.
|
||||
|
||||
### Filtering users that want to contribute
|
||||
|
||||
If a user utters their intention to contribute (e.g., by using the phrase "I want to contribute" in an issue or PR), the bot will add a comment with a link to the ["Would you like to contribute to PowerToys?" thread](https://github.com/microsoft/PowerToys/issues/28769).
|
||||
@@ -134,7 +134,7 @@ If you prefer, you can alternatively build prerequisite projects for the install
|
||||
|
||||
#### Locally compiling the installer
|
||||
|
||||
1. Open `installer\PowerToysSetup.sln`
|
||||
1. Open `installer\PowerToysSetup.slnx`
|
||||
1. In Visual Studio, in the `Solutions Configuration` drop-down menu select `Release`
|
||||
1. From the `Build` menu choose `Build Solution`.
|
||||
|
||||
@@ -144,9 +144,9 @@ To build the installer from the command line, run `Developer Command Prompt for
|
||||
|
||||
```
|
||||
git clean -xfd -e *exe -- .\installer\
|
||||
MSBuild -t:restore .\installer\PowerToysSetup.sln -p:RestorePackagesConfig=true /p:Platform="x64" /p:Configuration=Release
|
||||
MSBuild -t:Restore -m .\installer\PowerToysSetup.sln /t:PowerToysInstallerVNext /p:Configuration=Release /p:Platform="x64"
|
||||
MSBuild -t:Restore -m .\installer\PowerToysSetup.sln /t:PowerToysBootstrapperVNext /p:Configuration=Release /p:Platform="x64"
|
||||
MSBuild -t:restore .\installer\PowerToysSetup.slnx -p:RestorePackagesConfig=true /p:Platform="x64" /p:Configuration=Release
|
||||
MSBuild -t:Restore -m .\installer\PowerToysSetup.slnx /t:PowerToysInstallerVNext /p:Configuration=Release /p:Platform="x64"
|
||||
MSBuild -t:Restore -m .\installer\PowerToysSetup.slnx /t:PowerToysBootstrapperVNext /p:Configuration=Release /p:Platform="x64"
|
||||
```
|
||||
|
||||
### Supported arguments for the .EXE Bootstrapper installer
|
||||
|
||||
@@ -38,7 +38,7 @@ For C# modules, the settings are accessed through the `SettingsUtils` class in t
|
||||
using Microsoft.PowerToys.Settings.UI.Library;
|
||||
|
||||
// Read settings
|
||||
var settings = SettingsUtils.GetSettings<ModuleSettings>("ModuleName");
|
||||
var settings = SettingsUtils.Default.GetSettings<ModuleSettings>("ModuleName");
|
||||
bool enabled = settings.Enabled;
|
||||
```
|
||||
|
||||
@@ -49,7 +49,7 @@ using Microsoft.PowerToys.Settings.UI.Library;
|
||||
|
||||
// Write settings
|
||||
settings.Enabled = true;
|
||||
SettingsUtils.SaveSettings(settings.ToJsonString(), "ModuleName");
|
||||
SettingsUtils.Default.SaveSettings(settings.ToJsonString(), "ModuleName");
|
||||
```
|
||||
|
||||
## Settings Handling in Modules
|
||||
|
||||
@@ -19,7 +19,7 @@ You can build the entire solution from the command line, which is sometimes fast
|
||||
2. Navigate to the repository root directory
|
||||
3. Run the following command(don't forget to set the correct platform):
|
||||
```pwsh
|
||||
msbuild -restore -p:RestorePackagesConfig=true -p:Platform=ARM64 -m PowerToys.sln /tl /p:NuGetInteractive="true"
|
||||
msbuild -restore -p:RestorePackagesConfig=true -p:Platform=ARM64 -m PowerToys.slnx /tl /p:NuGetInteractive="true"
|
||||
```
|
||||
4. This process should complete in approximately 13-14 minutes for a full build
|
||||
|
||||
|
||||
@@ -42,10 +42,10 @@ Or reach out to "tools\build\BUILD-GUIDELINES.md"
|
||||
### Sample plain msbuild command
|
||||
```powershell
|
||||
# Restore:
|
||||
msbuild powertoys.sln -t:restore -p:configuration=debug -p:platform=x64 -m
|
||||
msbuild powertoys.slnx -t:restore -p:configuration=debug -p:platform=x64 -m
|
||||
|
||||
# Build powertoys sln
|
||||
msbuild powertoys.sln -p:configuration=debug -p:platform=x64 -m
|
||||
# Build powertoys slnx
|
||||
msbuild powertoys.slnx -p:configuration=debug -p:platform=x64 -m
|
||||
|
||||
# dotnet project
|
||||
msbuild src\settings-ui\Settings.UI\PowerToys.Settings.csproj -p:Platform=x64 -p:Configuration=Debug -m
|
||||
@@ -122,7 +122,7 @@ Similar for attach to managed code.
|
||||
|
||||
| Task | Command / Action | Notes |
|
||||
|------|------------------|-------|
|
||||
| Clean | `git clean -xdf` (careful) or `msbuild /t:Clean PowerToys.sln` | Deep clean removes packages & build outputs |
|
||||
| Clean | `git clean -xdf` (careful) or `msbuild /t:Clean PowerToys.slnx` | Deep clean removes packages & build outputs |
|
||||
| Rebuild single project | `msbuild path\to\proj.vcxproj /t:Rebuild -p:Platform=x64 -p:Configuration=Debug` | Faster than whole solution |
|
||||
| Generate installer (rare in inner loop) | See `tools\build\build-installer.ps1` | Usually not needed for local debug |
|
||||
| Resource conversion errors | Re-run restore + build | Triggers custom PowerShell targets |
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
- Exit PowerToys if it's running.
|
||||
|
||||
- Open `PowerToys.sln` in Visual Studio and build the solution.
|
||||
- Open `PowerToys.slnx` in Visual Studio and build the solution.
|
||||
|
||||
- Run tests in the Test Explorer (`Test > Test Explorer` or `Ctrl+E, T`).
|
||||
|
||||
|
||||
@@ -1,165 +0,0 @@
|
||||
# Localization
|
||||
|
||||
> **NOTE**: THIS DOCUMENT IS OUTDATED.
|
||||
> Follow [issue 15243](https://github.com/microsoft/PowerToys/issues/15243) for updates.
|
||||
|
||||
## Table of Contents
|
||||
1. [Localization on the pipeline (CDPX)](#localization-on-the-pipeline-cdpx)
|
||||
1. [UWP Special case](#uwp-special-case)
|
||||
2. [Enabling localization on a new project](#enabling-localization-on-a-new-project)
|
||||
1. [C++](#c)
|
||||
2. [C#](#c-1)
|
||||
3. [UWP](#uwp)
|
||||
3. [Lcl Files](#lcl-files)
|
||||
4. [Possible Issues in localization PRs (LEGO)](#possible-issues-in-localization-prs-lego)
|
||||
5. [Enabling localized MSI for a new project](#enabling-localized-msi-for-a-new-project)
|
||||
|
||||
## Localization on the pipeline (CDPX)
|
||||
[The localization step](https://github.com/microsoft/PowerToys/blob/86d77103e9c69686c297490acb04775d43ef8b76/.pipelines/pipeline.user.windows.yml#L45-L52) is run on the pipeline before the solution is built. This step runs the [build-localization](https://github.com/microsoft/PowerToys/blob/main/.pipelines/build-localization.cmd) script, which generates resx files for all the projects with localization enabled using the `Localization.XLoc` package.
|
||||
|
||||
The [`Localization.XLoc`](https://github.com/microsoft/PowerToys/blob/86d77103e9c69686c297490acb04775d43ef8b76/.pipelines/build-localization.cmd#L24-L25) tool is run on the repo root, and it checks for all occurrences of `LocProject.json`. Each localized project has a `LocProject.json` file in the project root, which contains the location of the English resx file, list of languages for localization, and the output path where the localized resx files are to be copied to. In addition to this, some other parameters can be set, such as whether the language ID should be added as a folder in the file path or in the file name. When the CDPX pipeline is run, the localization team is notified of changes in the English resx files. For each project with localization enabled, a `loc` folder (see [this](https://github.com/microsoft/PowerToys/tree/main/src/modules/launcher/Microsoft.Launcher/loc) for example) is created in the same directory as the `LocProject.json` file. The folder contains language specific folders which in turn have a nested folder path equivalent to `OutputPath` in the `LocProject.json`. Each of these folders contain one `lcl` file. The `lcl` files contain the English resources along with their translation for that language. These are described in more detail in the [Lcl files section](#lcl-files). Once the `.resx` files are generated, they will be used during the `Build PowerToys` step for localized versions of the modules.
|
||||
|
||||
Since the localization script requires certain nuget packages, the [`restore-localization`](https://github.com/microsoft/PowerToys/blob/main/.pipelines/restore-localization.cmd) script is run before running `build-localization` to install all the required packages. This script must [run in the `restore` step](https://github.com/microsoft/PowerToys/blob/86d77103e9c69686c297490acb04775d43ef8b76/.pipelines/pipeline.user.windows.yml#L37-L39) of pipeline because [the host is network isolated](https://onebranch.visualstudio.com/Pipeline/_wiki/wikis/Pipeline.wiki/2066/Consuming-Packages-in-a-CDPx-Pipeline?anchor=overview) at the `build` step. The [Toolset package source](https://github.com/microsoft/PowerToys/blob/86d77103e9c69686c297490acb04775d43ef8b76/.pipelines/pipeline.user.windows.yml#L23) is used for this.
|
||||
|
||||
The process and variables that can be tweaked on the pipeline are described in more detail on [onebranch (account required) under Localization](https://onebranch.visualstudio.com/Pipeline/_wiki/wikis/Pipeline.wiki/290/Localization).
|
||||
|
||||
The localized resource dlls for C# projects are added to the MSI only for build on the pipeline. This is done by checking if the [`IsPipeline` variable is defined](https://github.com/microsoft/PowerToys/blob/f92bd6ffd38014c228544bb8d68d0937ce4c2b6d/installer/PowerToysSetup/Product.wxs#L804-L805), which gets defined before [building the installer on the pipeline](https://github.com/microsoft/PowerToys/blob/f92bd6ffd38014c228544bb8d68d0937ce4c2b6d/.pipelines/build-installer.cmd#L4). This is done because the localized resx files are only present on the pipeline, and not having this check would result in the installer project failing to build locally.
|
||||
|
||||
## Enabling localization on a new project
|
||||
To enable localization on a new project, the first step is to create a file `LocProject.json` in the project root.
|
||||
|
||||
For example, for a project in the folder `src\path` where the resx file is present in `resources\Resources.resx`, the LocProject.json file will contain the following:
|
||||
```
|
||||
{
|
||||
"Projects": [
|
||||
{
|
||||
"LanguageSet": "Azure_Languages",
|
||||
"LocItems": [
|
||||
{
|
||||
"SourceFile": "src\\path\\resources\\Resources.resx",
|
||||
"CopyOption": "LangIDOnName",
|
||||
"OutputPath": "src\\path\\resources"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
The rest of the steps depend on the project type and are covered in the sections below. The steps to add the localized files to the MSI can be found in [Enabling localized MSI for a new project](#Enabling-localized-MSI-for-a-new-project).
|
||||
|
||||
### C++
|
||||
C++ projects do not support `resx` files, and instead use `rc` files along with `resource.h` files. The CDPX pipeline however doesn't support localizing `rc` files and the other alternative they support is directly translating the resources from the binary which makes it harder to maintain resources. To avoid this, a custom script has been added which expects a resx file and converts the entries to an rc file with a string table and adds resource declarations to a resource.h file so that the resources can be compiled with the C++ project.
|
||||
|
||||
If you already have a .rc file, copy the string table to a separate txt file and run the [convert-stringtable-to-resx.ps1](https://github.com/microsoft/PowerToys/blob/main/tools/build/convert-stringtable-to-resx.ps1) script on it. This script is not very robust to input, and requires the data in a specific format, where `IDS_ResName L"ResourceValue"` and any number of spaces can be present in between. The script converts this file to the format expected by [`resgen`](https://learn.microsoft.com/dotnet/framework/tools/resgen-exe-resource-file-generator#Convert), which will convert it to resx. The resource names are changed from all uppercase to title case, and the `IDS_` prefix is removed. Escape characters might have to be manually replaced, for example .rc files would have escaped double quotes as `""`, so this should be replaced with just `"` before converting to the resx files.
|
||||
|
||||
After generating the resx file, rename the existing rc and h files to ProjName.base.rc and resource.base.h. In the rc file remove the string table which is to be localized and in the .h file remove all `#define`s corresponding to localized resources. In the vcxproj of the C++ project, add the following build event:
|
||||
```
|
||||
<Target Name="GenerateResourceFiles" BeforeTargets="PrepareForBuild">
|
||||
<Exec Command="powershell -NonInteractive -executionpolicy Unrestricted $(SolutionDir)tools\build\convert-resx-to-rc.ps1 $(MSBuildThisFileDirectory) resource.base.h resource.h ProjName.base.rc ProjName.rc" />
|
||||
</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 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
|
||||
|
||||
STRINGTABLE
|
||||
BEGIN
|
||||
strings
|
||||
END
|
||||
|
||||
#endif
|
||||
```
|
||||
Since there is no API to identify the `AFX_TARG_*`, `LANG_*` or `SUBLANG_*` values from each langId from the pipeline, these are hardcoded in the script (for each language) as done in [lines 50-77 of `convert-resx-to-rc.ps1`](https://github.com/microsoft/PowerToys/blob/f92bd6ffd38014c228544bb8d68d0937ce4c2b6d/tools/build/convert-resx-to-rc.ps1#L50-L77). **If any other languages are added in the future, this script will have to be updated.** In order to determine what are the language codes, you can open the rc file in Resource View, right click the string table and press `Insert Copy` and choose the corresponding language. This autogenerates the required code and can be used to figure out the language codes. The files also add the resource declarations to a resource.h file, starting from 101 by default(this can be changed by an optional argument). Since the output files will be generated in `Generated Files`, any includes in these two files will require an additional `..\` and wherever resource.h is used, it will have to be included as `Generated Files\resource.h`. While adding `resource.base.h` and `ProjName.base.rc` to the vcxproj, these should be modified to not participate in the build to avoid build errors:
|
||||
```
|
||||
<None Include="Resources.resx" />
|
||||
```
|
||||
|
||||
Some rc/resource.h files might be used in multiple projects (for example, KBM). To ensure the projects build for these cases, the build event can be added to the entire directory so that the rc files are generated before any project is built. See [Directory.Build.targets](https://github.com/microsoft/PowerToys/blob/main/src/modules/keyboardmanager/Directory.Build.targets) for an example.
|
||||
|
||||
Check [this PR](https://github.com/microsoft/PowerToys/pull/6104) for an example for making these changes for a C++ project.
|
||||
|
||||
### C#
|
||||
Since C# projects natively support `resx` files, the only step required here is to include all the resx files in the build. For .NET Core projects this is done automatically and the .csproj does not need to be modified. For other projects, the following line needs to be added:
|
||||
```
|
||||
<EmbeddedResource Include="Properties\Resources.*.resx" />
|
||||
```
|
||||
|
||||
**Note:** Building with localized resources may cause a build warning `Referenced assembly 'mscorlib.dll' targets a different processor` which is a VS bug. More details can be found in [PowerToys issue #7269](https://github.com/microsoft/PowerToys/issues/7269).
|
||||
|
||||
**Note:** If a project needs to be migrated from XAML resources to resx, the easiest way to convert the resources would be to change to format to `=` separates resources by either manually (by Ctrl+H on a text editor), or by a script, and then running [`resgen`](https://learn.microsoft.com/dotnet/framework/tools/resgen-exe-resource-file-generator#Convert) on `Developer Command Prompt for VS` to convert it to resx format.
|
||||
```
|
||||
<system:String x:Key="wox_plugin_calculator_plugin_name">Calculator</system:String>
|
||||
<system:String x:Key="wox_plugin_calculator_plugin_description">Allows to do mathematical calculations.(Try 5*3-2 in Wox)</system:String>
|
||||
<system:String x:Key="wox_plugin_calculator_not_a_number">Not a number (NaN)</system:String>
|
||||
```
|
||||
to
|
||||
```
|
||||
wox_plugin_calculator_plugin_name=Calculator
|
||||
wox_plugin_calculator_plugin_description=Allows to do mathematical calculations.(Try 5*3-2 in Wox)
|
||||
wox_plugin_calculator_not_a_number=Not a number (NaN)
|
||||
```
|
||||
After adding the resx file to the project along with the resource generator, references to the strings will have to be replaced with `Properties.Resources.resName` rather than the custom APIs. Check [this PR](https://github.com/microsoft/PowerToys/pull/6165) for an example of the changes required.
|
||||
|
||||
### UWP
|
||||
UWP projects expect `resw` files rather than `resx` (the format is almost the same). Unlike other C# projects, the files are expected in the format `fullLangId\Resources.resw`. To include these files in the build, replace the following line in the csproj:
|
||||
```
|
||||
<PRIResource Include="Strings\en-us\Resources.resw" />
|
||||
```
|
||||
to
|
||||
```
|
||||
<PRIResource Include="Strings\*\Resources.resw" />
|
||||
```
|
||||
|
||||
## Lcl Files
|
||||
Lcl files contain all the resources that are present in the English resx file, along with a translation if it has been added.
|
||||
|
||||
For example, an entry for a resource in the lcl file looks like this:
|
||||
```
|
||||
<Item ItemId=";EditKeyboard_WindowName" ItemType="0;.resx" PsrId="211" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Remap keys]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Remapper des touches]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
```
|
||||
The `<Tgt>` element would not be present in the initial commits of the lcl files, as only the English version of the string would be present.
|
||||
|
||||
**Note:** The CDPX Localization system has a fail-safe check on the lcl files, where if the English string value which is present inside `<Val><![CDATA[*]]></Val>` does not match the value present in the English Resources.resx file then the translated value will not be copied to the localized resx file. This is present so that obsolete translations would not be loaded when the English resource has changed, and the English string will be used rather than the obsolete translation.
|
||||
|
||||
## Possible Issues in localization PRs (LEGO)
|
||||
Since the LEGO PRs update some of the strings in LCL files at a time, there can be multiple PRs which modify the same files, leading to merge conflicts. In most cases this would show up on GitHub as a merge conflict, but sometimes a bad git merge may occur, and the file could end up with incorrect formatting, such as two `<Tgt>` elements for a single resource. These can be fixed by ensuring the elements follow the format described in [this section](#lcl-files). To catch such errors, the build farm should be run for every LEGO PR and if any error occurs in the localization step, we should check the corresponding resx/lcl files for conflicts.
|
||||
|
||||
## Enabling localized MSI for a new project
|
||||
For C++ and UWP projects no additional files are generated with localization that need to be added to the MSI. For C++ projects all the resources are added to the dll/exe, while for UWP projects they are added to the `resources.pri` file (which is present even for an unlocalized project). To verify if the localized resources are added to the `resources.pri` file the following steps can be done:
|
||||
- Open `Developer Command Prompt for VS`
|
||||
- After navigating to the folder containing the pri file, run the following command:
|
||||
|
||||
makepri.exe dump /if .\resources.pri
|
||||
- Check the contents of the `resources.pri.xml` file that is generated from the command. The last section of the file will contain the resources with the strings in all the languages:
|
||||
```
|
||||
<NamedResource name="GeneralSettings_RunningAsAdminText" uri="ms-resource://f4f787a5-f0ae-47a9-be89-5408b1dd2b47/Resources/GeneralSettings_RunningAsAdminText">
|
||||
<Candidate qualifiers="Language-FR" type="String">
|
||||
<Value>Running as administrator</Value>
|
||||
</Candidate>
|
||||
<Candidate qualifiers="Language-EN-US" isDefault="true" type="String">
|
||||
<Value>Running as administrator</Value>
|
||||
</Candidate>
|
||||
</NamedResource>
|
||||
```
|
||||
|
||||
For C# projects, satellite dlls are generated when the project is built. For a project named `ProjName`, files are created in the format `langId\ProjName.resources.dll` where `langId` is in the same format as the lcl files. The satellite dlls need to be included with the MSI, but they must be added only if the solution is built from the build farm, as the localized resx files will not be present on local machines (and that could cause local builds of the installer to fail).
|
||||
This can be done by adding the directory name of the project to [Product.wxs near line 806](https://github.com/microsoft/PowerToys/blob/f92bd6ffd38014c228544bb8d68d0937ce4c2b6d/installer/PowerToysSetup/Product.wxs#L806) and a resource component for the project can be created in [Product.wxs near lines 845-847](https://github.com/microsoft/PowerToys/blob/f92bd6ffd38014c228544bb8d68d0937ce4c2b6d/installer/PowerToysSetup/Product.wxs#L845-L847) in this format:
|
||||
```
|
||||
<Component Id="ProjName_$(var.IdSafeLanguage)_Component" Directory="Resource$(var.IdSafeLanguage)ProjNameInstallFolder">
|
||||
<File Id="ProjName_$(var.IdSafeLanguage)_File" Source="$(var.BinX64Dir)modules\ProjName\$(var.Language)\ProjName.resources.dll" />
|
||||
</Component>
|
||||
```
|
||||
|
||||
We should also ensure the new dlls are signed by the pipeline. Currently all dlls of the form [`*.resources.dll` are signed](https://github.com/microsoft/PowerToys/blob/f92bd6ffd38014c228544bb8d68d0937ce4c2b6d/.pipelines/pipeline.user.windows.yml#L68).
|
||||
|
||||
**Note:** The resource dlls should be added to the MSI project only after the initial commit with the lcl files has been done by the Localization team. Otherwise, the pipeline will fail as there wouldn't be any resx files to generate the dlls.
|
||||
@@ -86,7 +86,7 @@ The module provides a user interface for configuring settings in the PowerToys S
|
||||
### Building and Testing
|
||||
|
||||
1. Clone the repository: `git clone https://github.com/microsoft/PowerToys.git`
|
||||
2. Open PowerToys.sln in Visual Studio
|
||||
2. Open PowerToys.slnx in Visual Studio
|
||||
3. Select the Release configuration and build the solution
|
||||
4. Run PowerToys.exe from the output directory to test the module
|
||||
|
||||
|
||||
@@ -161,7 +161,7 @@ FancyZones is divided into several projects:
|
||||
```
|
||||
git clone https://github.com/microsoft/PowerToys.git
|
||||
```
|
||||
2. Open `PowerToys.sln` in Visual Studio
|
||||
2. Open `PowerToys.slnx` in Visual Studio
|
||||
3. Select the Release configuration and build the solution
|
||||
4. If you encounter build errors, try deleting the x64 output folder and rebuild
|
||||
|
||||
@@ -244,7 +244,7 @@ UI tests are implemented using [Windows Application Driver](https://github.com/m
|
||||
|
||||
- Exit PowerToys if it's running
|
||||
- Run WinAppDriver.exe from the installation directory. Skip this step if installed in the default directory (`C:\Program Files (x86)\Windows Application Driver`); in this case, it'll be launched automatically during tests.
|
||||
- Open `PowerToys.sln` in Visual Studio and build the solution.
|
||||
- Open `PowerToys.slnx` in Visual Studio and build the solution.
|
||||
- Run tests in the Test Explorer (`Test > Test Explorer` or `Ctrl+E, T`).
|
||||
|
||||
>Note: notifications or other application windows, that are shown above the window under test, can disrupt the testing process.
|
||||
|
||||
@@ -11,7 +11,7 @@ Keyboard Manager consists of two main components:
|
||||
## Development Environment Setup
|
||||
|
||||
1. Clone the PowerToys repository
|
||||
2. Open `PowerToys.sln` in Visual Studio
|
||||
2. Open `PowerToys.slnx` in Visual Studio
|
||||
3. Ensure all NuGet packages are restored
|
||||
4. Build the entire solution in Debug configuration
|
||||
|
||||
|
||||
@@ -92,7 +92,7 @@ The module’s settings are exposed in the PowerToys Settings UI. Options includ
|
||||
3. Build the solution:
|
||||
|
||||
```sh
|
||||
msbuild -restore -p:RestorePackagesConfig=true -p:Platform=ARM64 -m PowerToys.sln
|
||||
msbuild -restore -p:RestorePackagesConfig=true -p:Platform=ARM64 -m PowerToys.slnx
|
||||
```
|
||||
|
||||
> Note: This may take some time.
|
||||
|
||||
@@ -53,7 +53,7 @@ The Screen Ruler module consists of several components:
|
||||
|
||||
### Building
|
||||
|
||||
1. Open PowerToys.sln in Visual Studio
|
||||
1. Open PowerToys.slnx in Visual Studio
|
||||
2. In the Solutions Configuration drop-down menu, select Release or Debug
|
||||
3. From the Build menu, choose Build Solution
|
||||
4. The executable app for Screen Ruler is named PowerToys.MeasureToolUI.exe
|
||||
|
||||
@@ -19,7 +19,7 @@ Shortcut Guide is a PowerToy that displays an overlay of available keyboard shor
|
||||
## Build and Debug Instructions
|
||||
|
||||
### Build
|
||||
1. Open PowerToys.sln in Visual Studio
|
||||
1. Open PowerToys.slnx in Visual Studio
|
||||
2. Select Release or Debug in the Solutions Configuration drop-down menu
|
||||
3. From the Build menu, choose Build Solution
|
||||
4. The executable is named PowerToys.ShortcutGuide.exe
|
||||
|
||||
@@ -38,6 +38,11 @@ Welcome to the PowerToys developer documentation. This documentation provides in
|
||||
- [Update Process](processes/update-process.md) - How PowerToys updates work
|
||||
- [GPO Implementation](processes/gpo.md) - Group Policy Objects implementation details
|
||||
|
||||
## Other Resources
|
||||
|
||||
- [aka.ms links](akaLinks.md) - List of short links
|
||||
- [Issue/PR commands](commands.md) - Special commands for managing issues and pull requests
|
||||
|
||||
## Fork, Clone, Branch and Create your PR
|
||||
|
||||
Once you've discussed your proposed feature/fix/etc. with a team member, and an approach or a spec has been written and approved, it's time to start development:
|
||||
@@ -80,7 +85,7 @@ Once you've discussed your proposed feature/fix/etc. with a team member, and an
|
||||
|
||||
### Install Visual Studio dependencies
|
||||
|
||||
1. Open the `PowerToys.sln` file.
|
||||
1. Open the `PowerToys.slnx` file.
|
||||
1. If you see a dialog that says `install extra components` in the solution explorer pane, click `install`
|
||||
|
||||
### Get Submodules to compile
|
||||
@@ -93,7 +98,7 @@ We have submodules that need to be initialized before you can compile most parts
|
||||
|
||||
### Compiling Source Code
|
||||
|
||||
- Open `PowerToys.sln` in Visual Studio.
|
||||
- Open `PowerToys.slnx` in Visual Studio.
|
||||
- In the `Solutions Configuration` drop-down menu select `Release` or `Debug`.
|
||||
- From the `Build` menu choose `Build Solution`, or press <kbd>Control</kbd>+<kbd>Shift</kbd>+<kbd>b</kbd> on your keyboard.
|
||||
- The build process may take several minutes depending on your computer's performance. Once it completes, the PowerToys binaries will be in your repo under `x64\Release\`.
|
||||
@@ -107,10 +112,10 @@ Our installer is two parts, an EXE and an MSI. The EXE (Bootstrapper) contains
|
||||
|
||||
The installer can only be compiled in `Release` mode; steps 1 and 2 must be performed before the MSI can be compiled.
|
||||
|
||||
1. Compile `PowerToys.sln`. Instructions are listed above.
|
||||
1. Compile `PowerToys.slnx`. Instructions are listed above.
|
||||
1. Compile `BugReportTool.sln` tool. Path from root: `tools\BugReportTool\BugReportTool.sln` (details listed below)
|
||||
1. Compile `StylesReportTool.sln` tool. Path from root: `tools\StylesReportTool\StylesReportTool.sln` (details listed below)
|
||||
1. Compile `PowerToysSetup.sln` Path from root: `installer\PowerToysSetup.sln` (details listed below)
|
||||
1. Compile `PowerToysSetup.slnx` Path from root: `installer\PowerToysSetup.slnx` (details listed below)
|
||||
|
||||
See [Installer](core/installer.md) for more details on building and debugging the installer.
|
||||
|
||||
|
||||
@@ -51,6 +51,7 @@ Contact the developers of a plugin directly for assistance with a specific plugi
|
||||
| [RandomGen](https://github.com/ruslanlap/PowerToysRun-RandomGen) | [ruslanlap](https://github.com/ruslanlap) | 🎲 Generate random data instantly with a single keystroke. Perfect for developers, testers, designers, and anyone who needs quick access to random data. Features include secure passwords, PINs, names, business data, dates, numbers, GUIDs, color codes, and more. Especially useful for designers who need random color codes and placeholder content. |
|
||||
| [Open With Cursor](https://github.com/VictorNoxx/PowerToys-Run-Cursor/) | [VictorNoxx](https://github.com/VictorNoxx) | Open Visual Studio, VS Code recents with Cursor AI |
|
||||
| [CheatSheets](https://github.com/ruslanlap/PowerToysRun-CheatSheets) | [ruslanlap](https://github.com/ruslanlap) | 📚 Find cheat sheets and command examples instantly from tldr pages, cheat.sh, and devhints.io. Features include favorites system, categories, offline mode, and smart caching. |
|
||||
| [QuickAI](https://github.com/ruslanlap/PowerToysRun-QuickAi) | [ruslanlap](https://github.com/ruslanlap) | AI-powered assistance with instant, smart responses from multiple providers (Groq, Together, Fireworks, OpenRouter, Cohere) |
|
||||
|
||||
## Extending software plugins
|
||||
|
||||
|
||||
@@ -1,96 +0,0 @@
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.1.32414.318
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "spdlog", "..\src\logging\logging.vcxproj", "{7E1E3F13-2BD6-3F75-A6A7-873A2B55C60F}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "logger", "..\src\common\logger\logger.vcxproj", "{D9B8FC84-322A-4F9F-BBB9-20915C47DDFD}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Version", "..\src\common\version\version.vcxproj", "{CC6E41AC-8174-4E8A-8D22-85DD7F4851DF}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "EtwTrace", "..\src\common\Telemetry\EtwTrace\EtwTrace.vcxproj", "{8F021B46-362B-485C-BFBA-CCF83E820CBD}"
|
||||
EndProject
|
||||
Project("{930C7802-8A8C-48F9-8165-68863BCCD9DD}") = "PowerToysInstallerVNext", "PowerToysSetupVNext\PowerToysInstallerVNext.wixproj", "{B6E94700-DF38-41F6-A3FD-18B69674AB1E}"
|
||||
EndProject
|
||||
Project("{930C7802-8A8C-48F9-8165-68863BCCD9DD}") = "PowerToysBootstrapperVNext", "PowerToysSetupVNext\PowerToysBootstrapperVNext.wixproj", "{DA4E9744-80BE-424C-B0F5-AFD8757DB575}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PowerToysSetupCustomActionsVNext", "PowerToysSetupCustomActionsVNext\PowerToysSetupCustomActionsVNext.vcxproj", "{B3A354B0-1E54-4B55-A962-FB5AF9330C19}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SilentFilesInUseBAFunction", "PowerToysSetupVNext\SilentFilesInUseBA\SilentFilesInUseBAFunction.vcxproj", "{F8B9F842-F5C3-4A2D-8C85-7F8B9E2B4F1D}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|ARM64 = Debug|ARM64
|
||||
Debug|x64 = Debug|x64
|
||||
Release|ARM64 = Release|ARM64
|
||||
Release|x64 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{7E1E3F13-2BD6-3F75-A6A7-873A2B55C60F}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{7E1E3F13-2BD6-3F75-A6A7-873A2B55C60F}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{7E1E3F13-2BD6-3F75-A6A7-873A2B55C60F}.Debug|x64.Build.0 = Debug|x64
|
||||
{7E1E3F13-2BD6-3F75-A6A7-873A2B55C60F}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{7E1E3F13-2BD6-3F75-A6A7-873A2B55C60F}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{7E1E3F13-2BD6-3F75-A6A7-873A2B55C60F}.Release|x64.ActiveCfg = Release|x64
|
||||
{7E1E3F13-2BD6-3F75-A6A7-873A2B55C60F}.Release|x64.Build.0 = Release|x64
|
||||
{D9B8FC84-322A-4F9F-BBB9-20915C47DDFD}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{D9B8FC84-322A-4F9F-BBB9-20915C47DDFD}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{D9B8FC84-322A-4F9F-BBB9-20915C47DDFD}.Debug|x64.Build.0 = Debug|x64
|
||||
{D9B8FC84-322A-4F9F-BBB9-20915C47DDFD}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{D9B8FC84-322A-4F9F-BBB9-20915C47DDFD}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{D9B8FC84-322A-4F9F-BBB9-20915C47DDFD}.Release|x64.ActiveCfg = Release|x64
|
||||
{D9B8FC84-322A-4F9F-BBB9-20915C47DDFD}.Release|x64.Build.0 = Release|x64
|
||||
{CC6E41AC-8174-4E8A-8D22-85DD7F4851DF}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{CC6E41AC-8174-4E8A-8D22-85DD7F4851DF}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{CC6E41AC-8174-4E8A-8D22-85DD7F4851DF}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{CC6E41AC-8174-4E8A-8D22-85DD7F4851DF}.Debug|x64.Build.0 = Debug|x64
|
||||
{CC6E41AC-8174-4E8A-8D22-85DD7F4851DF}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{CC6E41AC-8174-4E8A-8D22-85DD7F4851DF}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{CC6E41AC-8174-4E8A-8D22-85DD7F4851DF}.Release|x64.ActiveCfg = Release|x64
|
||||
{CC6E41AC-8174-4E8A-8D22-85DD7F4851DF}.Release|x64.Build.0 = Release|x64
|
||||
{8F021B46-362B-485C-BFBA-CCF83E820CBD}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{8F021B46-362B-485C-BFBA-CCF83E820CBD}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{8F021B46-362B-485C-BFBA-CCF83E820CBD}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{8F021B46-362B-485C-BFBA-CCF83E820CBD}.Debug|x64.Build.0 = Debug|x64
|
||||
{8F021B46-362B-485C-BFBA-CCF83E820CBD}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{8F021B46-362B-485C-BFBA-CCF83E820CBD}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{8F021B46-362B-485C-BFBA-CCF83E820CBD}.Release|x64.ActiveCfg = Release|x64
|
||||
{8F021B46-362B-485C-BFBA-CCF83E820CBD}.Release|x64.Build.0 = Release|x64
|
||||
{B6E94700-DF38-41F6-A3FD-18B69674AB1E}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{B6E94700-DF38-41F6-A3FD-18B69674AB1E}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{B6E94700-DF38-41F6-A3FD-18B69674AB1E}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{B6E94700-DF38-41F6-A3FD-18B69674AB1E}.Debug|x64.Build.0 = Debug|x64
|
||||
{B6E94700-DF38-41F6-A3FD-18B69674AB1E}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{B6E94700-DF38-41F6-A3FD-18B69674AB1E}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{B6E94700-DF38-41F6-A3FD-18B69674AB1E}.Release|x64.ActiveCfg = Release|x64
|
||||
{B6E94700-DF38-41F6-A3FD-18B69674AB1E}.Release|x64.Build.0 = Release|x64
|
||||
{DA4E9744-80BE-424C-B0F5-AFD8757DB575}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{DA4E9744-80BE-424C-B0F5-AFD8757DB575}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{DA4E9744-80BE-424C-B0F5-AFD8757DB575}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{DA4E9744-80BE-424C-B0F5-AFD8757DB575}.Debug|x64.Build.0 = Debug|x64
|
||||
{DA4E9744-80BE-424C-B0F5-AFD8757DB575}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{DA4E9744-80BE-424C-B0F5-AFD8757DB575}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{DA4E9744-80BE-424C-B0F5-AFD8757DB575}.Release|x64.ActiveCfg = Release|x64
|
||||
{DA4E9744-80BE-424C-B0F5-AFD8757DB575}.Release|x64.Build.0 = Release|x64
|
||||
{B3A354B0-1E54-4B55-A962-FB5AF9330C19}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{B3A354B0-1E54-4B55-A962-FB5AF9330C19}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{B3A354B0-1E54-4B55-A962-FB5AF9330C19}.Debug|x64.Build.0 = Debug|x64
|
||||
{B3A354B0-1E54-4B55-A962-FB5AF9330C19}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{B3A354B0-1E54-4B55-A962-FB5AF9330C19}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{B3A354B0-1E54-4B55-A962-FB5AF9330C19}.Release|x64.ActiveCfg = Release|x64
|
||||
{B3A354B0-1E54-4B55-A962-FB5AF9330C19}.Release|x64.Build.0 = Release|x64
|
||||
{F8B9F842-F5C3-4A2D-8C85-7F8B9E2B4F1D}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{F8B9F842-F5C3-4A2D-8C85-7F8B9E2B4F1D}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{F8B9F842-F5C3-4A2D-8C85-7F8B9E2B4F1D}.Debug|x64.Build.0 = Debug|x64
|
||||
{F8B9F842-F5C3-4A2D-8C85-7F8B9E2B4F1D}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{F8B9F842-F5C3-4A2D-8C85-7F8B9E2B4F1D}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{F8B9F842-F5C3-4A2D-8C85-7F8B9E2B4F1D}.Release|x64.ActiveCfg = Release|x64
|
||||
{F8B9F842-F5C3-4A2D-8C85-7F8B9E2B4F1D}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {B7A3DA30-D443-40FF-AC51-988AD41E3962}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
22
installer/PowerToysSetup.slnx
Normal file
22
installer/PowerToysSetup.slnx
Normal file
@@ -0,0 +1,22 @@
|
||||
<Solution>
|
||||
<Configurations>
|
||||
<Platform Name="ARM64" />
|
||||
<Platform Name="x64" />
|
||||
</Configurations>
|
||||
<Project Path="../src/common/logger/logger.vcxproj" Id="d9b8fc84-322a-4f9f-bbb9-20915c47ddfd">
|
||||
<Build Solution="Debug|ARM64" Project="false" />
|
||||
</Project>
|
||||
<Project Path="../src/common/Telemetry/EtwTrace/EtwTrace.vcxproj" Id="8f021b46-362b-485c-bfba-ccf83e820cbd" />
|
||||
<Project Path="../src/common/version/version.vcxproj" Id="cc6e41ac-8174-4e8a-8d22-85dd7f4851df" />
|
||||
<Project Path="../src/logging/logging.vcxproj" Id="7e1e3f13-2bd6-3f75-a6a7-873a2b55c60f">
|
||||
<Build Solution="Debug|ARM64" Project="false" />
|
||||
</Project>
|
||||
<Project Path="PowerToysSetupCustomActionsVNext/PowerToysSetupCustomActionsVNext.vcxproj" Id="b3a354b0-1e54-4b55-a962-fb5af9330c19">
|
||||
<Build Solution="Debug|ARM64" Project="false" />
|
||||
</Project>
|
||||
<Project Path="PowerToysSetupVNext/PowerToysBootstrapperVNext.wixproj" Type="b7dd6f7e-def8-4e67-b5b7-07ef123db6f0" />
|
||||
<Project Path="PowerToysSetupVNext/PowerToysInstallerVNext.wixproj" Type="b7dd6f7e-def8-4e67-b5b7-07ef123db6f0" />
|
||||
<Project Path="PowerToysSetupVNext/SilentFilesInUseBA/SilentFilesInUseBAFunction.vcxproj" Id="f8b9f842-f5c3-4a2d-8c85-7f8b9e2b4f1d">
|
||||
<Build Solution="Debug|ARM64" Project="false" />
|
||||
</Project>
|
||||
</Solution>
|
||||
@@ -31,6 +31,11 @@ namespace ManagedCommon
|
||||
/// </summary>
|
||||
public static string CurrentVersionLogDirectoryPath { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the path to the current log file.
|
||||
/// </summary>
|
||||
public static string CurrentLogFile { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the path to the log directory for the app.
|
||||
/// </summary>
|
||||
@@ -55,7 +60,9 @@ namespace ManagedCommon
|
||||
AppLogDirectoryPath = basePath;
|
||||
CurrentVersionLogDirectoryPath = versionedPath;
|
||||
|
||||
var logFilePath = Path.Combine(versionedPath, "Log_" + DateTime.Now.ToString(@"yyyy-MM-dd", CultureInfo.InvariantCulture) + ".log");
|
||||
var logFile = "Log_" + DateTime.Now.ToString(@"yyyy-MM-dd", CultureInfo.InvariantCulture) + ".log";
|
||||
var logFilePath = Path.Combine(versionedPath, logFile);
|
||||
CurrentLogFile = logFilePath;
|
||||
|
||||
Trace.Listeners.Add(new TextWriterTraceListener(logFilePath));
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace Microsoft.PowerToys.UITest
|
||||
public class SettingsConfigHelper
|
||||
{
|
||||
private static readonly JsonSerializerOptions IndentedJsonOptions = new() { WriteIndented = true };
|
||||
private static readonly SettingsUtils SettingsUtils = new SettingsUtils();
|
||||
private static readonly SettingsUtils SettingsUtils = SettingsUtils.Default;
|
||||
|
||||
/// <summary>
|
||||
/// Configures global PowerToys settings to enable only specified modules and disable all others.
|
||||
|
||||
@@ -16,9 +16,54 @@
|
||||
|
||||
namespace registry
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
struct on_exit
|
||||
{
|
||||
std::function<void()> f;
|
||||
|
||||
on_exit(std::function<void()> f) :
|
||||
f{ std::move(f) } {}
|
||||
~on_exit() { f(); }
|
||||
};
|
||||
|
||||
template<class... Ts>
|
||||
struct overloaded : Ts...
|
||||
{
|
||||
using Ts::operator()...;
|
||||
};
|
||||
|
||||
template<class... Ts>
|
||||
overloaded(Ts...) -> overloaded<Ts...>;
|
||||
|
||||
inline const wchar_t* getScopeName(HKEY scope)
|
||||
{
|
||||
if (scope == HKEY_LOCAL_MACHINE)
|
||||
{
|
||||
return L"HKLM";
|
||||
}
|
||||
else if (scope == HKEY_CURRENT_USER)
|
||||
{
|
||||
return L"HKCU";
|
||||
}
|
||||
else if (scope == HKEY_CLASSES_ROOT)
|
||||
{
|
||||
return L"HKCR";
|
||||
}
|
||||
else
|
||||
{
|
||||
return L"HK??";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace install_scope
|
||||
{
|
||||
const wchar_t INSTALL_SCOPE_REG_KEY[] = L"Software\\Classes\\powertoys\\";
|
||||
const wchar_t UNINSTALL_REG_KEY[] = L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
|
||||
|
||||
// Bundle UpgradeCode from PowerToys.wxs (with braces as stored in registry)
|
||||
const wchar_t BUNDLE_UPGRADE_CODE[] = L"{6341382D-C0A9-4238-9188-BE9607E3FAB2}";
|
||||
|
||||
enum class InstallScope
|
||||
{
|
||||
@@ -26,8 +71,67 @@ namespace registry
|
||||
PerUser,
|
||||
};
|
||||
|
||||
// Helper function to find PowerToys bundle in Windows Uninstall registry by BundleUpgradeCode
|
||||
inline bool find_powertoys_bundle_in_uninstall_registry(HKEY rootKey)
|
||||
{
|
||||
HKEY uninstallKey{};
|
||||
if (RegOpenKeyExW(rootKey, UNINSTALL_REG_KEY, 0, KEY_READ, &uninstallKey) != ERROR_SUCCESS)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
detail::on_exit closeUninstallKey{ [uninstallKey] { RegCloseKey(uninstallKey); } };
|
||||
|
||||
DWORD index = 0;
|
||||
wchar_t subKeyName[256];
|
||||
|
||||
// Enumerate all subkeys under Uninstall
|
||||
while (RegEnumKeyW(uninstallKey, index++, subKeyName, 256) == ERROR_SUCCESS)
|
||||
{
|
||||
HKEY productKey{};
|
||||
if (RegOpenKeyExW(uninstallKey, subKeyName, 0, KEY_READ, &productKey) != ERROR_SUCCESS)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
detail::on_exit closeProductKey{ [productKey] { RegCloseKey(productKey); } };
|
||||
|
||||
// Check BundleUpgradeCode value (specific to WiX Bundle installations)
|
||||
wchar_t bundleUpgradeCode[256]{};
|
||||
DWORD bundleUpgradeCodeSize = sizeof(bundleUpgradeCode);
|
||||
|
||||
if (RegQueryValueExW(productKey, L"BundleUpgradeCode", nullptr, nullptr,
|
||||
reinterpret_cast<LPBYTE>(bundleUpgradeCode), &bundleUpgradeCodeSize) == ERROR_SUCCESS)
|
||||
{
|
||||
if (_wcsicmp(bundleUpgradeCode, BUNDLE_UPGRADE_CODE) == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
inline const InstallScope get_current_install_scope()
|
||||
{
|
||||
// 1. Check HKCU Uninstall registry first (user-level bundle)
|
||||
// Note: MSI components are always in HKLM regardless of install scope,
|
||||
// but the Bundle entry will be in HKCU for per-user installations
|
||||
if (find_powertoys_bundle_in_uninstall_registry(HKEY_CURRENT_USER))
|
||||
{
|
||||
Logger::info(L"Found user-level PowerToys bundle via BundleUpgradeCode in HKCU");
|
||||
return InstallScope::PerUser;
|
||||
}
|
||||
|
||||
// 2. Check HKLM Uninstall registry (machine-level bundle)
|
||||
if (find_powertoys_bundle_in_uninstall_registry(HKEY_LOCAL_MACHINE))
|
||||
{
|
||||
Logger::info(L"Found machine-level PowerToys bundle via BundleUpgradeCode in HKLM");
|
||||
return InstallScope::PerMachine;
|
||||
}
|
||||
|
||||
// 3. Fallback to legacy custom registry key detection
|
||||
Logger::info(L"PowerToys bundle not found in Uninstall registry, falling back to legacy detection");
|
||||
|
||||
// Open HKLM key
|
||||
HKEY perMachineKey{};
|
||||
if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
|
||||
@@ -45,6 +149,7 @@ namespace registry
|
||||
&perUserKey) != ERROR_SUCCESS)
|
||||
{
|
||||
// both keys are missing
|
||||
Logger::warn(L"No PowerToys installation detected, defaulting to PerMachine");
|
||||
return InstallScope::PerMachine;
|
||||
}
|
||||
else
|
||||
@@ -96,47 +201,6 @@ namespace registry
|
||||
template<class>
|
||||
inline constexpr bool always_false_v = false;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
struct on_exit
|
||||
{
|
||||
std::function<void()> f;
|
||||
|
||||
on_exit(std::function<void()> f) :
|
||||
f{ std::move(f) } {}
|
||||
~on_exit() { f(); }
|
||||
};
|
||||
|
||||
template<class... Ts>
|
||||
struct overloaded : Ts...
|
||||
{
|
||||
using Ts::operator()...;
|
||||
};
|
||||
|
||||
template<class... Ts>
|
||||
overloaded(Ts...) -> overloaded<Ts...>;
|
||||
|
||||
inline const wchar_t* getScopeName(HKEY scope)
|
||||
{
|
||||
if (scope == HKEY_LOCAL_MACHINE)
|
||||
{
|
||||
return L"HKLM";
|
||||
}
|
||||
else if (scope == HKEY_CURRENT_USER)
|
||||
{
|
||||
return L"HKCU";
|
||||
}
|
||||
else if (scope == HKEY_CLASSES_ROOT)
|
||||
{
|
||||
return L"HKCR";
|
||||
}
|
||||
else
|
||||
{
|
||||
return L"HK??";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct ValueChange
|
||||
{
|
||||
using value_t = std::variant<DWORD, std::wstring>;
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace PowerToys.DSC.UnitTests.SettingsResourceTests;
|
||||
public abstract class SettingsResourceModuleTest<TSettingsConfig> : BaseDscTest
|
||||
where TSettingsConfig : ISettingsConfig, new()
|
||||
{
|
||||
private readonly SettingsUtils _settingsUtils = new();
|
||||
private readonly SettingsUtils _settingsUtils = SettingsUtils.Default;
|
||||
private TSettingsConfig _originalSettings;
|
||||
|
||||
protected TSettingsConfig DefaultSettings => new();
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace PowerToys.DSC.Models.FunctionData;
|
||||
public sealed class SettingsFunctionData<TSettingsConfig> : BaseFunctionData, ISettingsFunctionData
|
||||
where TSettingsConfig : ISettingsConfig, new()
|
||||
{
|
||||
private static readonly SettingsUtils _settingsUtils = new();
|
||||
private static readonly SettingsUtils _settingsUtils = SettingsUtils.Default;
|
||||
private static readonly TSettingsConfig _settingsConfig = new();
|
||||
|
||||
private readonly SettingsResourceObject<TSettingsConfig> _input;
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using AdvancedPaste.Converters;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Windows.UI;
|
||||
|
||||
namespace AdvancedPaste.UnitTests.ConvertersTests;
|
||||
|
||||
[TestClass]
|
||||
public sealed class HexColorToColorConverterTests
|
||||
{
|
||||
[TestMethod]
|
||||
public void TestConvert_ValidSixDigitHex_ReturnsColor()
|
||||
{
|
||||
Color? result = HexColorConverterHelper.ConvertHexColorToRgb("#FFBFAB");
|
||||
Assert.IsNotNull(result);
|
||||
|
||||
var color = (Windows.UI.Color)result;
|
||||
Assert.AreEqual(255, color.R);
|
||||
Assert.AreEqual(191, color.G);
|
||||
Assert.AreEqual(171, color.B);
|
||||
Assert.AreEqual(255, color.A);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestConvert_ValidThreeDigitHex_ReturnsColor()
|
||||
{
|
||||
Color? result = HexColorConverterHelper.ConvertHexColorToRgb("#abc");
|
||||
Assert.IsNotNull(result);
|
||||
|
||||
var color = (Windows.UI.Color)result;
|
||||
|
||||
// #abc should expand to #aabbcc
|
||||
Assert.AreEqual(170, color.R); // 0xaa
|
||||
Assert.AreEqual(187, color.G); // 0xbb
|
||||
Assert.AreEqual(204, color.B); // 0xcc
|
||||
Assert.AreEqual(255, color.A);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestConvert_NullOrEmpty_ReturnsNull()
|
||||
{
|
||||
Assert.IsNull(HexColorConverterHelper.ConvertHexColorToRgb(null));
|
||||
Assert.IsNull(HexColorConverterHelper.ConvertHexColorToRgb(string.Empty));
|
||||
Assert.IsNull(HexColorConverterHelper.ConvertHexColorToRgb(" "));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestConvert_InvalidHex_ReturnsNull()
|
||||
{
|
||||
Assert.IsNull(HexColorConverterHelper.ConvertHexColorToRgb("#GGGGGG"));
|
||||
Assert.IsNull(HexColorConverterHelper.ConvertHexColorToRgb("#12345"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using AdvancedPaste.Helpers;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
|
||||
namespace AdvancedPaste.UnitTests.HelpersTests;
|
||||
|
||||
[TestClass]
|
||||
public sealed class ClipboardItemHelperTests
|
||||
{
|
||||
[TestMethod]
|
||||
[DataRow("#FFBFAB", true)]
|
||||
[DataRow("#000000", true)]
|
||||
[DataRow("#FFFFFF", true)]
|
||||
[DataRow("#fff", true)]
|
||||
[DataRow("#abc", true)]
|
||||
[DataRow("#123456", true)]
|
||||
[DataRow("#AbCdEf", true)]
|
||||
[DataRow("FFBFAB", false)] // Missing #
|
||||
[DataRow("#GGGGGG", false)] // Invalid hex characters
|
||||
[DataRow("#12345", false)] // Wrong length
|
||||
[DataRow("#1234567", false)] // Too long
|
||||
[DataRow("", false)]
|
||||
[DataRow(null, false)]
|
||||
[DataRow(" #FFF ", true)] // Whitespace should be trimmed
|
||||
[DataRow("Not a color", false)]
|
||||
[DataRow("#", false)]
|
||||
[DataRow("##FFFFFF", false)]
|
||||
public void TestIsRgbHexColor(string input, bool expected)
|
||||
{
|
||||
bool result = ClipboardItemHelper.IsRgbHexColor(input);
|
||||
Assert.AreEqual(expected, result, $"IsRgbHexColor(\"{input}\") should return {expected}");
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,7 @@
|
||||
mc:Ignorable="d">
|
||||
<UserControl.Resources>
|
||||
<converters:DateTimeToFriendlyStringConverter x:Key="DateTimeToFriendlyStringConverter" />
|
||||
<converters:HexColorToBrushConverter x:Key="HexColorToBrushConverter" />
|
||||
<tkconverters:BoolToVisibilityConverter x:Name="BoolToVisibilityConverter" />
|
||||
</UserControl.Resources>
|
||||
<Grid ColumnSpacing="12">
|
||||
@@ -25,6 +26,26 @@
|
||||
Source="{x:Bind ClipboardItem.Image, Mode=OneWay}"
|
||||
Stretch="UniformToFill"
|
||||
Visibility="{x:Bind HasImage, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}" />
|
||||
<!-- Color preview with text -->
|
||||
<Grid Visibility="{x:Bind HasColor, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Ellipse
|
||||
Grid.Column="0"
|
||||
Width="8"
|
||||
Height="8"
|
||||
Margin="8,0,8,0"
|
||||
Fill="{x:Bind ClipboardItem.Content, Mode=OneWay, Converter={StaticResource HexColorToBrushConverter}}" />
|
||||
<TextBlock
|
||||
Grid.Column="1"
|
||||
VerticalAlignment="Center"
|
||||
FontSize="10"
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
Text="{x:Bind ClipboardItem.Content, Mode=OneWay}"
|
||||
TextWrapping="NoWrap" />
|
||||
</Grid>
|
||||
<!-- Text preview -->
|
||||
<TextBlock
|
||||
Margin="8,0,0,0"
|
||||
|
||||
@@ -38,9 +38,11 @@ namespace AdvancedPaste.Controls
|
||||
|
||||
public bool HasImage => ContentImage is not null;
|
||||
|
||||
public bool HasText => !string.IsNullOrEmpty(ContentText) && !HasImage;
|
||||
public bool HasText => !string.IsNullOrEmpty(ContentText) && !HasImage && !HasColor;
|
||||
|
||||
public bool HasGlyph => !HasImage && !HasText && !string.IsNullOrEmpty(IconGlyph);
|
||||
public bool HasGlyph => !HasImage && !HasText && !HasColor && !string.IsNullOrEmpty(IconGlyph);
|
||||
|
||||
public bool HasColor => ClipboardItemHelper.IsRgbHexColor(ContentText);
|
||||
|
||||
public ClipboardHistoryItemPreviewControl()
|
||||
{
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
namespace AdvancedPaste.Converters
|
||||
{
|
||||
public static class HexColorConverterHelper
|
||||
{
|
||||
public static Windows.UI.Color? ConvertHexColorToRgb(string hexColor)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Remove # if present
|
||||
var cleanHex = hexColor.TrimStart('#');
|
||||
|
||||
// Expand 3-digit hex to 6-digit (#ABC -> #AABBCC)
|
||||
if (cleanHex.Length == 3)
|
||||
{
|
||||
cleanHex = $"{cleanHex[0]}{cleanHex[0]}{cleanHex[1]}{cleanHex[1]}{cleanHex[2]}{cleanHex[2]}";
|
||||
}
|
||||
|
||||
if (cleanHex.Length == 6)
|
||||
{
|
||||
var r = System.Convert.ToByte(cleanHex.Substring(0, 2), 16);
|
||||
var g = System.Convert.ToByte(cleanHex.Substring(2, 2), 16);
|
||||
var b = System.Convert.ToByte(cleanHex.Substring(4, 2), 16);
|
||||
|
||||
return Windows.UI.Color.FromArgb(255, r, g, b);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Invalid color format - return null
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using Microsoft.UI.Xaml.Data;
|
||||
using Microsoft.UI.Xaml.Media;
|
||||
|
||||
namespace AdvancedPaste.Converters
|
||||
{
|
||||
public sealed partial class HexColorToBrushConverter : IValueConverter
|
||||
{
|
||||
public object ConvertBack(object value, Type targetType, object parameter, string language)
|
||||
=> throw new NotSupportedException();
|
||||
|
||||
public object Convert(object value, Type targetType, object parameter, string language)
|
||||
{
|
||||
if (value is not string hexColor || string.IsNullOrWhiteSpace(hexColor))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
Windows.UI.Color? color = HexColorConverterHelper.ConvertHexColorToRgb(hexColor);
|
||||
|
||||
return color != null ? new SolidColorBrush((Windows.UI.Color)color) : null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using AdvancedPaste.Models;
|
||||
using Microsoft.UI.Xaml.Media.Imaging;
|
||||
@@ -10,8 +11,11 @@ using Windows.ApplicationModel.DataTransfer;
|
||||
|
||||
namespace AdvancedPaste.Helpers
|
||||
{
|
||||
internal static class ClipboardItemHelper
|
||||
internal static partial class ClipboardItemHelper
|
||||
{
|
||||
// Compiled regex for better performance when checking multiple clipboard items
|
||||
private static readonly Regex HexColorRegex = HexColorCompiledRegex();
|
||||
|
||||
/// <summary>
|
||||
/// Creates a ClipboardItem from current clipboard data.
|
||||
/// </summary>
|
||||
@@ -55,6 +59,31 @@ namespace AdvancedPaste.Helpers
|
||||
return clipboardItem;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if text is a valid RGB hex color (e.g., #FFBFAB or #fff).
|
||||
/// </summary>
|
||||
public static bool IsRgbHexColor(string text)
|
||||
{
|
||||
if (text == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
string trimmedText = text.Trim();
|
||||
if (trimmedText.Length > 7)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(trimmedText))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Match #RGB or #RRGGBB format (case-insensitive)
|
||||
return HexColorRegex.IsMatch(trimmedText);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a BitmapImage from clipboard data.
|
||||
/// </summary>
|
||||
@@ -80,5 +109,8 @@ namespace AdvancedPaste.Helpers
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
[GeneratedRegex(@"^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6})$")]
|
||||
private static partial Regex HexColorCompiledRegex();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ namespace Hosts.Settings
|
||||
|
||||
public UserSettings()
|
||||
{
|
||||
_settingsUtils = new SettingsUtils();
|
||||
_settingsUtils = SettingsUtils.Default;
|
||||
var defaultSettings = new HostsProperties();
|
||||
ShowStartupWarning = defaultSettings.ShowStartupWarning;
|
||||
LoopbackDuplicates = defaultSettings.LoopbackDuplicates;
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="..\..\..\..\packages\Microsoft.WindowsAppSDK.1.8.250907003\build\native\Microsoft.WindowsAppSDK.props" Condition="Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.1.8.250907003\build\native\Microsoft.WindowsAppSDK.props')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.WindowsAppSDK.Base.1.8.250831001\build\native\Microsoft.WindowsAppSDK.Base.props" Condition="Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.Base.1.8.250831001\build\native\Microsoft.WindowsAppSDK.Base.props')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.WindowsAppSDK.Foundation.1.8.250906002\build\native\Microsoft.WindowsAppSDK.Foundation.props" Condition="Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.Foundation.1.8.250906002\build\native\Microsoft.WindowsAppSDK.Foundation.props')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.WindowsAppSDK.WinUI.1.8.250906003\build\native\Microsoft.WindowsAppSDK.WinUI.props" Condition="Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.WinUI.1.8.250906003\build\native\Microsoft.WindowsAppSDK.WinUI.props')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.WindowsAppSDK.Runtime.1.8.250907003\build\native\Microsoft.WindowsAppSDK.Runtime.props" Condition="Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.Runtime.1.8.250907003\build\native\Microsoft.WindowsAppSDK.Runtime.props')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.WindowsAppSDK.DWrite.1.8.25090401\build\Microsoft.WindowsAppSDK.DWrite.props" Condition="Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.DWrite.1.8.25090401\build\Microsoft.WindowsAppSDK.DWrite.props')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.WindowsAppSDK.InteractiveExperiences.1.8.250906004\build\native\Microsoft.WindowsAppSDK.InteractiveExperiences.props" Condition="Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.InteractiveExperiences.1.8.250906004\build\native\Microsoft.WindowsAppSDK.InteractiveExperiences.props')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.Windows.SDK.BuildTools.10.0.26100.4188\build\Microsoft.Windows.SDK.BuildTools.props" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.SDK.BuildTools.10.0.26100.4188\build\Microsoft.Windows.SDK.BuildTools.props')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.240111.5\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.240111.5\build\native\Microsoft.Windows.CppWinRT.props')" />
|
||||
<PropertyGroup Label="NuGet">
|
||||
<!-- Tell NuGet this is PackageReference style -->
|
||||
<RestoreProjectStyle>PackageReference</RestoreProjectStyle>
|
||||
|
||||
<!-- Tell NuGet we're a native project -->
|
||||
<NuGetTargetMoniker>native,Version=v0.0</NuGetTargetMoniker>
|
||||
|
||||
<!-- Tell NuGet we target Windows (use your existing WindowsTargetPlatformVersion) -->
|
||||
<NuGetTargetPlatformIdentifier>Windows</NuGetTargetPlatformIdentifier>
|
||||
<NuGetTargetPlatformVersion>$(WindowsTargetPlatformVersion)</NuGetTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<CppWinRTOptimized>true</CppWinRTOptimized>
|
||||
<CppWinRTRootNamespaceAutoMerge>true</CppWinRTRootNamespaceAutoMerge>
|
||||
@@ -31,6 +33,11 @@
|
||||
<WindowsAppSDKSelfContained>true</WindowsAppSDKSelfContained>
|
||||
<EnablePreviewMsixTooling>true</EnablePreviewMsixTooling>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.WindowsAppSDK" GeneratePathProperty="true" />
|
||||
<PackageReference Include="Microsoft.Windows.CppWinRT" GeneratePathProperty="true" />
|
||||
<PackageReference Include="Microsoft.Windows.ImplementationLibrary" GeneratePathProperty="true" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
@@ -38,7 +45,6 @@
|
||||
<DesktopCompatible>true</DesktopCompatible>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<Import Project="..\..\..\..\deps\spdlog.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets">
|
||||
@@ -118,9 +124,6 @@
|
||||
<WarnAsError>true</WarnAsError>
|
||||
</Midl>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\common\Display\Display.vcxproj">
|
||||
<Project>{caba8dfb-823b-4bf2-93ac-3f31984150d9}</Project>
|
||||
@@ -142,42 +145,5 @@
|
||||
<ResourceCompile Include="PowerToys.MeasureToolCore.rc" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.240111.5\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.240111.5\build\native\Microsoft.Windows.CppWinRT.targets')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.Windows.SDK.BuildTools.10.0.26100.4188\build\Microsoft.Windows.SDK.BuildTools.targets" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.SDK.BuildTools.10.0.26100.4188\build\Microsoft.Windows.SDK.BuildTools.targets')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.Web.WebView2.1.0.2903.40\build\native\Microsoft.Web.WebView2.targets" Condition="Exists('..\..\..\..\packages\Microsoft.Web.WebView2.1.0.2903.40\build\native\Microsoft.Web.WebView2.targets')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.WindowsAppSDK.1.8.250907003\build\native\Microsoft.WindowsAppSDK.targets" Condition="Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.1.8.250907003\build\native\Microsoft.WindowsAppSDK.targets')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.WindowsAppSDK.Base.1.8.250831001\build\native\Microsoft.WindowsAppSDK.Base.targets" Condition="Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.Base.1.8.250831001\build\native\Microsoft.WindowsAppSDK.Base.targets')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.WindowsAppSDK.Foundation.1.8.250906002\build\native\Microsoft.WindowsAppSDK.Foundation.targets" Condition="Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.Foundation.1.8.250906002\build\native\Microsoft.WindowsAppSDK.Foundation.targets')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.WindowsAppSDK.WinUI.1.8.250906003\build\native\Microsoft.WindowsAppSDK.WinUI.targets" Condition="Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.WinUI.1.8.250906003\build\native\Microsoft.WindowsAppSDK.WinUI.targets')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.WindowsAppSDK.Runtime.1.8.250907003\build\native\Microsoft.WindowsAppSDK.Runtime.targets" Condition="Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.Runtime.1.8.250907003\build\native\Microsoft.WindowsAppSDK.Runtime.targets')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.WindowsAppSDK.DWrite.1.8.25090401\build\Microsoft.WindowsAppSDK.DWrite.targets" Condition="Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.DWrite.1.8.25090401\build\Microsoft.WindowsAppSDK.DWrite.targets')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.WindowsAppSDK.InteractiveExperiences.1.8.250906004\build\native\Microsoft.WindowsAppSDK.InteractiveExperiences.targets" Condition="Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.InteractiveExperiences.1.8.250906004\build\native\Microsoft.WindowsAppSDK.InteractiveExperiences.targets')" />
|
||||
</ImportGroup>
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.240111.5\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.240111.5\build\native\Microsoft.Windows.CppWinRT.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.240111.5\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.240111.5\build\native\Microsoft.Windows.CppWinRT.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.SDK.BuildTools.10.0.26100.4188\build\Microsoft.Windows.SDK.BuildTools.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.SDK.BuildTools.10.0.26100.4188\build\Microsoft.Windows.SDK.BuildTools.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.SDK.BuildTools.10.0.26100.4188\build\Microsoft.Windows.SDK.BuildTools.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.SDK.BuildTools.10.0.26100.4188\build\Microsoft.Windows.SDK.BuildTools.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Web.WebView2.1.0.2903.40\build\native\Microsoft.Web.WebView2.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Web.WebView2.1.0.2903.40\build\native\Microsoft.Web.WebView2.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.1.8.250907003\build\native\Microsoft.WindowsAppSDK.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.WindowsAppSDK.1.8.250907003\build\native\Microsoft.WindowsAppSDK.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.1.8.250907003\build\native\Microsoft.WindowsAppSDK.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.WindowsAppSDK.1.8.250907003\build\native\Microsoft.WindowsAppSDK.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.Base.1.8.250831001\build\native\Microsoft.WindowsAppSDK.Base.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.WindowsAppSDK.Base.1.8.250831001\build\native\Microsoft.WindowsAppSDK.Base.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.Base.1.8.250831001\build\native\Microsoft.WindowsAppSDK.Base.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.WindowsAppSDK.Base.1.8.250831001\build\native\Microsoft.WindowsAppSDK.Base.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.Foundation.1.8.250906002\build\native\Microsoft.WindowsAppSDK.Foundation.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.WindowsAppSDK.Foundation.1.8.250906002\build\native\Microsoft.WindowsAppSDK.Foundation.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.Foundation.1.8.250906002\build\native\Microsoft.WindowsAppSDK.Foundation.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.WindowsAppSDK.Foundation.1.8.250906002\build\native\Microsoft.WindowsAppSDK.Foundation.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.WinUI.1.8.250906003\build\native\Microsoft.WindowsAppSDK.WinUI.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.WindowsAppSDK.WinUI.1.8.250906003\build\native\Microsoft.WindowsAppSDK.WinUI.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.WinUI.1.8.250906003\build\native\Microsoft.WindowsAppSDK.WinUI.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.WindowsAppSDK.WinUI.1.8.250906003\build\native\Microsoft.WindowsAppSDK.WinUI.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.Runtime.1.8.250907003\build\native\Microsoft.WindowsAppSDK.Runtime.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.WindowsAppSDK.Runtime.1.8.250907003\build\native\Microsoft.WindowsAppSDK.Runtime.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.Runtime.1.8.250907003\build\native\Microsoft.WindowsAppSDK.Runtime.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.WindowsAppSDK.Runtime.1.8.250907003\build\native\Microsoft.WindowsAppSDK.Runtime.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.DWrite.1.8.25090401\build\Microsoft.WindowsAppSDK.DWrite.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.WindowsAppSDK.DWrite.1.8.25090401\build\Microsoft.WindowsAppSDK.DWrite.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.DWrite.1.8.25090401\build\Microsoft.WindowsAppSDK.DWrite.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.WindowsAppSDK.DWrite.1.8.25090401\build\Microsoft.WindowsAppSDK.DWrite.targets'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.InteractiveExperiences.1.8.250906004\build\native\Microsoft.WindowsAppSDK.InteractiveExperiences.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.WindowsAppSDK.InteractiveExperiences.1.8.250906004\build\native\Microsoft.WindowsAppSDK.InteractiveExperiences.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.InteractiveExperiences.1.8.250906004\build\native\Microsoft.WindowsAppSDK.InteractiveExperiences.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.WindowsAppSDK.InteractiveExperiences.1.8.250906004\build\native\Microsoft.WindowsAppSDK.InteractiveExperiences.targets'))" />
|
||||
</Target>
|
||||
<Import Project="..\..\..\..\deps\spdlog.props" />
|
||||
</Project>
|
||||
@@ -1,17 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Web.WebView2" version="1.0.2903.40" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.240111.5" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.231216.1" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.SDK.BuildTools" version="10.0.26100.4188" targetFramework="native" />
|
||||
<package id="Microsoft.WindowsAppSDK" version="1.8.250907003" targetFramework="native" />
|
||||
<package id="Microsoft.WindowsAppSDK.Base" version="1.8.250831001" targetFramework="native" />
|
||||
<package id="Microsoft.WindowsAppSDK.Foundation" version="1.8.250906002" targetFramework="native" />
|
||||
<package id="Microsoft.WindowsAppSDK.WinUI" version="1.8.250906003" targetFramework="native" />
|
||||
<package id="Microsoft.WindowsAppSDK.Runtime" version="1.8.250907003" targetFramework="native" />
|
||||
<package id="Microsoft.WindowsAppSDK.DWrite" version="1.8.25090401" targetFramework="native" />
|
||||
<package id="Microsoft.WindowsAppSDK.InteractiveExperiences" version="1.8.250906004" targetFramework="native" />
|
||||
<package id="Microsoft.WindowsAppSDK.Widgets" version="1.8.250904007" targetFramework="native" />
|
||||
<package id="Microsoft.WindowsAppSDK.AI" version="1.8.37" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.SDK.BuildTools.MSIX" version="1.7.20250829.1" targetFramework="native" />
|
||||
</packages>
|
||||
@@ -73,6 +73,13 @@
|
||||
<ProjectReference Include="..\..\..\common\interop\PowerToys.Interop.vcxproj" />
|
||||
<ProjectReference Include="..\..\..\common\ManagedCommon\ManagedCommon.csproj" />
|
||||
<ProjectReference Include="..\..\..\settings-ui\Settings.UI.Library\Settings.UI.Library.csproj" />
|
||||
<ProjectReference Include="..\MeasureToolCore\PowerToys.MeasureToolCore.vcxproj" />
|
||||
<ProjectReference Include="..\MeasureToolCore\PowerToys.MeasureToolCore.vcxproj">
|
||||
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||
<BuildProject>true</BuildProject>
|
||||
</ProjectReference>
|
||||
<CsWinRTInputs Include="$(OutputPath)\PowerToys.MeasureToolCore.winmd" />
|
||||
<None Include="$(OutputPath)\PowerToys.MeasureToolCore.dll">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace MeasureToolUI
|
||||
{
|
||||
public sealed class Settings
|
||||
{
|
||||
private static readonly SettingsUtils ModuleSettings = new();
|
||||
private static readonly SettingsUtils ModuleSettings = SettingsUtils.Default;
|
||||
|
||||
public MeasureToolMeasureStyle DefaultMeasureStyle
|
||||
{
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="..\..\..\..\packages\Microsoft.WindowsAppSDK.1.8.250907003\build\native\Microsoft.WindowsAppSDK.props" Condition="Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.1.8.250907003\build\native\Microsoft.WindowsAppSDK.props')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.WindowsAppSDK.Base.1.8.250831001\build\native\Microsoft.WindowsAppSDK.Base.props" Condition="Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.Base.1.8.250831001\build\native\Microsoft.WindowsAppSDK.Base.props')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.WindowsAppSDK.Foundation.1.8.250906002\build\native\Microsoft.WindowsAppSDK.Foundation.props" Condition="Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.Foundation.1.8.250906002\build\native\Microsoft.WindowsAppSDK.Foundation.props')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.WindowsAppSDK.WinUI.1.8.250906003\build\native\Microsoft.WindowsAppSDK.WinUI.props" Condition="Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.WinUI.1.8.250906003\build\native\Microsoft.WindowsAppSDK.WinUI.props')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.WindowsAppSDK.Runtime.1.8.250907003\build\native\Microsoft.WindowsAppSDK.Runtime.props" Condition="Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.Runtime.1.8.250907003\build\native\Microsoft.WindowsAppSDK.Runtime.props')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.WindowsAppSDK.DWrite.1.8.25090401\build\Microsoft.WindowsAppSDK.DWrite.props" Condition="Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.DWrite.1.8.25090401\build\Microsoft.WindowsAppSDK.DWrite.props')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.WindowsAppSDK.InteractiveExperiences.1.8.250906004\build\native\Microsoft.WindowsAppSDK.InteractiveExperiences.props" Condition="Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.InteractiveExperiences.1.8.250906004\build\native\Microsoft.WindowsAppSDK.InteractiveExperiences.props')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.240111.5\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.240111.5\build\native\Microsoft.Windows.CppWinRT.props')" />
|
||||
<PropertyGroup Label="NuGet">
|
||||
<!-- Tell NuGet this is PackageReference style -->
|
||||
<RestoreProjectStyle>PackageReference</RestoreProjectStyle>
|
||||
|
||||
<!-- Tell NuGet we're a native project -->
|
||||
<NuGetTargetMoniker>native,Version=v0.0</NuGetTargetMoniker>
|
||||
|
||||
<!-- Tell NuGet we target Windows (use your existing WindowsTargetPlatformVersion) -->
|
||||
<NuGetTargetPlatformIdentifier>Windows</NuGetTargetPlatformIdentifier>
|
||||
<NuGetTargetPlatformVersion>$(WindowsTargetPlatformVersion)</NuGetTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>15.0</VCProjectVersion>
|
||||
<ProjectGuid>{e94fd11c-0591-456f-899f-efc0ca548336}</ProjectGuid>
|
||||
@@ -20,9 +23,12 @@
|
||||
<WindowsAppSdkBootstrapInitialize>false</WindowsAppSdkBootstrapInitialize>
|
||||
<WindowsAppSDKSelfContained>true</WindowsAppSDKSelfContained>
|
||||
<WindowsAppSDKVerifyTransitiveDependencies>false</WindowsAppSDKVerifyTransitiveDependencies>
|
||||
<!-- Force NuGet to treat this project strictly as packages.config style -->
|
||||
<RestoreProjectStyle>packages.config</RestoreProjectStyle>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.WindowsAppSDK" GeneratePathProperty="true"/>
|
||||
<PackageReference Include="Microsoft.WindowsAppSDK.Foundation" GeneratePathProperty="true"/>
|
||||
<PackageReference Include="Microsoft.Windows.CppWinRT" GeneratePathProperty="true"/>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
@@ -127,18 +133,18 @@
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="FindMyMouse.rc" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<!-- Deduplicate WindowsAppRuntimeAutoInitializer.cpp (added twice via transitive imports causing LNK4042). Remove all then add exactly once. -->
|
||||
<ItemGroup Condition="'$(PkgMicrosoft_WindowsAppSDK)'!=''">
|
||||
<!-- Remove any transitive inclusion first -->
|
||||
<ClCompile Remove="$(PkgMicrosoft_WindowsAppSDK)\include\WindowsAppRuntimeAutoInitializer.cpp" />
|
||||
<!-- Re-add once, but disable PCH because the SDK file doesn't include our pch.h -->
|
||||
<ClCompile Include="$(PkgMicrosoft_WindowsAppSDK)\include\WindowsAppRuntimeAutoInitializer.cpp">
|
||||
<Target Name="FixWinAppSDKAutoInitializer" BeforeTargets="ClCompile" AfterTargets="WindowsAppRuntimeAutoInitializer">
|
||||
<ItemGroup>
|
||||
<!-- Remove ALL injected versions of the file -->
|
||||
<ClCompile Remove="@(ClCompile)" Condition="'%(Filename)' == 'WindowsAppRuntimeAutoInitializer'" />
|
||||
|
||||
<!-- Add ONE copy back manually -->
|
||||
<ClCompile Include="$(PkgMicrosoft_WindowsAppSDK_Foundation)\include\WindowsAppRuntimeAutoInitializer.cpp">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
<Target Name="RemoveManagedWebView2CoreFromNativeOutDir" AfterTargets="Build">
|
||||
<ItemGroup>
|
||||
<_ToDelete Include="$(OutDir)Microsoft.Web.WebView2.Core.dll" />
|
||||
@@ -148,38 +154,4 @@
|
||||
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<Import Project="..\..\..\..\deps\spdlog.props" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.240111.5\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.240111.5\build\native\Microsoft.Windows.CppWinRT.targets')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.Web.WebView2.1.0.2903.40\build\native\Microsoft.Web.WebView2.targets" Condition="Exists('..\..\..\..\packages\Microsoft.Web.WebView2.1.0.2903.40\build\native\Microsoft.Web.WebView2.targets')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.Windows.SDK.BuildTools.10.0.26100.4188\build\Microsoft.Windows.SDK.BuildTools.targets" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.SDK.BuildTools.10.0.26100.4188\build\Microsoft.Windows.SDK.BuildTools.targets')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.WindowsAppSDK.1.8.250907003\build\native\Microsoft.WindowsAppSDK.targets" Condition="Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.1.8.250907003\build\native\Microsoft.WindowsAppSDK.targets')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.WindowsAppSDK.Base.1.8.250831001\build\native\Microsoft.WindowsAppSDK.Base.targets" Condition="Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.Base.1.8.250831001\build\native\Microsoft.WindowsAppSDK.Base.targets')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.WindowsAppSDK.Foundation.1.8.250906002\build\native\Microsoft.WindowsAppSDK.Foundation.targets" Condition="Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.Foundation.1.8.250906002\build\native\Microsoft.WindowsAppSDK.Foundation.targets')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.WindowsAppSDK.WinUI.1.8.250906003\build\native\Microsoft.WindowsAppSDK.WinUI.targets" Condition="Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.WinUI.1.8.250906003\build\native\Microsoft.WindowsAppSDK.WinUI.targets')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.WindowsAppSDK.Runtime.1.8.250907003\build\native\Microsoft.WindowsAppSDK.Runtime.targets" Condition="Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.Runtime.1.8.250907003\build\native\Microsoft.WindowsAppSDK.Runtime.targets')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.WindowsAppSDK.DWrite.1.8.25090401\build\Microsoft.WindowsAppSDK.DWrite.targets" Condition="Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.DWrite.1.8.25090401\build\Microsoft.WindowsAppSDK.DWrite.targets')" />
|
||||
<Import Project="..\..\..\..\packages\Microsoft.WindowsAppSDK.InteractiveExperiences.1.8.250906004\build\native\Microsoft.WindowsAppSDK.InteractiveExperiences.targets" Condition="Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.InteractiveExperiences.1.8.250906004\build\native\Microsoft.WindowsAppSDK.InteractiveExperiences.targets')" />
|
||||
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\\..\\..\\..\\packages\\Microsoft.Windows.CppWinRT.2.0.240111.5\\build\\native\\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '..\\..\\..\\..\\packages\\Microsoft.Windows.CppWinRT.2.0.240111.5\\build\\native\\Microsoft.Windows.CppWinRT.props'))" />
|
||||
<Error Condition="!Exists('..\\..\\..\\..\\packages\\Microsoft.Windows.CppWinRT.2.0.240111.5\\build\\native\\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\\..\\..\\..\\packages\\Microsoft.Windows.CppWinRT.2.0.240111.5\\build\\native\\Microsoft.Windows.CppWinRT.targets'))" />
|
||||
<Error Condition="!Exists('..\\..\\..\\..\\packages\\Microsoft.Web.WebView2.1.0.2903.40\\build\\native\\Microsoft.Web.WebView2.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\\..\\..\\..\\packages\\Microsoft.Web.WebView2.1.0.2903.40\\build\\native\\Microsoft.Web.WebView2.targets'))" />
|
||||
<Error Condition="!Exists('..\\..\\..\\..\\packages\\Microsoft.WindowsAppSDK.1.8.250907003\\build\\native\\Microsoft.WindowsAppSDK.props')" Text="$([System.String]::Format('$(ErrorText)', '..\\..\\..\\..\\packages\\Microsoft.WindowsAppSDK.1.8.250907003\\build\\native\\Microsoft.WindowsAppSDK.props'))" />
|
||||
<Error Condition="!Exists('..\\..\\..\\..\\packages\\Microsoft.WindowsAppSDK.1.8.250907003\\build\\native\\Microsoft.WindowsAppSDK.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\\..\\..\\..\\packages\\Microsoft.WindowsAppSDK.1.8.250907003\\build\\native\\Microsoft.WindowsAppSDK.targets'))" />
|
||||
<Error Condition="!Exists('..\\..\\..\\..\\packages\\Microsoft.WindowsAppSDK.Base.1.8.250831001\\build\\native\\Microsoft.WindowsAppSDK.Base.props')" Text="$([System.String]::Format('$(ErrorText)', '..\\..\\..\\..\\packages\\Microsoft.WindowsAppSDK.Base.1.8.250831001\\build\\native\\Microsoft.WindowsAppSDK.Base.props'))" />
|
||||
<Error Condition="!Exists('..\\..\\..\\..\\packages\\Microsoft.WindowsAppSDK.Base.1.8.250831001\\build\\native\\Microsoft.WindowsAppSDK.Base.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\\..\\..\\..\\packages\\Microsoft.WindowsAppSDK.Base.1.8.250831001\\build\\native\\Microsoft.WindowsAppSDK.Base.targets'))" />
|
||||
<Error Condition="!Exists('..\\..\\..\\..\\packages\\Microsoft.WindowsAppSDK.Foundation.1.8.250906002\\build\\native\\Microsoft.WindowsAppSDK.Foundation.props')" Text="$([System.String]::Format('$(ErrorText)', '..\\..\\..\\..\\packages\\Microsoft.WindowsAppSDK.Foundation.1.8.250906002\\build\\native\\Microsoft.WindowsAppSDK.Foundation.props'))" />
|
||||
<Error Condition="!Exists('..\\..\\..\\..\\packages\\Microsoft.WindowsAppSDK.Foundation.1.8.250906002\\build\\native\\Microsoft.WindowsAppSDK.Foundation.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\\..\\..\\..\\packages\\Microsoft.WindowsAppSDK.Foundation.1.8.250906002\\build\\native\\Microsoft.WindowsAppSDK.Foundation.targets'))" />
|
||||
<Error Condition="!Exists('..\\..\\..\\..\\packages\\Microsoft.WindowsAppSDK.WinUI.1.8.250906003\\build\\native\\Microsoft.WindowsAppSDK.WinUI.props')" Text="$([System.String]::Format('$(ErrorText)', '..\\..\\..\\..\\packages\\Microsoft.WindowsAppSDK.WinUI.1.8.250906003\\build\\native\\Microsoft.WindowsAppSDK.WinUI.props'))" />
|
||||
<Error Condition="!Exists('..\\..\\..\\..\\packages\\Microsoft.WindowsAppSDK.WinUI.1.8.250906003\\build\\native\\Microsoft.WindowsAppSDK.WinUI.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\\..\\..\\..\\packages\\Microsoft.WindowsAppSDK.WinUI.1.8.250906003\\build\\native\\Microsoft.WindowsAppSDK.WinUI.targets'))" />
|
||||
<Error Condition="!Exists('..\\..\\..\\..\\packages\\Microsoft.WindowsAppSDK.Runtime.1.8.250907003\\build\\native\\Microsoft.WindowsAppSDK.Runtime.props')" Text="$([System.String]::Format('$(ErrorText)', '..\\..\\..\\..\\packages\\Microsoft.WindowsAppSDK.Runtime.1.8.250907003\\build\\native\\Microsoft.WindowsAppSDK.Runtime.props'))" />
|
||||
<Error Condition="!Exists('..\\..\\..\\..\\packages\\Microsoft.WindowsAppSDK.Runtime.1.8.250907003\\build\\native\\Microsoft.WindowsAppSDK.Runtime.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\\..\\..\\..\\packages\\Microsoft.WindowsAppSDK.Runtime.1.8.250907003\\build\\native\\Microsoft.WindowsAppSDK.Runtime.targets'))" />
|
||||
<Error Condition="!Exists('..\\..\\..\\..\\packages\\Microsoft.WindowsAppSDK.DWrite.1.8.25090401\\build\\Microsoft.WindowsAppSDK.DWrite.props')" Text="$([System.String]::Format('$(ErrorText)', '..\\..\\..\\..\\packages\\Microsoft.WindowsAppSDK.DWrite.1.8.25090401\\build\\Microsoft.WindowsAppSDK.DWrite.props'))" />
|
||||
<Error Condition="!Exists('..\\..\\..\\..\\packages\\Microsoft.WindowsAppSDK.DWrite.1.8.25090401\\build\\Microsoft.WindowsAppSDK.DWrite.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\\..\\..\\..\\packages\\Microsoft.WindowsAppSDK.DWrite.1.8.25090401\\build\\Microsoft.WindowsAppSDK.DWrite.targets'))" />
|
||||
<Error Condition="!Exists('..\\..\\..\\..\\packages\\Microsoft.WindowsAppSDK.InteractiveExperiences.1.8.250906004\\build\\native\\Microsoft.WindowsAppSDK.InteractiveExperiences.props')" Text="$([System.String]::Format('$(ErrorText)', '..\\..\\..\\..\\packages\\Microsoft.WindowsAppSDK.InteractiveExperiences.1.8.250906004\\build\\native\\Microsoft.WindowsAppSDK.InteractiveExperiences.props'))" />
|
||||
<Error Condition="!Exists('..\\..\\..\\..\\packages\\Microsoft.WindowsAppSDK.InteractiveExperiences.1.8.250906004\\build\\native\\Microsoft.WindowsAppSDK.InteractiveExperiences.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\\..\\..\\..\\packages\\Microsoft.WindowsAppSDK.InteractiveExperiences.1.8.250906004\\build\\native\\Microsoft.WindowsAppSDK.InteractiveExperiences.targets'))" />
|
||||
</Target>
|
||||
</Project>
|
||||
@@ -1,12 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.240111.5" targetFramework="native" />
|
||||
<package id="Microsoft.WindowsAppSDK" version="1.8.250907003" targetFramework="native" />
|
||||
<package id="Microsoft.WindowsAppSDK.Base" version="1.8.250831001" targetFramework="native" />
|
||||
<package id="Microsoft.WindowsAppSDK.Foundation" version="1.8.250906002" targetFramework="native" />
|
||||
<package id="Microsoft.WindowsAppSDK.WinUI" version="1.8.250906003" targetFramework="native" />
|
||||
<package id="Microsoft.WindowsAppSDK.Runtime" version="1.8.250907003" targetFramework="native" />
|
||||
<package id="Microsoft.WindowsAppSDK.DWrite" version="1.8.25090401" targetFramework="native" />
|
||||
<package id="Microsoft.WindowsAppSDK.InteractiveExperiences" version="1.8.250906004" targetFramework="native" />
|
||||
<package id="Microsoft.Web.WebView2" version="1.0.2903.40" targetFramework="native" />
|
||||
</packages>
|
||||
@@ -53,7 +53,7 @@ internal sealed class SettingsHelper
|
||||
lock (this.LockObject)
|
||||
{
|
||||
{
|
||||
var settingsUtils = new SettingsUtils();
|
||||
var settingsUtils = SettingsUtils.Default;
|
||||
|
||||
// set this to 1 to disable retries
|
||||
var remainingRetries = 5;
|
||||
|
||||
@@ -1,248 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
// <summary>
|
||||
// Encrypt/decrypt implementation.
|
||||
// </summary>
|
||||
// <history>
|
||||
// 2008 created by Truong Do (ductdo).
|
||||
// 2009-... modified by Truong Do (TruongDo).
|
||||
// 2023- Included in PowerToys.
|
||||
// </history>
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using MouseWithoutBorders.Core;
|
||||
|
||||
namespace MouseWithoutBorders
|
||||
{
|
||||
internal partial class Common
|
||||
{
|
||||
#pragma warning disable SYSLIB0021
|
||||
private static AesCryptoServiceProvider symAl;
|
||||
#pragma warning restore SYSLIB0021
|
||||
#pragma warning disable SA1307 // Accessible fields should begin with upper-case letter
|
||||
internal static string myKey;
|
||||
#pragma warning restore SA1307
|
||||
private static uint magicNumber;
|
||||
private static Random ran = new(); // Used for non encryption related functionality.
|
||||
internal const int SymAlBlockSize = 16;
|
||||
|
||||
/// <summary>
|
||||
/// This is used for the first encryption block, the following blocks will be combined with the cipher text of the previous block.
|
||||
/// Thus identical blocks in the socket stream would be encrypted to different cipher text blocks.
|
||||
/// The first block is a handshake one containing random data.
|
||||
/// Related Unit Test: TestEncryptDecrypt
|
||||
/// </summary>
|
||||
internal static readonly string InitialIV = ulong.MaxValue.ToString(CultureInfo.InvariantCulture);
|
||||
|
||||
internal static Random Ran
|
||||
{
|
||||
get => Common.ran ??= new Random();
|
||||
set => Common.ran = value;
|
||||
}
|
||||
|
||||
internal static uint MagicNumber
|
||||
{
|
||||
get => Common.magicNumber;
|
||||
set => Common.magicNumber = value;
|
||||
}
|
||||
|
||||
internal static string MyKey
|
||||
{
|
||||
get => Common.myKey;
|
||||
|
||||
set
|
||||
{
|
||||
if (Common.myKey != value)
|
||||
{
|
||||
Common.myKey = value;
|
||||
_ = Task.Factory.StartNew(
|
||||
() => Common.GenLegalKey(),
|
||||
System.Threading.CancellationToken.None,
|
||||
TaskCreationOptions.None,
|
||||
TaskScheduler.Default); // Cache the key to improve UX.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static string KeyDisplayedText(string key)
|
||||
{
|
||||
string displayedValue = string.Empty;
|
||||
int i = 0;
|
||||
|
||||
do
|
||||
{
|
||||
int length = Math.Min(4, key.Length - i);
|
||||
displayedValue += string.Concat(key.AsSpan(i, length), " ");
|
||||
i += 4;
|
||||
}
|
||||
while (i < key.Length - 1);
|
||||
|
||||
return displayedValue.Trim();
|
||||
}
|
||||
|
||||
internal static bool GeneratedKey { get; set; }
|
||||
|
||||
internal static bool KeyCorrupted { get; set; }
|
||||
|
||||
internal static void InitEncryption()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (symAl == null)
|
||||
{
|
||||
#pragma warning disable SYSLIB0021 // No proper replacement for now
|
||||
symAl = new AesCryptoServiceProvider();
|
||||
#pragma warning restore SYSLIB0021
|
||||
symAl.KeySize = 256;
|
||||
symAl.BlockSize = SymAlBlockSize * 8;
|
||||
symAl.Padding = PaddingMode.Zeros;
|
||||
symAl.Mode = CipherMode.CBC;
|
||||
symAl.GenerateIV();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Log(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly ConcurrentDictionary<string, byte[]> LegalKeyDictionary = new(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
internal static byte[] GenLegalKey()
|
||||
{
|
||||
byte[] rv;
|
||||
string myKey = Common.MyKey;
|
||||
|
||||
if (!LegalKeyDictionary.TryGetValue(myKey, out byte[] value))
|
||||
{
|
||||
Rfc2898DeriveBytes key = new(
|
||||
myKey,
|
||||
Common.GetBytesU(InitialIV),
|
||||
50000,
|
||||
HashAlgorithmName.SHA512);
|
||||
rv = key.GetBytes(32);
|
||||
_ = LegalKeyDictionary.AddOrUpdate(myKey, rv, (k, v) => rv);
|
||||
}
|
||||
else
|
||||
{
|
||||
rv = value;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
private static byte[] GenLegalIV()
|
||||
{
|
||||
string st = InitialIV;
|
||||
int ivLength = symAl.IV.Length;
|
||||
if (st.Length > ivLength)
|
||||
{
|
||||
st = st[..ivLength];
|
||||
}
|
||||
else if (st.Length < ivLength)
|
||||
{
|
||||
st = st.PadRight(ivLength, ' ');
|
||||
}
|
||||
|
||||
return GetBytes(st);
|
||||
}
|
||||
|
||||
internal static Stream GetEncryptedStream(Stream encryptedStream)
|
||||
{
|
||||
ICryptoTransform encryptor;
|
||||
encryptor = symAl.CreateEncryptor(GenLegalKey(), GenLegalIV());
|
||||
return new CryptoStream(encryptedStream, encryptor, CryptoStreamMode.Write);
|
||||
}
|
||||
|
||||
internal static Stream GetDecryptedStream(Stream encryptedStream)
|
||||
{
|
||||
ICryptoTransform decryptor;
|
||||
decryptor = symAl.CreateDecryptor(GenLegalKey(), GenLegalIV());
|
||||
return new CryptoStream(encryptedStream, decryptor, CryptoStreamMode.Read);
|
||||
}
|
||||
|
||||
internal static uint Get24BitHash(string st)
|
||||
{
|
||||
if (string.IsNullOrEmpty(st))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
byte[] bytes = new byte[PACKAGE_SIZE];
|
||||
for (int i = 0; i < PACKAGE_SIZE; i++)
|
||||
{
|
||||
if (i < st.Length)
|
||||
{
|
||||
bytes[i] = (byte)st[i];
|
||||
}
|
||||
}
|
||||
|
||||
var hash = SHA512.Create();
|
||||
byte[] hashValue = hash.ComputeHash(bytes);
|
||||
|
||||
for (int i = 0; i < 50000; i++)
|
||||
{
|
||||
hashValue = hash.ComputeHash(hashValue);
|
||||
}
|
||||
|
||||
Logger.LogDebug(string.Format(CultureInfo.CurrentCulture, "magic: {0},{1},{2}", hashValue[0], hashValue[1], hashValue[^1]));
|
||||
hash.Clear();
|
||||
return (uint)((hashValue[0] << 23) + (hashValue[1] << 16) + (hashValue[^1] << 8) + hashValue[2]);
|
||||
}
|
||||
|
||||
internal static string GetDebugInfo(string st)
|
||||
{
|
||||
return string.IsNullOrEmpty(st) ? st : ((byte)(Common.GetBytesU(st).Sum(value => value) % 256)).ToString(CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
internal static string CreateDefaultKey()
|
||||
{
|
||||
return CreateRandomKey();
|
||||
}
|
||||
|
||||
private const int PW_LENGTH = 16;
|
||||
|
||||
public static string CreateRandomKey()
|
||||
{
|
||||
// Not including characters like "'`O0& since they are confusing to users.
|
||||
string[] chars = new[] { "abcdefghjkmnpqrstuvxyz", "ABCDEFGHJKMNPQRSTUVXYZ", "123456789", "~!@#$%^*()_-+=:;<,>.?/\\|[]" };
|
||||
char[][] charactersUsedForKey = chars.Select(charset => Enumerable.Range(0, charset.Length - 1).Select(i => charset[i]).ToArray()).ToArray();
|
||||
byte[] randomData = new byte[1];
|
||||
string key = string.Empty;
|
||||
|
||||
do
|
||||
{
|
||||
foreach (string set in chars)
|
||||
{
|
||||
randomData = RandomNumberGenerator.GetBytes(1);
|
||||
key += set[randomData[0] % set.Length];
|
||||
|
||||
if (key.Length >= PW_LENGTH)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
while (key.Length < PW_LENGTH);
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
internal static bool IsKeyValid(string key, out string error)
|
||||
{
|
||||
error = string.IsNullOrEmpty(key) || key.Length < 16
|
||||
? "Key must have at least 16 characters in length (spaces are discarded). Key must be auto generated in one of the machines."
|
||||
: null;
|
||||
|
||||
return error == null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,262 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
// <summary>
|
||||
// Package format/conversion.
|
||||
// </summary>
|
||||
// <history>
|
||||
// 2008 created by Truong Do (ductdo).
|
||||
// 2009-... modified by Truong Do (TruongDo).
|
||||
// 2023- Included in PowerToys.
|
||||
// </history>
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// In X64, we are WOW
|
||||
[module: SuppressMessage("Microsoft.Portability", "CA1900:ValueTypeFieldsShouldBePortable", Scope = "type", Target = "MouseWithoutBorders.DATA", Justification = "Dotnet port with style preservation")]
|
||||
|
||||
namespace MouseWithoutBorders
|
||||
{
|
||||
internal enum PackageType// : int
|
||||
{
|
||||
// Search for PACKAGE_TYPE_RELATED before changing these!
|
||||
Invalid = 0xFF,
|
||||
|
||||
Error = 0xFE,
|
||||
|
||||
Hi = 2,
|
||||
Hello = 3,
|
||||
ByeBye = 4,
|
||||
|
||||
Heartbeat = 20,
|
||||
Awake = 21,
|
||||
HideMouse = 50,
|
||||
Heartbeat_ex = 51,
|
||||
Heartbeat_ex_l2 = 52,
|
||||
Heartbeat_ex_l3 = 53,
|
||||
|
||||
Clipboard = 69,
|
||||
ClipboardDragDrop = 70,
|
||||
ClipboardDragDropEnd = 71,
|
||||
ExplorerDragDrop = 72,
|
||||
ClipboardCapture = 73,
|
||||
CaptureScreenCommand = 74,
|
||||
ClipboardDragDropOperation = 75,
|
||||
ClipboardDataEnd = 76,
|
||||
MachineSwitched = 77,
|
||||
ClipboardAsk = 78,
|
||||
ClipboardPush = 79,
|
||||
|
||||
NextMachine = 121,
|
||||
Keyboard = 122,
|
||||
Mouse = 123,
|
||||
ClipboardText = 124,
|
||||
ClipboardImage = 125,
|
||||
|
||||
Handshake = 126,
|
||||
HandshakeAck = 127,
|
||||
|
||||
Matrix = 128,
|
||||
MatrixSwapFlag = 2,
|
||||
MatrixTwoRowFlag = 4,
|
||||
}
|
||||
|
||||
internal struct PackageMonitor
|
||||
{
|
||||
internal ulong Keyboard;
|
||||
internal ulong Mouse;
|
||||
internal ulong Heartbeat;
|
||||
internal ulong ByeBye;
|
||||
internal ulong Hello;
|
||||
internal ulong Matrix;
|
||||
internal ulong ClipboardText;
|
||||
internal ulong ClipboardImage;
|
||||
internal ulong Clipboard;
|
||||
internal ulong ClipboardDragDrop;
|
||||
internal ulong ClipboardDragDropEnd;
|
||||
internal ulong ClipboardAsk;
|
||||
internal ulong ExplorerDragDrop;
|
||||
internal ulong Nil;
|
||||
|
||||
internal PackageMonitor(ulong value)
|
||||
{
|
||||
ClipboardDragDrop = ClipboardDragDropEnd = ExplorerDragDrop =
|
||||
Keyboard = Mouse = Heartbeat = ByeBye = Hello = Clipboard =
|
||||
Matrix = ClipboardImage = ClipboardText = Nil = ClipboardAsk = value;
|
||||
}
|
||||
}
|
||||
|
||||
internal enum ID : uint
|
||||
{
|
||||
NONE = 0,
|
||||
ALL = 255,
|
||||
}
|
||||
|
||||
internal enum ClipboardPostAction : uint
|
||||
{
|
||||
Other = 0,
|
||||
Desktop = 1,
|
||||
Mspaint = 2,
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct KEYBDDATA
|
||||
{
|
||||
[SuppressMessage("StyleCop.CSharp.NamingRules", "SA1307:Accessible fields should begin with upper-case letter", Justification = "Same name as in winAPI")]
|
||||
internal int wVk;
|
||||
[SuppressMessage("StyleCop.CSharp.NamingRules", "SA1307:Accessible fields should begin with upper-case letter", Justification = "Same name as in winAPI")]
|
||||
internal int dwFlags;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct MOUSEDATA
|
||||
{
|
||||
internal int X;
|
||||
internal int Y;
|
||||
internal int WheelDelta;
|
||||
[SuppressMessage("StyleCop.CSharp.NamingRules", "SA1307:Accessible fields should begin with upper-case letter", Justification = "Same name as in winAPI")]
|
||||
internal int dwFlags;
|
||||
}
|
||||
|
||||
// The beauty of "union" in C#
|
||||
[StructLayout(LayoutKind.Explicit)]
|
||||
internal class DATA
|
||||
{
|
||||
[FieldOffset(0)]
|
||||
internal PackageType Type; // 4 (first byte = package type, 1 = checksum, 2+3 = magic no.)
|
||||
|
||||
[FieldOffset(sizeof(PackageType))]
|
||||
internal int Id; // 4
|
||||
|
||||
[FieldOffset(sizeof(PackageType) + sizeof(uint))]
|
||||
internal ID Src; // 4
|
||||
|
||||
[FieldOffset(sizeof(PackageType) + (2 * sizeof(uint)))]
|
||||
internal ID Des; // 4
|
||||
|
||||
[FieldOffset(sizeof(PackageType) + (3 * sizeof(uint)))]
|
||||
internal long DateTime;
|
||||
|
||||
[FieldOffset(sizeof(PackageType) + (3 * sizeof(uint)) + sizeof(long))]
|
||||
internal KEYBDDATA Kd;
|
||||
|
||||
[FieldOffset(sizeof(PackageType) + (3 * sizeof(uint)))]
|
||||
internal MOUSEDATA Md;
|
||||
|
||||
[FieldOffset(sizeof(PackageType) + (3 * sizeof(uint)))]
|
||||
internal ID Machine1;
|
||||
|
||||
[FieldOffset(sizeof(PackageType) + (4 * sizeof(uint)))]
|
||||
internal ID Machine2;
|
||||
|
||||
[FieldOffset(sizeof(PackageType) + (5 * sizeof(uint)))]
|
||||
internal ID Machine3;
|
||||
|
||||
[FieldOffset(sizeof(PackageType) + (6 * sizeof(uint)))]
|
||||
internal ID Machine4;
|
||||
|
||||
[FieldOffset(sizeof(PackageType) + (3 * sizeof(uint)))]
|
||||
internal ClipboardPostAction PostAction;
|
||||
|
||||
[FieldOffset(sizeof(PackageType) + (7 * sizeof(uint)))]
|
||||
private long machineNameP1;
|
||||
|
||||
[FieldOffset(sizeof(PackageType) + (7 * sizeof(uint)) + sizeof(long))]
|
||||
private long machineNameP2;
|
||||
|
||||
[FieldOffset(sizeof(PackageType) + (7 * sizeof(uint)) + (2 * sizeof(long)))]
|
||||
private long machineNameP3;
|
||||
|
||||
[FieldOffset(sizeof(PackageType) + (7 * sizeof(uint)) + (3 * sizeof(long)))]
|
||||
private long machineNameP4;
|
||||
|
||||
internal string MachineName
|
||||
{
|
||||
get
|
||||
{
|
||||
string name = Common.GetString(BitConverter.GetBytes(machineNameP1))
|
||||
+ Common.GetString(BitConverter.GetBytes(machineNameP2))
|
||||
+ Common.GetString(BitConverter.GetBytes(machineNameP3))
|
||||
+ Common.GetString(BitConverter.GetBytes(machineNameP4));
|
||||
return name.Trim();
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
byte[] machineName = Common.GetBytes(value.PadRight(32, ' '));
|
||||
machineNameP1 = BitConverter.ToInt64(machineName, 0);
|
||||
machineNameP2 = BitConverter.ToInt64(machineName, 8);
|
||||
machineNameP3 = BitConverter.ToInt64(machineName, 16);
|
||||
machineNameP4 = BitConverter.ToInt64(machineName, 24);
|
||||
}
|
||||
}
|
||||
|
||||
public DATA()
|
||||
{
|
||||
}
|
||||
|
||||
public DATA(byte[] initialData)
|
||||
{
|
||||
Bytes = initialData;
|
||||
}
|
||||
|
||||
internal byte[] Bytes
|
||||
{
|
||||
get
|
||||
{
|
||||
byte[] buf = new byte[IsBigPackage ? Common.PACKAGE_SIZE_EX : Common.PACKAGE_SIZE];
|
||||
Array.Copy(StructToBytes(this), buf, IsBigPackage ? Common.PACKAGE_SIZE_EX : Common.PACKAGE_SIZE);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
Debug.Assert(value.Length <= Common.PACKAGE_SIZE_EX, "Length > package size");
|
||||
byte[] buf = new byte[Common.PACKAGE_SIZE_EX];
|
||||
Array.Copy(value, buf, value.Length);
|
||||
BytesToStruct(buf, this);
|
||||
}
|
||||
}
|
||||
|
||||
internal bool IsBigPackage
|
||||
{
|
||||
get => Type == 0
|
||||
? throw new InvalidOperationException("Package type not set.")
|
||||
: Type switch
|
||||
{
|
||||
PackageType.Hello or PackageType.Awake or PackageType.Heartbeat or PackageType.Heartbeat_ex or PackageType.Handshake or PackageType.HandshakeAck or PackageType.ClipboardPush or PackageType.Clipboard or PackageType.ClipboardAsk or PackageType.ClipboardImage or PackageType.ClipboardText or PackageType.ClipboardDataEnd => true,
|
||||
_ => (Type & PackageType.Matrix) == PackageType.Matrix,
|
||||
};
|
||||
}
|
||||
|
||||
private byte[] StructToBytes(object structObject)
|
||||
{
|
||||
byte[] bytes = new byte[Common.PACKAGE_SIZE_EX];
|
||||
GCHandle bHandle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
|
||||
Marshal.StructureToPtr(structObject, Marshal.UnsafeAddrOfPinnedArrayElement(bytes, 0), false);
|
||||
bHandle.Free();
|
||||
return bytes;
|
||||
}
|
||||
|
||||
private void BytesToStruct(byte[] value, object structObject)
|
||||
{
|
||||
GCHandle bHandle = GCHandle.Alloc(value, GCHandleType.Pinned);
|
||||
Marshal.PtrToStructure(Marshal.UnsafeAddrOfPinnedArrayElement(value, 0), structObject);
|
||||
bHandle.Free();
|
||||
}
|
||||
}
|
||||
|
||||
internal partial class Common
|
||||
{
|
||||
internal const byte PACKAGE_SIZE = 32;
|
||||
internal const byte PACKAGE_SIZE_EX = 64;
|
||||
internal const byte WP_PACKAGE_SIZE = 6;
|
||||
internal static PackageMonitor PackageSent;
|
||||
internal static PackageMonitor PackageReceived;
|
||||
internal static int PackageID;
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
|
||||
using ManagedCommon;
|
||||
using Microsoft.PowerToys.Telemetry;
|
||||
using MouseWithoutBorders.Class;
|
||||
|
||||
using Logger = MouseWithoutBorders.Core.Logger;
|
||||
|
||||
namespace MouseWithoutBorders
|
||||
{
|
||||
internal class ShutdownWithPowerToys
|
||||
{
|
||||
public static void WaitForPowerToysRunner(ETWTrace etwTrace)
|
||||
{
|
||||
try
|
||||
{
|
||||
RunnerHelper.WaitForPowerToysRunnerExitFallback(() =>
|
||||
{
|
||||
etwTrace?.Dispose();
|
||||
Common.MainForm.Quit(true, false);
|
||||
});
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Log(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,131 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
// <summary>
|
||||
// Virtual key constants.
|
||||
// </summary>
|
||||
// <history>
|
||||
// 2008 created by Truong Do (ductdo).
|
||||
// 2009-... modified by Truong Do (TruongDo).
|
||||
// 2023- Included in PowerToys.
|
||||
// </history>
|
||||
using System;
|
||||
|
||||
namespace MouseWithoutBorders
|
||||
{
|
||||
internal enum VK : ushort
|
||||
{
|
||||
CAPITAL = 0x14,
|
||||
NUMLOCK = 0x90,
|
||||
SHIFT = 0x10,
|
||||
CONTROL = 0x11,
|
||||
MENU = 0x12,
|
||||
ESCAPE = 0x1B,
|
||||
BACK = 0x08,
|
||||
TAB = 0x09,
|
||||
RETURN = 0x0D,
|
||||
PRIOR = 0x21,
|
||||
NEXT = 0x22,
|
||||
END = 0x23,
|
||||
HOME = 0x24,
|
||||
LEFT = 0x25,
|
||||
UP = 0x26,
|
||||
RIGHT = 0x27,
|
||||
DOWN = 0x28,
|
||||
SELECT = 0x29,
|
||||
PRINT = 0x2A,
|
||||
EXECUTE = 0x2B,
|
||||
SNAPSHOT = 0x2C,
|
||||
INSERT = 0x2D,
|
||||
DELETE = 0x2E,
|
||||
HELP = 0x2F,
|
||||
NUMPAD0 = 0x60,
|
||||
NUMPAD1 = 0x61,
|
||||
NUMPAD2 = 0x62,
|
||||
NUMPAD3 = 0x63,
|
||||
NUMPAD4 = 0x64,
|
||||
NUMPAD5 = 0x65,
|
||||
NUMPAD6 = 0x66,
|
||||
NUMPAD7 = 0x67,
|
||||
NUMPAD8 = 0x68,
|
||||
NUMPAD9 = 0x69,
|
||||
MULTIPLY = 0x6A,
|
||||
ADD = 0x6B,
|
||||
SEPARATOR = 0x6C,
|
||||
SUBTRACT = 0x6D,
|
||||
DECIMAL = 0x6E,
|
||||
DIVIDE = 0x6F,
|
||||
F1 = 0x70,
|
||||
F2 = 0x71,
|
||||
F3 = 0x72,
|
||||
F4 = 0x73,
|
||||
F5 = 0x74,
|
||||
F6 = 0x75,
|
||||
F7 = 0x76,
|
||||
F8 = 0x77,
|
||||
F9 = 0x78,
|
||||
F10 = 0x79,
|
||||
F11 = 0x7A,
|
||||
F12 = 0x7B,
|
||||
OEM_1 = 0xBA,
|
||||
OEM_PLUS = 0xBB,
|
||||
OEM_COMMA = 0xBC,
|
||||
OEM_MINUS = 0xBD,
|
||||
OEM_PERIOD = 0xBE,
|
||||
OEM_2 = 0xBF,
|
||||
OEM_3 = 0xC0,
|
||||
MEDIA_NEXT_TRACK = 0xB0,
|
||||
MEDIA_PREV_TRACK = 0xB1,
|
||||
MEDIA_STOP = 0xB2,
|
||||
MEDIA_PLAY_PAUSE = 0xB3,
|
||||
LWIN = 0x5B,
|
||||
RWIN = 0x5C,
|
||||
LSHIFT = 0xA0,
|
||||
RSHIFT = 0xA1,
|
||||
LCONTROL = 0xA2,
|
||||
RCONTROL = 0xA3,
|
||||
LMENU = 0xA4,
|
||||
RMENU = 0xA5,
|
||||
}
|
||||
|
||||
internal partial class Common
|
||||
{
|
||||
internal const ushort KEYEVENTF_KEYDOWN = 0x0001;
|
||||
internal const ushort KEYEVENTF_KEYUP = 0x0002;
|
||||
|
||||
internal const int WH_MOUSE = 7;
|
||||
internal const int WH_KEYBOARD = 2;
|
||||
internal const int WH_MOUSE_LL = 14;
|
||||
internal const int WH_KEYBOARD_LL = 13;
|
||||
|
||||
internal const int WM_MOUSEMOVE = 0x200;
|
||||
internal const int WM_LBUTTONDOWN = 0x201;
|
||||
internal const int WM_RBUTTONDOWN = 0x204;
|
||||
internal const int WM_MBUTTONDOWN = 0x207;
|
||||
internal const int WM_XBUTTONDOWN = 0x20B;
|
||||
internal const int WM_LBUTTONUP = 0x202;
|
||||
internal const int WM_RBUTTONUP = 0x205;
|
||||
internal const int WM_MBUTTONUP = 0x208;
|
||||
internal const int WM_XBUTTONUP = 0x20C;
|
||||
internal const int WM_LBUTTONDBLCLK = 0x203;
|
||||
internal const int WM_RBUTTONDBLCLK = 0x206;
|
||||
internal const int WM_MBUTTONDBLCLK = 0x209;
|
||||
internal const int WM_MOUSEWHEEL = 0x020A;
|
||||
internal const int WM_MOUSEHWHEEL = 0x020E;
|
||||
|
||||
internal const int WM_KEYDOWN = 0x100;
|
||||
internal const int WM_KEYUP = 0x101;
|
||||
internal const int WM_SYSKEYDOWN = 0x104;
|
||||
internal const int WM_SYSKEYUP = 0x105;
|
||||
|
||||
[Flags]
|
||||
internal enum LLKHF
|
||||
{
|
||||
EXTENDED = 0x01,
|
||||
INJECTED = 0x10,
|
||||
ALTDOWN = 0x20,
|
||||
UP = 0x80,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,363 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
using System.Windows.Forms;
|
||||
|
||||
// <summary>
|
||||
// Screen/Desktop helper functions.
|
||||
// </summary>
|
||||
// <history>
|
||||
// 2008 created by Truong Do (ductdo).
|
||||
// 2009-... modified by Truong Do (TruongDo).
|
||||
// 2023- Included in PowerToys.
|
||||
// </history>
|
||||
using MouseWithoutBorders.Class;
|
||||
using MouseWithoutBorders.Core;
|
||||
|
||||
using Thread = MouseWithoutBorders.Core.Thread;
|
||||
|
||||
namespace MouseWithoutBorders
|
||||
{
|
||||
// Desktops, and GetScreenConfig routines
|
||||
internal partial class Common
|
||||
{
|
||||
private static MyRectangle newDesktopBounds;
|
||||
private static MyRectangle newPrimaryScreenBounds;
|
||||
private static string activeDesktop;
|
||||
|
||||
internal static string ActiveDesktop => Common.activeDesktop;
|
||||
|
||||
internal static void SystemEvents_DisplaySettingsChanged(object sender, EventArgs e)
|
||||
{
|
||||
GetScreenConfig();
|
||||
}
|
||||
|
||||
internal static readonly List<Point> SensitivePoints = new();
|
||||
|
||||
private static bool MonitorEnumProc(IntPtr hMonitor, IntPtr hdcMonitor, ref NativeMethods.RECT lprcMonitor, IntPtr dwData)
|
||||
{
|
||||
// lprcMonitor is wrong!!! => using GetMonitorInfo(...)
|
||||
// Log(String.Format( CultureInfo.CurrentCulture,"MONITOR: l{0}, t{1}, r{2}, b{3}", lprcMonitor.Left, lprcMonitor.Top, lprcMonitor.Right, lprcMonitor.Bottom));
|
||||
NativeMethods.MonitorInfoEx mi = default;
|
||||
mi.cbSize = Marshal.SizeOf(mi);
|
||||
_ = NativeMethods.GetMonitorInfo(hMonitor, ref mi);
|
||||
|
||||
try
|
||||
{
|
||||
// For logging only
|
||||
_ = NativeMethods.GetDpiForMonitor(hMonitor, 0, out uint dpiX, out uint dpiY);
|
||||
Logger.Log(string.Format(CultureInfo.CurrentCulture, "MONITOR: ({0}, {1}, {2}, {3}). DPI: ({4}, {5})", mi.rcMonitor.Left, mi.rcMonitor.Top, mi.rcMonitor.Right, mi.rcMonitor.Bottom, dpiX, dpiY));
|
||||
}
|
||||
catch (DllNotFoundException)
|
||||
{
|
||||
Logger.Log("GetDpiForMonitor is unsupported in Windows 7 and lower.");
|
||||
}
|
||||
catch (EntryPointNotFoundException)
|
||||
{
|
||||
Logger.Log("GetDpiForMonitor is unsupported in Windows 7 and lower.");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Log(e);
|
||||
}
|
||||
|
||||
if (mi.rcMonitor.Left == 0 && mi.rcMonitor.Top == 0 && mi.rcMonitor.Right != 0 && mi.rcMonitor.Bottom != 0)
|
||||
{
|
||||
// Primary screen
|
||||
_ = Interlocked.Exchange(ref screenWidth, mi.rcMonitor.Right - mi.rcMonitor.Left);
|
||||
_ = Interlocked.Exchange(ref screenHeight, mi.rcMonitor.Bottom - mi.rcMonitor.Top);
|
||||
|
||||
newPrimaryScreenBounds.Left = mi.rcMonitor.Left;
|
||||
newPrimaryScreenBounds.Top = mi.rcMonitor.Top;
|
||||
newPrimaryScreenBounds.Right = mi.rcMonitor.Right;
|
||||
newPrimaryScreenBounds.Bottom = mi.rcMonitor.Bottom;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mi.rcMonitor.Left < newDesktopBounds.Left)
|
||||
{
|
||||
newDesktopBounds.Left = mi.rcMonitor.Left;
|
||||
}
|
||||
|
||||
if (mi.rcMonitor.Top < newDesktopBounds.Top)
|
||||
{
|
||||
newDesktopBounds.Top = mi.rcMonitor.Top;
|
||||
}
|
||||
|
||||
if (mi.rcMonitor.Right > newDesktopBounds.Right)
|
||||
{
|
||||
newDesktopBounds.Right = mi.rcMonitor.Right;
|
||||
}
|
||||
|
||||
if (mi.rcMonitor.Bottom > newDesktopBounds.Bottom)
|
||||
{
|
||||
newDesktopBounds.Bottom = mi.rcMonitor.Bottom;
|
||||
}
|
||||
}
|
||||
|
||||
lock (SensitivePoints)
|
||||
{
|
||||
SensitivePoints.Add(new Point(mi.rcMonitor.Left, mi.rcMonitor.Top));
|
||||
SensitivePoints.Add(new Point(mi.rcMonitor.Right, mi.rcMonitor.Top));
|
||||
SensitivePoints.Add(new Point(mi.rcMonitor.Right, mi.rcMonitor.Bottom));
|
||||
SensitivePoints.Add(new Point(mi.rcMonitor.Left, mi.rcMonitor.Bottom));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
internal static void GetScreenConfig()
|
||||
{
|
||||
try
|
||||
{
|
||||
Logger.LogDebug("==================== GetScreenConfig started");
|
||||
newDesktopBounds = new MyRectangle();
|
||||
newPrimaryScreenBounds = new MyRectangle();
|
||||
newDesktopBounds.Left = newPrimaryScreenBounds.Left = Screen.PrimaryScreen.Bounds.Left;
|
||||
newDesktopBounds.Top = newPrimaryScreenBounds.Top = Screen.PrimaryScreen.Bounds.Top;
|
||||
newDesktopBounds.Right = newPrimaryScreenBounds.Right = Screen.PrimaryScreen.Bounds.Right;
|
||||
newDesktopBounds.Bottom = newPrimaryScreenBounds.Bottom = Screen.PrimaryScreen.Bounds.Bottom;
|
||||
|
||||
Logger.Log(string.Format(
|
||||
CultureInfo.CurrentCulture,
|
||||
"logon = {0} PrimaryScreenBounds = {1},{2},{3},{4} desktopBounds = {5},{6},{7},{8}",
|
||||
Common.RunOnLogonDesktop,
|
||||
Common.newPrimaryScreenBounds.Left,
|
||||
Common.newPrimaryScreenBounds.Top,
|
||||
Common.newPrimaryScreenBounds.Right,
|
||||
Common.newPrimaryScreenBounds.Bottom,
|
||||
Common.newDesktopBounds.Left,
|
||||
Common.newDesktopBounds.Top,
|
||||
Common.newDesktopBounds.Right,
|
||||
Common.newDesktopBounds.Bottom));
|
||||
|
||||
#if USE_MANAGED_ROUTINES
|
||||
// Managed routines do not work well when running on secure desktop:(
|
||||
screenWidth = Screen.PrimaryScreen.Bounds.Width;
|
||||
screenHeight = Screen.PrimaryScreen.Bounds.Height;
|
||||
screenCount = Screen.AllScreens.Length;
|
||||
for (int i = 0; i < Screen.AllScreens.Length; i++)
|
||||
{
|
||||
if (Screen.AllScreens[i].Bounds.Left < desktopBounds.Left) desktopBounds.Left = Screen.AllScreens[i].Bounds.Left;
|
||||
if (Screen.AllScreens[i].Bounds.Top < desktopBounds.Top) desktopBounds.Top = Screen.AllScreens[i].Bounds.Top;
|
||||
if (Screen.AllScreens[i].Bounds.Right > desktopBounds.Right) desktopBounds.Right = Screen.AllScreens[i].Bounds.Right;
|
||||
if (Screen.AllScreens[i].Bounds.Bottom > desktopBounds.Bottom) desktopBounds.Bottom = Screen.AllScreens[i].Bounds.Bottom;
|
||||
}
|
||||
#else
|
||||
lock (SensitivePoints)
|
||||
{
|
||||
SensitivePoints.Clear();
|
||||
}
|
||||
|
||||
NativeMethods.EnumDisplayMonitors(IntPtr.Zero, IntPtr.Zero, MonitorEnumProc, IntPtr.Zero);
|
||||
|
||||
// 1000 calls to EnumDisplayMonitors cost a dozen of milliseconds
|
||||
#endif
|
||||
Interlocked.Exchange(ref MachineStuff.desktopBounds, newDesktopBounds);
|
||||
Interlocked.Exchange(ref MachineStuff.primaryScreenBounds, newPrimaryScreenBounds);
|
||||
|
||||
Logger.Log(string.Format(
|
||||
CultureInfo.CurrentCulture,
|
||||
"logon = {0} PrimaryScreenBounds = {1},{2},{3},{4} desktopBounds = {5},{6},{7},{8}",
|
||||
Common.RunOnLogonDesktop,
|
||||
MachineStuff.PrimaryScreenBounds.Left,
|
||||
MachineStuff.PrimaryScreenBounds.Top,
|
||||
MachineStuff.PrimaryScreenBounds.Right,
|
||||
MachineStuff.PrimaryScreenBounds.Bottom,
|
||||
MachineStuff.DesktopBounds.Left,
|
||||
MachineStuff.DesktopBounds.Top,
|
||||
MachineStuff.DesktopBounds.Right,
|
||||
MachineStuff.DesktopBounds.Bottom));
|
||||
|
||||
Logger.Log("==================== GetScreenConfig ended");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Log(e);
|
||||
}
|
||||
}
|
||||
|
||||
#if USING_SCREEN_SAVER_ROUTINES
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto)]
|
||||
private static extern int PostMessage(IntPtr hWnd, int wMsg, int wParam, int lParam);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto)]
|
||||
private static extern IntPtr OpenDesktop(string hDesktop, int Flags, bool Inherit, UInt32 DesiredAccess);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto)]
|
||||
private static extern bool CloseDesktop(IntPtr hDesktop);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto)]
|
||||
private static extern bool EnumDesktopWindows( IntPtr hDesktop, EnumDesktopWindowsProc callback, IntPtr lParam);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto)]
|
||||
private static extern bool IsWindowVisible(IntPtr hWnd);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto)]
|
||||
private static extern bool SystemParametersInfo(int uAction, int uParam, ref int pvParam, int flags);
|
||||
|
||||
private delegate bool EnumDesktopWindowsProc(IntPtr hDesktop, IntPtr lParam);
|
||||
private const int WM_CLOSE = 16;
|
||||
private const int SPI_GETSCREENSAVERRUNNING = 114;
|
||||
|
||||
internal static bool IsScreenSaverRunning()
|
||||
{
|
||||
int isRunning = 0;
|
||||
SystemParametersInfo(SPI_GETSCREENSAVERRUNNING, 0,ref isRunning, 0);
|
||||
return (isRunning != 0);
|
||||
}
|
||||
|
||||
internal static void CloseScreenSaver()
|
||||
{
|
||||
IntPtr hDesktop = OpenDesktop("Screen-saver", 0, false, DESKTOP_READOBJECTS | DESKTOP_WRITEOBJECTS);
|
||||
if (hDesktop != IntPtr.Zero)
|
||||
{
|
||||
LogDebug("Closing screen saver...");
|
||||
EnumDesktopWindows(hDesktop, new EnumDesktopWindowsProc(CloseScreenSaverFunc), IntPtr.Zero);
|
||||
CloseDesktop(hDesktop);
|
||||
}
|
||||
}
|
||||
|
||||
private static bool CloseScreenSaverFunc(IntPtr hWnd, IntPtr lParam)
|
||||
{
|
||||
if (IsWindowVisible(hWnd))
|
||||
{
|
||||
LogDebug("Posting WM_CLOSE to " + hWnd.ToString(CultureInfo.InvariantCulture));
|
||||
PostMessage(hWnd, WM_CLOSE, 0, 0);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
internal static string GetMyDesktop()
|
||||
{
|
||||
byte[] arThreadDesktop = new byte[256];
|
||||
IntPtr hD = NativeMethods.GetThreadDesktop(NativeMethods.GetCurrentThreadId());
|
||||
if (hD != IntPtr.Zero)
|
||||
{
|
||||
_ = NativeMethods.GetUserObjectInformation(hD, NativeMethods.UOI_NAME, arThreadDesktop, arThreadDesktop.Length, out _);
|
||||
return GetString(arThreadDesktop).Replace("\0", string.Empty);
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
internal static string GetInputDesktop()
|
||||
{
|
||||
byte[] arInputDesktop = new byte[256];
|
||||
IntPtr hD = NativeMethods.OpenInputDesktop(0, false, NativeMethods.DESKTOP_READOBJECTS);
|
||||
if (hD != IntPtr.Zero)
|
||||
{
|
||||
_ = NativeMethods.GetUserObjectInformation(hD, NativeMethods.UOI_NAME, arInputDesktop, arInputDesktop.Length, out _);
|
||||
return GetString(arInputDesktop).Replace("\0", string.Empty);
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
internal static void StartMMService(string desktopToRunMouseWithoutBordersOn)
|
||||
{
|
||||
if (!Common.RunWithNoAdminRight)
|
||||
{
|
||||
Logger.LogDebug("*** Starting on active Desktop: " + desktopToRunMouseWithoutBordersOn);
|
||||
Service.StartMouseWithoutBordersService(desktopToRunMouseWithoutBordersOn);
|
||||
}
|
||||
}
|
||||
|
||||
internal static void CheckForDesktopSwitchEvent(bool cleanupIfExit)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!IsMyDesktopActive() || Common.CurrentProcess.SessionId != NativeMethods.WTSGetActiveConsoleSessionId())
|
||||
{
|
||||
Helper.RunDDHelper(true);
|
||||
int waitCount = 20;
|
||||
|
||||
while (NativeMethods.WTSGetActiveConsoleSessionId() == 0xFFFFFFFF && waitCount > 0)
|
||||
{
|
||||
waitCount--;
|
||||
Logger.LogDebug("The session is detached/attached.");
|
||||
Thread.Sleep(500);
|
||||
}
|
||||
|
||||
string myDesktop = GetMyDesktop();
|
||||
activeDesktop = GetInputDesktop();
|
||||
|
||||
Logger.LogDebug("*** Active Desktop = " + activeDesktop);
|
||||
Logger.LogDebug("*** My Desktop = " + myDesktop);
|
||||
|
||||
if (myDesktop.Equals(activeDesktop, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
Logger.LogDebug("*** Active Desktop == My Desktop (TS session)");
|
||||
}
|
||||
|
||||
if (!activeDesktop.Equals("winlogon", StringComparison.OrdinalIgnoreCase) &&
|
||||
!activeDesktop.Equals("default", StringComparison.OrdinalIgnoreCase) &&
|
||||
!activeDesktop.Equals("disconnect", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
try
|
||||
{
|
||||
StartMMService(activeDesktop);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Log($"{nameof(CheckForDesktopSwitchEvent)}: {e}");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!myDesktop.Equals(activeDesktop, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
Logger.Log("*** Active Desktop <> My Desktop");
|
||||
}
|
||||
|
||||
uint sid = NativeMethods.WTSGetActiveConsoleSessionId();
|
||||
|
||||
if (Process.GetProcessesByName(Common.BinaryName).Any(p => (uint)p.SessionId == sid))
|
||||
{
|
||||
Logger.Log("Found MouseWithoutBorders on the active session!");
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.Log("MouseWithoutBorders not found on the active session!");
|
||||
StartMMService(null);
|
||||
}
|
||||
}
|
||||
|
||||
if (!myDesktop.Equals("winlogon", StringComparison.OrdinalIgnoreCase) &&
|
||||
!myDesktop.Equals("default", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
Logger.LogDebug("*** Desktop inactive, exiting: " + myDesktop);
|
||||
Setting.Values.LastX = JUST_GOT_BACK_FROM_SCREEN_SAVER;
|
||||
if (cleanupIfExit)
|
||||
{
|
||||
InitAndCleanup.Cleanup();
|
||||
}
|
||||
|
||||
Process.GetCurrentProcess().KillProcess();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Log(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static Point p;
|
||||
|
||||
internal static bool IsMyDesktopActive()
|
||||
{
|
||||
return NativeMethods.GetCursorPos(ref p);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -315,7 +315,7 @@ namespace MouseWithoutBorders
|
||||
if (!acquireMutex)
|
||||
{
|
||||
Process[] ps = Process.GetProcessesByName(Common.BinaryName);
|
||||
Logger.TelemetryLogTrace($"Balance: {socketMutexBalance}, Active: {IsMyDesktopActive()}, Sid/Console: {Process.GetCurrentProcess().SessionId}/{NativeMethods.WTSGetActiveConsoleSessionId()}, Desktop/Input: {GetMyDesktop()}/{GetInputDesktop()}, count: {ps?.Length}.", SeverityLevel.Warning);
|
||||
Logger.TelemetryLogTrace($"Balance: {socketMutexBalance}, Active: {WinAPI.IsMyDesktopActive()}, Sid/Console: {Process.GetCurrentProcess().SessionId}/{NativeMethods.WTSGetActiveConsoleSessionId()}, Desktop/Input: {WinAPI.GetMyDesktop()}/{WinAPI.GetInputDesktop()}, count: {ps?.Length}.", SeverityLevel.Warning);
|
||||
}
|
||||
|
||||
Logger.LogDebug("SOCKET MUTEX ENDED.");
|
||||
@@ -358,7 +358,7 @@ namespace MouseWithoutBorders
|
||||
|
||||
Logger.TelemetryLogTrace($"[{actionName}] took more than {(long)timeout.TotalSeconds}, restarting the process.", SeverityLevel.Warning, true);
|
||||
|
||||
string desktop = Common.GetMyDesktop();
|
||||
string desktop = WinAPI.GetMyDesktop();
|
||||
MachineStuff.oneInstanceCheck?.Close();
|
||||
_ = Process.Start(Application.ExecutablePath, desktop);
|
||||
Logger.LogDebug($"Started on desktop {desktop}");
|
||||
@@ -514,7 +514,7 @@ namespace MouseWithoutBorders
|
||||
|
||||
internal static void SendHeartBeat(bool initial = false)
|
||||
{
|
||||
SendPackage(ID.ALL, initial && Common.GeneratedKey ? PackageType.Heartbeat_ex : PackageType.Heartbeat);
|
||||
SendPackage(ID.ALL, initial && Encryption.GeneratedKey ? PackageType.Heartbeat_ex : PackageType.Heartbeat);
|
||||
}
|
||||
|
||||
private static long lastSendNextMachine;
|
||||
@@ -550,7 +550,7 @@ namespace MouseWithoutBorders
|
||||
|
||||
internal static void SendAwakeBeat()
|
||||
{
|
||||
if (!Common.RunOnLogonDesktop && !Common.RunOnScrSaverDesktop && Common.IsMyDesktopActive() &&
|
||||
if (!Common.RunOnLogonDesktop && !Common.RunOnScrSaverDesktop && WinAPI.IsMyDesktopActive() &&
|
||||
Setting.Values.BlockScreenSaver && lastRealInputEventCount != Event.RealInputEventCount)
|
||||
{
|
||||
SendPackage(ID.ALL, PackageType.Awake);
|
||||
@@ -568,7 +568,7 @@ namespace MouseWithoutBorders
|
||||
{
|
||||
if (lastInputEventCount == Event.InputEventCount)
|
||||
{
|
||||
if (!Common.RunOnLogonDesktop && !Common.RunOnScrSaverDesktop && Common.IsMyDesktopActive())
|
||||
if (!Common.RunOnLogonDesktop && !Common.RunOnScrSaverDesktop && WinAPI.IsMyDesktopActive())
|
||||
{
|
||||
PokeMyself();
|
||||
}
|
||||
@@ -577,13 +577,13 @@ namespace MouseWithoutBorders
|
||||
lastInputEventCount = Event.InputEventCount;
|
||||
}
|
||||
|
||||
private static void PokeMyself()
|
||||
internal static void PokeMyself()
|
||||
{
|
||||
int x, y = 0;
|
||||
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
x = Ran.Next(-9, 10);
|
||||
x = Encryption.Ran.Next(-9, 10);
|
||||
InputSimulation.MoveMouseRelative(x, y);
|
||||
Thread.Sleep(50);
|
||||
InputSimulation.MoveMouseRelative(-x, -y);
|
||||
@@ -677,7 +677,7 @@ namespace MouseWithoutBorders
|
||||
{
|
||||
Common.MMSleep(0.2);
|
||||
InputSimulation.SendKey(new KEYBDDATA() { wVk = (int)VK.SNAPSHOT });
|
||||
InputSimulation.SendKey(new KEYBDDATA() { dwFlags = (int)Common.LLKHF.UP, wVk = (int)VK.SNAPSHOT });
|
||||
InputSimulation.SendKey(new KEYBDDATA() { dwFlags = (int)WM.LLKHF.UP, wVk = (int)VK.SNAPSHOT });
|
||||
|
||||
Logger.LogDebug("PrepareScreenCapture: SNAPSHOT simulated.");
|
||||
|
||||
@@ -710,7 +710,7 @@ namespace MouseWithoutBorders
|
||||
"\"" + Environment.ExpandEnvironmentVariables(@"%SystemRoot%\System32\Mspaint.exe") +
|
||||
"\"",
|
||||
"\"" + file + "\"",
|
||||
GetInputDesktop(),
|
||||
WinAPI.GetInputDesktop(),
|
||||
1);
|
||||
|
||||
// CreateNormalIntegrityProcess(Environment.ExpandEnvironmentVariables(@"%SystemRoot%\System32\Mspaint.exe") +
|
||||
@@ -919,7 +919,7 @@ namespace MouseWithoutBorders
|
||||
|
||||
try
|
||||
{
|
||||
data.Id = Interlocked.Increment(ref PackageID);
|
||||
data.Id = Interlocked.Increment(ref Package.PackageID);
|
||||
|
||||
bool updateClientSockets = false;
|
||||
|
||||
@@ -999,7 +999,7 @@ namespace MouseWithoutBorders
|
||||
}
|
||||
else
|
||||
{
|
||||
PackageSent.Nil++;
|
||||
Package.PackageSent.Nil++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1379,7 +1379,7 @@ namespace MouseWithoutBorders
|
||||
|
||||
if (string.IsNullOrEmpty(machine_Name))
|
||||
{
|
||||
machine_Name = "RANDOM" + Ran.Next().ToString(CultureInfo.CurrentCulture);
|
||||
machine_Name = "RANDOM" + Encryption.Ran.Next().ToString(CultureInfo.CurrentCulture);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1533,13 +1533,13 @@ namespace MouseWithoutBorders
|
||||
|
||||
internal static void SendOrReceiveARandomDataBlockPerInitialIV(Stream st, bool send = true)
|
||||
{
|
||||
byte[] ranData = new byte[SymAlBlockSize];
|
||||
byte[] ranData = new byte[Encryption.SymAlBlockSize];
|
||||
|
||||
try
|
||||
{
|
||||
if (send)
|
||||
{
|
||||
ranData = RandomNumberGenerator.GetBytes(SymAlBlockSize);
|
||||
ranData = RandomNumberGenerator.GetBytes(Encryption.SymAlBlockSize);
|
||||
st.Write(ranData, 0, ranData.Length);
|
||||
}
|
||||
else
|
||||
|
||||
@@ -109,7 +109,7 @@ namespace MouseWithoutBorders.Class
|
||||
// Install Mouse Hook
|
||||
mouseHookProcedure = new NativeMethods.HookProc(MouseHookProc);
|
||||
hMouseHook = NativeMethods.SetWindowsHookEx(
|
||||
Common.WH_MOUSE_LL,
|
||||
WM.WH_MOUSE_LL,
|
||||
mouseHookProcedure,
|
||||
Marshal.GetHINSTANCE(
|
||||
Assembly.GetExecutingAssembly().GetModules()[0]),
|
||||
@@ -126,7 +126,7 @@ namespace MouseWithoutBorders.Class
|
||||
// Install Keyboard Hook
|
||||
keyboardHookProcedure = new NativeMethods.HookProc(KeyboardHookProc);
|
||||
hKeyboardHook = NativeMethods.SetWindowsHookEx(
|
||||
Common.WH_KEYBOARD_LL,
|
||||
WM.WH_KEYBOARD_LL,
|
||||
keyboardHookProcedure,
|
||||
Marshal.GetHINSTANCE(
|
||||
Assembly.GetExecutingAssembly().GetModules()[0]),
|
||||
@@ -233,7 +233,7 @@ namespace MouseWithoutBorders.Class
|
||||
|
||||
if (nCode >= 0 && MouseEvent != null)
|
||||
{
|
||||
if (wParam == Common.WM_LBUTTONUP && SkipMouseUpCount > 0)
|
||||
if (wParam == WM.WM_LBUTTONUP && SkipMouseUpCount > 0)
|
||||
{
|
||||
Logger.LogDebug($"{nameof(SkipMouseUpCount)}: {SkipMouseUpCount}.");
|
||||
SkipMouseUpCount--;
|
||||
@@ -241,7 +241,7 @@ namespace MouseWithoutBorders.Class
|
||||
return rv;
|
||||
}
|
||||
|
||||
if ((wParam == Common.WM_LBUTTONUP || wParam == Common.WM_LBUTTONDOWN) && SkipMouseUpDown)
|
||||
if ((wParam == WM.WM_LBUTTONUP || wParam == WM.WM_LBUTTONDOWN) && SkipMouseUpDown)
|
||||
{
|
||||
rv = NativeMethods.CallNextHookEx(hMouseHook, nCode, wParam, lParam);
|
||||
return rv;
|
||||
@@ -370,7 +370,7 @@ namespace MouseWithoutBorders.Class
|
||||
|
||||
private bool ProcessKeyEx(int vkCode, int flags, KEYBDDATA hookCallbackKeybdData)
|
||||
{
|
||||
if ((flags & (int)Common.LLKHF.UP) == (int)Common.LLKHF.UP)
|
||||
if ((flags & (int)WM.LLKHF.UP) == (int)WM.LLKHF.UP)
|
||||
{
|
||||
EasyMouseKeyDown = false;
|
||||
|
||||
@@ -553,7 +553,7 @@ namespace MouseWithoutBorders.Class
|
||||
KeyboardEvent(hookCallbackKeybdData);
|
||||
}
|
||||
|
||||
hookCallbackKeybdData.dwFlags |= (int)Common.LLKHF.UP;
|
||||
hookCallbackKeybdData.dwFlags |= (int)WM.LLKHF.UP;
|
||||
|
||||
foreach (var code in codes)
|
||||
{
|
||||
|
||||
@@ -112,12 +112,12 @@ namespace MouseWithoutBorders.Class
|
||||
uint scanCode = 0;
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/ms644967(VS.85).aspx
|
||||
if ((kd.dwFlags & (int)Common.LLKHF.UP) == (int)Common.LLKHF.UP)
|
||||
if ((kd.dwFlags & (int)WM.LLKHF.UP) == (int)WM.LLKHF.UP)
|
||||
{
|
||||
dwFlags = NativeMethods.KEYEVENTF.KEYUP;
|
||||
}
|
||||
|
||||
if ((kd.dwFlags & (int)Common.LLKHF.EXTENDED) == (int)Common.LLKHF.EXTENDED)
|
||||
if ((kd.dwFlags & (int)WM.LLKHF.EXTENDED) == (int)WM.LLKHF.EXTENDED)
|
||||
{
|
||||
dwFlags |= NativeMethods.KEYEVENTF.EXTENDEDKEY;
|
||||
}
|
||||
@@ -173,44 +173,44 @@ namespace MouseWithoutBorders.Class
|
||||
mouse_input.mi.dy = (int)dy;
|
||||
mouse_input.mi.mouseData = md.WheelDelta;
|
||||
|
||||
if (md.dwFlags != Common.WM_MOUSEMOVE)
|
||||
if (md.dwFlags != WM.WM_MOUSEMOVE)
|
||||
{
|
||||
Logger.LogDebug($"InputSimulation.SendMouse: x = {md.X}, y = {md.Y}, WheelDelta = {md.WheelDelta}, dwFlags = {md.dwFlags}.");
|
||||
}
|
||||
|
||||
switch (md.dwFlags)
|
||||
{
|
||||
case Common.WM_MOUSEMOVE:
|
||||
case WM.WM_MOUSEMOVE:
|
||||
mouse_input.mi.dwFlags |= (int)(NativeMethods.MOUSEEVENTF.MOVE | NativeMethods.MOUSEEVENTF.ABSOLUTE);
|
||||
break;
|
||||
case Common.WM_LBUTTONDOWN:
|
||||
case WM.WM_LBUTTONDOWN:
|
||||
mouse_input.mi.dwFlags |= (int)NativeMethods.MOUSEEVENTF.LEFTDOWN;
|
||||
break;
|
||||
case Common.WM_LBUTTONUP:
|
||||
case WM.WM_LBUTTONUP:
|
||||
mouse_input.mi.dwFlags |= (int)NativeMethods.MOUSEEVENTF.LEFTUP;
|
||||
break;
|
||||
case Common.WM_RBUTTONDOWN:
|
||||
case WM.WM_RBUTTONDOWN:
|
||||
mouse_input.mi.dwFlags |= (int)NativeMethods.MOUSEEVENTF.RIGHTDOWN;
|
||||
break;
|
||||
case Common.WM_RBUTTONUP:
|
||||
case WM.WM_RBUTTONUP:
|
||||
mouse_input.mi.dwFlags |= (int)NativeMethods.MOUSEEVENTF.RIGHTUP;
|
||||
break;
|
||||
case Common.WM_MBUTTONDOWN:
|
||||
case WM.WM_MBUTTONDOWN:
|
||||
mouse_input.mi.dwFlags |= (int)NativeMethods.MOUSEEVENTF.MIDDLEDOWN;
|
||||
break;
|
||||
case Common.WM_MBUTTONUP:
|
||||
case WM.WM_MBUTTONUP:
|
||||
mouse_input.mi.dwFlags |= (int)NativeMethods.MOUSEEVENTF.MIDDLEUP;
|
||||
break;
|
||||
case Common.WM_MOUSEWHEEL:
|
||||
case WM.WM_MOUSEWHEEL:
|
||||
mouse_input.mi.dwFlags |= (int)NativeMethods.MOUSEEVENTF.WHEEL;
|
||||
break;
|
||||
case Common.WM_MOUSEHWHEEL:
|
||||
case WM.WM_MOUSEHWHEEL:
|
||||
mouse_input.mi.dwFlags |= (int)NativeMethods.MOUSEEVENTF.HWHEEL;
|
||||
break;
|
||||
case Common.WM_XBUTTONUP:
|
||||
case WM.WM_XBUTTONUP:
|
||||
mouse_input.mi.dwFlags |= (int)NativeMethods.MOUSEEVENTF.XUP;
|
||||
break;
|
||||
case Common.WM_XBUTTONDOWN:
|
||||
case WM.WM_XBUTTONDOWN:
|
||||
mouse_input.mi.dwFlags |= (int)NativeMethods.MOUSEEVENTF.XDOWN;
|
||||
break;
|
||||
|
||||
@@ -373,7 +373,7 @@ namespace MouseWithoutBorders.Class
|
||||
{
|
||||
eatKey = false;
|
||||
|
||||
if ((flags & (int)Common.LLKHF.UP) == (int)Common.LLKHF.UP)
|
||||
if ((flags & (int)WM.LLKHF.UP) == (int)WM.LLKHF.UP)
|
||||
{
|
||||
switch ((VK)vkCode)
|
||||
{
|
||||
|
||||
@@ -143,7 +143,7 @@ namespace MouseWithoutBorders.Class
|
||||
return;
|
||||
}
|
||||
|
||||
string myDesktop = Common.GetMyDesktop();
|
||||
string myDesktop = WinAPI.GetMyDesktop();
|
||||
|
||||
if (firstArg.Equals("winlogon", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
@@ -305,8 +305,8 @@ namespace MouseWithoutBorders.Class
|
||||
|
||||
MachineStuff.ClearComputerMatrix();
|
||||
Setting.Values.MyKey = securityKey;
|
||||
Common.MyKey = securityKey;
|
||||
Common.MagicNumber = Common.Get24BitHash(Common.MyKey);
|
||||
Encryption.MyKey = securityKey;
|
||||
Encryption.MagicNumber = Encryption.Get24BitHash(Encryption.MyKey);
|
||||
MachineStuff.MachineMatrix = new string[MachineStuff.MAX_MACHINE] { pcName.Trim().ToUpper(CultureInfo.CurrentCulture), Common.MachineName.Trim(), string.Empty, string.Empty };
|
||||
|
||||
string[] machines = MachineStuff.MachineMatrix;
|
||||
@@ -328,8 +328,8 @@ namespace MouseWithoutBorders.Class
|
||||
|
||||
Setting.Values.EasyMouse = (int)EasyMouseOption.Enable;
|
||||
MachineStuff.ClearComputerMatrix();
|
||||
Setting.Values.MyKey = Common.MyKey = Common.CreateRandomKey();
|
||||
Common.GeneratedKey = true;
|
||||
Setting.Values.MyKey = Encryption.MyKey = Encryption.CreateRandomKey();
|
||||
Encryption.GeneratedKey = true;
|
||||
|
||||
Setting.Values.PauseInstantSaving = false;
|
||||
Setting.Values.SaveSettings();
|
||||
|
||||
@@ -109,9 +109,9 @@ namespace MouseWithoutBorders.Class
|
||||
|
||||
var shouldReopenSockets = false;
|
||||
|
||||
if (Common.MyKey != _properties.SecurityKey.Value)
|
||||
if (Encryption.MyKey != _properties.SecurityKey.Value)
|
||||
{
|
||||
Common.MyKey = _properties.SecurityKey.Value;
|
||||
Encryption.MyKey = _properties.SecurityKey.Value;
|
||||
shouldReopenSockets = true;
|
||||
}
|
||||
|
||||
@@ -192,7 +192,7 @@ namespace MouseWithoutBorders.Class
|
||||
|
||||
internal Settings()
|
||||
{
|
||||
_settingsUtils = new SettingsUtils();
|
||||
_settingsUtils = SettingsUtils.Default;
|
||||
|
||||
_watcher = SettingsHelper.GetFileWatcher("MouseWithoutBorders", "settings.json", () =>
|
||||
{
|
||||
@@ -489,7 +489,7 @@ namespace MouseWithoutBorders.Class
|
||||
}
|
||||
else
|
||||
{
|
||||
string randomKey = Common.CreateDefaultKey();
|
||||
string randomKey = Encryption.CreateDefaultKey();
|
||||
_properties.SecurityKey.Value = randomKey;
|
||||
|
||||
return randomKey;
|
||||
@@ -1055,7 +1055,7 @@ namespace MouseWithoutBorders.Class
|
||||
|
||||
if (machineId == 0)
|
||||
{
|
||||
var newMachineId = Common.Ran.Next();
|
||||
var newMachineId = Encryption.Ran.Next();
|
||||
_properties.MachineID.Value = newMachineId;
|
||||
machineId = newMachineId;
|
||||
if (!PauseInstantSaving)
|
||||
|
||||
@@ -101,7 +101,7 @@ namespace MouseWithoutBorders.Class
|
||||
{
|
||||
if (encryptedStream == null && BackingSocket.Connected)
|
||||
{
|
||||
encryptedStream = Common.GetEncryptedStream(new NetworkStream(BackingSocket));
|
||||
encryptedStream = Encryption.GetEncryptedStream(new NetworkStream(BackingSocket));
|
||||
Common.SendOrReceiveARandomDataBlockPerInitialIV(encryptedStream);
|
||||
}
|
||||
|
||||
@@ -115,7 +115,7 @@ namespace MouseWithoutBorders.Class
|
||||
{
|
||||
if (decryptedStream == null && BackingSocket.Connected)
|
||||
{
|
||||
decryptedStream = Common.GetDecryptedStream(new NetworkStream(BackingSocket));
|
||||
decryptedStream = Encryption.GetDecryptedStream(new NetworkStream(BackingSocket));
|
||||
Common.SendOrReceiveARandomDataBlockPerInitialIV(decryptedStream, false);
|
||||
}
|
||||
|
||||
@@ -181,7 +181,7 @@ namespace MouseWithoutBorders.Class
|
||||
Logger.LogDebug("SocketStuff started.");
|
||||
|
||||
bASE_PORT = port;
|
||||
Common.Ran = new Random();
|
||||
Encryption.Ran = new Random();
|
||||
|
||||
Logger.LogDebug("Validating session...");
|
||||
|
||||
@@ -221,11 +221,11 @@ namespace MouseWithoutBorders.Class
|
||||
|
||||
if (Setting.Values.IsMyKeyRandom)
|
||||
{
|
||||
Setting.Values.MyKey = Common.MyKey;
|
||||
Setting.Values.MyKey = Encryption.MyKey;
|
||||
}
|
||||
|
||||
Common.MagicNumber = Common.Get24BitHash(Common.MyKey);
|
||||
Common.PackageID = Setting.Values.PackageID;
|
||||
Encryption.MagicNumber = Encryption.Get24BitHash(Encryption.MyKey);
|
||||
Package.PackageID = Setting.Values.PackageID;
|
||||
|
||||
TcpPort = bASE_PORT;
|
||||
|
||||
@@ -242,7 +242,7 @@ namespace MouseWithoutBorders.Class
|
||||
Logger.TelemetryLogTrace($"{nameof(SocketStuff)}: {e.Message}", SeverityLevel.Warning);
|
||||
}
|
||||
|
||||
Common.GetScreenConfig();
|
||||
WinAPI.GetScreenConfig();
|
||||
|
||||
if (firstRun && Common.RunOnScrSaverDesktop)
|
||||
{
|
||||
@@ -305,7 +305,7 @@ namespace MouseWithoutBorders.Class
|
||||
sleepSecs = 10;
|
||||
|
||||
// It is reasonable to give a try on restarting MwB processes in other sessions.
|
||||
if (restartCount++ < 5 && Common.IsMyDesktopActive() && !Common.RunOnLogonDesktop && !Common.RunOnScrSaverDesktop)
|
||||
if (restartCount++ < 5 && WinAPI.IsMyDesktopActive() && !Common.RunOnLogonDesktop && !Common.RunOnScrSaverDesktop)
|
||||
{
|
||||
Logger.TelemetryLogTrace("Restarting the service dues to WSAEADDRINUSE.", SeverityLevel.Warning);
|
||||
Program.StartService();
|
||||
@@ -361,7 +361,7 @@ namespace MouseWithoutBorders.Class
|
||||
{
|
||||
Setting.Values.LastX = Common.LastX;
|
||||
Setting.Values.LastY = Common.LastY;
|
||||
Setting.Values.PackageID = Common.PackageID;
|
||||
Setting.Values.PackageID = Package.PackageID;
|
||||
|
||||
// Common.Log("Saving IP: " + Setting.Values.DesMachineID.ToString(CultureInfo.CurrentCulture));
|
||||
Setting.Values.DesMachineID = (uint)Common.DesMachineID;
|
||||
@@ -505,10 +505,10 @@ namespace MouseWithoutBorders.Class
|
||||
throw new ExpectedSocketException(log);
|
||||
}
|
||||
|
||||
bytes[3] = (byte)((Common.MagicNumber >> 24) & 0xFF);
|
||||
bytes[2] = (byte)((Common.MagicNumber >> 16) & 0xFF);
|
||||
bytes[3] = (byte)((Encryption.MagicNumber >> 24) & 0xFF);
|
||||
bytes[2] = (byte)((Encryption.MagicNumber >> 16) & 0xFF);
|
||||
bytes[1] = 0;
|
||||
for (int i = 2; i < Common.PACKAGE_SIZE; i++)
|
||||
for (int i = 2; i < Package.PACKAGE_SIZE; i++)
|
||||
{
|
||||
bytes[1] = (byte)(bytes[1] + bytes[i]);
|
||||
}
|
||||
@@ -535,13 +535,13 @@ namespace MouseWithoutBorders.Class
|
||||
|
||||
magic = (buf[3] << 24) + (buf[2] << 16);
|
||||
|
||||
if (magic != (Common.MagicNumber & 0xFFFF0000))
|
||||
if (magic != (Encryption.MagicNumber & 0xFFFF0000))
|
||||
{
|
||||
Logger.Log("Magic number invalid!");
|
||||
buf[0] = (byte)PackageType.Invalid;
|
||||
}
|
||||
|
||||
for (int i = 2; i < Common.PACKAGE_SIZE; i++)
|
||||
for (int i = 2; i < Package.PACKAGE_SIZE; i++)
|
||||
{
|
||||
checksum = (byte)(checksum + buf[i]);
|
||||
}
|
||||
@@ -557,7 +557,7 @@ namespace MouseWithoutBorders.Class
|
||||
|
||||
internal static DATA TcpReceiveData(TcpSk tcp, out int bytesReceived)
|
||||
{
|
||||
byte[] buf = new byte[Common.PACKAGE_SIZE_EX];
|
||||
byte[] buf = new byte[Package.PACKAGE_SIZE_EX];
|
||||
Stream decryptedStream = tcp.DecryptedStream;
|
||||
|
||||
if (tcp.BackingSocket == null || !tcp.BackingSocket.Connected || decryptedStream == null)
|
||||
@@ -571,9 +571,9 @@ namespace MouseWithoutBorders.Class
|
||||
|
||||
try
|
||||
{
|
||||
bytesReceived = decryptedStream.ReadEx(buf, 0, Common.PACKAGE_SIZE);
|
||||
bytesReceived = decryptedStream.ReadEx(buf, 0, Package.PACKAGE_SIZE);
|
||||
|
||||
if (bytesReceived != Common.PACKAGE_SIZE)
|
||||
if (bytesReceived != Package.PACKAGE_SIZE)
|
||||
{
|
||||
buf[0] = bytesReceived == 0 ? (byte)PackageType.Error : (byte)PackageType.Invalid;
|
||||
}
|
||||
@@ -586,9 +586,9 @@ namespace MouseWithoutBorders.Class
|
||||
|
||||
if (package.IsBigPackage)
|
||||
{
|
||||
bytesReceived = decryptedStream.ReadEx(buf, Common.PACKAGE_SIZE, Common.PACKAGE_SIZE);
|
||||
bytesReceived = decryptedStream.ReadEx(buf, Package.PACKAGE_SIZE, Package.PACKAGE_SIZE);
|
||||
|
||||
if (bytesReceived != Common.PACKAGE_SIZE)
|
||||
if (bytesReceived != Package.PACKAGE_SIZE)
|
||||
{
|
||||
buf[0] = bytesReceived == 0 ? (byte)PackageType.Error : (byte)PackageType.Invalid;
|
||||
}
|
||||
@@ -614,28 +614,28 @@ namespace MouseWithoutBorders.Class
|
||||
switch (type)
|
||||
{
|
||||
case PackageType.Keyboard:
|
||||
Common.PackageSent.Keyboard++;
|
||||
Package.PackageSent.Keyboard++;
|
||||
break;
|
||||
|
||||
case PackageType.Mouse:
|
||||
Common.PackageSent.Mouse++;
|
||||
Package.PackageSent.Mouse++;
|
||||
break;
|
||||
|
||||
case PackageType.Heartbeat:
|
||||
case PackageType.Heartbeat_ex:
|
||||
Common.PackageSent.Heartbeat++;
|
||||
Package.PackageSent.Heartbeat++;
|
||||
break;
|
||||
|
||||
case PackageType.Hello:
|
||||
Common.PackageSent.Hello++;
|
||||
Package.PackageSent.Hello++;
|
||||
break;
|
||||
|
||||
case PackageType.ByeBye:
|
||||
Common.PackageSent.ByeBye++;
|
||||
Package.PackageSent.ByeBye++;
|
||||
break;
|
||||
|
||||
case PackageType.Matrix:
|
||||
Common.PackageSent.Matrix++;
|
||||
Package.PackageSent.Matrix++;
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -643,11 +643,11 @@ namespace MouseWithoutBorders.Class
|
||||
switch (subtype)
|
||||
{
|
||||
case (byte)PackageType.ClipboardText:
|
||||
Common.PackageSent.ClipboardText++;
|
||||
Package.PackageSent.ClipboardText++;
|
||||
break;
|
||||
|
||||
case (byte)PackageType.ClipboardImage:
|
||||
Common.PackageSent.ClipboardImage++;
|
||||
Package.PackageSent.ClipboardImage++;
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -1266,7 +1266,7 @@ namespace MouseWithoutBorders.Class
|
||||
string strIP = string.Empty;
|
||||
ID remoteID = ID.NONE;
|
||||
|
||||
byte[] buf = RandomNumberGenerator.GetBytes(Common.PACKAGE_SIZE_EX);
|
||||
byte[] buf = RandomNumberGenerator.GetBytes(Package.PACKAGE_SIZE_EX);
|
||||
d = new DATA(buf);
|
||||
|
||||
TcpSk currentTcp = tcp;
|
||||
@@ -1280,8 +1280,8 @@ namespace MouseWithoutBorders.Class
|
||||
|
||||
try
|
||||
{
|
||||
currentSocket.SendBufferSize = Common.PACKAGE_SIZE * 10000;
|
||||
currentSocket.ReceiveBufferSize = Common.PACKAGE_SIZE * 10000;
|
||||
currentSocket.SendBufferSize = Package.PACKAGE_SIZE * 10000;
|
||||
currentSocket.ReceiveBufferSize = Package.PACKAGE_SIZE * 10000;
|
||||
currentSocket.NoDelay = true; // This is very interesting to know:(
|
||||
currentSocket.SendTimeout = 500;
|
||||
d.MachineName = Common.MachineName;
|
||||
@@ -1829,7 +1829,7 @@ namespace MouseWithoutBorders.Class
|
||||
}
|
||||
while (rv > 0);
|
||||
|
||||
if ((rv = Common.PACKAGE_SIZE - (sentCount % Common.PACKAGE_SIZE)) > 0)
|
||||
if ((rv = Package.PACKAGE_SIZE - (sentCount % Package.PACKAGE_SIZE)) > 0)
|
||||
{
|
||||
Array.Clear(buf, 0, buf.Length);
|
||||
ecStream.Write(buf, 0, rv);
|
||||
@@ -1900,7 +1900,7 @@ namespace MouseWithoutBorders.Class
|
||||
}
|
||||
while (rv > 0);
|
||||
|
||||
if ((rv = sentCount % Common.PACKAGE_SIZE) > 0)
|
||||
if ((rv = sentCount % Package.PACKAGE_SIZE) > 0)
|
||||
{
|
||||
Array.Clear(buf, 0, buf.Length);
|
||||
ecStream.Write(buf, 0, rv);
|
||||
@@ -1984,7 +1984,7 @@ namespace MouseWithoutBorders.Class
|
||||
if (tcp.MachineId == Setting.Values.MachineId)
|
||||
{
|
||||
tcp = null;
|
||||
Setting.Values.MachineId = Common.Ran.Next();
|
||||
Setting.Values.MachineId = Encryption.Ran.Next();
|
||||
InitAndCleanup.UpdateMachineTimeAndID();
|
||||
InitAndCleanup.PleaseReopenSocket = InitAndCleanup.REOPEN_WHEN_HOTKEY;
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ namespace MouseWithoutBorders.Class
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!Common.IsMyDesktopActive())
|
||||
if (!WinAPI.IsMyDesktopActive())
|
||||
{
|
||||
// We can just throw the SocketException but to avoid a redundant log entry:
|
||||
throw new ExpectedSocketException($"{nameof(StartServer)}: The desktop is no longer active.");
|
||||
|
||||
@@ -270,15 +270,15 @@ internal static class Clipboard
|
||||
int index = 0;
|
||||
int len;
|
||||
DATA package = new();
|
||||
byte[] buf = new byte[Common.PACKAGE_SIZE_EX];
|
||||
int dataStart = Common.PACKAGE_SIZE_EX - DATA_SIZE;
|
||||
byte[] buf = new byte[Package.PACKAGE_SIZE_EX];
|
||||
int dataStart = Package.PACKAGE_SIZE_EX - DATA_SIZE;
|
||||
|
||||
while (true)
|
||||
{
|
||||
if ((index + DATA_SIZE) > l)
|
||||
{
|
||||
len = l - index;
|
||||
Array.Clear(buf, 0, Common.PACKAGE_SIZE_EX);
|
||||
Array.Clear(buf, 0, Package.PACKAGE_SIZE_EX);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -315,7 +315,7 @@ internal static class Clipboard
|
||||
}
|
||||
|
||||
MemoryStream m = new();
|
||||
int dataStart = Common.PACKAGE_SIZE_EX - DATA_SIZE;
|
||||
int dataStart = Package.PACKAGE_SIZE_EX - DATA_SIZE;
|
||||
m.Write(data.Bytes, dataStart, DATA_SIZE);
|
||||
int unexpectedCount = 0;
|
||||
|
||||
@@ -809,27 +809,27 @@ internal static class Clipboard
|
||||
MachineName = Common.MachineName,
|
||||
};
|
||||
|
||||
byte[] buf = new byte[Common.PACKAGE_SIZE_EX];
|
||||
byte[] buf = new byte[Package.PACKAGE_SIZE_EX];
|
||||
|
||||
NetworkStream ns = new(s);
|
||||
enStream = Common.GetEncryptedStream(ns);
|
||||
enStream = Encryption.GetEncryptedStream(ns);
|
||||
Common.SendOrReceiveARandomDataBlockPerInitialIV(enStream);
|
||||
Logger.LogDebug($"{nameof(ShakeHand)}: Writing header package.");
|
||||
enStream.Write(package.Bytes, 0, Common.PACKAGE_SIZE_EX);
|
||||
enStream.Write(package.Bytes, 0, Package.PACKAGE_SIZE_EX);
|
||||
|
||||
Logger.LogDebug($"{nameof(ShakeHand)}: Sent: clientPush={clientPushData}, postAction={postAction}.");
|
||||
|
||||
deStream = Common.GetDecryptedStream(ns);
|
||||
deStream = Encryption.GetDecryptedStream(ns);
|
||||
Common.SendOrReceiveARandomDataBlockPerInitialIV(deStream, false);
|
||||
|
||||
Logger.LogDebug($"{nameof(ShakeHand)}: Reading header package.");
|
||||
|
||||
int bytesReceived = deStream.ReadEx(buf, 0, Common.PACKAGE_SIZE_EX);
|
||||
int bytesReceived = deStream.ReadEx(buf, 0, Package.PACKAGE_SIZE_EX);
|
||||
package.Bytes = buf;
|
||||
|
||||
string name = "Unknown";
|
||||
|
||||
if (bytesReceived == Common.PACKAGE_SIZE_EX)
|
||||
if (bytesReceived == Package.PACKAGE_SIZE_EX)
|
||||
{
|
||||
if (package.Type is PackageType.Clipboard or PackageType.ClipboardPush)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// <summary>
|
||||
// Package format/conversion.
|
||||
// </summary>
|
||||
// <history>
|
||||
// 2008 created by Truong Do (ductdo).
|
||||
// 2009-... modified by Truong Do (TruongDo).
|
||||
// 2023- Included in PowerToys.
|
||||
// </history>
|
||||
namespace MouseWithoutBorders.Core;
|
||||
|
||||
internal enum ClipboardPostAction : uint
|
||||
{
|
||||
Other = 0,
|
||||
Desktop = 1,
|
||||
Mspaint = 2,
|
||||
}
|
||||
150
src/modules/MouseWithoutBorders/App/Core/DATA.cs
Normal file
150
src/modules/MouseWithoutBorders/App/Core/DATA.cs
Normal file
@@ -0,0 +1,150 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// In X64, we are WOW
|
||||
[module: SuppressMessage("Microsoft.Portability", "CA1900:ValueTypeFieldsShouldBePortable", Scope = "type", Target = "MouseWithoutBorders.Core.DATA", Justification = "Dotnet port with style preservation")]
|
||||
|
||||
// <summary>
|
||||
// Package format/conversion.
|
||||
// </summary>
|
||||
// <history>
|
||||
// 2008 created by Truong Do (ductdo).
|
||||
// 2009-... modified by Truong Do (TruongDo).
|
||||
// 2023- Included in PowerToys.
|
||||
// </history>
|
||||
namespace MouseWithoutBorders.Core;
|
||||
|
||||
// The beauty of "union" in C#
|
||||
[StructLayout(LayoutKind.Explicit)]
|
||||
internal sealed class DATA
|
||||
{
|
||||
[FieldOffset(0)]
|
||||
internal PackageType Type; // 4 (first byte = package type, 1 = checksum, 2+3 = magic no.)
|
||||
|
||||
[FieldOffset(sizeof(PackageType))]
|
||||
internal int Id; // 4
|
||||
|
||||
[FieldOffset(sizeof(PackageType) + sizeof(uint))]
|
||||
internal ID Src; // 4
|
||||
|
||||
[FieldOffset(sizeof(PackageType) + (2 * sizeof(uint)))]
|
||||
internal ID Des; // 4
|
||||
|
||||
[FieldOffset(sizeof(PackageType) + (3 * sizeof(uint)))]
|
||||
internal long DateTime;
|
||||
|
||||
[FieldOffset(sizeof(PackageType) + (3 * sizeof(uint)) + sizeof(long))]
|
||||
internal KEYBDDATA Kd;
|
||||
|
||||
[FieldOffset(sizeof(PackageType) + (3 * sizeof(uint)))]
|
||||
internal MOUSEDATA Md;
|
||||
|
||||
[FieldOffset(sizeof(PackageType) + (3 * sizeof(uint)))]
|
||||
internal ID Machine1;
|
||||
|
||||
[FieldOffset(sizeof(PackageType) + (4 * sizeof(uint)))]
|
||||
internal ID Machine2;
|
||||
|
||||
[FieldOffset(sizeof(PackageType) + (5 * sizeof(uint)))]
|
||||
internal ID Machine3;
|
||||
|
||||
[FieldOffset(sizeof(PackageType) + (6 * sizeof(uint)))]
|
||||
internal ID Machine4;
|
||||
|
||||
[FieldOffset(sizeof(PackageType) + (3 * sizeof(uint)))]
|
||||
internal ClipboardPostAction PostAction;
|
||||
|
||||
[FieldOffset(sizeof(PackageType) + (7 * sizeof(uint)))]
|
||||
private long machineNameP1;
|
||||
|
||||
[FieldOffset(sizeof(PackageType) + (7 * sizeof(uint)) + sizeof(long))]
|
||||
private long machineNameP2;
|
||||
|
||||
[FieldOffset(sizeof(PackageType) + (7 * sizeof(uint)) + (2 * sizeof(long)))]
|
||||
private long machineNameP3;
|
||||
|
||||
[FieldOffset(sizeof(PackageType) + (7 * sizeof(uint)) + (3 * sizeof(long)))]
|
||||
private long machineNameP4;
|
||||
|
||||
internal string MachineName
|
||||
{
|
||||
get
|
||||
{
|
||||
string name = Common.GetString(BitConverter.GetBytes(machineNameP1))
|
||||
+ Common.GetString(BitConverter.GetBytes(machineNameP2))
|
||||
+ Common.GetString(BitConverter.GetBytes(machineNameP3))
|
||||
+ Common.GetString(BitConverter.GetBytes(machineNameP4));
|
||||
return name.Trim();
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
byte[] machineName = Common.GetBytes(value.PadRight(32, ' '));
|
||||
machineNameP1 = BitConverter.ToInt64(machineName, 0);
|
||||
machineNameP2 = BitConverter.ToInt64(machineName, 8);
|
||||
machineNameP3 = BitConverter.ToInt64(machineName, 16);
|
||||
machineNameP4 = BitConverter.ToInt64(machineName, 24);
|
||||
}
|
||||
}
|
||||
|
||||
public DATA()
|
||||
{
|
||||
}
|
||||
|
||||
public DATA(byte[] initialData)
|
||||
{
|
||||
Bytes = initialData;
|
||||
}
|
||||
|
||||
internal byte[] Bytes
|
||||
{
|
||||
get
|
||||
{
|
||||
byte[] buf = new byte[IsBigPackage ? Package.PACKAGE_SIZE_EX : Package.PACKAGE_SIZE];
|
||||
Array.Copy(StructToBytes(this), buf, IsBigPackage ? Package.PACKAGE_SIZE_EX : Package.PACKAGE_SIZE);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
Debug.Assert(value.Length <= Package.PACKAGE_SIZE_EX, "Length > package size");
|
||||
byte[] buf = new byte[Package.PACKAGE_SIZE_EX];
|
||||
Array.Copy(value, buf, value.Length);
|
||||
BytesToStruct(buf, this);
|
||||
}
|
||||
}
|
||||
|
||||
internal bool IsBigPackage
|
||||
{
|
||||
get => Type == 0
|
||||
? throw new InvalidOperationException("Package type not set.")
|
||||
: Type switch
|
||||
{
|
||||
PackageType.Hello or PackageType.Awake or PackageType.Heartbeat or PackageType.Heartbeat_ex or PackageType.Handshake or PackageType.HandshakeAck or PackageType.ClipboardPush or PackageType.Clipboard or PackageType.ClipboardAsk or PackageType.ClipboardImage or PackageType.ClipboardText or PackageType.ClipboardDataEnd => true,
|
||||
_ => (Type & PackageType.Matrix) == PackageType.Matrix,
|
||||
};
|
||||
}
|
||||
|
||||
private byte[] StructToBytes(object structObject)
|
||||
{
|
||||
byte[] bytes = new byte[Package.PACKAGE_SIZE_EX];
|
||||
GCHandle bHandle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
|
||||
Marshal.StructureToPtr(structObject, Marshal.UnsafeAddrOfPinnedArrayElement(bytes, 0), false);
|
||||
bHandle.Free();
|
||||
return bytes;
|
||||
}
|
||||
|
||||
private void BytesToStruct(byte[] value, object structObject)
|
||||
{
|
||||
GCHandle bHandle = GCHandle.Alloc(value, GCHandleType.Pinned);
|
||||
Marshal.PtrToStructure(Marshal.UnsafeAddrOfPinnedArrayElement(value, 0), structObject);
|
||||
bHandle.Free();
|
||||
}
|
||||
}
|
||||
@@ -67,20 +67,20 @@ internal static class DragDrop
|
||||
return;
|
||||
}
|
||||
|
||||
if (wParam == Common.WM_LBUTTONDOWN)
|
||||
if (wParam == WM.WM_LBUTTONDOWN)
|
||||
{
|
||||
MouseDown = true;
|
||||
DragMachine = MachineStuff.desMachineID;
|
||||
MachineStuff.dropMachineID = ID.NONE;
|
||||
Logger.LogDebug("DragDropStep01: MouseDown");
|
||||
}
|
||||
else if (wParam == Common.WM_LBUTTONUP)
|
||||
else if (wParam == WM.WM_LBUTTONUP)
|
||||
{
|
||||
MouseDown = false;
|
||||
Logger.LogDebug("DragDropStep01: MouseUp");
|
||||
}
|
||||
|
||||
if (wParam == Common.WM_RBUTTONUP && IsDropping)
|
||||
if (wParam == WM.WM_RBUTTONUP && IsDropping)
|
||||
{
|
||||
IsDropping = false;
|
||||
Clipboard.LastIDWithClipboardData = ID.NONE;
|
||||
@@ -252,7 +252,7 @@ internal static class DragDrop
|
||||
|
||||
internal static void DragDropStep09(int wParam)
|
||||
{
|
||||
if (wParam == Common.WM_MOUSEMOVE && IsDropping)
|
||||
if (wParam == WM.WM_MOUSEMOVE && IsDropping)
|
||||
{
|
||||
// Show/Move form
|
||||
Common.DoSomethingInUIThread(() =>
|
||||
@@ -260,7 +260,7 @@ internal static class DragDrop
|
||||
_ = NativeMethods.PostMessage(Common.MainForm.Handle, NativeMethods.WM_SHOW_DRAG_DROP, (IntPtr)0, (IntPtr)0);
|
||||
});
|
||||
}
|
||||
else if (wParam == Common.WM_LBUTTONUP && (IsDropping || IsDragging))
|
||||
else if (wParam == WM.WM_LBUTTONUP && (IsDropping || IsDragging))
|
||||
{
|
||||
if (IsDropping)
|
||||
{
|
||||
|
||||
245
src/modules/MouseWithoutBorders/App/Core/Encryption.cs
Normal file
245
src/modules/MouseWithoutBorders/App/Core/Encryption.cs
Normal file
@@ -0,0 +1,245 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
// <summary>
|
||||
// Encrypt/decrypt implementation.
|
||||
// </summary>
|
||||
// <history>
|
||||
// 2008 created by Truong Do (ductdo).
|
||||
// 2009-... modified by Truong Do (TruongDo).
|
||||
// 2023- Included in PowerToys.
|
||||
// </history>
|
||||
namespace MouseWithoutBorders.Core;
|
||||
|
||||
internal static class Encryption
|
||||
{
|
||||
#pragma warning disable SYSLIB0021
|
||||
private static AesCryptoServiceProvider symAl;
|
||||
#pragma warning restore SYSLIB0021
|
||||
#pragma warning disable SA1307 // Accessible fields should begin with upper-case letter
|
||||
internal static string myKey;
|
||||
#pragma warning restore SA1307
|
||||
private static uint magicNumber;
|
||||
private static Random ran = new(); // Used for non encryption related functionality.
|
||||
internal const int SymAlBlockSize = 16;
|
||||
|
||||
/// <summary>
|
||||
/// This is used for the first encryption block, the following blocks will be combined with the cipher text of the previous block.
|
||||
/// Thus identical blocks in the socket stream would be encrypted to different cipher text blocks.
|
||||
/// The first block is a handshake one containing random data.
|
||||
/// Related Unit Test: TestEncryptDecrypt
|
||||
/// </summary>
|
||||
private static readonly string InitialIV = ulong.MaxValue.ToString(CultureInfo.InvariantCulture);
|
||||
|
||||
internal static Random Ran
|
||||
{
|
||||
get => Encryption.ran ??= new Random();
|
||||
set => Encryption.ran = value;
|
||||
}
|
||||
|
||||
internal static uint MagicNumber
|
||||
{
|
||||
get => Encryption.magicNumber;
|
||||
set => Encryption.magicNumber = value;
|
||||
}
|
||||
|
||||
internal static string MyKey
|
||||
{
|
||||
get => Encryption.myKey;
|
||||
|
||||
set
|
||||
{
|
||||
if (Encryption.myKey != value)
|
||||
{
|
||||
Encryption.myKey = value;
|
||||
_ = Task.Factory.StartNew(
|
||||
() => Encryption.GenLegalKey(),
|
||||
System.Threading.CancellationToken.None,
|
||||
TaskCreationOptions.None,
|
||||
TaskScheduler.Default); // Cache the key to improve UX.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static string KeyDisplayedText(string key)
|
||||
{
|
||||
string displayedValue = string.Empty;
|
||||
int i = 0;
|
||||
|
||||
do
|
||||
{
|
||||
int length = Math.Min(4, key.Length - i);
|
||||
displayedValue += string.Concat(key.AsSpan(i, length), " ");
|
||||
i += 4;
|
||||
}
|
||||
while (i < key.Length - 1);
|
||||
|
||||
return displayedValue.Trim();
|
||||
}
|
||||
|
||||
internal static bool GeneratedKey { get; set; }
|
||||
|
||||
internal static bool KeyCorrupted { get; set; }
|
||||
|
||||
internal static void InitEncryption()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (symAl == null)
|
||||
{
|
||||
#pragma warning disable SYSLIB0021 // No proper replacement for now
|
||||
symAl = new AesCryptoServiceProvider();
|
||||
#pragma warning restore SYSLIB0021
|
||||
symAl.KeySize = 256;
|
||||
symAl.BlockSize = SymAlBlockSize * 8;
|
||||
symAl.Padding = PaddingMode.Zeros;
|
||||
symAl.Mode = CipherMode.CBC;
|
||||
symAl.GenerateIV();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Log(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly ConcurrentDictionary<string, byte[]> LegalKeyDictionary = new(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
private static byte[] GenLegalKey()
|
||||
{
|
||||
byte[] rv;
|
||||
string myKey = Encryption.MyKey;
|
||||
|
||||
if (!LegalKeyDictionary.TryGetValue(myKey, out byte[] value))
|
||||
{
|
||||
Rfc2898DeriveBytes key = new(
|
||||
myKey,
|
||||
Common.GetBytesU(InitialIV),
|
||||
50000,
|
||||
HashAlgorithmName.SHA512);
|
||||
rv = key.GetBytes(32);
|
||||
_ = LegalKeyDictionary.AddOrUpdate(myKey, rv, (k, v) => rv);
|
||||
}
|
||||
else
|
||||
{
|
||||
rv = value;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
private static byte[] GenLegalIV()
|
||||
{
|
||||
string st = InitialIV;
|
||||
int ivLength = symAl.IV.Length;
|
||||
if (st.Length > ivLength)
|
||||
{
|
||||
st = st[..ivLength];
|
||||
}
|
||||
else if (st.Length < ivLength)
|
||||
{
|
||||
st = st.PadRight(ivLength, ' ');
|
||||
}
|
||||
|
||||
return Common.GetBytes(st);
|
||||
}
|
||||
|
||||
internal static Stream GetEncryptedStream(Stream encryptedStream)
|
||||
{
|
||||
ICryptoTransform encryptor;
|
||||
encryptor = symAl.CreateEncryptor(GenLegalKey(), GenLegalIV());
|
||||
return new CryptoStream(encryptedStream, encryptor, CryptoStreamMode.Write);
|
||||
}
|
||||
|
||||
internal static Stream GetDecryptedStream(Stream encryptedStream)
|
||||
{
|
||||
ICryptoTransform decryptor;
|
||||
decryptor = symAl.CreateDecryptor(GenLegalKey(), GenLegalIV());
|
||||
return new CryptoStream(encryptedStream, decryptor, CryptoStreamMode.Read);
|
||||
}
|
||||
|
||||
internal static uint Get24BitHash(string st)
|
||||
{
|
||||
if (string.IsNullOrEmpty(st))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
byte[] bytes = new byte[Package.PACKAGE_SIZE];
|
||||
for (int i = 0; i < Package.PACKAGE_SIZE; i++)
|
||||
{
|
||||
if (i < st.Length)
|
||||
{
|
||||
bytes[i] = (byte)st[i];
|
||||
}
|
||||
}
|
||||
|
||||
var hash = SHA512.Create();
|
||||
byte[] hashValue = hash.ComputeHash(bytes);
|
||||
|
||||
for (int i = 0; i < 50000; i++)
|
||||
{
|
||||
hashValue = hash.ComputeHash(hashValue);
|
||||
}
|
||||
|
||||
Logger.LogDebug(string.Format(CultureInfo.CurrentCulture, "magic: {0},{1},{2}", hashValue[0], hashValue[1], hashValue[^1]));
|
||||
hash.Clear();
|
||||
return (uint)((hashValue[0] << 23) + (hashValue[1] << 16) + (hashValue[^1] << 8) + hashValue[2]);
|
||||
}
|
||||
|
||||
internal static string GetDebugInfo(string st)
|
||||
{
|
||||
return string.IsNullOrEmpty(st) ? st : ((byte)(Common.GetBytesU(st).Sum(value => value) % 256)).ToString(CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
internal static string CreateDefaultKey()
|
||||
{
|
||||
return CreateRandomKey();
|
||||
}
|
||||
|
||||
private const int PW_LENGTH = 16;
|
||||
|
||||
internal static string CreateRandomKey()
|
||||
{
|
||||
// Not including characters like "'`O0& since they are confusing to users.
|
||||
string[] chars = new[] { "abcdefghjkmnpqrstuvxyz", "ABCDEFGHJKMNPQRSTUVXYZ", "123456789", "~!@#$%^*()_-+=:;<,>.?/\\|[]" };
|
||||
char[][] charactersUsedForKey = chars.Select(charset => Enumerable.Range(0, charset.Length - 1).Select(i => charset[i]).ToArray()).ToArray();
|
||||
byte[] randomData = new byte[1];
|
||||
string key = string.Empty;
|
||||
|
||||
do
|
||||
{
|
||||
foreach (string set in chars)
|
||||
{
|
||||
randomData = RandomNumberGenerator.GetBytes(1);
|
||||
key += set[randomData[0] % set.Length];
|
||||
|
||||
if (key.Length >= PW_LENGTH)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
while (key.Length < PW_LENGTH);
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
internal static bool IsKeyValid(string key, out string error)
|
||||
{
|
||||
error = string.IsNullOrEmpty(key) || key.Length < 16
|
||||
? "Key must have at least 16 characters in length (spaces are discarded). Key must be auto generated in one of the machines."
|
||||
: null;
|
||||
|
||||
return error == null;
|
||||
}
|
||||
}
|
||||
@@ -70,7 +70,7 @@ internal static class Event
|
||||
// Check if easy mouse setting is enabled.
|
||||
bool isEasyMouseEnabled = IsSwitchingByMouseEnabled();
|
||||
|
||||
if (isEasyMouseEnabled && Common.Sk != null && (Common.DesMachineID == Common.MachineID || !Setting.Values.MoveMouseRelatively) && e.dwFlags == Common.WM_MOUSEMOVE)
|
||||
if (isEasyMouseEnabled && Common.Sk != null && (Common.DesMachineID == Common.MachineID || !Setting.Values.MoveMouseRelatively) && e.dwFlags == WM.WM_MOUSEMOVE)
|
||||
{
|
||||
Point p = MachineStuff.MoveToMyNeighbourIfNeeded(e.X, e.Y, MachineStuff.desMachineID);
|
||||
|
||||
@@ -115,7 +115,7 @@ internal static class Event
|
||||
|
||||
Common.SkSend(MousePackage, null, false);
|
||||
|
||||
if (MousePackage.Md.dwFlags is Common.WM_LBUTTONUP or Common.WM_RBUTTONUP)
|
||||
if (MousePackage.Md.dwFlags is WM.WM_LBUTTONUP or WM.WM_RBUTTONUP)
|
||||
{
|
||||
Thread.Sleep(10);
|
||||
}
|
||||
@@ -265,7 +265,7 @@ internal static class Event
|
||||
KeybdPackage.Kd = e;
|
||||
KeybdPackage.DateTime = Common.GetTick();
|
||||
Common.SkSend(KeybdPackage, null, false);
|
||||
if (KeybdPackage.Kd.dwFlags is Common.WM_KEYUP or Common.WM_SYSKEYUP)
|
||||
if (KeybdPackage.Kd.dwFlags is WM.WM_KEYUP or WM.WM_SYSKEYUP)
|
||||
{
|
||||
Thread.Sleep(10);
|
||||
}
|
||||
|
||||
@@ -290,7 +290,7 @@ internal static class Helper
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Common.IsMyDesktopActive())
|
||||
if (!WinAPI.IsMyDesktopActive())
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -314,7 +314,7 @@ internal static class Helper
|
||||
_ = Launch.CreateProcessInInputDesktopSession(
|
||||
$"\"{Path.GetDirectoryName(Application.ExecutablePath)}\\{HelperProcessName}.exe\"",
|
||||
string.Empty,
|
||||
Common.GetInputDesktop(),
|
||||
WinAPI.GetInputDesktop(),
|
||||
0);
|
||||
|
||||
Clipboard.HasSwitchedMachineSinceLastCopy = true;
|
||||
@@ -379,7 +379,7 @@ internal static class Helper
|
||||
log += "=============================================================================================================================\r\n";
|
||||
log += $"{Application.ProductName} version {Application.ProductVersion}\r\n";
|
||||
|
||||
log += $"{Setting.Values.Username}/{Common.GetDebugInfo(Common.MyKey)}\r\n";
|
||||
log += $"{Setting.Values.Username}/{Encryption.GetDebugInfo(Encryption.MyKey)}\r\n";
|
||||
log += $"{Common.MachineName}/{Common.MachineID}/{Common.DesMachineID}\r\n";
|
||||
log += $"Id: {Setting.Values.DeviceId}\r\n";
|
||||
log += $"Matrix: {string.Join(",", MachineStuff.MachineMatrix)}\r\n";
|
||||
|
||||
19
src/modules/MouseWithoutBorders/App/Core/ID.cs
Normal file
19
src/modules/MouseWithoutBorders/App/Core/ID.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
// <summary>
|
||||
// Package format/conversion.
|
||||
// </summary>
|
||||
// <history>
|
||||
// 2008 created by Truong Do (ductdo).
|
||||
// 2009-... modified by Truong Do (TruongDo).
|
||||
// 2023- Included in PowerToys.
|
||||
// </history>
|
||||
namespace MouseWithoutBorders.Core;
|
||||
|
||||
internal enum ID : uint
|
||||
{
|
||||
NONE = 0,
|
||||
ALL = 255,
|
||||
}
|
||||
@@ -89,23 +89,23 @@ internal static class InitAndCleanup
|
||||
internal static void Init()
|
||||
{
|
||||
_ = Helper.GetUserName();
|
||||
Common.GeneratedKey = true;
|
||||
Encryption.GeneratedKey = true;
|
||||
|
||||
try
|
||||
{
|
||||
Common.MyKey = Setting.Values.MyKey;
|
||||
Encryption.MyKey = Setting.Values.MyKey;
|
||||
int tmp = Setting.Values.MyKeyDaysToExpire;
|
||||
}
|
||||
catch (FormatException e)
|
||||
{
|
||||
Common.KeyCorrupted = true;
|
||||
Setting.Values.MyKey = Common.MyKey = Common.CreateRandomKey();
|
||||
Encryption.KeyCorrupted = true;
|
||||
Setting.Values.MyKey = Encryption.MyKey = Encryption.CreateRandomKey();
|
||||
Logger.Log(e.Message);
|
||||
}
|
||||
catch (CryptographicException e)
|
||||
{
|
||||
Common.KeyCorrupted = true;
|
||||
Setting.Values.MyKey = Common.MyKey = Common.CreateRandomKey();
|
||||
Encryption.KeyCorrupted = true;
|
||||
Setting.Values.MyKey = Encryption.MyKey = Encryption.CreateRandomKey();
|
||||
Logger.Log(e.Message);
|
||||
}
|
||||
|
||||
@@ -127,14 +127,14 @@ internal static class InitAndCleanup
|
||||
bool dummy = Setting.Values.DrawMouseEx;
|
||||
Common.Is64bitOS = IntPtr.Size == 8;
|
||||
Common.tcpPort = Setting.Values.TcpPort;
|
||||
Common.GetScreenConfig();
|
||||
Common.PackageSent = new PackageMonitor(0);
|
||||
Common.PackageReceived = new PackageMonitor(0);
|
||||
WinAPI.GetScreenConfig();
|
||||
Package.PackageSent = new PackageMonitor(0);
|
||||
Package.PackageReceived = new PackageMonitor(0);
|
||||
SetupMachineNameAndID();
|
||||
Common.InitEncryption();
|
||||
Encryption.InitEncryption();
|
||||
CreateHelperThreads();
|
||||
|
||||
SystemEvents.DisplaySettingsChanged += new EventHandler(Common.SystemEvents_DisplaySettingsChanged);
|
||||
SystemEvents.DisplaySettingsChanged += new EventHandler(WinAPI.SystemEvents_DisplaySettingsChanged);
|
||||
NetworkChange.NetworkAvailabilityChanged += new NetworkAvailabilityChangedEventHandler(NetworkChange_NetworkAvailabilityChanged);
|
||||
SystemEvents.PowerModeChanged += new PowerModeChangedEventHandler(SystemEvents_PowerModeChanged);
|
||||
PleaseReopenSocket = 9;
|
||||
@@ -220,7 +220,7 @@ internal static class InitAndCleanup
|
||||
lastReleaseAllKeysCall = Common.GetTick();
|
||||
|
||||
KEYBDDATA kd;
|
||||
kd.dwFlags = (int)Common.LLKHF.UP;
|
||||
kd.dwFlags = (int)WM.LLKHF.UP;
|
||||
|
||||
VK[] keys = new VK[]
|
||||
{
|
||||
@@ -266,7 +266,7 @@ internal static class InitAndCleanup
|
||||
true);
|
||||
}
|
||||
|
||||
if (!Common.IsMyDesktopActive())
|
||||
if (!WinAPI.IsMyDesktopActive())
|
||||
{
|
||||
PleaseReopenSocket = 0;
|
||||
}
|
||||
|
||||
25
src/modules/MouseWithoutBorders/App/Core/KEYBDDATA.cs
Normal file
25
src/modules/MouseWithoutBorders/App/Core/KEYBDDATA.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// <summary>
|
||||
// Package format/conversion.
|
||||
// </summary>
|
||||
// <history>
|
||||
// 2008 created by Truong Do (ductdo).
|
||||
// 2009-... modified by Truong Do (TruongDo).
|
||||
// 2023- Included in PowerToys.
|
||||
// </history>
|
||||
namespace MouseWithoutBorders.Core;
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct KEYBDDATA
|
||||
{
|
||||
[SuppressMessage("StyleCop.CSharp.NamingRules", "SA1307:Accessible fields should begin with upper-case letter", Justification = "Same name as in winAPI")]
|
||||
internal int wVk;
|
||||
[SuppressMessage("StyleCop.CSharp.NamingRules", "SA1307:Accessible fields should begin with upper-case letter", Justification = "Same name as in winAPI")]
|
||||
internal int dwFlags;
|
||||
}
|
||||
@@ -121,52 +121,52 @@ internal static class Logger
|
||||
{
|
||||
string log;
|
||||
|
||||
if (!lastPackageSent.Equals(Common.PackageSent))
|
||||
if (!lastPackageSent.Equals(Package.PackageSent))
|
||||
{
|
||||
log = string.Format(
|
||||
CultureInfo.CurrentCulture,
|
||||
"SENT:" + HeaderSENT,
|
||||
Common.PackageSent.Heartbeat,
|
||||
Common.PackageSent.Keyboard,
|
||||
Common.PackageSent.Mouse,
|
||||
Common.PackageSent.Hello,
|
||||
Common.PackageSent.Matrix,
|
||||
Common.PackageSent.ClipboardText,
|
||||
Common.PackageSent.ClipboardImage,
|
||||
Common.PackageSent.ByeBye,
|
||||
Common.PackageSent.Clipboard,
|
||||
Common.PackageSent.ClipboardDragDrop,
|
||||
Common.PackageSent.ClipboardDragDropEnd,
|
||||
Common.PackageSent.ExplorerDragDrop,
|
||||
Package.PackageSent.Heartbeat,
|
||||
Package.PackageSent.Keyboard,
|
||||
Package.PackageSent.Mouse,
|
||||
Package.PackageSent.Hello,
|
||||
Package.PackageSent.Matrix,
|
||||
Package.PackageSent.ClipboardText,
|
||||
Package.PackageSent.ClipboardImage,
|
||||
Package.PackageSent.ByeBye,
|
||||
Package.PackageSent.Clipboard,
|
||||
Package.PackageSent.ClipboardDragDrop,
|
||||
Package.PackageSent.ClipboardDragDropEnd,
|
||||
Package.PackageSent.ExplorerDragDrop,
|
||||
Event.inputEventCount,
|
||||
Common.PackageSent.Nil);
|
||||
Package.PackageSent.Nil);
|
||||
Log(log);
|
||||
lastPackageSent = Common.PackageSent; // Copy data
|
||||
lastPackageSent = Package.PackageSent; // Copy data
|
||||
}
|
||||
|
||||
if (!lastPackageReceived.Equals(Common.PackageReceived))
|
||||
if (!lastPackageReceived.Equals(Package.PackageReceived))
|
||||
{
|
||||
log = string.Format(
|
||||
CultureInfo.CurrentCulture,
|
||||
"RECEIVED:" + HeaderRECEIVED,
|
||||
Common.PackageReceived.Heartbeat,
|
||||
Common.PackageReceived.Keyboard,
|
||||
Common.PackageReceived.Mouse,
|
||||
Common.PackageReceived.Hello,
|
||||
Common.PackageReceived.Matrix,
|
||||
Common.PackageReceived.ClipboardText,
|
||||
Common.PackageReceived.ClipboardImage,
|
||||
Common.PackageReceived.ByeBye,
|
||||
Common.PackageReceived.Clipboard,
|
||||
Common.PackageReceived.ClipboardDragDrop,
|
||||
Common.PackageReceived.ClipboardDragDropEnd,
|
||||
Common.PackageReceived.ExplorerDragDrop,
|
||||
Package.PackageReceived.Heartbeat,
|
||||
Package.PackageReceived.Keyboard,
|
||||
Package.PackageReceived.Mouse,
|
||||
Package.PackageReceived.Hello,
|
||||
Package.PackageReceived.Matrix,
|
||||
Package.PackageReceived.ClipboardText,
|
||||
Package.PackageReceived.ClipboardImage,
|
||||
Package.PackageReceived.ByeBye,
|
||||
Package.PackageReceived.Clipboard,
|
||||
Package.PackageReceived.ClipboardDragDrop,
|
||||
Package.PackageReceived.ClipboardDragDropEnd,
|
||||
Package.PackageReceived.ExplorerDragDrop,
|
||||
Event.invalidPackageCount,
|
||||
Common.PackageReceived.Nil,
|
||||
Package.PackageReceived.Nil,
|
||||
Receiver.processedPackageCount,
|
||||
Receiver.skippedPackageCount);
|
||||
Log(log);
|
||||
lastPackageReceived = Common.PackageReceived;
|
||||
lastPackageReceived = Package.PackageReceived;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -209,9 +209,9 @@ internal static class Logger
|
||||
"Private Mem: " + (Process.GetCurrentProcess().PrivateMemorySize64 / 1024).ToString(CultureInfo.CurrentCulture) + "KB",
|
||||
sb.ToString());
|
||||
|
||||
if (!string.IsNullOrEmpty(Common.myKey))
|
||||
if (!string.IsNullOrEmpty(Encryption.myKey))
|
||||
{
|
||||
log = log.Replace(Common.MyKey, Common.GetDebugInfo(Common.MyKey));
|
||||
log = log.Replace(Encryption.MyKey, Encryption.GetDebugInfo(Encryption.MyKey));
|
||||
}
|
||||
|
||||
log += Thread.DumpThreadsStack();
|
||||
@@ -251,14 +251,18 @@ internal static class Logger
|
||||
{
|
||||
typeof(Clipboard),
|
||||
typeof(DragDrop),
|
||||
typeof(Encryption),
|
||||
typeof(Event),
|
||||
typeof(InitAndCleanup),
|
||||
typeof(Helper),
|
||||
typeof(Launch),
|
||||
typeof(Logger),
|
||||
typeof(MachineStuff),
|
||||
typeof(Package),
|
||||
typeof(Receiver),
|
||||
typeof(Service),
|
||||
typeof(WinAPI),
|
||||
typeof(WM),
|
||||
};
|
||||
foreach (var staticType in staticTypes)
|
||||
{
|
||||
@@ -294,7 +298,7 @@ internal static class Logger
|
||||
// strArr[3] = t.FullName;
|
||||
strArr[4] = " = ";
|
||||
strArr[5] = objName.Equals("myKey", StringComparison.OrdinalIgnoreCase)
|
||||
? Common.GetDebugInfo(objString)
|
||||
? Encryption.GetDebugInfo(objString)
|
||||
: objName.Equals("lastClipboardObject", StringComparison.OrdinalIgnoreCase)
|
||||
? string.Empty
|
||||
: objString
|
||||
|
||||
26
src/modules/MouseWithoutBorders/App/Core/MOUSEDATA.cs
Normal file
26
src/modules/MouseWithoutBorders/App/Core/MOUSEDATA.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// <summary>
|
||||
// Package format/conversion.
|
||||
// </summary>
|
||||
// <history>
|
||||
// 2008 created by Truong Do (ductdo).
|
||||
// 2009-... modified by Truong Do (TruongDo).
|
||||
// 2023- Included in PowerToys.
|
||||
// </history>
|
||||
namespace MouseWithoutBorders.Core;
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct MOUSEDATA
|
||||
{
|
||||
internal int X;
|
||||
internal int Y;
|
||||
internal int WheelDelta;
|
||||
[SuppressMessage("StyleCop.CSharp.NamingRules", "SA1307:Accessible fields should begin with upper-case letter", Justification = "Same name as in winAPI")]
|
||||
internal int dwFlags;
|
||||
}
|
||||
@@ -221,9 +221,9 @@ internal static class MachineStuff
|
||||
|
||||
if (Setting.Values.BlockMouseAtCorners)
|
||||
{
|
||||
lock (Common.SensitivePoints)
|
||||
lock (WinAPI.SensitivePoints)
|
||||
{
|
||||
foreach (Point p in Common.SensitivePoints)
|
||||
foreach (Point p in WinAPI.SensitivePoints)
|
||||
{
|
||||
if (Math.Abs(p.X - x) < 100 && Math.Abs(p.Y - y) < 100)
|
||||
{
|
||||
@@ -793,8 +793,8 @@ internal static class MachineStuff
|
||||
internal static void ShowSetupForm(bool reopenSockets = false)
|
||||
{
|
||||
Logger.LogDebug("========== BEGIN THE SETUP EXPERIENCE ==========", true);
|
||||
Setting.Values.MyKey = Common.MyKey = Common.CreateRandomKey();
|
||||
Common.GeneratedKey = true;
|
||||
Setting.Values.MyKey = Encryption.MyKey = Encryption.CreateRandomKey();
|
||||
Encryption.GeneratedKey = true;
|
||||
|
||||
if (Process.GetCurrentProcess().SessionId != NativeMethods.WTSGetActiveConsoleSessionId())
|
||||
{
|
||||
@@ -1067,7 +1067,7 @@ internal static class MachineStuff
|
||||
|
||||
internal static void AssertOneInstancePerDesktopSession()
|
||||
{
|
||||
string eventName = $"Global\\{Application.ProductName}-{FrmAbout.AssemblyVersion}-{Common.GetMyDesktop()}-{Common.CurrentProcess.SessionId}";
|
||||
string eventName = $"Global\\{Application.ProductName}-{FrmAbout.AssemblyVersion}-{WinAPI.GetMyDesktop()}-{Common.CurrentProcess.SessionId}";
|
||||
oneInstanceCheck = new EventWaitHandle(false, EventResetMode.ManualReset, eventName, out bool created);
|
||||
|
||||
if (!created)
|
||||
|
||||
23
src/modules/MouseWithoutBorders/App/Core/Package.cs
Normal file
23
src/modules/MouseWithoutBorders/App/Core/Package.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
// <summary>
|
||||
// Package format/conversion.
|
||||
// </summary>
|
||||
// <history>
|
||||
// 2008 created by Truong Do (ductdo).
|
||||
// 2009-... modified by Truong Do (TruongDo).
|
||||
// 2023- Included in PowerToys.
|
||||
// </history>
|
||||
namespace MouseWithoutBorders.Core;
|
||||
|
||||
internal static class Package
|
||||
{
|
||||
internal const byte PACKAGE_SIZE = 32;
|
||||
internal const byte PACKAGE_SIZE_EX = 64;
|
||||
private const byte WP_PACKAGE_SIZE = 6;
|
||||
internal static PackageMonitor PackageSent;
|
||||
internal static PackageMonitor PackageReceived;
|
||||
internal static int PackageID;
|
||||
}
|
||||
38
src/modules/MouseWithoutBorders/App/Core/PackageMonitor.cs
Normal file
38
src/modules/MouseWithoutBorders/App/Core/PackageMonitor.cs
Normal file
@@ -0,0 +1,38 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
// <summary>
|
||||
// Package format/conversion.
|
||||
// </summary>
|
||||
// <history>
|
||||
// 2008 created by Truong Do (ductdo).
|
||||
// 2009-... modified by Truong Do (TruongDo).
|
||||
// 2023- Included in PowerToys.
|
||||
// </history>
|
||||
namespace MouseWithoutBorders.Core;
|
||||
|
||||
internal struct PackageMonitor
|
||||
{
|
||||
internal ulong Keyboard;
|
||||
internal ulong Mouse;
|
||||
internal ulong Heartbeat;
|
||||
internal ulong ByeBye;
|
||||
internal ulong Hello;
|
||||
internal ulong Matrix;
|
||||
internal ulong ClipboardText;
|
||||
internal ulong ClipboardImage;
|
||||
internal ulong Clipboard;
|
||||
internal ulong ClipboardDragDrop;
|
||||
internal ulong ClipboardDragDropEnd;
|
||||
internal ulong ClipboardAsk;
|
||||
internal ulong ExplorerDragDrop;
|
||||
internal ulong Nil;
|
||||
|
||||
internal PackageMonitor(ulong value)
|
||||
{
|
||||
ClipboardDragDrop = ClipboardDragDropEnd = ExplorerDragDrop =
|
||||
Keyboard = Mouse = Heartbeat = ByeBye = Hello = Clipboard =
|
||||
Matrix = ClipboardImage = ClipboardText = Nil = ClipboardAsk = value;
|
||||
}
|
||||
}
|
||||
57
src/modules/MouseWithoutBorders/App/Core/PackageType.cs
Normal file
57
src/modules/MouseWithoutBorders/App/Core/PackageType.cs
Normal file
@@ -0,0 +1,57 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
// <summary>
|
||||
// Package format/conversion.
|
||||
// </summary>
|
||||
// <history>
|
||||
// 2008 created by Truong Do (ductdo).
|
||||
// 2009-... modified by Truong Do (TruongDo).
|
||||
// 2023- Included in PowerToys.
|
||||
// </history>
|
||||
namespace MouseWithoutBorders.Core;
|
||||
|
||||
internal enum PackageType // : int
|
||||
{
|
||||
// Search for PACKAGE_TYPE_RELATED before changing these!
|
||||
Invalid = 0xFF,
|
||||
|
||||
Error = 0xFE,
|
||||
|
||||
Hi = 2,
|
||||
Hello = 3,
|
||||
ByeBye = 4,
|
||||
|
||||
Heartbeat = 20,
|
||||
Awake = 21,
|
||||
HideMouse = 50,
|
||||
Heartbeat_ex = 51,
|
||||
Heartbeat_ex_l2 = 52,
|
||||
Heartbeat_ex_l3 = 53,
|
||||
|
||||
Clipboard = 69,
|
||||
ClipboardDragDrop = 70,
|
||||
ClipboardDragDropEnd = 71,
|
||||
ExplorerDragDrop = 72,
|
||||
ClipboardCapture = 73,
|
||||
CaptureScreenCommand = 74,
|
||||
ClipboardDragDropOperation = 75,
|
||||
ClipboardDataEnd = 76,
|
||||
MachineSwitched = 77,
|
||||
ClipboardAsk = 78,
|
||||
ClipboardPush = 79,
|
||||
|
||||
NextMachine = 121,
|
||||
Keyboard = 122,
|
||||
Mouse = 123,
|
||||
ClipboardText = 124,
|
||||
ClipboardImage = 125,
|
||||
|
||||
Handshake = 126,
|
||||
HandshakeAck = 127,
|
||||
|
||||
Matrix = 128,
|
||||
MatrixSwapFlag = 2,
|
||||
MatrixTwoRowFlag = 4,
|
||||
}
|
||||
@@ -93,7 +93,7 @@ internal static class Receiver
|
||||
switch (package.Type)
|
||||
{
|
||||
case PackageType.Keyboard:
|
||||
Common.PackageReceived.Keyboard++;
|
||||
Package.PackageReceived.Keyboard++;
|
||||
if (package.Des == Common.MachineID || package.Des == ID.ALL)
|
||||
{
|
||||
JustGotAKey = Common.GetTick();
|
||||
@@ -102,7 +102,7 @@ internal static class Receiver
|
||||
bool nonElevated = Common.RunWithNoAdminRight && false;
|
||||
if (nonElevated && Setting.Values.OneWayControlMode)
|
||||
{
|
||||
if ((package.Kd.dwFlags & (int)Common.LLKHF.UP) == (int)Common.LLKHF.UP)
|
||||
if ((package.Kd.dwFlags & (int)WM.LLKHF.UP) == (int)WM.LLKHF.UP)
|
||||
{
|
||||
Helper.ShowOneWayModeMessage();
|
||||
}
|
||||
@@ -116,7 +116,7 @@ internal static class Receiver
|
||||
break;
|
||||
|
||||
case PackageType.Mouse:
|
||||
Common.PackageReceived.Mouse++;
|
||||
Package.PackageReceived.Mouse++;
|
||||
|
||||
if (package.Des == Common.MachineID || package.Des == ID.ALL)
|
||||
{
|
||||
@@ -127,16 +127,16 @@ internal static class Receiver
|
||||
|
||||
// NOTE(@yuyoyuppe): disabled to drop elevation requirement
|
||||
bool nonElevated = Common.RunWithNoAdminRight && false;
|
||||
if (nonElevated && Setting.Values.OneWayControlMode && package.Md.dwFlags != Common.WM_MOUSEMOVE)
|
||||
if (nonElevated && Setting.Values.OneWayControlMode && package.Md.dwFlags != WM.WM_MOUSEMOVE)
|
||||
{
|
||||
if (!DragDrop.IsDropping)
|
||||
{
|
||||
if (package.Md.dwFlags is Common.WM_LBUTTONDOWN or Common.WM_RBUTTONDOWN)
|
||||
if (package.Md.dwFlags is WM.WM_LBUTTONDOWN or WM.WM_RBUTTONDOWN)
|
||||
{
|
||||
Helper.ShowOneWayModeMessage();
|
||||
}
|
||||
}
|
||||
else if (package.Md.dwFlags is Common.WM_LBUTTONUP or Common.WM_RBUTTONUP)
|
||||
else if (package.Md.dwFlags is WM.WM_LBUTTONUP or WM.WM_RBUTTONUP)
|
||||
{
|
||||
DragDrop.IsDropping = false;
|
||||
}
|
||||
@@ -146,7 +146,7 @@ internal static class Receiver
|
||||
|
||||
if (Math.Abs(package.Md.X) >= Event.MOVE_MOUSE_RELATIVE && Math.Abs(package.Md.Y) >= Event.MOVE_MOUSE_RELATIVE)
|
||||
{
|
||||
if (package.Md.dwFlags == Common.WM_MOUSEMOVE)
|
||||
if (package.Md.dwFlags == WM.WM_MOUSEMOVE)
|
||||
{
|
||||
InputSimulation.MoveMouseRelative(
|
||||
package.Md.X < 0 ? package.Md.X + Event.MOVE_MOUSE_RELATIVE : package.Md.X - Event.MOVE_MOUSE_RELATIVE,
|
||||
@@ -203,19 +203,19 @@ internal static class Receiver
|
||||
break;
|
||||
|
||||
case PackageType.ExplorerDragDrop:
|
||||
Common.PackageReceived.ExplorerDragDrop++;
|
||||
Package.PackageReceived.ExplorerDragDrop++;
|
||||
DragDrop.DragDropStep03(package);
|
||||
break;
|
||||
|
||||
case PackageType.Heartbeat:
|
||||
case PackageType.Heartbeat_ex:
|
||||
Common.PackageReceived.Heartbeat++;
|
||||
Package.PackageReceived.Heartbeat++;
|
||||
|
||||
Common.GeneratedKey = Common.GeneratedKey || package.Type == PackageType.Heartbeat_ex;
|
||||
Encryption.GeneratedKey = Encryption.GeneratedKey || package.Type == PackageType.Heartbeat_ex;
|
||||
|
||||
if (Common.GeneratedKey)
|
||||
if (Encryption.GeneratedKey)
|
||||
{
|
||||
Setting.Values.MyKey = Common.MyKey;
|
||||
Setting.Values.MyKey = Encryption.MyKey;
|
||||
Common.SendPackage(ID.ALL, PackageType.Heartbeat_ex_l2);
|
||||
}
|
||||
|
||||
@@ -230,26 +230,26 @@ internal static class Receiver
|
||||
break;
|
||||
|
||||
case PackageType.Heartbeat_ex_l2:
|
||||
Common.GeneratedKey = true;
|
||||
Setting.Values.MyKey = Common.MyKey;
|
||||
Encryption.GeneratedKey = true;
|
||||
Setting.Values.MyKey = Encryption.MyKey;
|
||||
Common.SendPackage(ID.ALL, PackageType.Heartbeat_ex_l3);
|
||||
|
||||
break;
|
||||
|
||||
case PackageType.Heartbeat_ex_l3:
|
||||
Common.GeneratedKey = true;
|
||||
Setting.Values.MyKey = Common.MyKey;
|
||||
Encryption.GeneratedKey = true;
|
||||
Setting.Values.MyKey = Encryption.MyKey;
|
||||
|
||||
break;
|
||||
|
||||
case PackageType.Awake:
|
||||
Common.PackageReceived.Heartbeat++;
|
||||
Package.PackageReceived.Heartbeat++;
|
||||
_ = MachineStuff.AddToMachinePool(package);
|
||||
Common.HumanBeingDetected();
|
||||
break;
|
||||
|
||||
case PackageType.Hello:
|
||||
Common.PackageReceived.Hello++;
|
||||
Package.PackageReceived.Hello++;
|
||||
Common.SendHeartBeat();
|
||||
string newMachine = MachineStuff.AddToMachinePool(package);
|
||||
if (Setting.Values.MachineMatrixString == null)
|
||||
@@ -262,16 +262,16 @@ internal static class Receiver
|
||||
break;
|
||||
|
||||
case PackageType.Hi:
|
||||
Common.PackageReceived.Hello++;
|
||||
Package.PackageReceived.Hello++;
|
||||
break;
|
||||
|
||||
case PackageType.ByeBye:
|
||||
Common.PackageReceived.ByeBye++;
|
||||
Package.PackageReceived.ByeBye++;
|
||||
Common.ProcessByeByeMessage(package);
|
||||
break;
|
||||
|
||||
case PackageType.Clipboard:
|
||||
Common.PackageReceived.Clipboard++;
|
||||
Package.PackageReceived.Clipboard++;
|
||||
if (!Common.RunOnLogonDesktop && !Common.RunOnScrSaverDesktop)
|
||||
{
|
||||
Clipboard.clipboardCopiedTime = Common.GetTick();
|
||||
@@ -291,7 +291,7 @@ internal static class Receiver
|
||||
break;
|
||||
|
||||
case PackageType.ClipboardCapture:
|
||||
Common.PackageReceived.Clipboard++;
|
||||
Package.PackageReceived.Clipboard++;
|
||||
if (!Common.RunOnLogonDesktop && !Common.RunOnScrSaverDesktop)
|
||||
{
|
||||
if (package.Des == Common.MachineID || package.Des == ID.ALL)
|
||||
@@ -304,7 +304,7 @@ internal static class Receiver
|
||||
break;
|
||||
|
||||
case PackageType.CaptureScreenCommand:
|
||||
Common.PackageReceived.Clipboard++;
|
||||
Package.PackageReceived.Clipboard++;
|
||||
if (package.Des == Common.MachineID || package.Des == ID.ALL)
|
||||
{
|
||||
Common.SendImage(package.Src, Common.CaptureScreen());
|
||||
@@ -313,7 +313,7 @@ internal static class Receiver
|
||||
break;
|
||||
|
||||
case PackageType.ClipboardAsk:
|
||||
Common.PackageReceived.ClipboardAsk++;
|
||||
Package.PackageReceived.ClipboardAsk++;
|
||||
|
||||
if (package.Des == Common.MachineID)
|
||||
{
|
||||
@@ -344,17 +344,17 @@ internal static class Receiver
|
||||
break;
|
||||
|
||||
case PackageType.ClipboardDragDrop:
|
||||
Common.PackageReceived.ClipboardDragDrop++;
|
||||
Package.PackageReceived.ClipboardDragDrop++;
|
||||
DragDrop.DragDropStep08(package);
|
||||
break;
|
||||
|
||||
case PackageType.ClipboardDragDropOperation:
|
||||
Common.PackageReceived.ClipboardDragDrop++;
|
||||
Package.PackageReceived.ClipboardDragDrop++;
|
||||
DragDrop.DragDropStep08_2(package);
|
||||
break;
|
||||
|
||||
case PackageType.ClipboardDragDropEnd:
|
||||
Common.PackageReceived.ClipboardDragDropEnd++;
|
||||
Package.PackageReceived.ClipboardDragDropEnd++;
|
||||
DragDrop.DragDropStep12();
|
||||
break;
|
||||
|
||||
@@ -363,11 +363,11 @@ internal static class Receiver
|
||||
Clipboard.clipboardCopiedTime = 0;
|
||||
if (package.Type == PackageType.ClipboardImage)
|
||||
{
|
||||
Common.PackageReceived.ClipboardImage++;
|
||||
Package.PackageReceived.ClipboardImage++;
|
||||
}
|
||||
else
|
||||
{
|
||||
Common.PackageReceived.ClipboardText++;
|
||||
Package.PackageReceived.ClipboardText++;
|
||||
}
|
||||
|
||||
if (tcp != null)
|
||||
@@ -390,7 +390,7 @@ internal static class Receiver
|
||||
default:
|
||||
if ((package.Type & PackageType.Matrix) == PackageType.Matrix)
|
||||
{
|
||||
Common.PackageReceived.Matrix++;
|
||||
Package.PackageReceived.Matrix++;
|
||||
MachineStuff.UpdateMachineMatrix(package);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
|
||||
using ManagedCommon;
|
||||
using Microsoft.PowerToys.Telemetry;
|
||||
|
||||
namespace MouseWithoutBorders.Core;
|
||||
|
||||
internal static class ShutdownWithPowerToys
|
||||
{
|
||||
internal static void WaitForPowerToysRunner(ETWTrace etwTrace)
|
||||
{
|
||||
try
|
||||
{
|
||||
RunnerHelper.WaitForPowerToysRunnerExitFallback(() =>
|
||||
{
|
||||
etwTrace?.Dispose();
|
||||
Common.MainForm.Quit(true, false);
|
||||
});
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Log(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
88
src/modules/MouseWithoutBorders/App/Core/VK.cs
Normal file
88
src/modules/MouseWithoutBorders/App/Core/VK.cs
Normal file
@@ -0,0 +1,88 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
// <summary>
|
||||
// Virtual key constants.
|
||||
// </summary>
|
||||
// <history>
|
||||
// 2008 created by Truong Do (ductdo).
|
||||
// 2009-... modified by Truong Do (TruongDo).
|
||||
// 2023- Included in PowerToys.
|
||||
// </history>
|
||||
namespace MouseWithoutBorders.Core;
|
||||
|
||||
internal enum VK : ushort
|
||||
{
|
||||
CAPITAL = 0x14,
|
||||
NUMLOCK = 0x90,
|
||||
SHIFT = 0x10,
|
||||
CONTROL = 0x11,
|
||||
MENU = 0x12,
|
||||
ESCAPE = 0x1B,
|
||||
BACK = 0x08,
|
||||
TAB = 0x09,
|
||||
RETURN = 0x0D,
|
||||
PRIOR = 0x21,
|
||||
NEXT = 0x22,
|
||||
END = 0x23,
|
||||
HOME = 0x24,
|
||||
LEFT = 0x25,
|
||||
UP = 0x26,
|
||||
RIGHT = 0x27,
|
||||
DOWN = 0x28,
|
||||
SELECT = 0x29,
|
||||
PRINT = 0x2A,
|
||||
EXECUTE = 0x2B,
|
||||
SNAPSHOT = 0x2C,
|
||||
INSERT = 0x2D,
|
||||
DELETE = 0x2E,
|
||||
HELP = 0x2F,
|
||||
NUMPAD0 = 0x60,
|
||||
NUMPAD1 = 0x61,
|
||||
NUMPAD2 = 0x62,
|
||||
NUMPAD3 = 0x63,
|
||||
NUMPAD4 = 0x64,
|
||||
NUMPAD5 = 0x65,
|
||||
NUMPAD6 = 0x66,
|
||||
NUMPAD7 = 0x67,
|
||||
NUMPAD8 = 0x68,
|
||||
NUMPAD9 = 0x69,
|
||||
MULTIPLY = 0x6A,
|
||||
ADD = 0x6B,
|
||||
SEPARATOR = 0x6C,
|
||||
SUBTRACT = 0x6D,
|
||||
DECIMAL = 0x6E,
|
||||
DIVIDE = 0x6F,
|
||||
F1 = 0x70,
|
||||
F2 = 0x71,
|
||||
F3 = 0x72,
|
||||
F4 = 0x73,
|
||||
F5 = 0x74,
|
||||
F6 = 0x75,
|
||||
F7 = 0x76,
|
||||
F8 = 0x77,
|
||||
F9 = 0x78,
|
||||
F10 = 0x79,
|
||||
F11 = 0x7A,
|
||||
F12 = 0x7B,
|
||||
OEM_1 = 0xBA,
|
||||
OEM_PLUS = 0xBB,
|
||||
OEM_COMMA = 0xBC,
|
||||
OEM_MINUS = 0xBD,
|
||||
OEM_PERIOD = 0xBE,
|
||||
OEM_2 = 0xBF,
|
||||
OEM_3 = 0xC0,
|
||||
MEDIA_NEXT_TRACK = 0xB0,
|
||||
MEDIA_PREV_TRACK = 0xB1,
|
||||
MEDIA_STOP = 0xB2,
|
||||
MEDIA_PLAY_PAUSE = 0xB3,
|
||||
LWIN = 0x5B,
|
||||
RWIN = 0x5C,
|
||||
LSHIFT = 0xA0,
|
||||
RSHIFT = 0xA1,
|
||||
LCONTROL = 0xA2,
|
||||
RCONTROL = 0xA3,
|
||||
LMENU = 0xA4,
|
||||
RMENU = 0xA5,
|
||||
}
|
||||
55
src/modules/MouseWithoutBorders/App/Core/WM.cs
Normal file
55
src/modules/MouseWithoutBorders/App/Core/WM.cs
Normal file
@@ -0,0 +1,55 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
|
||||
// <summary>
|
||||
// Virtual key constants.
|
||||
// </summary>
|
||||
// <history>
|
||||
// 2008 created by Truong Do (ductdo).
|
||||
// 2009-... modified by Truong Do (TruongDo).
|
||||
// 2023- Included in PowerToys.
|
||||
// </history>
|
||||
namespace MouseWithoutBorders.Core;
|
||||
|
||||
internal partial class WM
|
||||
{
|
||||
internal const ushort KEYEVENTF_KEYDOWN = 0x0001;
|
||||
internal const ushort KEYEVENTF_KEYUP = 0x0002;
|
||||
|
||||
internal const int WH_MOUSE = 7;
|
||||
internal const int WH_KEYBOARD = 2;
|
||||
internal const int WH_MOUSE_LL = 14;
|
||||
internal const int WH_KEYBOARD_LL = 13;
|
||||
|
||||
internal const int WM_MOUSEMOVE = 0x200;
|
||||
internal const int WM_LBUTTONDOWN = 0x201;
|
||||
internal const int WM_RBUTTONDOWN = 0x204;
|
||||
internal const int WM_MBUTTONDOWN = 0x207;
|
||||
internal const int WM_XBUTTONDOWN = 0x20B;
|
||||
internal const int WM_LBUTTONUP = 0x202;
|
||||
internal const int WM_RBUTTONUP = 0x205;
|
||||
internal const int WM_MBUTTONUP = 0x208;
|
||||
internal const int WM_XBUTTONUP = 0x20C;
|
||||
internal const int WM_LBUTTONDBLCLK = 0x203;
|
||||
internal const int WM_RBUTTONDBLCLK = 0x206;
|
||||
internal const int WM_MBUTTONDBLCLK = 0x209;
|
||||
internal const int WM_MOUSEWHEEL = 0x020A;
|
||||
internal const int WM_MOUSEHWHEEL = 0x020E;
|
||||
|
||||
internal const int WM_KEYDOWN = 0x100;
|
||||
internal const int WM_KEYUP = 0x101;
|
||||
internal const int WM_SYSKEYDOWN = 0x104;
|
||||
internal const int WM_SYSKEYUP = 0x105;
|
||||
|
||||
[Flags]
|
||||
internal enum LLKHF
|
||||
{
|
||||
EXTENDED = 0x01,
|
||||
INJECTED = 0x10,
|
||||
ALTDOWN = 0x20,
|
||||
UP = 0x80,
|
||||
}
|
||||
}
|
||||
359
src/modules/MouseWithoutBorders/App/Core/WinAPI.cs
Normal file
359
src/modules/MouseWithoutBorders/App/Core/WinAPI.cs
Normal file
@@ -0,0 +1,359 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
using System.Windows.Forms;
|
||||
|
||||
using MouseWithoutBorders.Class;
|
||||
|
||||
// <summary>
|
||||
// Screen/Desktop helper functions.
|
||||
// </summary>
|
||||
// <history>
|
||||
// 2008 created by Truong Do (ductdo).
|
||||
// 2009-... modified by Truong Do (TruongDo).
|
||||
// 2023- Included in PowerToys.
|
||||
// </history>
|
||||
namespace MouseWithoutBorders.Core;
|
||||
|
||||
// Desktops, and GetScreenConfig routines
|
||||
internal static class WinAPI
|
||||
{
|
||||
private static MyRectangle newDesktopBounds;
|
||||
private static MyRectangle newPrimaryScreenBounds;
|
||||
private static string activeDesktop;
|
||||
|
||||
private static string ActiveDesktop => WinAPI.activeDesktop;
|
||||
|
||||
internal static void SystemEvents_DisplaySettingsChanged(object sender, EventArgs e)
|
||||
{
|
||||
GetScreenConfig();
|
||||
}
|
||||
|
||||
internal static readonly List<Point> SensitivePoints = new();
|
||||
|
||||
private static bool MonitorEnumProc(IntPtr hMonitor, IntPtr hdcMonitor, ref NativeMethods.RECT lprcMonitor, IntPtr dwData)
|
||||
{
|
||||
// lprcMonitor is wrong!!! => using GetMonitorInfo(...)
|
||||
// Log(String.Format( CultureInfo.CurrentCulture,"MONITOR: l{0}, t{1}, r{2}, b{3}", lprcMonitor.Left, lprcMonitor.Top, lprcMonitor.Right, lprcMonitor.Bottom));
|
||||
NativeMethods.MonitorInfoEx mi = default;
|
||||
mi.cbSize = Marshal.SizeOf(mi);
|
||||
_ = NativeMethods.GetMonitorInfo(hMonitor, ref mi);
|
||||
|
||||
try
|
||||
{
|
||||
// For logging only
|
||||
_ = NativeMethods.GetDpiForMonitor(hMonitor, 0, out uint dpiX, out uint dpiY);
|
||||
Logger.Log(string.Format(CultureInfo.CurrentCulture, "MONITOR: ({0}, {1}, {2}, {3}). DPI: ({4}, {5})", mi.rcMonitor.Left, mi.rcMonitor.Top, mi.rcMonitor.Right, mi.rcMonitor.Bottom, dpiX, dpiY));
|
||||
}
|
||||
catch (DllNotFoundException)
|
||||
{
|
||||
Logger.Log("GetDpiForMonitor is unsupported in Windows 7 and lower.");
|
||||
}
|
||||
catch (EntryPointNotFoundException)
|
||||
{
|
||||
Logger.Log("GetDpiForMonitor is unsupported in Windows 7 and lower.");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Log(e);
|
||||
}
|
||||
|
||||
if (mi.rcMonitor.Left == 0 && mi.rcMonitor.Top == 0 && mi.rcMonitor.Right != 0 && mi.rcMonitor.Bottom != 0)
|
||||
{
|
||||
// Primary screen
|
||||
_ = Interlocked.Exchange(ref Common.screenWidth, mi.rcMonitor.Right - mi.rcMonitor.Left);
|
||||
_ = Interlocked.Exchange(ref Common.screenHeight, mi.rcMonitor.Bottom - mi.rcMonitor.Top);
|
||||
|
||||
newPrimaryScreenBounds.Left = mi.rcMonitor.Left;
|
||||
newPrimaryScreenBounds.Top = mi.rcMonitor.Top;
|
||||
newPrimaryScreenBounds.Right = mi.rcMonitor.Right;
|
||||
newPrimaryScreenBounds.Bottom = mi.rcMonitor.Bottom;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mi.rcMonitor.Left < newDesktopBounds.Left)
|
||||
{
|
||||
newDesktopBounds.Left = mi.rcMonitor.Left;
|
||||
}
|
||||
|
||||
if (mi.rcMonitor.Top < newDesktopBounds.Top)
|
||||
{
|
||||
newDesktopBounds.Top = mi.rcMonitor.Top;
|
||||
}
|
||||
|
||||
if (mi.rcMonitor.Right > newDesktopBounds.Right)
|
||||
{
|
||||
newDesktopBounds.Right = mi.rcMonitor.Right;
|
||||
}
|
||||
|
||||
if (mi.rcMonitor.Bottom > newDesktopBounds.Bottom)
|
||||
{
|
||||
newDesktopBounds.Bottom = mi.rcMonitor.Bottom;
|
||||
}
|
||||
}
|
||||
|
||||
lock (SensitivePoints)
|
||||
{
|
||||
SensitivePoints.Add(new Point(mi.rcMonitor.Left, mi.rcMonitor.Top));
|
||||
SensitivePoints.Add(new Point(mi.rcMonitor.Right, mi.rcMonitor.Top));
|
||||
SensitivePoints.Add(new Point(mi.rcMonitor.Right, mi.rcMonitor.Bottom));
|
||||
SensitivePoints.Add(new Point(mi.rcMonitor.Left, mi.rcMonitor.Bottom));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
internal static void GetScreenConfig()
|
||||
{
|
||||
try
|
||||
{
|
||||
Logger.LogDebug("==================== GetScreenConfig started");
|
||||
newDesktopBounds = new MyRectangle();
|
||||
newPrimaryScreenBounds = new MyRectangle();
|
||||
newDesktopBounds.Left = newPrimaryScreenBounds.Left = Screen.PrimaryScreen.Bounds.Left;
|
||||
newDesktopBounds.Top = newPrimaryScreenBounds.Top = Screen.PrimaryScreen.Bounds.Top;
|
||||
newDesktopBounds.Right = newPrimaryScreenBounds.Right = Screen.PrimaryScreen.Bounds.Right;
|
||||
newDesktopBounds.Bottom = newPrimaryScreenBounds.Bottom = Screen.PrimaryScreen.Bounds.Bottom;
|
||||
|
||||
Logger.Log(string.Format(
|
||||
CultureInfo.CurrentCulture,
|
||||
"logon = {0} PrimaryScreenBounds = {1},{2},{3},{4} desktopBounds = {5},{6},{7},{8}",
|
||||
Common.RunOnLogonDesktop,
|
||||
WinAPI.newPrimaryScreenBounds.Left,
|
||||
WinAPI.newPrimaryScreenBounds.Top,
|
||||
WinAPI.newPrimaryScreenBounds.Right,
|
||||
WinAPI.newPrimaryScreenBounds.Bottom,
|
||||
WinAPI.newDesktopBounds.Left,
|
||||
WinAPI.newDesktopBounds.Top,
|
||||
WinAPI.newDesktopBounds.Right,
|
||||
WinAPI.newDesktopBounds.Bottom));
|
||||
|
||||
#if USE_MANAGED_ROUTINES
|
||||
// Managed routines do not work well when running on secure desktop:(
|
||||
screenWidth = Screen.PrimaryScreen.Bounds.Width;
|
||||
screenHeight = Screen.PrimaryScreen.Bounds.Height;
|
||||
screenCount = Screen.AllScreens.Length;
|
||||
for (int i = 0; i < Screen.AllScreens.Length; i++)
|
||||
{
|
||||
if (Screen.AllScreens[i].Bounds.Left < desktopBounds.Left) desktopBounds.Left = Screen.AllScreens[i].Bounds.Left;
|
||||
if (Screen.AllScreens[i].Bounds.Top < desktopBounds.Top) desktopBounds.Top = Screen.AllScreens[i].Bounds.Top;
|
||||
if (Screen.AllScreens[i].Bounds.Right > desktopBounds.Right) desktopBounds.Right = Screen.AllScreens[i].Bounds.Right;
|
||||
if (Screen.AllScreens[i].Bounds.Bottom > desktopBounds.Bottom) desktopBounds.Bottom = Screen.AllScreens[i].Bounds.Bottom;
|
||||
}
|
||||
#else
|
||||
lock (SensitivePoints)
|
||||
{
|
||||
SensitivePoints.Clear();
|
||||
}
|
||||
|
||||
NativeMethods.EnumDisplayMonitors(IntPtr.Zero, IntPtr.Zero, MonitorEnumProc, IntPtr.Zero);
|
||||
|
||||
// 1000 calls to EnumDisplayMonitors cost a dozen of milliseconds
|
||||
#endif
|
||||
Interlocked.Exchange(ref MachineStuff.desktopBounds, newDesktopBounds);
|
||||
Interlocked.Exchange(ref MachineStuff.primaryScreenBounds, newPrimaryScreenBounds);
|
||||
|
||||
Logger.Log(string.Format(
|
||||
CultureInfo.CurrentCulture,
|
||||
"logon = {0} PrimaryScreenBounds = {1},{2},{3},{4} desktopBounds = {5},{6},{7},{8}",
|
||||
Common.RunOnLogonDesktop,
|
||||
MachineStuff.PrimaryScreenBounds.Left,
|
||||
MachineStuff.PrimaryScreenBounds.Top,
|
||||
MachineStuff.PrimaryScreenBounds.Right,
|
||||
MachineStuff.PrimaryScreenBounds.Bottom,
|
||||
MachineStuff.DesktopBounds.Left,
|
||||
MachineStuff.DesktopBounds.Top,
|
||||
MachineStuff.DesktopBounds.Right,
|
||||
MachineStuff.DesktopBounds.Bottom));
|
||||
|
||||
Logger.Log("==================== GetScreenConfig ended");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Log(e);
|
||||
}
|
||||
}
|
||||
|
||||
#if USING_SCREEN_SAVER_ROUTINES
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto)]
|
||||
private static extern int PostMessage(IntPtr hWnd, int wMsg, int wParam, int lParam);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto)]
|
||||
private static extern IntPtr OpenDesktop(string hDesktop, int Flags, bool Inherit, UInt32 DesiredAccess);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto)]
|
||||
private static extern bool CloseDesktop(IntPtr hDesktop);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto)]
|
||||
private static extern bool EnumDesktopWindows( IntPtr hDesktop, EnumDesktopWindowsProc callback, IntPtr lParam);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto)]
|
||||
private static extern bool IsWindowVisible(IntPtr hWnd);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto)]
|
||||
private static extern bool SystemParametersInfo(int uAction, int uParam, ref int pvParam, int flags);
|
||||
|
||||
private delegate bool EnumDesktopWindowsProc(IntPtr hDesktop, IntPtr lParam);
|
||||
private const int WM_CLOSE = 16;
|
||||
private const int SPI_GETSCREENSAVERRUNNING = 114;
|
||||
|
||||
internal static bool IsScreenSaverRunning()
|
||||
{
|
||||
int isRunning = 0;
|
||||
SystemParametersInfo(SPI_GETSCREENSAVERRUNNING, 0,ref isRunning, 0);
|
||||
return (isRunning != 0);
|
||||
}
|
||||
|
||||
internal static void CloseScreenSaver()
|
||||
{
|
||||
IntPtr hDesktop = OpenDesktop("Screen-saver", 0, false, DESKTOP_READOBJECTS | DESKTOP_WRITEOBJECTS);
|
||||
if (hDesktop != IntPtr.Zero)
|
||||
{
|
||||
LogDebug("Closing screen saver...");
|
||||
EnumDesktopWindows(hDesktop, new EnumDesktopWindowsProc(CloseScreenSaverFunc), IntPtr.Zero);
|
||||
CloseDesktop(hDesktop);
|
||||
}
|
||||
}
|
||||
|
||||
private static bool CloseScreenSaverFunc(IntPtr hWnd, IntPtr lParam)
|
||||
{
|
||||
if (IsWindowVisible(hWnd))
|
||||
{
|
||||
LogDebug("Posting WM_CLOSE to " + hWnd.ToString(CultureInfo.InvariantCulture));
|
||||
PostMessage(hWnd, WM_CLOSE, 0, 0);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
internal static string GetMyDesktop()
|
||||
{
|
||||
byte[] arThreadDesktop = new byte[256];
|
||||
IntPtr hD = NativeMethods.GetThreadDesktop(NativeMethods.GetCurrentThreadId());
|
||||
if (hD != IntPtr.Zero)
|
||||
{
|
||||
_ = NativeMethods.GetUserObjectInformation(hD, NativeMethods.UOI_NAME, arThreadDesktop, arThreadDesktop.Length, out _);
|
||||
return Common.GetString(arThreadDesktop).Replace("\0", string.Empty);
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
internal static string GetInputDesktop()
|
||||
{
|
||||
byte[] arInputDesktop = new byte[256];
|
||||
IntPtr hD = NativeMethods.OpenInputDesktop(0, false, NativeMethods.DESKTOP_READOBJECTS);
|
||||
if (hD != IntPtr.Zero)
|
||||
{
|
||||
_ = NativeMethods.GetUserObjectInformation(hD, NativeMethods.UOI_NAME, arInputDesktop, arInputDesktop.Length, out _);
|
||||
return Common.GetString(arInputDesktop).Replace("\0", string.Empty);
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
private static void StartMMService(string desktopToRunMouseWithoutBordersOn)
|
||||
{
|
||||
if (!Common.RunWithNoAdminRight)
|
||||
{
|
||||
Logger.LogDebug("*** Starting on active Desktop: " + desktopToRunMouseWithoutBordersOn);
|
||||
Service.StartMouseWithoutBordersService(desktopToRunMouseWithoutBordersOn);
|
||||
}
|
||||
}
|
||||
|
||||
internal static void CheckForDesktopSwitchEvent(bool cleanupIfExit)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!IsMyDesktopActive() || Common.CurrentProcess.SessionId != NativeMethods.WTSGetActiveConsoleSessionId())
|
||||
{
|
||||
Helper.RunDDHelper(true);
|
||||
int waitCount = 20;
|
||||
|
||||
while (NativeMethods.WTSGetActiveConsoleSessionId() == 0xFFFFFFFF && waitCount > 0)
|
||||
{
|
||||
waitCount--;
|
||||
Logger.LogDebug("The session is detached/attached.");
|
||||
Thread.Sleep(500);
|
||||
}
|
||||
|
||||
string myDesktop = GetMyDesktop();
|
||||
activeDesktop = GetInputDesktop();
|
||||
|
||||
Logger.LogDebug("*** Active Desktop = " + activeDesktop);
|
||||
Logger.LogDebug("*** My Desktop = " + myDesktop);
|
||||
|
||||
if (myDesktop.Equals(activeDesktop, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
Logger.LogDebug("*** Active Desktop == My Desktop (TS session)");
|
||||
}
|
||||
|
||||
if (!activeDesktop.Equals("winlogon", StringComparison.OrdinalIgnoreCase) &&
|
||||
!activeDesktop.Equals("default", StringComparison.OrdinalIgnoreCase) &&
|
||||
!activeDesktop.Equals("disconnect", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
try
|
||||
{
|
||||
StartMMService(activeDesktop);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Log($"{nameof(CheckForDesktopSwitchEvent)}: {e}");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!myDesktop.Equals(activeDesktop, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
Logger.Log("*** Active Desktop <> My Desktop");
|
||||
}
|
||||
|
||||
uint sid = NativeMethods.WTSGetActiveConsoleSessionId();
|
||||
|
||||
if (Process.GetProcessesByName(Common.BinaryName).Any(p => (uint)p.SessionId == sid))
|
||||
{
|
||||
Logger.Log("Found MouseWithoutBorders on the active session!");
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.Log("MouseWithoutBorders not found on the active session!");
|
||||
StartMMService(null);
|
||||
}
|
||||
}
|
||||
|
||||
if (!myDesktop.Equals("winlogon", StringComparison.OrdinalIgnoreCase) &&
|
||||
!myDesktop.Equals("default", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
Logger.LogDebug("*** Desktop inactive, exiting: " + myDesktop);
|
||||
Setting.Values.LastX = Common.JUST_GOT_BACK_FROM_SCREEN_SAVER;
|
||||
if (cleanupIfExit)
|
||||
{
|
||||
InitAndCleanup.Cleanup();
|
||||
}
|
||||
|
||||
Process.GetCurrentProcess().KillProcess();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Log(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static Point p;
|
||||
|
||||
internal static bool IsMyDesktopActive()
|
||||
{
|
||||
return NativeMethods.GetCursorPos(ref p);
|
||||
}
|
||||
}
|
||||
@@ -42,7 +42,7 @@ namespace MouseWithoutBorders
|
||||
|
||||
protected string GetSecureKey()
|
||||
{
|
||||
return Common.MyKey;
|
||||
return Encryption.MyKey;
|
||||
}
|
||||
|
||||
private void BackButton_Click(object sender, EventArgs e)
|
||||
|
||||
@@ -89,8 +89,8 @@ namespace MouseWithoutBorders
|
||||
{
|
||||
if (GetSecureKey() != SecurityCodeField.Text)
|
||||
{
|
||||
Common.MyKey = Regex.Replace(SecurityCodeField.Text, @"\s+", string.Empty);
|
||||
SecurityCode = Common.MyKey;
|
||||
Encryption.MyKey = Regex.Replace(SecurityCodeField.Text, @"\s+", string.Empty);
|
||||
SecurityCode = Encryption.MyKey;
|
||||
}
|
||||
|
||||
MachineStuff.MachineMatrix = new string[MachineStuff.MAX_MACHINE] { ComputerNameField.Text.Trim().ToUpper(CultureInfo.CurrentCulture), Common.MachineName.Trim(), string.Empty, string.Empty };
|
||||
|
||||
@@ -135,7 +135,7 @@ namespace MouseWithoutBorders
|
||||
internal void UpdateKeyTextBox()
|
||||
{
|
||||
_ = Helper.GetUserName();
|
||||
textBoxEnc.Text = Common.MyKey;
|
||||
textBoxEnc.Text = Encryption.MyKey;
|
||||
}
|
||||
|
||||
private void InitAll()
|
||||
@@ -505,19 +505,19 @@ namespace MouseWithoutBorders
|
||||
|
||||
private bool UpdateKey(string newKey)
|
||||
{
|
||||
if (!Common.IsKeyValid(newKey, out string rv))
|
||||
if (!Encryption.IsKeyValid(newKey, out string rv))
|
||||
{
|
||||
ShowKeyErrorMsg(rv);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!newKey.Equals(Common.MyKey, StringComparison.OrdinalIgnoreCase))
|
||||
if (!newKey.Equals(Encryption.MyKey, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
Common.MyKey = newKey;
|
||||
Common.GeneratedKey = false;
|
||||
Encryption.MyKey = newKey;
|
||||
Encryption.GeneratedKey = false;
|
||||
}
|
||||
|
||||
Common.MagicNumber = Common.Get24BitHash(Common.MyKey);
|
||||
Encryption.MagicNumber = Encryption.Get24BitHash(Encryption.MyKey);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1116,10 +1116,10 @@ namespace MouseWithoutBorders
|
||||
|
||||
if (MessageBox.Show(message, Application.ProductName, MessageBoxButtons.YesNo, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2) == DialogResult.Yes)
|
||||
{
|
||||
Setting.Values.MyKey = Common.MyKey = Common.CreateRandomKey();
|
||||
textBoxEnc.Text = Common.MyKey;
|
||||
Setting.Values.MyKey = Encryption.MyKey = Encryption.CreateRandomKey();
|
||||
textBoxEnc.Text = Encryption.MyKey;
|
||||
checkBoxShowKey.Checked = true;
|
||||
Common.GeneratedKey = true;
|
||||
Encryption.GeneratedKey = true;
|
||||
ButtonOK_Click(null, null);
|
||||
Common.ShowToolTip("New security key was generated, update other machines to the same key.", 10000, ToolTipIcon.Info, false);
|
||||
}
|
||||
|
||||
@@ -318,7 +318,7 @@ namespace MouseWithoutBorders
|
||||
|
||||
try
|
||||
{
|
||||
if (!Common.IsMyDesktopActive() || Common.CurrentProcess.SessionId != NativeMethods.WTSGetActiveConsoleSessionId())
|
||||
if (!WinAPI.IsMyDesktopActive() || Common.CurrentProcess.SessionId != NativeMethods.WTSGetActiveConsoleSessionId())
|
||||
{
|
||||
myDesktopNotActive = true;
|
||||
|
||||
@@ -348,7 +348,7 @@ namespace MouseWithoutBorders
|
||||
Common.Hook?.ResetLastSwitchKeys();
|
||||
});
|
||||
|
||||
Common.CheckForDesktopSwitchEvent(true);
|
||||
WinAPI.CheckForDesktopSwitchEvent(true);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -369,21 +369,21 @@ namespace MouseWithoutBorders
|
||||
if (myDesktopNotActive)
|
||||
{
|
||||
myDesktopNotActive = false;
|
||||
Common.MyKey = Setting.Values.MyKey;
|
||||
Encryption.MyKey = Setting.Values.MyKey;
|
||||
}
|
||||
|
||||
MachineStuff.UpdateMachinePoolStringSetting();
|
||||
|
||||
if (!Common.RunOnLogonDesktop && !Common.RunOnScrSaverDesktop && (Setting.Values.FirstRun || Common.KeyCorrupted))
|
||||
if (!Common.RunOnLogonDesktop && !Common.RunOnScrSaverDesktop && (Setting.Values.FirstRun || Encryption.KeyCorrupted))
|
||||
{
|
||||
if (!shownSetupFormOneTime)
|
||||
{
|
||||
shownSetupFormOneTime = true;
|
||||
MachineStuff.ShowMachineMatrix();
|
||||
|
||||
if (Common.KeyCorrupted && !Setting.Values.FirstRun)
|
||||
if (Encryption.KeyCorrupted && !Setting.Values.FirstRun)
|
||||
{
|
||||
Common.KeyCorrupted = false;
|
||||
Encryption.KeyCorrupted = false;
|
||||
string msg = "The security key is corrupted for some reason, please re-setup.";
|
||||
MessageBox.Show(msg, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||
}
|
||||
@@ -490,9 +490,9 @@ namespace MouseWithoutBorders
|
||||
|
||||
if (count == 600)
|
||||
{
|
||||
if (!Common.GeneratedKey)
|
||||
if (!Encryption.GeneratedKey)
|
||||
{
|
||||
Common.MyKey = Setting.Values.MyKey;
|
||||
Encryption.MyKey = Setting.Values.MyKey;
|
||||
|
||||
if (!Common.RunOnLogonDesktop && !Common.RunOnScrSaverDesktop)
|
||||
{
|
||||
@@ -505,7 +505,7 @@ namespace MouseWithoutBorders
|
||||
Common.ShowToolTip("The security key must be auto generated in one of the machines.", 10000);
|
||||
}
|
||||
}
|
||||
else if (!Common.KeyCorrupted && !Common.RunOnLogonDesktop && !Common.RunOnScrSaverDesktop && !Setting.Values.FirstRun && Common.AtLeastOneSocketConnected())
|
||||
else if (!Encryption.KeyCorrupted && !Common.RunOnLogonDesktop && !Common.RunOnScrSaverDesktop && !Setting.Values.FirstRun && Common.AtLeastOneSocketConnected())
|
||||
{
|
||||
int myKeyDaysToExpire = Setting.Values.MyKeyDaysToExpire;
|
||||
|
||||
@@ -531,7 +531,7 @@ namespace MouseWithoutBorders
|
||||
#if SHOW_ON_WINLOGON
|
||||
// if (Common.RunOnLogonDesktop) ShowMouseWithoutBordersUiOnWinLogonDesktop(false);
|
||||
#endif
|
||||
Common.CheckForDesktopSwitchEvent(true);
|
||||
WinAPI.CheckForDesktopSwitchEvent(true);
|
||||
MachineStuff.UpdateClientSockets("helperTimer_Tick"); // Sockets may be closed by the remote host when both machines switch desktop at the same time.
|
||||
}
|
||||
|
||||
@@ -582,7 +582,7 @@ namespace MouseWithoutBorders
|
||||
|
||||
int rv = 0;
|
||||
|
||||
if (!Common.RunOnLogonDesktop && !Common.RunOnScrSaverDesktop && Common.IsMyDesktopActive() && (rv = Helper.SendMessageToHelper(0x400, IntPtr.Zero, IntPtr.Zero)) <= 0)
|
||||
if (!Common.RunOnLogonDesktop && !Common.RunOnScrSaverDesktop && WinAPI.IsMyDesktopActive() && (rv = Helper.SendMessageToHelper(0x400, IntPtr.Zero, IntPtr.Zero)) <= 0)
|
||||
{
|
||||
Logger.TelemetryLogTrace($"{Helper.HELPER_FORM_TEXT} not found: {rv}", SeverityLevel.Warning);
|
||||
}
|
||||
|
||||
@@ -46,79 +46,6 @@ avgSendTime = 0
|
||||
maxSendTime = 0
|
||||
totalSendCount = 0
|
||||
totalSendTime = 0
|
||||
magicNumber = 0
|
||||
ran = System.Random
|
||||
--_impl = System.Random+XoshiroImpl
|
||||
----_s0 = ????????????
|
||||
----_s1 = ????????????
|
||||
----_s2 = ????????????
|
||||
----_s3 = ????????????
|
||||
--<Shared>k__BackingField = System.Random+ThreadSafeRandom
|
||||
InitialIV = ????????????
|
||||
<GeneratedKey>k__BackingField = False
|
||||
<KeyCorrupted>k__BackingField = False
|
||||
LegalKeyDictionary = Concurrent.ConcurrentDictionary`2[System.String,System.Byte[]]
|
||||
--_tables = Concurrent.ConcurrentDictionary`2+Tables[System.String,System.Byte[]]
|
||||
----_comparer = Generic.NonRandomizedStringEqualityComparer+OrdinalIgnoreCaseComparer
|
||||
----_buckets = Concurrent.ConcurrentDictionary`2+VolatileNode[System.String,System.Byte[]][]
|
||||
------System.Collections.Concurrent.ConcurrentDictionary`2+VolatileNode[System.String,System.Byte[]][] = Concurrent.ConcurrentDictionary`2+VolatileNode[System.String,System.Byte[]][]: N/A
|
||||
----_fastModBucketsMultiplier = 498560650640798693
|
||||
----_locks = O[]
|
||||
------System.Object[] = O[]: N/A
|
||||
----_countPerLock = 32[]
|
||||
------[0] = 0
|
||||
------[1] = 0
|
||||
------[2] = 0
|
||||
------[3] = 0
|
||||
------[4] = 0
|
||||
------[5] = 0
|
||||
------[6] = 0
|
||||
------[7] = 0
|
||||
--_budget = ????????????
|
||||
--_growLockArray = True
|
||||
--_comparerIsDefaultForClasses = False
|
||||
PackageSent = MouseWithoutBorders.PackageMonitor
|
||||
--Keyboard = 0
|
||||
--Mouse = 0
|
||||
--Heartbeat = 0
|
||||
--ByeBye = 0
|
||||
--Hello = 0
|
||||
--Matrix = 0
|
||||
--ClipboardText = 0
|
||||
--ClipboardImage = 0
|
||||
--Clipboard = 0
|
||||
--ClipboardDragDrop = 0
|
||||
--ClipboardDragDropEnd = 0
|
||||
--ClipboardAsk = 0
|
||||
--ExplorerDragDrop = 0
|
||||
--Nil = 0
|
||||
PackageReceived = MouseWithoutBorders.PackageMonitor
|
||||
--Keyboard = 0
|
||||
--Mouse = 0
|
||||
--Heartbeat = 0
|
||||
--ByeBye = 0
|
||||
--Hello = 0
|
||||
--Matrix = 0
|
||||
--ClipboardText = 0
|
||||
--ClipboardImage = 0
|
||||
--Clipboard = 0
|
||||
--ClipboardDragDrop = 0
|
||||
--ClipboardDragDropEnd = 0
|
||||
--ClipboardAsk = 0
|
||||
--ExplorerDragDrop = 0
|
||||
--Nil = 0
|
||||
PackageID = 0
|
||||
SensitivePoints = Generic.List`1[Point]
|
||||
--_items = Point[]
|
||||
----System.Drawing.Point[] = Point[]: N/A
|
||||
--_size = 0
|
||||
--_version = 0
|
||||
--s_emptyArray = Point[]
|
||||
----System.Drawing.Point[] = Point[]: N/A
|
||||
p = {X=0,Y=0}
|
||||
--x = 0
|
||||
--y = 0
|
||||
--Empty = {X=0,Y=0}
|
||||
<IpcChannelCreated>k__BackingField = False
|
||||
TOGGLE_ICONS_SIZE = 4
|
||||
ICON_ONE = 0
|
||||
@@ -128,34 +55,6 @@ ICON_BIG_CLIPBOARD = 3
|
||||
ICON_ERROR = 4
|
||||
JUST_GOT_BACK_FROM_SCREEN_SAVER = 9999
|
||||
NETWORK_STREAM_BUF_SIZE = 1048576
|
||||
SymAlBlockSize = 16
|
||||
PW_LENGTH = 16
|
||||
PACKAGE_SIZE = 32
|
||||
PACKAGE_SIZE_EX = 64
|
||||
WP_PACKAGE_SIZE = 6
|
||||
KEYEVENTF_KEYDOWN = 1
|
||||
KEYEVENTF_KEYUP = 2
|
||||
WH_MOUSE = 7
|
||||
WH_KEYBOARD = 2
|
||||
WH_MOUSE_LL = 14
|
||||
WH_KEYBOARD_LL = 13
|
||||
WM_MOUSEMOVE = 512
|
||||
WM_LBUTTONDOWN = 513
|
||||
WM_RBUTTONDOWN = 516
|
||||
WM_MBUTTONDOWN = 519
|
||||
WM_XBUTTONDOWN = 523
|
||||
WM_LBUTTONUP = 514
|
||||
WM_RBUTTONUP = 517
|
||||
WM_MBUTTONUP = 520
|
||||
WM_XBUTTONUP = 524
|
||||
WM_LBUTTONDBLCLK = 515
|
||||
WM_RBUTTONDBLCLK = 518
|
||||
WM_MBUTTONDBLCLK = 521
|
||||
WM_MOUSEWHEEL = 522
|
||||
WM_KEYDOWN = 256
|
||||
WM_KEYUP = 257
|
||||
WM_SYSKEYDOWN = 260
|
||||
WM_SYSKEYUP = 261
|
||||
[Clipboard]
|
||||
===============
|
||||
Comma = System.Char[]
|
||||
@@ -193,16 +92,51 @@ dragDropStep05ExCalledByIpc = 0
|
||||
isDropping = False
|
||||
dragMachine = NONE
|
||||
<MouseDown>k__BackingField = False
|
||||
[Encryption]
|
||||
===============
|
||||
magicNumber = 0
|
||||
ran = System.Random
|
||||
--_impl = System.Random+XoshiroImpl
|
||||
----_s0 = ????????????
|
||||
----_s1 = ????????????
|
||||
----_s2 = ????????????
|
||||
----_s3 = ????????????
|
||||
--<Shared>k__BackingField = System.Random+ThreadSafeRandom
|
||||
InitialIV = ????????????
|
||||
<GeneratedKey>k__BackingField = False
|
||||
<KeyCorrupted>k__BackingField = False
|
||||
LegalKeyDictionary = Concurrent.ConcurrentDictionary`2[System.String,System.Byte[]]
|
||||
--_tables = Concurrent.ConcurrentDictionary`2+Tables[System.String,System.Byte[]]
|
||||
----_comparer = Generic.NonRandomizedStringEqualityComparer+OrdinalIgnoreCaseComparer
|
||||
----_buckets = Concurrent.ConcurrentDictionary`2+VolatileNode[System.String,System.Byte[]][]
|
||||
------System.Collections.Concurrent.ConcurrentDictionary`2+VolatileNode[System.String,System.Byte[]][] = Concurrent.ConcurrentDictionary`2+VolatileNode[System.String,System.Byte[]][]: N/A
|
||||
----_fastModBucketsMultiplier = 498560650640798693
|
||||
----_locks = O[]
|
||||
------System.Object[] = O[]: N/A
|
||||
----_countPerLock = 32[]
|
||||
------[0] = 0
|
||||
------[1] = 0
|
||||
------[2] = 0
|
||||
------[3] = 0
|
||||
------[4] = 0
|
||||
------[5] = 0
|
||||
------[6] = 0
|
||||
------[7] = 0
|
||||
--_budget = ????????????
|
||||
--_growLockArray = True
|
||||
--_comparerIsDefaultForClasses = False
|
||||
SymAlBlockSize = 16
|
||||
PW_LENGTH = 16
|
||||
[Event]
|
||||
===============
|
||||
KeybdPackage = MouseWithoutBorders.DATA
|
||||
KeybdPackage = MouseWithoutBorders.Core.DATA
|
||||
--Type = 0
|
||||
--Id = 0
|
||||
--Src = NONE
|
||||
--Des = NONE
|
||||
--DateTime = 0
|
||||
--Kd = MouseWithoutBorders.KEYBDDATA
|
||||
--Md = MouseWithoutBorders.MOUSEDATA
|
||||
--Kd = MouseWithoutBorders.Core.KEYBDDATA
|
||||
--Md = MouseWithoutBorders.Core.MOUSEDATA
|
||||
--Machine1 = NONE
|
||||
--Machine2 = NONE
|
||||
--Machine3 = NONE
|
||||
@@ -212,14 +146,14 @@ KeybdPackage = MouseWithoutBorders.DATA
|
||||
--machineNameP2 = 0
|
||||
--machineNameP3 = 0
|
||||
--machineNameP4 = 0
|
||||
MousePackage = MouseWithoutBorders.DATA
|
||||
MousePackage = MouseWithoutBorders.Core.DATA
|
||||
--Type = 0
|
||||
--Id = 0
|
||||
--Src = NONE
|
||||
--Des = NONE
|
||||
--DateTime = 0
|
||||
--Kd = MouseWithoutBorders.KEYBDDATA
|
||||
--Md = MouseWithoutBorders.MOUSEDATA
|
||||
--Kd = MouseWithoutBorders.Core.KEYBDDATA
|
||||
--Md = MouseWithoutBorders.Core.MOUSEDATA
|
||||
--Machine1 = NONE
|
||||
--Machine2 = NONE
|
||||
--Machine3 = NONE
|
||||
@@ -296,7 +230,7 @@ LogCounter = Concurrent.ConcurrentDictionary`2[System.String,32]
|
||||
allLogsIndex = 0
|
||||
lastHour = 0
|
||||
exceptionCount = 0
|
||||
lastPackageSent = MouseWithoutBorders.PackageMonitor
|
||||
lastPackageSent = MouseWithoutBorders.Core.PackageMonitor
|
||||
--Keyboard = 0
|
||||
--Mouse = 0
|
||||
--Heartbeat = 0
|
||||
@@ -311,7 +245,7 @@ lastPackageSent = MouseWithoutBorders.PackageMonitor
|
||||
--ClipboardAsk = 0
|
||||
--ExplorerDragDrop = 0
|
||||
--Nil = 0
|
||||
lastPackageReceived = MouseWithoutBorders.PackageMonitor
|
||||
lastPackageReceived = MouseWithoutBorders.Core.PackageMonitor
|
||||
--Keyboard = 0
|
||||
--Mouse = 0
|
||||
--Heartbeat = 0
|
||||
@@ -366,6 +300,42 @@ MAX_SOCKET = 8
|
||||
HEARTBEAT_TIMEOUT = 1500000
|
||||
SKIP_PIXELS = 1
|
||||
JUMP_PIXELS = 2
|
||||
[Package]
|
||||
===============
|
||||
PackageSent = MouseWithoutBorders.Core.PackageMonitor
|
||||
--Keyboard = 0
|
||||
--Mouse = 0
|
||||
--Heartbeat = 0
|
||||
--ByeBye = 0
|
||||
--Hello = 0
|
||||
--Matrix = 0
|
||||
--ClipboardText = 0
|
||||
--ClipboardImage = 0
|
||||
--Clipboard = 0
|
||||
--ClipboardDragDrop = 0
|
||||
--ClipboardDragDropEnd = 0
|
||||
--ClipboardAsk = 0
|
||||
--ExplorerDragDrop = 0
|
||||
--Nil = 0
|
||||
PackageReceived = MouseWithoutBorders.Core.PackageMonitor
|
||||
--Keyboard = 0
|
||||
--Mouse = 0
|
||||
--Heartbeat = 0
|
||||
--ByeBye = 0
|
||||
--Hello = 0
|
||||
--Matrix = 0
|
||||
--ClipboardText = 0
|
||||
--ClipboardImage = 0
|
||||
--Clipboard = 0
|
||||
--ClipboardDragDrop = 0
|
||||
--ClipboardDragDropEnd = 0
|
||||
--ClipboardAsk = 0
|
||||
--ExplorerDragDrop = 0
|
||||
--Nil = 0
|
||||
PackageID = 0
|
||||
PACKAGE_SIZE = 32
|
||||
PACKAGE_SIZE_EX = 64
|
||||
WP_PACKAGE_SIZE = 6
|
||||
[Receiver]
|
||||
===============
|
||||
QUEUE_SIZE = 50
|
||||
@@ -436,3 +406,41 @@ lastStartServiceTime = ????????????
|
||||
--MinValue = 01/01/0001 00:00:00
|
||||
--MaxValue = 31/12/9999 23:59:59
|
||||
--UnixEpoch = 01/01/1970 00:00:00
|
||||
[WinAPI]
|
||||
===============
|
||||
SensitivePoints = Generic.List`1[Point]
|
||||
--_items = Point[]
|
||||
----System.Drawing.Point[] = Point[]: N/A
|
||||
--_size = 0
|
||||
--_version = 0
|
||||
--s_emptyArray = Point[]
|
||||
----System.Drawing.Point[] = Point[]: N/A
|
||||
p = {X=0,Y=0}
|
||||
--x = 0
|
||||
--y = 0
|
||||
--Empty = {X=0,Y=0}
|
||||
[WM]
|
||||
===============
|
||||
KEYEVENTF_KEYDOWN = 1
|
||||
KEYEVENTF_KEYUP = 2
|
||||
WH_MOUSE = 7
|
||||
WH_KEYBOARD = 2
|
||||
WH_MOUSE_LL = 14
|
||||
WH_KEYBOARD_LL = 13
|
||||
WM_MOUSEMOVE = 512
|
||||
WM_LBUTTONDOWN = 513
|
||||
WM_RBUTTONDOWN = 516
|
||||
WM_MBUTTONDOWN = 519
|
||||
WM_XBUTTONDOWN = 523
|
||||
WM_LBUTTONUP = 514
|
||||
WM_RBUTTONUP = 517
|
||||
WM_MBUTTONUP = 520
|
||||
WM_XBUTTONUP = 524
|
||||
WM_LBUTTONDBLCLK = 515
|
||||
WM_RBUTTONDBLCLK = 518
|
||||
WM_MBUTTONDBLCLK = 521
|
||||
WM_MOUSEWHEEL = 522
|
||||
WM_KEYDOWN = 256
|
||||
WM_KEYUP = 257
|
||||
WM_SYSKEYDOWN = 260
|
||||
WM_SYSKEYUP = 261
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace PowerOCR.Settings
|
||||
[ImportingConstructor]
|
||||
public UserSettings(Helpers.IThrottledActionInvoker throttledActionInvoker)
|
||||
{
|
||||
_settingsUtils = new SettingsUtils();
|
||||
_settingsUtils = SettingsUtils.Default;
|
||||
ActivationShortcut = new SettingItem<string>(DefaultActivationShortcut);
|
||||
PreferredLanguage = new SettingItem<string>(string.Empty);
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace WorkspacesEditor.Utils
|
||||
public class Settings
|
||||
{
|
||||
private const string WorkspacesModuleName = "Workspaces";
|
||||
private static readonly SettingsUtils _settingsUtils = new();
|
||||
private static readonly SettingsUtils _settingsUtils = SettingsUtils.Default;
|
||||
|
||||
public static WorkspacesSettings ReadSettings()
|
||||
{
|
||||
|
||||
@@ -133,7 +133,7 @@ namespace WorkspacesEditor.ViewModels
|
||||
_orderByIndex = value;
|
||||
OnPropertyChanged(new PropertyChangedEventArgs(nameof(WorkspacesView)));
|
||||
settings.Properties.SortBy = (WorkspacesProperties.SortByProperty)value;
|
||||
settings.Save(new SettingsUtils());
|
||||
settings.Save(SettingsUtils.Default);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ namespace Awake.Core
|
||||
{
|
||||
_tokenSource = new CancellationTokenSource();
|
||||
_stateQueue = [];
|
||||
ModuleSettings = new SettingsUtils();
|
||||
ModuleSettings = SettingsUtils.Default;
|
||||
}
|
||||
|
||||
internal static void StartMonitor()
|
||||
|
||||
@@ -51,7 +51,7 @@ namespace Awake
|
||||
|
||||
private static async Task<int> Main(string[] args)
|
||||
{
|
||||
_settingsUtils = new SettingsUtils();
|
||||
_settingsUtils = SettingsUtils.Default;
|
||||
|
||||
LockMutex = new Mutex(true, Core.Constants.AppName, out bool instantiated);
|
||||
|
||||
|
||||
@@ -11,15 +11,15 @@ public class GalleryGridPropertiesViewModel : IGridPropertiesViewModel
|
||||
{
|
||||
private readonly ExtensionObject<IGalleryGridLayout> _model;
|
||||
|
||||
public bool ShowTitle { get; private set; }
|
||||
|
||||
public bool ShowSubtitle { get; private set; }
|
||||
|
||||
public GalleryGridPropertiesViewModel(IGalleryGridLayout galleryGridLayout)
|
||||
{
|
||||
_model = new(galleryGridLayout);
|
||||
}
|
||||
|
||||
public bool ShowTitle { get; set; }
|
||||
|
||||
public bool ShowSubtitle { get; set; }
|
||||
|
||||
public void InitializeProperties()
|
||||
{
|
||||
var model = _model.Unsafe;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user