In order to request UAC elevated privilege from Python, when calling an external program, you can just do
ctypes.windll.shell32.ShellExecuteW(None, "runas", my_binary_file_path, "", None, 1)
Yet, assuming your Python script is executing with admin rights, how can you call an external program without admin rigths?
One approach, which I prefer, is to run as the shell user. Start by opening the shell process and duplicating its Token. You can get the shell process PID by calling
GetShellWindowand thenGetWindowThreadProcessId. Usually this is Explorer.By default, an administrator account doesn't have SeAssignPrimaryTokenPrivilege, in which case you can't call
CreateProcessAsUserdirectly. You have to request a more privileged process to make the call on your behalf.CreateProcessWithTokenWdoes this for you by making a remote procedure call to the Secondary Logon service.PyWin32 doesn't wrap
GetShellWindowandCreateProcessWithTokenW, so you'll need to use ctypes to call them.Rarely a Windows system may be running without a regular shell, or with a shell the fails to register its window via
SetShellWindow[Ex]. In this case,GetShellWindowreturnsNULL. As a fallback for this case, you can use a somewhat questionable (but working) method to get the session user's token and callCreateProcessAsUser.Begin by getting the PID of the session's Windows subsystem process, csrss.exe. The easiest way is to call the undocumented (but stable) function
CsrGetProcessId. Enable SeDebugPrivilege to open this process with limited-query access. Then open its Token, duplicate it, and impersonate. Now you have the required SeTcbPrivilege to get the session user's Token viaWTSQueryUserToken, and you also have SeAssignPrimaryTokenPrivilege to be able to callCreateProcessAsUser.imports and ctypes definitions
helper functions
main functions