Reputation: 1568
I realize that this question is "answered" at the following thread: Specifying the running directory for Scheduled Tasks using schtasks.exe
However, I'm still having trouble understanding the answer and seeing exactly what the result would look like for my situation.
My schtasks command looks like this:
Schtasks /Create /TR "C:\Program Files\Java\jre6\bin\javaw.exe main.MoveFile input.txt" /SC WEEKLY /TN mytask
I want to specify the start in directory of "C:\My Library". Putting a "\" before the tr section fills in a start-in directory of "C:\Program Files\Java\jre6\bin".
I've messed around with it a lot, but I just can't seem to make it work.
Upvotes: 26
Views: 91277
Reputation: 564
To schedule a task that will run from an specific directory. If we call this directory c:\x
whenever the pwd
command is executed it will print c:\x
. Every path from there is relative to that directory.
Another example: running java -jar myapp.jar
will execute the JAR file located in c:\x\myapp.jar
It is impossible to set that specific parameter using the command schtasks /create
Is a bit steppy (like in too many steps):
Create the task as specific as you can using the schtasks /create
command. Try to set every parameter to the desired value: start time, repetition, duration, etc...
In this case the /tn
argument is mandatory, so set it: \tn mytask
Export the newly created task to XML using schtasks /query /tn mytask /xml > mytask.xml
Open mytasks.xml
in your favorite editor. You should see something like this (I've hidden the not interesting parts):
<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
<RegistrationInfo>...
</RegistrationInfo>
<Triggers>...
</Triggers>
<Settings>...
</Settings>
<Actions Context="Author">
<Exec>
<Command>java</Command>
<Arguments>-jar c:\x\myapp.jar</Arguments>
</Exec>
</Actions>
<Principals>...
</Principals>
</Task>
<Exec>
section, below to the <Argument>
field introduce a new field:<WorkingDirectory>c:\x\</WorkingDirectory>
And save the file. This field is defined in the xml schema definition here https://learn.microsoft.com/en-us/windows/desktop/taskschd/task-scheduler-schema
Delete the previously created task (to recreate it using the modified xml): schtasks /delete /tn mytask
Create the task again using /xml
argument: schtasks \tn mytask \xml mytask.xml
Execute it using schtasks /run /tn mytask
.
Upvotes: 2
Reputation: 594
If all else fails, you can redirect to a batch file that sets it's own CD, then calls your program.
for example:
Schtasks /Create /TR "C:\example\batch.bat" /SC WEEKLY /TN mytask
As the schtask, and
cd "%temp%\"
"C:\Program Files\Java\jre6\bin\javaw.exe main.MoveFile input.txt"
as "C:\example\batch.bat". That should keep the current directory as whatever you change it to in the batch file and keep all references relative to that.
Upvotes: 17
Reputation: 1
The only way would be to use an XML Flle, use the following command: schtasks /Create /XML C:\file.xml /TN TaskName /RU domain\username /RP password
Sample XML File that will run every day at 23:00, the C:\taskfolder will set the run in directory:
<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
<RegistrationInfo>
<Date>2016-07-13T07:56:56</Date>
<Author>Administrator</Author>
</RegistrationInfo>
<Triggers>
<CalendarTrigger>
<StartBoundary>2016-07-13T23:00:00</StartBoundary>
<Enabled>true</Enabled>
<ScheduleByDay>
<DaysInterval>1</DaysInterval>
</ScheduleByDay>
</CalendarTrigger>
</Triggers>
<Principals>
<Principal id="Author">
<UserId>domain\Administrator</UserId>
<LogonType>Password</LogonType>
<RunLevel>HighestAvailable</RunLevel>
</Principal>
</Principals>
<Settings>
<MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
<DisallowStartIfOnBatteries>true</DisallowStartIfOnBatteries>
<StopIfGoingOnBatteries>true</StopIfGoingOnBatteries>
<AllowHardTerminate>true</AllowHardTerminate>
<StartWhenAvailable>false</StartWhenAvailable>
<RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
<IdleSettings>
<StopOnIdleEnd>true</StopOnIdleEnd>
<RestartOnIdle>false</RestartOnIdle>
</IdleSettings>
<AllowStartOnDemand>true</AllowStartOnDemand>
<Enabled>true</Enabled>
<Hidden>false</Hidden>
<RunOnlyIfIdle>false</RunOnlyIfIdle>
<WakeToRun>false</WakeToRun>
<ExecutionTimeLimit>P3D</ExecutionTimeLimit>
<Priority>7</Priority>
</Settings>
<Actions Context="Author">
<Exec>
<Command>C:\taskfolder\task.bat</Command>
<WorkingDirectory>C:\taskfolder</WorkingDirectory>
</Exec>
</Actions>
</Task>
Upvotes: 0
Reputation: 3519
Note: Here is the issue that I just saw with this..
Note: You have to have two lines:
REM NOTE:You have to create the schedule first
SCHTASKS /S SERVER /CREATE /TN "SERVER_RESTART" /RU "" /TR "D:\WORK\scripts\__server_restart.bat 1" /SC MONTHLY /MO FIRST /D SUN /ST:02:10
REM The next line is run to set the run in folder as well as set the: run as: NT AUTHORITY\SYSTEM
SCHTASKS /S SERVER /CHANGE /TN "SERVER_RESTART" /RU "" /TR "D:\WORK\scripts\__server_restart.bat 1"
One of the things that I have noticed with Windows 2008, is that it handles batch scripts much better than 2003, for example. I don't think the "run in" Folder is as important as I just ran the server restart on a test machine manually from Task Scheduler and it runs just fine..
For the folks that maybe running into issues with escaping characters and such, consider the following:
SCHTASKS /CHANGE /S SERVER /RU "" /TR "powershell -file "\"D:\WORK\ps\zip_up_files\zip_up_files.ps1"\"" /TN "PowerShell - New Archive"
or, another example:
SCHTASKS /CREATE /S SERVER /RU "" /TR "powershell -file "\"D:\WORK\ps\page_test.ps1"\"" /TN "PowerShell - Page Test" /SC MINUTE /MO 3 /ST:23:00
Note: The extra Quoting and the extra backslashes.
Hope this helps!
Upvotes: 0
Reputation: 13871
UPDATE: Note that starting from Powershell v3 (but only under Windows 2012 and higher!) there's new API which I find much more attractive:
$taskPath = "\MyTasksFolder\"
$name = 'MyTask'
$runAt = '5:00 AM'
$exe = 'my.exe'
$params = 'command line arguments'
$location = "C:\Path\To\MyTask"
Unregister-ScheduledTask -TaskName $name -TaskPath $taskPath -Confirm:$false -ErrorAction:SilentlyContinue
$action = New-ScheduledTaskAction –Execute "$location\$exe" -Argument "$params" -WorkingDirectory $location
$trigger = New-ScheduledTaskTrigger -Daily -At $runAt
Register-ScheduledTask –TaskName $name -TaskPath $taskPath -Action $action –Trigger $trigger –User 'someuser' -Password 'somepassword' | Out-Null
Amal's solution with /v1
switch is great but doesn't allow to create tasks in custom folders (ie you can't create "MyCompany\MyTask" and everything ends up in the root folder), so I finally ended up with a PowerShell script described below.
Usage:
CreateScheduledTask -computer:"hostname-or-ip" `
-taskName:"MyFolder\MyTask" `
-command:"foo.exe" `
-arguments:"/some:args /here" `
-workingFolder:"C:\path\to\the\folder" `
-startTime:"21:00" `
-enable:"false" `
-runAs:"DOMAIN\user" `
-runAsPassword:"p@$$w0rd"
(Note, enable
must be lowercase - for a boolean you'd need $value.ToString().ToLower()
)
Implementation:
The function uses XML task definition and "Schedule.Service" COM object.
#####################################################
#
# Creates a Windows scheduled task triggered DAILY.
# Assumes TODAY start date, puts "run-as" user as task author.
#
#####################################################
function CreateScheduledTask($computer, $taskName, $command, $arguments, $workingFolder, $startTime, $enable, $runAs, $runAsPassword)
{
$xmlTemplate = "<?xml version='1.0' encoding='UTF-16'?>
<Task version='1.2' xmlns='http://schemas.microsoft.com/windows/2004/02/mit/task'>
<RegistrationInfo>
<Date>{0}</Date>
<Author>{1}</Author>
</RegistrationInfo>
<Triggers>
<CalendarTrigger>
<StartBoundary>{2}</StartBoundary>
<Enabled>true</Enabled>
<ScheduleByDay>
<DaysInterval>1</DaysInterval>
</ScheduleByDay>
</CalendarTrigger>
</Triggers>
<Principals>
<Principal id='Author'>
<UserId>{1}</UserId>
<LogonType>Password</LogonType>
<RunLevel>LeastPrivilege</RunLevel>
</Principal>
</Principals>
<Settings>
<IdleSettings>
<Duration>PT10M</Duration>
<WaitTimeout>PT1H</WaitTimeout>
<StopOnIdleEnd>true</StopOnIdleEnd>
<RestartOnIdle>false</RestartOnIdle>
</IdleSettings>
<MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
<DisallowStartIfOnBatteries>true</DisallowStartIfOnBatteries>
<StopIfGoingOnBatteries>true</StopIfGoingOnBatteries>
<AllowHardTerminate>true</AllowHardTerminate>
<StartWhenAvailable>false</StartWhenAvailable>
<RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
<AllowStartOnDemand>true</AllowStartOnDemand>
<Enabled>{3}</Enabled>
<Hidden>false</Hidden>
<RunOnlyIfIdle>false</RunOnlyIfIdle>
<WakeToRun>false</WakeToRun>
<ExecutionTimeLimit>P3D</ExecutionTimeLimit>
<Priority>7</Priority>
</Settings>
<Actions Context='Author'>
<Exec>
<Command>{4}</Command>
<Arguments>{5}</Arguments>
<WorkingDirectory>{6}</WorkingDirectory>
</Exec>
</Actions>
</Task>"
$registrationDateTime = [DateTime]::Now.ToString("yyyy-MM-dd") + "T" + [DateTime]::Now.ToString("HH:mm:ss")
$startDateTime = [DateTime]::Now.ToString("yyyy-MM-dd") + "T" + $startTime + ":00"
$xml = $xmlTemplate -f $registrationDateTime, $runAs, $startDateTime, $enable, $command, $arguments, $workingFolder
$sch = new-object -ComObject("Schedule.Service")
$sch.Connect($computer)
$task = $sch.NewTask($null)
$task.XmlText = $xml
$createOrUpdateFlag = 6
$sch.GetFolder("\").RegisterTaskDefinition($taskName, $task, $createOrUpdateFlag, $runAs, $runAsPassword, $null, $null) | out-null
}
Upvotes: 15
Reputation: 49
Try
cd /d "C:\Program Files\Java\jre6\bin" & schtasks /create /tr "C:\Program Files\Java\jre6\bin\javaw.exe main.MoveFile input.txt" /sc WEEKLY /tn mytask
Change working directory and then run schtasks.
Upvotes: 2
Reputation: 6567
As you note, the trick of using the extra quotes in the /TR parameter only allows you to use the same directory as where the executable resides. If you want to specify a different working directory, you should use the /XML option and specify an XML file that lists the working directory. The command would be something like this:
SchTasks /Create /TN "Foo" /XML task.xml
The XML file would look something like this:
<?xml version="1.0" ?>
<Task xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
<RegistrationInfo>
<Date>2006-05-02T13:21:17</Date>
<Author>AuthorName</Author>
<Version>1.0.0</Version>
<Description>Call MoveFile</Description>
</RegistrationInfo>
<Triggers>
<CalendarTrigger>
<StartBoundary>2011-11-02T00:00:00</StartBoundary>
<ScheduleByDay>
<DaysInterval>1</DaysInterval>
</ScheduleByDay>
</CalendarTrigger>
</Triggers>
<Principals>
<Principal>
<UserId>Administrator</UserId>
<LogonType>InteractiveToken</LogonType>
</Principal>
</Principals>
<Settings>
<Enabled>true</Enabled>
<AllowStartOnDemand>true</AllowStartOnDemand>
<AllowHardTerminate>true</AllowHardTerminate>
</Settings>
<Actions>
<Exec>
<Command>C:\Program Files\Java\jre6\bin\javaw.exe</Command>
<Arguments>main.MoveFile input.txt</Arguments>
<WorkingDirectory>C:\My Library</WorkingDirectory>
</Exec>
</Actions>
</Task>
There's more information about the XML schema here: http://msdn.microsoft.com/en-us/library/windows/desktop/aa383609(v=VS.85).aspx
Upvotes: 3
Reputation:
I have found that if you use the 8.3 naming convention in the SCHTASKS command line for the path and file names the "Start In" field is polulated with the file path -
e.g. "C:\Progra~1\NBVCl~1\nbv_up~1.exe" will result in "C:\Progra~1\NBVCl~1" appearing in the "start In" area
Upvotes: 0
Reputation: 1479
Not sure what version of Windows you are on, but from reading the other question it looks like schtasks on Vista / Server 2008 does not provide a command option that would allow you to specify a "start-in" directory directly. The workarounds people provided were:
Upvotes: 14