1

I am trying to make an app in tray that would switch power plans if user was inactive for 5 minutes. The main problem is that it shows in task bar for every 5 sec (so, when the loop starts). But the problem happens only when I compile this to exe via pyinstaller, in Python compiler this works as it should.

my problem (gif)

pyinstaller command: pyinstaller --noconfirm --onefile --windowed --icon "C:/Users/LEGION/PycharmProjects/game/astlofo4.ico" --name "Astlofo" "C:/Users/LEGION/PycharmProjects/game/helper.py"

code of the problem function is:

def inactive():
    while True:
        output = subprocess.check_output(["powercfg", "-getactivescheme"])
        if (win32api.GetTickCount() - win32api.GetLastInputInfo()) > 300000: #300000
            if not output == b'GUID \xe1\xe5\xa5\xac\xeb \xaf\xa8\xe2\xa0\xad\xa8\xef: 30edd295-bb03-4f04-9ca5-1d6625c371f5  (\x8f\xe0\xae\xe1\xe2\xae\xa9)':
                subprocess.call("powercfg /s 30edd295-bb03-4f04-9ca5-1d6625c371f5")
                print('power saving')
                systray.update(icon='C:/Users/LEGION/PycharmProjects/game/astolfo2inactive.ico')
        else:
            if not output == b'GUID \xe1\xe5\xa5\xac\xeb \xaf\xa8\xe2\xa0\xad\xa8\xef: 04d7a134-5010-4cd2-ac8e-0bd74104d4fa  (\x8d\xa5 \xa8\xa3\xe0\xeb)':
                subprocess.call("powercfg /s 04d7a134-5010-4cd2-ac8e-0bd74104d4fa")
                print('balanced')
                systray.update(icon='C:/Users/LEGION/PycharmProjects/game/astolfo2.ico')
        time.sleep(5)

Full code of the programm:

from infi.systray import SysTrayIcon
from PIL import ImageGrab
from pynput import mouse, keyboard
import psutil, time, keyboard, os, subprocess, win32api, threading
from datetime import datetime, timedelta

only_but = 1
text = 'Zoom'

def onquit(systray):
    for proc in psutil.process_iter():
        if proc.name() == "Астольфік.exe":
            proc.kill()

def open_dir(systray):
    os.startfile('C:/Users/LEGION/Pictures/Zoom')
def only_button(systray):
    global only_but, text
    if only_but == 0:
        only_but = 1  # only Zoom
        text = 'Zoom'
    elif only_but == 1:
        only_but = 2  # const on
        text = 'const on'
    elif only_but == 2:
        only_but = 0  # off
        text = 'off'

    systray.update(hover_text=f"Всього {len(os.listdir('C:/Users/LEGION/Pictures/Zoom/'))} screens| {text}")
    return only_but


# saving screenshot whether the Zoom is on or const on and mouse4 pressed
def on_click(x, y, button, pressed):  # mouse4 is pressed
    global only_but, text
    if pressed and (button == mouse.Button.x1) and (only_but != 0):
        if ((button == mouse.Button.x1) and (("Zoom.exe" in (p.name() for p in psutil.process_iter())
        and (only_but == 1))) or ((button == mouse.Button.x1) and (only_but == 2))):

            timestamp = datetime.now().strftime('%Y-%m-%d %H-%M-%S')
            keyboard.send('alt+SNAPSHOT')
            time.sleep(1)
            try:
                img = ImageGrab.grabclipboard()
                try:
                    img.save(f'C:/Users/LEGION/Pictures/Zoom/{timestamp}.png')
                except:
                    print('ERROR saving')
            except:
                print('ERROR clipboard')

            systray.update(hover_text=f"Всього {len(os.listdir('C:/Users/LEGION/Pictures/Zoom/'))} скриншотів | {text}")


menu = (("Screens dir", 'C:/Users/LEGION/PycharmProjects/game/folder.ico', open_dir),
        ('Switch', None, only_button),
        )
systray = SysTrayIcon("C:/Users/LEGION/PycharmProjects/game/astolfo2.ico",
                      f"{len(os.listdir('C:/Users/LEGION/Pictures/Zoom/'))} Screens| {text}", menu,
                      on_quit=onquit, default_menu_index=2)
systray.start()


def inactive():
    while True:
        output = subprocess.check_output(["powercfg", "-getactivescheme"])
        if (win32api.GetTickCount() - win32api.GetLastInputInfo()) > 300000: #300000
            if not output == b'GUID \xe1\xe5\xa5\xac\xeb \xaf\xa8\xe2\xa0\xad\xa8\xef: 30edd295-bb03-4f04-9ca5-1d6625c371f5  (\x8f\xe0\xae\xe1\xe2\xae\xa9)':
                subprocess.call("powercfg /s 30edd295-bb03-4f04-9ca5-1d6625c371f5")
                print('power saving')
                systray.update(icon='C:/Users/LEGION/PycharmProjects/game/astolfo2dnd.ico')
        else:
            if not output == b'GUID \xe1\xe5\xa5\xac\xeb \xaf\xa8\xe2\xa0\xad\xa8\xef: 04d7a134-5010-4cd2-ac8e-0bd74104d4fa  (\x8d\xa5 \xa8\xa3\xe0\xeb)':
                subprocess.call("powercfg /s 04d7a134-5010-4cd2-ac8e-0bd74104d4fa")
                print('balanced')
                systray.update(icon='C:/Users/LEGION/PycharmProjects/game/astolfo2.ico')
        time.sleep(5)

# Collect events until released
def mouse_listener():
    with mouse.Listener(on_click=on_click) as listener:
        listener.join()

thread1 = threading.Thread(target=inactive)
thread1.start()
thread2 = threading.Thread(target=mouse_listener)
thread2.start()

Hope we can make this work

4
  • If the systray.update call is the cause, you could of course remember the last setting and only call it again when it changes. Commented Oct 4, 2023 at 8:18
  • @MichaelButscher It's not. I removed all the systray.update and nothing changed. Could problem be in subprocess.check_output? Commented Oct 4, 2023 at 8:45
  • You could try to play around with the Windows-specific arguments creationflags and startupinfo of check_output and call. Especially you can try subprocess.DETACHED_PROCESS as value for creationflags Commented Oct 4, 2023 at 9:01
  • @MichaelButscher Thanks! subprocess.DETACHED_PROCESS worked for check_output and for call I've looked into creationflags and found subprocess.CREATE_NO_WINDOW Commented Oct 4, 2023 at 12:55

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.