28

I need to set up a Windows Scheduled Task. It accepts 1 parameter/argument which is a path and can contain spaces. My Scheduled task does not work - it "breaks" the parameter up at the first space.

If I run it in the Command Prompt I can just wrap the argument in " " and it works fine, however, this does not work in the Scheduled Task UI.

e.g. C:\Program Files\xyz\FTP File Transfer\FTPFileTransferTask.exe "C:\Program Files\xyz\The Interface\Folder Path"

I have tried wrapping the argument with " " ' ' [ ] () and have tried filling in the spaces with %20, ~1 etc. with no luck.

I know of one solution to make a bat file and use " " around my argument but I don't want to add more complexity.

I tried it on Windows 7 and Windows 2008 Server and both failed. There seems to be no discussions on this?

4
  • 1
    Are you putting the argument in the Program/script section or the Add arguments (optional) section when you edit the Scheduled Task? May 19, 2011 at 20:03
  • It would be helpful if you specified which program you're using exactly, as the correct wrapping of arguments is at the discretion of the program and not Scheduled Taks. WinSCP, for example, expects double quotes (""..."") when you have to nest quotes. May 23, 2011 at 21:25
  • It's pretty unclear as to 1) what is failing, the task or your .exe, and 2)exactly what you entered and where in the TaskSched UI. Could it be that where TaskSched asks for a command (full path to executable), you are trying to give it a command-line (very different thing)?
    – kreemoweet
    Dec 30, 2011 at 21:42
  • Why against batch file? It makes things so simple! Or you can shoot for powershell script if you are feeling adventurous.. Oct 31, 2013 at 23:29

9 Answers 9

11
schtasks.exe /create /SC WEEKLY /D SUN /SD 11/12/2015 /ST 12:00:00 /TN "taskname" /TR "'c:\program files(x86)\task.exe' Arguments"

Note the use of ' in the path of a file to be run.

7

I've worked with scheduled tasks and you generally put the arguments in its own text input box. This means that you point the action to the program/script field points to the exe and the "Add Arguments" field should have all of the parameters. (source)

Blog image

I believe this behavior was added to prevent spaces in the file path to the exe causing problems.

I do this all of the time with PowerShell scripts. Here is an example:

  • Program/script: powershell.exe
  • Add arguments: -command "& 'C:\HSD - Copy\logoffstudents.ps1' " -NonInteractive
  • Start in: Blank
