2011-04-14 05:24:06 +0000 2011-04-14 05:24:06 +0000
15
15

Como passar um argumento a uma tarefa agendada com espaços no Windows

Preciso de configurar uma Tarefa Programada do Windows. Aceita 1 parâmetro/argumento que é um caminho e pode conter espaços. A minha tarefa agendada não funciona - ela “quebra” o parâmetro no primeiro espaço.

Se o executar no Prompt de Comando, posso simplesmente embrulhar o argumento em “ ” e funciona bem, no entanto, isto não funciona na IU de Tarefa Programada.

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

tentei embrulhar o argumento com “ ” “ e tentei preencher os espaços com %20, ~1 etc. sem sorte.

Conheço uma solução para fazer um ficheiro de morcego e usar ” “ em torno do meu argumento, mas não quero acrescentar mais complexidade.

Tentei no Windows 7 e Windows 2008 Server e ambos falharam. Parece não haver discussões sobre isto?

Respostas (8)

6
6
6
2016-04-12 05:46:09 +0000
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 a utilização de ' no caminho de um ficheiro a ser executado.

6
6
6
2011-05-19 20:24:00 +0000

Já trabalhei com tarefas agendadas e, em geral, os argumentos são colocados na sua própria caixa de entrada de texto. Isto significa que aponta a acção para os pontos do campo programa/script para o exe e o campo “Adicionar Argumentos” deve ter todos os parâmetros. fonte )

Creio que este comportamento foi adicionado para evitar que espaços no caminho do ficheiro para o exe causassem problemas.

Faço isto a toda a hora com os scripts PowerShell. Aqui está um exemplo:

  • Programa/script: powershell.exe
  • Adicionar argumentos* : -command “& ‘C:\HSD - Copy\logoffstudents.ps1’” -NonInteractive
  • Iniciar em: Em branco
3
3
3
2011-04-14 06:31:15 +0000

Neste caso, poderia contornar o problema passando o seu parâmetro de caminho no formato 8.3.

Pode descobrir o formato 8.3 para o seu caminho abrindo um prompt de comando e emitindo o comando dir /x na raiz da sua drive.

Deverá ver uma entrada semelhante a

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

para o seu directório de Ficheiros de Programas.

depois mude o directório para Ficheiros de Programas com cd "Program Files“, seguido de cd xyz e emissão dir /x novamente para encontrar o nome do formato 8.3 para "A Interface”, e assim por diante.

O seu caminho final para o exemplo que deu ficaria algo parecido:

C:\PROGRA~1\XYZ\THEINT~1\FOLDER~1
1
1
1
2013-10-27 22:45:45 +0000

Tive um problema semelhante com a VLC, que estava a utilizar no Windows XP. O truque é enclausurar o argumento do comando cmd entre aspas duplas.

Aqui está um exemplo do que utilizei (agendando uma gravação às 15:00):

às 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 a utilização de aspas duplas logo após /c e no fim do comando (após .mpg). O argumento com espaços neste caso é "C:\Documents and Settings\..."&.

1
1
1
2017-02-15 13:27:49 +0000

Uma forma de o conseguir é utilizando a concha de poder da linha de comando.

Adicione este código a um ficheiro chamado 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-*"

Depois a partir da linha de comando OU um ficheiro ps1 que poderia executar:

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)

Cada item respectivo na matriz de parâmetros de tarefa seria passado como $(Arg0), $(Arg1), e $(Arg2).

0
0
0
2014-04-28 13:52:02 +0000

Defina a sua tarefa programada da seguinte forma

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

0
0
0
2015-04-20 19:48:47 +0000

Pode ajudar a compreender o problema a partir de uma perspectiva diferente. Digamos que é o programador que foi encarregado de adicionar um programador de tarefas ao Windows. Como o faria? Tem vários problemas com que se defrontar: Se a tarefa for executada como outra pessoa que não o utilizador ligado, deverá irritar o utilizador ligado com algum erro de popups? E se não houver nenhum utilizador logado no momento em que a tarefa é executada? E quanto à diferença entre um programa GUI e um programa de consola? As GUI não têm stdin, stdout, e stderr; o conceito não tem sentido nelas. E os programas internos ou externos ao COMMAND.COM/CMD.EXE? Ou outros motores de scripting? E quanto aos caminhos com espaços no nome do comando? Ou nos parâmetros (opções/argumentos)? (Como está a tentar lidar com agora…)

Embora não esteja 100% certo sobre os internos ou detalhes técnicos completos neste caso, as respostas parecem ser… As tarefas são executadas numa sessão isolada, não interactiva, que não pode interagir com o utilizador actualmente registado (se houver); É executado esperando que não haja saída da consola, uma vez que é não interactiva, não pode simplesmente interromper qualquer utilizador registado para mostrar a saída, de qualquer forma (e se houver saída, stdin é o bitbucket/NULL, stdout e stderr são registados na instalação de registo do sistema); Os espaços são tratados contornando o problema: o nome do comando é tomado EXACTLY tal como está, e os parâmetros são passados para o comando são especificados noutra caixa de entrada nas propriedades da Tarefa.

O que tudo significa é que a sua tarefa tem de ser executada como se fosse um daemon (no mundo Un*x). Tudo é estático e preciso. O nome do comando é o verdadeiro nome do comando, sem quaisquer parâmetros. Isto inclui muitas vezes a execução de intérpretes de comando/script, tais como CMD.EXE! Os parâmetros, se existirem, são especificados noutro local, e devem ser conhecidos quando se configura a tarefa (ou seja, não se pode alterar os parâmetros “on-the-fly”). E assim por diante.

Portanto, se quiser incluir parâmetros, tem de utilizar a secção de parâmetros para especificar os parâmetros. O Agendador de Tarefas não tenta analisar o nome do comando para o dividir em “comando” e “args”, como fazem os programas de linha de comando. Apenas o trata como um nome de comando grande e completo. Da mesma forma, se quiser parâmetros variáveis, como a utilização de %1 … %n em ficheiros BATCH, não o pode fazer a partir do próprio Agendador de Tarefas; terá de encontrar outra forma. (Note que também não pode utilizar variáveis de ambiente, uma vez que o ambiente passado para o programa depende do ambiente com que a tarefa é iniciada, NÃO do ambiente “actual”). Poderá utilizar um ficheiro temporário para guardar os parâmetros, mas como deve especificar um nome de ficheiro estático nas propriedades da Tarefa, o que acontece quando se está numa rede com 5000 utilizadores e quatro deles tentam executar a mesma tarefa ao mesmo tempo? Todos eles vão tentar escrever no mesmo ficheiro temporário ao mesmo tempo, provavelmente também não o que você queria. (Também há soluções para este problema, mas isso vai demasiado longe fora do âmbito desta pergunta e resposta…)

Portanto, resposta final: No caso simples – o caminho que pretende passar como parâmetro é estático e não muda – ou tem de especificar os parâmetros na propriedade Tarefa apropriada (Argumentos) em vez de na caixa Programa/Roteiro, ou utilizar um ficheiro de lote. Num caso mais complexo – terá de fazer a pergunta certa ou pesquisar como funcionam os demónios e como utilizar o bloqueio/semáforos e tais para a comunicação inter-processo (IPC).

Boa sorte.

-1
-1
-1
2019-06-27 16:39:40 +0000

A Microsoft tem um boletim sobre isto https://support.microsoft.com/en-us/help/823093/a-scheduled-task-does-not-run-when-you-use-schtasks-exe-to-create-it-a

Basicamente diz para utilizar a sequência “\” antes e depois do nome do ficheiro do lote.