1

I've set up my tkinter app, built with pyinstaller, to display a splash screen on startup. Due to the intended use scenario of this app I have also set it up to permit only one app instance at a time. Before I instantiate my tkinter Root class, I run my instance_check function:

def instance_check() -> bool:
    """
    Only permit one application instance at a time. if the app is already
    running, restore and focus the existing window.
    """
    user32 = ctypes.WinDLL('user32')
    if hwnd := user32.FindWindowW(None, APP_NAME):  # if a matching app window exists...
        if not user32.IsZoomed(hwnd):  # if the window isn't maximized...
            user32.ShowWindow(hwnd, 1)  # activate/restore the window
        user32.SetForegroundWindow(hwnd)  # focus the window
        sys.exit()  # bail - don't expect a return value
    return True  # otherwise: only one app instance found

e.g.:

if __name__ == '__main__':
    if instance_check():
        root = Root()
        root.mainloop()

When starting the 1st app instance, everything works as expected - the app starts after the splash screen. Howevew, the splash screen is shown regardless of the return value of instance_check. When starting another app instance after the 1st, the splash screen appears and then the existing window is focused (as intended).

I gather that this is because the splash screen is bundled into my pyinstaller build spec when I create my executable, so I'm wondering if there's any way to skip it if instance_check fails. I fully expect the answer to be "No", but I figured it was worth asking. Any help is appreciated.

Additional, possibly irrelevant info: The app is built in Python 3.11 on Windows 10 and will only ever be run on Windows machines

JRiggles
  • 4,847
  • 1
  • 12
  • 27
  • Why didn't you built your own splash screen? You would have control over it then. A wild guess is that your splash is in the `windows.ini` file, which is called before your python script. So I guess, no is the answer. – Thingamabobs Nov 15 '22 at 16:57
  • @Thingamabobs because pyinstaller has splash screen support out of the box and building my own splash screen from scratch seemed unnecessary. Would this `windows.ini` file end up in the temp `_MEI####` folder created by pyinstaller at runtime? – JRiggles Nov 15 '22 at 17:00
  • I'm not familiar with the process, so I can't help you out here. – Thingamabobs Nov 15 '22 at 17:03
  • FYI, in case anyone else stumbles across this: alas, there is *not* a `windows.ini` file in the `_MEI` dir – JRiggles Nov 15 '22 at 17:10
  • I suppose you have checked out [this thread](https://stackoverflow.com/questions/68863050/pyinstaller-loading-splash-screen) ? – mnikley Nov 16 '22 at 17:45
  • @mnikley I have, I'm afraid it's relevant to the issue however. I'm having no trouble displaying my splash screen or closing it when it's done. Rather, I'm trying to *prevent* the splash screen under certain conditions. Thanks though. – JRiggles Nov 16 '22 at 18:00
  • You should consider to use a mutex instead, I guess this way it will work. – Thingamabobs Nov 16 '22 at 18:54
  • @Thingamabobs Could you elaborate on that a bit? – JRiggles Nov 16 '22 at 18:56
  • since your program looks like windows specific anyway, why not try to prevent the program from running on the os level ? But I just remembered that this still will not close the entry point, you could just delegate in a different direction. However, it would still be an improvement to your code. – Thingamabobs Nov 16 '22 at 19:04

0 Answers0