I'm teaching myself Python.
I wrote this code for work to help me troubleshoot end users PCs. It opens a GUI with a selection of buttons. It's written in python using pyinstaller to convert it to an executable. It's super slow - taking 10-15+ seconds to run on a PC. Why is it so slow and how can I improve it overall?
The command I user for pyinstaller is pyinstaller -F -w <scriptname.py>
As an aside, the program opens an elevated command prompt by default. How do I make that an option?
from tkinter import *
import os, ctypes, sys
root=Tk()
root.title('Common Fixes')
root.geometry("250x500")
def mapSharedDrives():
os.system('cmd /c " map_drives.bat')
def is_admin():
try:
return ctypes.windll.shell32.IsUserAnAdmin()
except:
return False
if is_admin():
button=[]
os.system('cmd /c "color a"')
def showSystemInfo():
os.system('cmd /c "systeminfo | find /i "Host Name" & systeminfo | find /i "boot time" & pause"')
def restartPC ():
os.system('cmd /c "shutdown /r"')
def deleteWindowsCredentials():
os.system('cmd /c "del %TEMP%\List.txt /s /f /q & del %TEMP%\tokensonly.txt /s /f /q"')
def updateGroupPolicy():
os.system('cmd /c "del %windir%\system32\GroupPolicy\ /s /f /q & gpupdate /force"')
def sfcScanNow():
os.system('cmd /c "sfc /scannow & pause"')
def restartPrintSpooler():
os.system('cmd /c "net stop spooler & net start spooler"')
def DISM():
os.system('cmd /c "DISM /Online /Cleanup-Image /RestoreHealth & pause"')
def addSwitchUser():
os.system('cmd /c "reg add HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System /v HideFastUserSwitching /t REG_DWORD /d 0 /f"')
def increaseOutlookMessageSize():
os.system('cmd /c "reg add HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office16円.0\Outlook\PST /v MaxLargeFileSize /t REG_DWORD /d 204800 /f & reg add HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office16円.0\Outlook\PST /v WarnLargeFileSize /t REG_DWORD /d 184320 /f"')
def increaseOutlookAttachmentSize():
os.system('cmd /c "reg add HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office\Outlook /v MaximumAttachmentSize /t REG_DWORD /d 81920 /f"')
def deleteOutlookFiles():
os.system('cmd /c "del %USERPROFILE%\AppData\Roaming\Microsoft\Outlook /s /f /q & del %USERPROFILE%\AppData\Local\Microsoft\Outlook /s /f /q & rmdir %USERPROFILE%\appdata\local\Microsoft\Outlook /s /q & reg delete HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office16円.0\Outlook\Profiles /f & reg delete HKEY_CURRENT_USER\Software\Policies\Microsoft\office\14.0\outlook /f & reg delete HKEY_CURRENT_USER\Software\Microsoft\Office\15.0\Outlook /f & reg delete HKEY_CURRENT_USER\Software\Microsoft\Office\12.0\Outlook /f & reg delete HKEY_CURRENT_USER\Software\Microsoft\Office\11.0\Outlook /f & reg delete HKEY_CURRENT_USER\Software\Microsoft\Office\10.0\Outlook /f & pause"')
buttons = {
"PC Info &\nLast Restarted": showSystemInfo,
"Restart the PC": restartPC,
"Delete Windows\nCredentials": deleteWindowsCredentials,
"Update Group Policy": updateGroupPolicy,
"SFC /Scannow": sfcScanNow,
"Restart Print Spooler": restartPrintSpooler,
"DISM": DISM,
"Add Switch User": addSwitchUser,
"Increase Outlook\nMessage Size": increaseOutlookMessageSize,
"Increase Outlook\nAttachment Size": increaseOutlookAttachmentSize,
"Delete Outlook Files": deleteOutlookFiles,
}
for title, func in buttons.items():
b = Button(height=2, width=15, text=title, command=func)
b.pack()
else:
# Re-run the program with admin rights
ctypes.windll.shell32.ShellExecuteW(None, "runas", sys.executable, " ".join(sys.argv), None, 1)
buttons = {
"Map a Network Drive": mapSharedDrives,
"Admin Scripts":is_admin
}
for title, func in buttons.items():
b = Button(height=2, width=15, text=title, command=func)
b.pack()
root.mainloop()
-
2\$\begingroup\$ Welcome to code review! Asking how to improve the code is fine, however asking "...How do I make that an option?" is a feature request, which is not on-topic for this site. \$\endgroup\$Sᴀᴍ Onᴇᴌᴀ– Sᴀᴍ Onᴇᴌᴀ ♦2022年01月26日 23:06:11 +00:00Commented Jan 26, 2022 at 23:06
1 Answer 1
mapSharedDrives
should be map_shared_drives
by PEP8.
Never bare except:
. For is_admin
, if you know that a specific exception indicates the user is not an admin, catch only that exception.
Move your global code starting with if is_admin():
into functions.
Don't os.system('cmd /c x')
; instead call into one of the subprocess
methods passing x
, ideally with shell=False
. Some of your commands shouldn't be external calls at all, such as del
which should use pathlib.Path.unlink()
, or winreg
module instead of the reg
calls.
An example of invoking subprocess
:
from os import environ
from pathlib import Path
from subprocess import check_output
systeminfo = Path(environ['WINDIR']) / 'system32/systeminfo.exe'
output = check_output((systeminfo,), encoding='utf-8', shell=False)
lines = output.splitlines()
hostname, = (line for line in lines if line.startswith('Host Name'))
boot_time, = (line for line in lines if line.startswith('System Boot Time'))
print(hostname)
print(boot_time)
Even this is a poor example, because hostname
has a Python built-in.
-
\$\begingroup\$ Thanks for your input. I'm not sure what mean when you say, "Don't os.system('cmd /c x'); instead call into one of the subprocess methods passing x, ideally with shell=False" , can give me an example? What subprocess method do you recommend? \$\endgroup\$user18013413– user180134132022年01月27日 00:14:23 +00:00Commented Jan 27, 2022 at 0:14
-
\$\begingroup\$ Example added; not all subprocess calls will look alike \$\endgroup\$Reinderien– Reinderien2022年01月27日 00:57:38 +00:00Commented Jan 27, 2022 at 0:57
Explore related questions
See similar questions with these tags.