26

I have created a script that moves files from one folder to another. But since the original folder is the Downloads folder I need it to always run in the background.

I also have a standard Batch file that looks something like this:

@py C:\\Python\Scripts\moveDLs.py %*

I'm using Windows 10. I have found info for Linux and OS on how to use nohup in the batch file. Is there a Windows version?

If there is do you need to execute the script every time you restart or switch the PC on?

Also, how do you terminate the process when you do manage to make it permanent?

Many Thanks

Giorgos Myrianthous
  • 36,235
  • 20
  • 134
  • 156
Thanos Dodd
  • 572
  • 1
  • 4
  • 14
  • Consider [this](https://superuser.com/questions/954950/run-a-script-on-start-up-on-windows-10) – Gabriel Melo Dec 01 '19 at 12:31
  • 1
    That's helpful on how to run a script on StartUp but I think I still need to add something to make it run constantly. Currently my program only performs one run and then closes – Thanos Dodd Dec 01 '19 at 12:38
  • you can try using [watchdog](https://pypi.org/project/watchdog) – Nullman Dec 01 '19 at 12:38

5 Answers5

33

On Windows, you can use pythonw.exe in order to run a python script as a background process:

Python scripts (files with the extension .py) will be executed by python.exe by default. This executable opens a terminal, which stays open even if the program uses a GUI. If you do not want this to happen, use the extension .pyw which will cause the script to be executed by pythonw.exe by default (both executables are located in the top-level of your Python installation directory). This suppresses the terminal window on startup.

For example,

C:\ThanosDodd\Python3.6\pythonw.exe C:\\Python\Scripts\moveDLs.py

In order to make your script run continuously, you can use sched for event scheduling:

The sched module defines a class which implements a general purpose event scheduler

import sched
import time

event_schedule = sched.scheduler(time.time, time.sleep)

def do_something():
    print("Hello, World!")
    event_schedule.enter(30, 1, do_something, (sc,))

event_schedule.enter(30, 1, do_something, (s,))
event_schedule.run()

Now in order to kill a background process on Windows, you simply need to run:

taskkill /pid processId /f

Where processId is the ID of the process you want to kill.

Giorgos Myrianthous
  • 36,235
  • 20
  • 134
  • 156
  • 1
    Thanks. Before I attempt this, as for the termination, will the process appear in the task manager? Or alternatively, what would the process ID be called? Is it simply the Batch file name? – Thanos Dodd Dec 03 '19 at 13:49
  • 1
    @ThanosDodd You can find the processId by running `tasklist`. You should be associate the service name with the PID. – Giorgos Myrianthous Dec 03 '19 at 13:53
  • Last question: Do I need to add anything to make it a continuous process or does SimonN's time module idea solve this adequately? – Thanos Dodd Dec 04 '19 at 11:26
  • @ThanosDodd It depends. on what you are trying to achieve. SimonN's approach should do the trick but I feel it is more natural to use other means like cron jobs (or scheduled tasks for Windows). You can find more information in this post: https://stackoverflow.com/questions/7195503/setting-up-a-cron-job-in-windows – Giorgos Myrianthous Dec 04 '19 at 11:29
  • Yes, I've used the Task Scheduler before but the most frequent option is 'every 5 minutes'. What I'm looking for is the file moves as soon as in enters the Downloads folder – Thanos Dodd Dec 04 '19 at 11:44
7

One option is to change your script so it is intended to run continuously rather than repeatedly. Just wrap the whole thing in a while loop and add a sleep.

import time

while True:
   your_script_here
   time.sleep(300)

In order to make sure this starts up with the machine and to provide automatic restarts in the event of an exception I'd recommend making it into a Windows service using Non-Sucking Service Manager (www.nssm.cc). There are a few steps to this (see the docs) but once done your script will be just another windows service which you can start and stop from the standard services.msc utility.

Simon Notley
  • 2,070
  • 3
  • 12
  • 18
  • Thanks for the insight. Are you aware why an error occurs when a new file appears in the folder when you use the infinite loop without the time.sleep function??? – Thanos Dodd Dec 04 '19 at 16:32
  • 2
    Using it without the time.sleep is a bad idea as it will loop as quickly as it possibly can and consume all your CPU (at least all that it can access). I suspect the crash is because it's trying to access a file which hasn't been fully written or perhaps even a transient file that appears during the download which then vanishes. This could happen without the sleep if you were unlucky but without the sleep it's a virtual certainty. – Simon Notley Dec 04 '19 at 17:24
2

I've found a solution that works:

import shutil, os, time

while True:
    for filename in os.listdir('folderToMoveFrom'):
        if filename.endswith((desired file extensions)):
            shutil.move( (folderToMoveFrom + filename), folderToMoveTo)
    time.sleep(6)

If you perform the above code without the time.sleep() function the program crashes after a new file enters the folder due to a 'file not found' error nested inside another 'file not found' error. Not sure what that's about but I'm happy with what I have so far. Only thing you need to do now is add the script to the Task Scheduler to run under Pythonw so it operates as a background process. Or instead of running the script you could run a batch file as long as you remember to add the appropriate instruction for pythonw. You only need to start the process once of course.

Thanos Dodd
  • 572
  • 1
  • 4
  • 14
1

If you want a code to run continuously in the background, you will need to change the file extension

from .py in .pyw

Before running the script you need to do the following:

From the CMD (command prompt) console, run the command: pip install pythonw

To start the program run the following command in CMD (in the folder where the file is located): pythonw YOUR-FILE.pyw

Now the process will run continuously in the background. To stop the process, you must run the command:

TASKKILL /F /IM pythonw.exe

CAREFUL!!! All commands are run from the command line in the folder where the file is located.

If you want to simply run the file with python YOUR-FILE.pyw, you can do that too, but you should always keep the console open. You can stop the execution with ctrl + C from Command Prompt (CMD)

SOURCE HERE:

Just Me
  • 864
  • 2
  • 18
  • 28
0

I wanted to create a shortcut key that I would be able to use whenever the PC is on. I didn't want to use while True so I did this

import keyboard as k

k.add_hotkey("alt+s", lambda: k.write('Hello'))
k.wait('ctrl+shift+1') #this is a combo that I know I don't use so the program keeps running

And then put the python file in C:\Users\Administrator\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup

P4Penguin
  • 23
  • 3