1

I have a batch file to execute Python and run a Python script that works fine when run manually. But when run using Windows Task Scheduler, the Python Script gives me a traceback because it can't find a .TXT file that's in the same file as the Python script.

There are many flavors of the "batch file works manually but not with Task Scheduler" problem. I think my problem may be related to the fact that my Python script is in a virtual environment. It may also be related to Windows user accounts and permissions. Past posts about Task Scheduler have been resolved with changing settings related to user accounts but so far that hasn't worked for me.

More details on Windows Task Scheduler settings:

Here are the settings I've chosen for the task:

enter image description here

My task gets closest to working when I use the "run only when user is logged on option. If I choose "run whether user is logged on or not" the task opens a Command Prompt but doesn't appear to execute anything.

More details about batch file

My batch file looks like this:

"C:\Users\MyPathtovirtualenvironment\virtualenv\Scripts\python.exe" "C:\Users\fried\Desktop\calendaralert\court_calendar_alert1.3_automatic.py" 
pause

When run manually, it does what it's supposed to: it executes Python from within the virtual environment, then loads the Python script, which runs correctly except when it's run from Windows Task Scheduler.

More details on Python script

The Python script works fine when run by itself in the command prompt and as a batch file, so I don't think there's anything directly wrong with it. Here's the part of the script that causes the traceback.

with open('replacements.txt') as f:
    replacements = dict(x.rstrip().split("!") for x in f)

The replacements.txt file is in the same folder as my Python program. I also tried putting copies of the file within the Virtual Environment folder and the /scripts subfolder without success.

martineau
  • 119,623
  • 25
  • 170
  • 301
  • 2
    Your code is assuming the current working directory is set to something. Try opening the file using it's absolute path (i.e. not relative to the cwd). – martineau Aug 24 '20 at 14:26
  • Oh, duh. Thanks. I was so used to Python finding things from current directory it didn't occur to me to put in the whole path. Problem solved! – Sam Friedman Aug 24 '20 at 14:31
  • 1
    It can be tricky scheduling scripts in the Task Scheduler. Another common mistake is to assume that the script will be run as though **you** were the currently logged-in user. – martineau Aug 24 '20 at 14:35
  • @martineau, in this case the task will only run in an interactive session owned by the user named "fried", which happens to also be the user who created the task. Since it requests "highest privileges", if "fried" is an administrator, the task will use the administrator token that's linked to the session access token. Otherwise if "fried" is a standard user or a user that's exempt from UAC, it will just use the session access token (i.e. `WTSQueryUserToken` for the session ID). – Eryk Sun Aug 24 '20 at 21:12
  • @ErykSun: Thanks, I know (much) of that and was primarily thinking about the scenario in this [answer of mine](https://stackoverflow.com/a/4209102/355230). – martineau Aug 24 '20 at 21:20
  • You can set the working directory of a task, which should be obvious in the dialog where you set the executable and command line. Generally, the working directory is a convenience for file paths in command-line arguments. But in this case "replacements.txt" looks like it should always be found as a private resource that's relative to the script location. There's no need to hard code an absolute path in this case. Use, for example, `os.path.join(os.path.dirname(__file__), 'replacements.txt')`. – Eryk Sun Aug 24 '20 at 21:20
  • @ErykSun: Yes, I know about the `__file__` trick, too — simply felt it wasn't appropriate or necessary to go into it at this juncture, as I suspect is also true of most of your comments thus far… – martineau Aug 24 '20 at 21:26
  • I suggest you post an answer. – martineau Aug 24 '20 at 21:40
  • I have too many answers for my liking. (I know about 500 answers is only a drop in the bucket compared to many SO users. It's personal.) I'd rather Sam work through it, master the problem, and either post an answer or look for a duplicate question. It's better that way for the community and, IMHO, better for Sam to work the entire question from start to finish to create a good question with a useful answer. – Eryk Sun Aug 24 '20 at 21:55

1 Answers1

0

Just came across this problem, while running a python script on a windows ec2 instance. The problem got solved by adding this at the top:

import os
path = "your-directory-path"
os.chdir(path)