[installer] Auto-start PowerToys as logged-in user from installer run… (#27793)

* [installer] Auto-start PowerToys as logged-in user from installer running as SYSTEM

* spellcheck

* Address feedback

* spellcheck
This commit is contained in:
Stefan Markovic 2023-08-04 09:59:33 +02:00 committed by GitHub
parent d4213c3e30
commit adbc273bcf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 176 additions and 189 deletions

View File

@ -1,28 +1,15 @@
aaaa
AAAAEF
AAB
AABAD
AACB
AACD
AAD
AADF
abap
abcdefghjkmnpqrstuvxyz
ABE
abgr
abi
ABlocked
ABOUTBOX
Abug
ACA
accctrl
Acceleratorkeys
ACCEPTFILES
ACCESSDENIED
accessibilityinsights
ACDB
ACFC
ACFF
Acl
aclapi
AClient
@ -40,18 +27,7 @@ adml
admx
advapi
advfirewall
AEAA
AEAD
AECC
AED
AEE
AEEB
AFAE
AFAEFC
AFDA
AFE
AFeature
AFFE
AFFINETRANSFORM
AFX
AGGREGATABLE
@ -77,7 +53,6 @@ ansicolor
ANull
AOC
aocfnapldcnfbofgmbbllojgocaelgdd
AOT
APARTMENTTHREADED
APeriod
apidl
@ -143,36 +118,13 @@ AValid
awakeness
AWAYMODE
AYUV
azcli
azman
azor
backtracer
BAF
bak
BBE
bbwe
BCA
BCB
BCCE
BCCEA
bck
BDB
BDBAD
BDCC
BDDF
BDFB
BEAA
BEB
BEEAADF
BEEC
BEFA
betadele
betsegaw
BFC
BFDE
BFEB
BFF
BFFA
BGR
bgra
bhid
@ -227,48 +179,28 @@ BValue
byapp
BYPOSITION
bytearray
CABD
CALG
callbackptr
calpwstr
cameligo
Cangjie
CANRENAME
CAPTUREBLT
CAPTURECHANGED
CAtl
CBA
CBB
CBF
CCCCDE
cch
CCHDEVICENAME
CCHFORMNAME
CCom
CContext
CDAC
CDBF
CDCE
CDD
CDE
cdecl
CDeclaration
CDEF
cdpx
CEAF
CEBAC
CEBD
CECB
CElems
CENTERALIGN
ceq
certlm
certmgr
CFAADB
CFBBF
CFEE
CFFEE
CFFF
cguid
CHANGECBCHAIN
changecursor
@ -346,7 +278,6 @@ comsupp
comsuppw
comsuppwd
comutil
concrt
CONFIGW
CONFLICTINGMODIFIERKEY
CONFLICTINGMODIFIERSHORTCUT
@ -414,10 +345,8 @@ CYSCREEN
CYSMICON
CYVIRTUALSCREEN
cziplib
DAA
Dac
dacl
DAF
damienleroy
DARKPURPLE
DARKTEAL
@ -429,30 +358,18 @@ dataversion
DATAW
davidegiacometti
Dayof
DBAE
DBB
DBBDA
DBDE
Dbg
Dbghelp
DBLCLKS
DBLEPSILON
DCAB
DCapture
DCBA
DCBC
DCCB
DCEFCB
DCF
DCOM
dcommon
dcomp
dcompi
DComposition
dcr
dcs
DDCDD
DDCE
DDEIf
DDevice
ddf
@ -463,7 +380,6 @@ debugbreak
DECLAR
declspec
decryptor
DED
Dedup
DEFAULTBOOTSTRAPPERINSTALLFOLDER
DEFAULTCOLOR
@ -485,7 +401,6 @@ DENORMAL
Deondre
depersist
deprioritized
depsfileslistspath
deref
DESKTOPABSOLUTEEDITING
DESKTOPABSOLUTEPARSING
@ -500,9 +415,6 @@ DEVMODEW
DEVMON
devpkey
DEVSOURCE
DFAB
DFB
DFBEA
DIIRFLAG
dimm
directshow
@ -549,13 +461,11 @@ dvr
DVSD
DVSL
DVTARGETDEVICE
DWINRT
dwl
dwm
dwmapi
DWMCOLORIZATIONCOLORCHANGED
DWMCOMPOSITIONCHANGED
dwmcorei
DWMNCRENDERINGCHANGED
Dwmp
DWMSENDICONICLIVEPREVIEWBITMAP
@ -571,41 +481,13 @@ dxgi
dxgidebug
dxgiformat
dxguid
EAAFE
EABF
EAC
EADC
EAF
EBCF
EBD
EBE
ecl
ecount
EData
EDB
EDCCC
EDFAE
Edid
edis
EDITKEYBOARD
editkeyboardwindow
EDITSHORTCUTS
editshortcutswindow
edshift
EEA
EEB
EEBBE
EEBD
EED
EEDA
EEEE
EEF
EEFA
EFB
EFC
EFDD
EFE
EFFEFC
EFile
eip
ekus
@ -634,7 +516,6 @@ ERRORTITLE
ESettings
esize
esrp
estructuredtext
etl
etstat
etw
@ -672,45 +553,14 @@ EXTENDEDKEY
EXTENDEDVERBS
EXTRINSICPROPERTIES
eyetracker
FABC
FAEDDA
FAF
FAFD
fancymouse
fancyzone
FANCYZONESDRAWLAYOUTTEST
FANCYZONESEDITOR
Farbraum
FARPROC
FBB
FBC
FBDE
FBF
FCAE
FCB
FCCFF
FCD
FCDB
FCDD
FCE
FDB
FDBF
FDC
FDCD
FDE
FDEF
FDF
fdw
FECF
FEDF
FEEF
feimage
FFB
FFBCF
FFBE
FFDDD
FFEB
FFEBEF
fff
fileapi
FILEEXPLORER
@ -787,14 +637,12 @@ GPOCA
gpp
GPT
gpu
graphql
GSM
gtm
gui
guiddata
guiddef
guidgenerator
GUIDv
GUITHREADINFO
GValue
gwl
@ -1022,7 +870,6 @@ JPN
jpnime
Jsons
jsonval
julia
junja
jxr
jyuwono
@ -1047,11 +894,9 @@ keynum
keyremaps
Keytool
keyup
Kfiles
KILLFOCUS
killrunner
Knownfolders
kotlin
KSPROPERTY
Kybd
LAlt
@ -1083,7 +928,6 @@ LError
Lessthan
LEVELID
LExit
lexon
lhs
lhwnd
LIBID
@ -1283,7 +1127,6 @@ msc
msclr
mscorlib
msdata
msdax
msedge
MSGFLT
MSIFASTINSTALL
@ -1300,7 +1143,6 @@ msrc
msstore
mst
msvc
msvcp
MTND
Mul
MULTIPLEUSE
@ -1310,7 +1152,6 @@ mwb
MWBEx
myfile
MYICON
mysql
NAMECHANGE
nameof
namespaceanddescendants
@ -1360,7 +1201,6 @@ NIF
nint
NLD
NLog
nls
NLSTEXT
NNN
NOACTIVATE
@ -1490,7 +1330,6 @@ PARENTRELATIVEPARSING
PArgb
parray
PARTIALCONFIRMATIONDIALOGTITLE
pascaligo
pasteplain
PATCOPY
pathcch
@ -1532,7 +1371,6 @@ pfn
pfo
pft
pgp
pgsql
pguid
PHANDLE
phbm
@ -1560,12 +1398,10 @@ Pnp
Popups
POPUPWINDOW
posix
postiats
poweraccent
powerlauncher
POWEROCR
powerpreview
powerquery
powerrename
POWERRENAMECONTEXTMENU
powerrenameinput
@ -1607,9 +1443,9 @@ printmanagement
prm
proactively
PROCESSKEY
processthreadsapi
PRODEXT
PRODUCTVERSION
productwxspath
Progman
programdata
PROGRAMFILES
@ -1686,7 +1522,6 @@ RECTL
rectp
rects
redirectedfrom
redis
Redist
redistributable
reencode
@ -1719,7 +1554,6 @@ REMAPSUCCESSFUL
REMAPUNSUCCESSFUL
Remotable
remoteip
Removedir
Removelnk
renamable
RENAMEONCOLLISION
@ -1786,7 +1620,6 @@ rungameid
RUNLEVEL
runsettings
runtimeclass
runtimedepsjsonpath
runtimeobject
runtimepack
runtimes
@ -1894,6 +1727,7 @@ SHOWNOACTIVATE
SHOWNORMAL
SHOWWINDOW
shtypes
sia
SIATTRIBFLAGS
SICHINT
sid
@ -2028,7 +1862,6 @@ SYSMENU
SYSTEMAPPS
systemroot
SYSTEMTIME
systemverilog
sysvol
Tadele
talynone
@ -2048,7 +1881,6 @@ taskkill
tasklist
taskschd
tchar
tcl
Tcollab
tcp
tcs
@ -2071,7 +1903,6 @@ textblock
TEXTEXTRACTOR
TEXTINCLUDE
tgz
themeresources
THH
THICKFRAME
THISCOMPONENT
@ -2122,9 +1953,7 @@ TYPESHORTCUT
UAC
UAL
uap
uby
udit
Udk
Udp
uefi
UHash
@ -2169,6 +1998,7 @@ USEDEFAULT
USEFILEATTRIBUTES
USERDATA
USERDOMAIN
Userenv
userprofile
USESHOWWINDOW
USESTDHANDLES
@ -2186,16 +2016,12 @@ valuegenerator
Vanara
variantassignment
vcamp
vccorlib
vcdl
vcgtq
VCINSTALLDIR
vcm
vcomp
Vcpkg
vcproj
VCRT
vcruntime
vcvars
VDesktop
vdi
@ -2308,7 +2134,7 @@ WINL
winlogon
winmd
winmm
WINNT
winnt
winres
winrt
winsdk
@ -2353,7 +2179,6 @@ workspaces
wox
wparam
wpf
wpfdepsjsonpath
wpftmp
wpr
wprp
@ -2380,7 +2205,6 @@ WTS
wtsapi
WTSAT
Wubi
wuceffectsi
WVC
Wwan
Wwanpp
@ -2392,7 +2216,6 @@ XBUTTON
XBUTTONDBLCLK
XBUTTONDOWN
XBUTTONUP
xcopy
XDocument
XDOWN
XElement
@ -2417,7 +2240,6 @@ yinwang
yinyue
YOffset
YPels
ypescript
YResolution
YStr
YUY

View File

@ -133,6 +133,7 @@
<InstallExecuteSequence>
<Custom Action="DetectPrevInstallPath" After="AppSearch" />
<Custom Action="SetRegisterPowerToysSchTaskParam" Before="RegisterPowerToysSchTask" />
<Custom Action="SetLaunchPowerToysParam" Before="LaunchPowerToys" />
<Custom Action="SetApplyModulesRegistryChangeSetsParam" Before="ApplyModulesRegistryChangeSets" />
<Custom Action="SetUnApplyModulesRegistryChangeSetsParam" Before="UnApplyModulesRegistryChangeSets" />
<Custom Action="RegisterPowerToysSchTask" After="InstallFiles">
@ -171,17 +172,22 @@
</Custom>-->
<Custom Action="TerminateProcesses" Before="InstallValidate" />
<Custom Action="LaunchPowerToys" After="InstallFinalize">NOT Installed</Custom>
<Custom Action="LaunchPowerToys" Before="InstallFinalize">NOT Installed</Custom>
</InstallExecuteSequence>
<CustomAction Id="SetLaunchPowerToysParam"
Property="LaunchPowerToys"
Value="[INSTALLFOLDER]" />
<CustomAction
Id="LaunchPowerToys"
Execute="immediate"
Return="ignore"
Impersonate="yes"
Return="asyncNoWait"
FileKey="PowerToys.exe"
ExeCommand="--dont-elevate" />
Execute="deferred"
BinaryKey="PTCustomActions"
DllEntry="LaunchPowerToysCA"
/>
<CustomAction
Id="TerminateProcesses"

View File

@ -2,7 +2,6 @@
#include "resource.h"
#include "RcResource.h"
#include <ProjectTelemetry.h>
#include <spdlog/sinks/base_sink.h>
#include "../../src/common/logger/logger.h"
@ -16,6 +15,11 @@
#include <winrt/Windows.Foundation.h>
#include <winrt/Windows.Management.Deployment.h>
#include <wtsapi32.h>
#include <processthreadsapi.h>
#include <UserEnv.h>
#include <winnt.h>
using namespace std;
HINSTANCE DLL_HANDLE = nullptr;
@ -50,6 +54,160 @@ LExit:
return hr;
}
BOOL IsLocalSystem()
{
HANDLE hToken;
UCHAR bTokenUser[sizeof(TOKEN_USER) + 8 + 4 * SID_MAX_SUB_AUTHORITIES];
PTOKEN_USER pTokenUser = (PTOKEN_USER)bTokenUser;
ULONG cbTokenUser;
SID_IDENTIFIER_AUTHORITY siaNT = SECURITY_NT_AUTHORITY;
PSID pSystemSid;
BOOL bSystem;
// open process token
if (!OpenProcessToken(GetCurrentProcess(),
TOKEN_QUERY,
&hToken))
return FALSE;
// retrieve user SID
if (!GetTokenInformation(hToken, TokenUser, pTokenUser,
sizeof(bTokenUser), &cbTokenUser))
{
CloseHandle(hToken);
return FALSE;
}
CloseHandle(hToken);
// allocate LocalSystem well-known SID
if (!AllocateAndInitializeSid(&siaNT, 1, SECURITY_LOCAL_SYSTEM_RID,
0, 0, 0, 0, 0, 0, 0, &pSystemSid))
return FALSE;
// compare the user SID from the token with the LocalSystem SID
bSystem = EqualSid(pTokenUser->User.Sid, pSystemSid);
FreeSid(pSystemSid);
return bSystem;
}
UINT __stdcall LaunchPowerToysCA(MSIHANDLE hInstall)
{
HRESULT hr = S_OK;
UINT er = ERROR_SUCCESS;
std::wstring installationFolder, path, args;
std::wstring commandLine;
hr = WcaInitialize(hInstall, "LaunchPowerToys");
ExitOnFailure(hr, "Failed to initialize");
hr = getInstallFolder(hInstall, installationFolder);
ExitOnFailure(hr, "Failed to get installFolder.");
path = installationFolder;
path += L"\\PowerToys.exe";
args = L"--dont-elevate";
commandLine = L"\"" + path + L"\" ";
commandLine += args;
BOOL isSystemUser = IsLocalSystem();
if (isSystemUser) {
HANDLE hUserToken = NULL;
DWORD dwSessionId;
ProcessIdToSessionId(GetCurrentProcessId(), &dwSessionId);
auto rv = WTSQueryUserToken(dwSessionId, &hUserToken);
if (rv == 0)
{
ExitOnFailure(hr, "Failed to query user token");
}
HANDLE hUserTokenDup;
if (DuplicateTokenEx(hUserToken, TOKEN_ALL_ACCESS, NULL, SECURITY_IMPERSONATION_LEVEL::SecurityImpersonation, TOKEN_TYPE::TokenPrimary, &hUserTokenDup) == 0)
{
CloseHandle(hUserToken);
CloseHandle(hUserTokenDup);
ExitOnFailure(hr, "Failed to duplicate user token");
}
if (ImpersonateLoggedOnUser(hUserTokenDup))
{
STARTUPINFO startupInfo{ .cb = sizeof(STARTUPINFO), .wShowWindow = SW_SHOWNORMAL };
PROCESS_INFORMATION processInformation;
PVOID lpEnvironment = NULL;
CreateEnvironmentBlock(&lpEnvironment, hUserTokenDup, FALSE);
CreateProcessAsUser(
hUserTokenDup,
NULL,
commandLine.data(),
NULL,
NULL,
FALSE,
CREATE_DEFAULT_ERROR_MODE | CREATE_UNICODE_ENVIRONMENT,
lpEnvironment,
NULL,
&startupInfo,
&processInformation);
if (!CloseHandle(processInformation.hProcess))
{
er = ERROR_INSTALL_FAILURE;
}
if (!CloseHandle(processInformation.hThread))
{
er = ERROR_INSTALL_FAILURE;
}
RevertToSelf();
CloseHandle(hUserToken);
CloseHandle(hUserTokenDup);
}
else
{
ExitOnFailure(hr, "Failed to duplicate user token");
}
}
else
{
STARTUPINFO startupInfo{ .cb = sizeof(STARTUPINFO), .wShowWindow = SW_SHOWNORMAL };
PROCESS_INFORMATION processInformation;
// Start the resizer
CreateProcess(
NULL,
commandLine.data(),
NULL,
NULL,
TRUE,
0,
NULL,
NULL,
&startupInfo,
&processInformation);
if (!CloseHandle(processInformation.hProcess))
{
ExitOnFailure(hr, "Failed to close process handle");
}
if (!CloseHandle(processInformation.hThread))
{
ExitOnFailure(hr, "Failed to close thread handle");
}
}
LExit:
er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
return WcaFinalize(er);
}
UINT __stdcall CheckGPOCA(MSIHANDLE hInstall)
{
HRESULT hr = S_OK;

View File

@ -1,6 +1,7 @@
LIBRARY "PowerToysSetupCustomActions"
EXPORTS
LaunchPowerToysCA
CheckGPOCA
ApplyModulesRegistryChangeSetsCA
CreateScheduledTaskCA

View File

@ -88,7 +88,7 @@
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<AdditionalDependencies>WindowsApp.lib;Newdev.lib;Crypt32.lib;msi.lib;wcautil.lib;Psapi.lib;Pathcch.lib;comsupp.lib;taskschd.lib;Secur32.lib;msi.lib;dutil.lib;wcautil.lib;Version.lib;Shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>Userenv.lib;Wtsapi32.lib;WindowsApp.lib;Newdev.lib;Crypt32.lib;msi.lib;wcautil.lib;Psapi.lib;Pathcch.lib;comsupp.lib;taskschd.lib;Secur32.lib;msi.lib;dutil.lib;wcautil.lib;Version.lib;Shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<ModuleDefinitionFile>CustomAction.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>