6
  • Thanks, but the problem is that one of my paramaters IS a file path (and has a space in it). So in your example 100 will work, but what if you wanted to pass "C:\Start Folder"?
    – Rodney
    May 20, 2011 at 4:55
  • I just use quotes in my programs and it works. The ampersand is only required with powershell. This symbol is the CALL operator and allows me to bring up a powershell command. In most cases, quotes is all you need. At this point, you might want to look into contacting the creator of the exe to see if they support scheduled tasks. I have run into a few rare programs that just refuse to run as a scheduled task. I think there are subtle differences on how the parameters are passed that can cause problems. Sorry I can't help more. May 23, 2011 at 19:39
  • At worst, you can restructure the folder to eliminate the spaces. It's not what you want, but it could be the only way to make it work. May 23, 2011 at 19:41
  • Thanks Doltknuckle - I know I could also do it with a .bat file (and use "" around the param (like you do in the Powershell script. I am sure it is a bug in the Windows Task editor UI... (I am the creator of the .exe ;) - It works fine through a test harness and from the command prompt but not through the Windows UI...
    – Rodney
    May 24, 2011 at 1:29
  • 1
    If you made the exe, this may be a question for stackoverflow. I have a feeling that you may need to modify your parameter handling when this exe is used with scheduled task. One suggestion is to have your exe log the parameters received to a file so you can see what is being passed. It would at least allow you to see if the scheduled task parameters are the same as the command line parameters. May 24, 2011 at 17:21
5

In this case, you could work around the problem by passing your path parameter in 8.3 format.

You can discover the 8.3 format for your path by opening a command prompt and issuing the command dir /x in the root of your drive.

You should see an entry similar to

11/04/2011  12:10    <DIR>          PROGRA~1     Program Files

for your Program Files directory.

Then change directory to Program Files with cd "Program Files" followed by cd xyz and issue dir /x again to find the 8.3 format name for "The Interface", and so on.

Your final path for the example you gave would look something like:

C:\PROGRA~1\XYZ\THEINT~1\FOLDER~1
6
  • Thanks, I appreciate the answer, however this causes further problems. Basically I am calling an EXE .NET app which I wrote which uses this param folder path for something - it does not like the 8.3 format and cannot find the path. So, is there any other way to do it?
    – Rodney
    Apr 15, 2011 at 5:45
  • 1
    ps - So is this is bug in the Windows Scheduled Task app? Spaces are very common!
    – Rodney
    Apr 15, 2011 at 5:45
  • A quick test on windows 7 works for me. Can you walk us through the steps you took to set up the task, as there as various ways. Thanks for the edit there Gareth, looks much nicer.
    – Keith
    Apr 15, 2011 at 16:59
  • So the task runs ok with this formatting, but then my .NET program (which accepts the path as an arg string) does not uncompress the path from the 8.3 format. So perhaps it is a programming question - how to handle 8.3 paths?
    – Rodney
    Apr 18, 2011 at 23:38
  • I know this us old, but did you try hyphen (-) ? Apr 20, 2013 at 15:03
1

I had a similar problem with VLC, which I was using on Windows XP. The trick is to enclose the argument of the cmd command in double quotes.

Here is an example of what I used (scheduling a recording at 15:00):

at 15:00 cmd /c ""C:\Programmi\VideoLAN\VLC\vlc.exe dvb-t://frequency=698000000 :program=4006 :run-time=5 --sout "C:\Documents and Settings\UserName\Documents\Video\VLC\test.mpg"""

Note the use of double quotes just after /c and at the end of the command (after .mpg). The argument with spaces in this case is "C:\Documents and Settings\..."

1

One way you could accomplish this is using powershell from the command line.

Add this code to a file called MyModule.psm1.

$TASK_STATE_UNKNOWN   = 0;
$TASK_STATE_DISABLED  = 1;
$TASK_STATE_QUEUED    = 2;
$TASK_STATE_READY     = 3;
$TASK_STATE_RUNNING   = 4;
Function Run-Task(
        [ValidateNotNullOrEmpty()][string]
        [Parameter(Mandatory=$true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
        $ComputerName, 
        [ValidateNotNullOrEmpty()][string]
        [Parameter(Mandatory=$true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
        $Foldername, 
        [ValidateNotNullOrEmpty()][string]
        [Parameter(Mandatory=$true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
        $Taskname, 
        [int] $maxwait = 0, 
        [string[]]
        [Parameter(Mandatory=$false, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
        $TaskParameters = $null
    ){
    $TaskScheduler = New-Object -ComObject Schedule.Service
    $TaskScheduler.Connect($ComputerName)
    $ScheduledTaskFolder = $TaskScheduler.GetFolder($Foldername)
    $ScheduledTask = $ScheduledTaskFolder.GetTask($TaskName)

    if(-not $ScheduledTask) {
        return $Null
    }

    $ScheduledTask.Enabled = $True
    $ScheduledTask.Run($TaskParameters)

    if($maxwait -gt 0){
        $seconds = 5
        $i = 0;
        Start-Sleep -Seconds $seconds
        while ($ScheduledTask.State -eq $TASK_STATE_RUNNING)
        {
            if(($i * $seconds) -gt $maxwait) { 
                break; 
            } 
            Start-Sleep -Seconds $seconds        
            $i++;
        }
    }
    return $ScheduledTask
}

Export-ModuleMember -Variable "TASK_STATE*"
Export-ModuleMember -Function "Run-*"

Then from the command line OR a ps1 file you could run:

Import-Module $(Get-Item .\MyModule.psm1 | Resolve-Path -Relative) -DisableNameChecking -Force

$task = Run-Task -ComputerName "$env:COMPUTERNAME" -Taskname "Foo" -Foldername "\" -TaskParameters "test", "Tim C", $(Get-Date -format G)

Each respective item in the taskparameters array would get passed in as $(Arg0), $(Arg1), and $(Arg2).

0

Set your scheduled task as follows

cmd /c C:\Program Files\xyz\FTP File Transfer\FTPFileTransferTask.exe "C:\Program Files\xyz\The Interface\Folder Path"

0

It might help to understand the problem from a different perspective.. Let's say you're the programmer who's been charged with adding a task scheduler to Windows. How would you do it? You have several problems to contend with: If the task is run as someone other than the logged in user, should you annoy the logged in user with any error popups? What if there is no logged in user at the time the task is run? What about the difference between a GUI program and a console program? GUI's don't have stdin, stdout, and stderr; the concept is meaningless in them. What about programs internal or external to COMMAND.COM/CMD.EXE? Or other scripting engines? What about paths with spaces in the command name? Or in the parameters (options/arguments)? (As you're trying to deal with now..)

While I'm not 100% certain about the internals or full technical details in this case, the answers seem to be.. Tasks are run in an isolated, non-interactive session, which cannot interact with the currently logged in user (if any); It's run expecting there to be no console output, since it's non-interactive, it cannot just interrupt any logged in user to show the output, anyhow (and if there is output, stdin is the bitbucket/NULL, stdout and stderr get logged to the system logging facility); Spaces are handled by bypassing the issue: the command name is taken EXACTLY as is, and parameters are passed to the command are specified in another input box in the Task properties.

What all the means is that your task has to be run as if it were like a daemon (in the Un*x world). Everything is static and precise. The command name is the actual command name, without any parameters. This often includes running command/script interpreters, such as CMD.EXE! The parameters, if any, are specified elsewhere, and must be known when you set up the task (that is, you cannot change the parameters "on-the-fly"). And so on.

So, if you want to include parameters, you have to use the parameters section to specify the parameters. The Task Scheduler does not try to parse the command name to split it in to "command" and "args" like command line programs do. It just treats it as one big, full command name. Likewise, if you want variable parameters, like using %1 .. %n in BATCH files, you cannot do so from the Task Scheduler itself; You'll have to find another way. (Note that you cannot use environment variables, either, since the environment passed to the program depends on the environment the task is started with, NOT the "current" environment.) You could use a temporary file to save the parameters, but since you must specify a static filename in the Task properties, what happens when you are on a network with 5000 users and four of them try to run the same task at the same time? They'll all clobber each other trying to write to the same temp file at the same time, probably not what you wanted, either. (There are solutions to this problem, too, but that's going too far outside the scope of this question and answer..)

So final answer: In the simple case -- the path you want to pass as a parameter is static and does not change -- you either have to specify the parameters in the appropriate Task property (Arguments) rather than in the Program/Script box, or use a batch file. In a more complex case -- you'll need to ask the right question or research how daemons work and how to use locking/semaphores and such for inter-process communication (IPC).

Good luck.

0

By passing two arguments instead of one in the "Add arguments (optional)" input box. As follows :

/myArg1:"C:\Program Files\xyz\FTP File Transfer\FTPFileTransferTask.exe" 
/myArg2:"C:\Program Files\xyz\The Interface\Folder Path"

Just retrieve and process these two arguments in the invoked script. In VBS by example, use WScript.Arguments to retrieve the arguments passed.

-1

Microsoft has a bulletin on this: https://support.microsoft.com/en-us/help/823093/a-scheduled-task-does-not-run-when-you-use-schtasks-exe-to-create-it-a

Basically it says to use the sequence "\" before and after name of the batch file.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .