I'm using ctypes.windll.shell32.ShellExecuteW
in order to run a script with administrator privileges. I do NOT want to use win32api
because that is a package that requires installation, where ctypes
does not. I've realized that using the following script (simplified), if the script is run in a directory with a space in it (e.g. "C:\Users\User\Documents\My Folder"), even if the UAC request is granted, the script does not gain administrator privileges. As long as the script is not executed in a directory with a space in the name, it works fine.
The script:
# Name of script is TryAdmin.py
import ctypes, sys, os
def is_admin():
try:
return ctypes.windll.shell32.IsUserAnAdmin()
except:
return False
if is_admin():
print("I'm an Admin!")
input()
else:
b=ctypes.windll.shell32.ShellExecuteW(None,'runas',sys.executable,os.getcwd()+'\\TryAdmin.py',None,1)
if b==5: # The user denied UAC Elevation
# Explain to user that the program needs the elevation
print("""Why would you click "No"? I need you to click yes so that I can
have administrator privileges so that I can execute properly. Without admin
privileges, I don't work at all! Please try again.""")
input()
while b==5: # Request UAC elevation until user grants it
b=ctypes.windll.shell32.ShellExecuteW(None,'runas',sys.executable,os.getcwd()+'\\TryAdmin.py',None,1)
if b!=5:
sys.exit()
# else
print('Try again!')
input()
else:
sys.exit()
This question ShellExecute: Verb "runas" does not work for batch files with spaces in path is similar but in C++.
It has a nice explanation of the possible reason for your issue, related to quoting issues.
If you quote the arguments (or at least the second one) you should fix the issue.
b=ctypes.windll.shell32.ShellExecuteW(
None, 'runas',
'"' + sys.executable + '"',
'"' + os.getcwd() + '\\TryAdmin.py' + '"',
None, 1)