2

Hello I can't get an app to self uninstall. After converting a .py script to .exe when I press the button it is supposed to delete/uninstall itself from my computer.

Actually I would like it to uninstall completely from my computer after pressing the button from the .exe how to do it?

Here is the code:

from tkinter import * 
import os 



root = Tk()
root.geometry("300x400")



def func(*args): 
    
    os.remove(__file__)
    root.destroy()




Button1 = Button(root,text="Delete",fg="green",width=10,height=5)
Button1.pack(side=TOP)

Button1.bind('<Button-1>', func)

root.mainloop()

I expect the program to self uninstall after I press the button and I tried the code above that doesn't work (when I convert the .py file to a .exe file the exe file is not deleting itself when I press the button on the .exe file)

EDIT: The code above work with python file .py but not with .exe files ! why ?

Meme410
  • 113
  • 9
  • Interesting question! I'm guessing the exe file cannot be removed due to it being opened? Maybe you could start a daemon thread to remove it? – Mandera Oct 28 '22 at 01:27
  • root.destroy() isn't suppose the instantly 'destroy' the root ? So it's closed ? I'll try it with a daemon thread anyway – Meme410 Oct 28 '22 at 01:59
  • 1
    Build a proper installer and uninstaller - it will deal with all the exceptions you'd have to deal with otherwise. (needing admin rights, installing in alternate locations, removing additional settings, etc.) There are many (free and paid) solutions out there, some examples include InnoSetup, Wix, InstallShield, vdproj, NSIS, Squirrel, etc. - some require some coding or scripting, but many just allow you to click together an installer with minimal effort using a wizard, once you have the working .exe – Grismar Oct 28 '22 at 01:59
  • Related: [Cannot use `__file__` in exe](https://stackoverflow.com/questions/50959340/pyinstaller-exes-file-refers-to-a-py-file) and [script removing itself](https://stackoverflow.com/questions/10112601/how-to-make-scripts-auto-delete-at-the-end-of-execution). I tried both daemon thread and `atexit` approach but neither worked. @Grismar's idea sounds good – Mandera Oct 28 '22 at 02:08

1 Answers1

2

After a lot of searching, I found a solution using this answer!

The trick is to start a separate external process that deletes the file after a delay

from tkinter import Tk, Button, TOP
import subprocess
import sys

def func(*args):
    root.destroy()
    subprocess.Popen(f"cmd /c ping localhost -n 3 > nul & del {sys.executable}")

root = Tk()
root.geometry("300x400")

Button1 = Button(root,text="Delete",fg="green",width=10,height=5)
Button1.pack(side=TOP)
Button1.bind('<Button-1>', func)
root.mainloop()

This answer explains why you should use sys.executable instead of __file__ inside the exe

I tried these approaches without success

  • Registering the removal of the file with atexit
  • Starting a daemon thread to remove the file after a delay with threading
  • Starting a daemon process to remove the file after a delay with multiprocessing
  • Running os.chmod to change permissions
  • Running as administrator

Tested with pyinstaller --onefile randomtesting.py (pip install pyinstaller)

Mandera
  • 2,647
  • 3
  • 21
  • 26
  • 1
    Thanks a lot, I also tested the daemon thread thing it doesn't worked aswell but this solution works fine thanks ! – Meme410 Oct 29 '22 at 06:00