AceCentre / FaceCommander

Control your computer by making faces
Apache License 2.0
2 stars 1 forks source link

Open on startup #6

Open gavinhenderson opened 4 months ago

gavinhenderson commented 4 months ago

A user should be able to change a setting to get FaceCommander to open on startup. This will allow people who use AAC to have their device automatically setup when they turn it on.

sjjhsjjh commented 3 months ago

Hi, I suppose that's something to add in the Inno specification. Here's a likely looking SO. https://stackoverflow.com/questions/40146434/option-to-make-application-automatically-start-with-windows-when-installing-usin

gavinhenderson commented 3 months ago

As long as that allows it to be user configurable then it sounds good.

I think by default we probably want 'open on start up' disabled but we definitely want users to have the option to enable it.

sjjhsjjh commented 3 months ago

Just noticed this when testing the name change in the installer. image Maybe that means start it every time, or maybe it only means start it at the end of the installation.

sjjhsjjh commented 3 months ago

So, I just ticked the Automatically start ... option in the above and rebooted. FaceCommander was started automatically. Also it was detecting my face movements and I managed to click on a link in the browser by opening my mouth. Anyway I think this issue can be closed.

willwade commented 3 months ago

Yeah - I had "fun" doing that in the inno6 installer. @gavinhenderson were you thinking you could turn this auto startup on/off or is the installer step good-enough UX?

gavinhenderson commented 3 months ago

I think my preference is the user can change a setting inside of FaceCommander to decide if it opens on launch or not.

The person installing the app may not be the person setting up the app or using it. People also tend to 'test' apps like this a lot, so at install time they definitely wont want to open on startup but once they decided it meets their needs they will want to enable it. They probably could go through the installer again but it would be nicer if they can do it directly in the app.

We did it in EyeCommander using this npm package: https://www.npmjs.com/package/auto-launch

There might be something similar in Python?

willwade commented 3 months ago

?

https://stackoverflow.com/a/45617568/1123094

gavinhenderson commented 3 months ago

I would personally prefer a well used library to handle this sort of thing. These sorts of things are riddled with edge cases. Although that may not exist so we might have to roll our own setup

sjjhsjjh commented 3 months ago

That NPM package says how it works too. https://www.npmjs.com/package/auto-launch#windows I'm kind of surprised that an application is allowed to make itself automatically launch.

sjjhsjjh commented 3 months ago

Not sure but for later maybe this looks interesting here. https://docs.python.org/3/library/subprocess.html#windows-popen-helpers

sjjhsjjh commented 2 months ago

SO answer here suggests using the Windows Task Scheduler. https://stackoverflow.com/a/4439204/7657675

There's a Python interface near here. https://github.com/786raees/task-scheduler-python/tree/main And some similar code posted here. https://medium.com/@ajay.bile007/programmatic-way-of-creating-task-in-windows-task-scheduler-8673c5d5b897

Both of those seem to sit on some win32 COM business from the pywin32 project. https://pypi.org/project/pywin32/

It looks like it would be necessary to search the pywin32 repo to find documentation on parameters for example. More later ...

willwade commented 2 months ago

I had this snippet lying around from another project. Any use?

import os
import win32com.client

def create_task(task_name, script_path):
    scheduler = win32com.client.Dispatch('Schedule.Service')
    scheduler.Connect()
    root_folder = scheduler.GetFolder('\\')
    task_def = scheduler.NewTask(0)

    # Set task settings
    task_def.RegistrationInfo.Description = 'Start Python app on startup'
    task_def.Principal.UserId = 'SYSTEM'
    task_def.Principal.LogonType = 3  # Logon interactively

    # Trigger: At logon
    trigger = task_def.Triggers.Create(1)  # 1 is for logon trigger
    trigger.UserId = os.getlogin()

    # Action: Start the Python script
    action = task_def.Actions.Create(0)  # 0 is for action to start a program
    action.Path = 'python'
    action.Arguments = f'"{script_path}"'
    action.WorkingDirectory = os.path.dirname(script_path)

    # Register the task
    root_folder.RegisterTaskDefinition(
        task_name,
        task_def,
        6,  # Replace existing task if present
        None,
        None,
        3,  # Logon interactively
        None
    )
    print(f'Task "{task_name}" created successfully.')

def delete_task(task_name):
    scheduler = win32com.client.Dispatch('Schedule.Service')
    scheduler.Connect()
    root_folder = scheduler.GetFolder('\\')
    root_folder.DeleteTask(task_name, 0)
    print(f'Task "{task_name}" deleted successfully.')

if __name__ == "__main__":
    import sys
    if len(sys.argv) != 3:
        print("Usage: python manage_startup.py <add/remove> <script_path>")
        sys.exit(1)

    action = sys.argv[1]
    script_path = sys.argv[2]
    task_name = "PythonAppStartup"

    if action == "add":
        create_task(task_name, script_path)
    elif action == "remove":
        delete_task(task_name)
    else:
        print("Invalid action. Use 'add' or 'remove'.")
sjjhsjjh commented 2 months ago

Oh yes I'm sure it will be.