13

Мне нужно настроить запланированное задание Windows. Он принимает 1 параметр / аргумент, который является путем и может содержать пробелы. Мое запланированное задание не работает - оно "разбивает" параметр на первый пробел.

Если я запускаю его в командной строке, я могу просто обернуть аргумент в "", и он работает нормально, однако, это не работает в пользовательском интерфейсе запланированных задач.

например, C:\Program Files\xyz\FTP File Transfer\FTPFileTransferTask.exe "C:\Program Files\xyz\The Interface\Folder Path"

Я попытался обернуть аргумент с помощью "" '' [] () и попытался заполнить пробелы с% 20, ~ 1 и т.д. Безуспешно.

Мне известно об одном решении создать файл bat и использовать «» в моем аргументе, но я не хочу добавлять больше сложности.

Я попробовал это на Windows 7 и Windows 2008 Server, и оба потерпели неудачу. Кажется, нет никаких дискуссий по этому поводу?

7 ответов7

5

Я работал с запланированными задачами, и вы обычно помещали аргументы в собственное поле ввода текста. Это означает, что вы указываете действие на поле программы / скрипта, указывает на исполняемый файл, и поле "Добавить аргументы" должно иметь все параметры. (источник)

Изображение блога

Я считаю, что это поведение было добавлено, чтобы предотвратить пробелы в пути к файлу exe, вызывая проблемы.

Я делаю это все время с помощью скриптов PowerShell. Вот пример:

  • Программа / скрипт: powershell.exe
  • Добавьте аргументы: -команда "& 'C:\HSD - Copy\logoffstudents.ps1'" -NonInteractive
  • Начало в: Пусто
4
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"

Обратите внимание на использование ' в пути к файлу, который нужно запустить.

2

В этом случае вы можете обойти проблему, передав параметр path в формате 8.3.

Вы можете найти формат 8.3 для вашего пути, открыв командную строку и введя команду dir /x в корне вашего диска.

Вы должны увидеть запись, похожую на

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

для вашей директории Program Files.

Затем измените каталог на Program Files с помощью cd "Program Files », затем cd xyz и снова введите dir /x чтобы найти имя формата 8.3 для "The Interface", и так далее.

Ваш окончательный путь к приведенному вами примеру будет выглядеть примерно так:

C:\PROGRA~1\XYZ\THEINT~1\FOLDER~1
1

У меня была похожая проблема с VLC, которую я использовал в Windows XP. Хитрость заключается в том, чтобы заключить аргумент команды cmd в двойные кавычки.

Вот пример того, что я использовал (планирование записи на 15:00):

в 15:00: cmd /c "" C:\Programmi\VideoLAN\VLC\vlc.exe \UserName \Documents \Video \VLC\test.mpg ""»

Обратите внимание на использование двойных кавычек сразу после /c и в конце команды (после .mpg). Аргумент с пробелами в этом случае - "C:\Documents and Settings\..."

1

Один из способов сделать это - использовать powershell из командной строки.

Добавьте этот код в файл с именем 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-*"

Затем из командной строки ИЛИ файл ps1 вы можете запустить:

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)

Каждый соответствующий элемент в массиве taskparameters будет передан как $(Arg0), $(Arg1) и $(Arg2).

1

Это может помочь понять проблему с другой точки зрения. Допустим, вы программист, которому поручено добавить планировщик задач в Windows. Как бы вы это сделали? У вас есть несколько проблем, с которыми приходится сталкиваться: если задание выполняется от имени другого пользователя, а не вошедшего в систему пользователя, следует ли раздражать вошедшего в систему пользователя всплывающими сообщениями об ошибках? Что делать, если во время выполнения задачи не было зарегистрированного пользователя? Как насчет разницы между программой с графическим интерфейсом и консольной программой? Графические интерфейсы не имеют stdin, stdout и stderr; понятие бессмысленно в них. Как насчет программ, внутренних или внешних для COMMAND.COM/CMD.EXE? Или другие скриптовые движки? Как насчет путей с пробелами в имени команды? Или в параметрах (опциях / аргументах)? (Как вы пытаетесь справиться сейчас ..)

Хотя я не уверен на 100% насчет внутренних деталей или полных технических деталей в этом случае, ответы вроде бы ... Задачи выполняются в изолированном неинтерактивном сеансе, который не может взаимодействовать с вошедшим в данный момент пользователем (если есть); Он запускается, ожидая, что не будет никакого вывода на консоль, так как он неинтерактивный, он не может просто прервать работу любого вошедшего в систему пользователя, чтобы показать вывод (во всяком случае, если вывод есть, stdin - это bitbucket/NULL, stdout и stderr будут зарегистрированы в средство регистрации системы); Пробелы обрабатываются путем обхода проблемы: имя команды принимается ТОЧНО как есть, а параметры, передаваемые команде, указываются в другом поле ввода в свойствах Задачи.

Все это означает, что ваша задача должна выполняться, как если бы она была похожа на демона (в мире Un * x). Все статично и точно. Имя команды - это фактическое имя команды без каких-либо параметров. Это часто включает запуск интерпретаторов команд / сценариев, таких как CMD.EXE! Параметры, если таковые имеются, указываются в другом месте и должны быть известны при настройке задачи (то есть вы не можете изменять параметры «на лету»). И так далее.

Таким образом, если вы хотите включить параметры, вы должны использовать раздел параметров, чтобы указать параметры. Планировщик задач не пытается разобрать имя команды, чтобы разделить его на "команду" и "аргументы", как это делают программы командной строки. Он просто обрабатывает это как одно большое полное имя команды. Аналогично, если вам нужны переменные параметры, такие как использование% 1 ..% n в файлах BATCH, вы не можете сделать это из самого планировщика задач; Тебе придется найти другой путь. (Обратите внимание, что вы также не можете использовать переменные среды, поскольку среда, передаваемая в программу, зависит от среды, в которой запускается задача, а не от "текущей" среды.) Вы можете использовать временный файл для сохранения параметров, но, поскольку вы должны указать статическое имя файла в свойствах Задачи, что произойдет, когда вы находитесь в сети с 5000 пользователями, и четверо из них пытаются запустить одну и ту же задачу одновременно? Все они будут сжимать друг друга, пытаясь записать в один и тот же временный файл одновременно, вероятно, не то, что вы хотели. (Есть решения этой проблемы, но это выходит за рамки этого вопроса и ответа ..)

Итак, окончательный ответ: в простом случае - путь, который вы хотите передать в качестве параметра, является статическим и не изменяется - вы должны либо указать параметры в соответствующем свойстве Task (Аргументы), а не в поле Program/Script или используйте командный файл. В более сложном случае - вам нужно задать правильный вопрос или исследовать, как работают демоны и как использовать блокировку / семафоры и тому подобное для межпроцессного взаимодействия (IPC).

Удачи.

0

Установите запланированное задание следующим образом

cmd /c C:\Program Files\xyz\ Передача файлов по FTP \ FTPFileTransferTask.exe "C:\Program Files\xyz\ Интерфейс \ Путь к папке"

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .