Como passar um argumento para uma tarefa agendada do Windows com espaços nele

15

Preciso configurar uma tarefa agendada do Windows. Ele aceita 1 parâmetro / argumento, que é um caminho e pode conter espaços. Minha tarefa agendada não funciona - ela "quebra" o parâmetro no primeiro espaço.

Se eu executá-lo no prompt de comando, posso apenas envolver o argumento em "" e ele funciona bem, no entanto, isso não funciona na interface do usuário da tarefa agendada.

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

Tentei agrupar o argumento com "" '' [] () e tentei preencher os espaços com% 20, ~ 1 etc. sem sorte.

Conheço uma solução para criar um arquivo bat e usar "" em torno do meu argumento, mas não quero adicionar mais complexidade.

Eu tentei no Windows 7 e Windows 2008 Server e ambos falharam. Parece não haver discussões sobre isso?

Rodney
fonte
1
Você está colocando o argumento na seção Programa / script ou Adicionar argumentos (opcional) ao editar a Tarefa agendada?
William Jackson
Seria útil se você especificasse qual programa está usando exatamente, pois o agrupamento correto de argumentos fica a critério do programa e não as Tarefas agendadas. O WinSCP, por exemplo, espera aspas duplas ("" ... "") quando você precisar aninhar aspas.
Tobias Plutat 23/05
Não está claro quanto a 1) o que está falhando, a tarefa ou o seu .exe e 2) exatamente o que você digitou e onde na interface do usuário TaskSched. Será que, onde o TaskSched solicita um comando (caminho completo para o executável), você está tentando fornecer uma linha de comando (coisa muito diferente)?
kreemoweet
Por que contra o arquivo em lote? Isso torna as coisas tão simples! Ou você pode atirar para o script powershell se você estiver se sentindo aventureiro ..
tumchaaditya

Respostas:

6

Eu trabalhei com tarefas agendadas e você geralmente coloca os argumentos em sua própria caixa de entrada de texto. Isso significa que você aponta a ação para o campo de programa / script, aponta para o exe e o campo "Adicionar argumentos" deve ter todos os parâmetros. ( fonte )

Imagem do blog

Acredito que esse comportamento foi adicionado para impedir que espaços no caminho do arquivo para o exe causem problemas.

Faço isso o tempo todo com scripts do PowerShell. Aqui está um exemplo:

  • Programa / script: powershell.exe
  • Adicione argumentos : -command "& 'C: \ HSD - Copy \ logoffstudents.ps1'" -NonInteractive
  • Início em: Blank
Doltknuckle
fonte
Obrigado, mas o problema é que um dos meus paramaters É um caminho de arquivo (e tem um espaço nele). Então, no seu exemplo, 100 funcionará, mas e se você quiser passar "C: \ Start Folder"?
Rodney
Eu apenas uso aspas nos meus programas e funciona. Oe comercial é necessário apenas com o PowerShell. Este símbolo é o operador CALL e me permite abrir um comando do PowerShell. Na maioria dos casos, é tudo o que você precisa. Nesse ponto, convém entrar em contato com o criador do exe para ver se eles oferecem suporte a tarefas agendadas. Encontrei alguns programas raros que simplesmente se recusam a executar como uma tarefa agendada. Eu acho que existem diferenças sutis em como os parâmetros são passados ​​que podem causar problemas. Desculpe, não posso ajudar mais.
Doltknuckle 23/05
Na pior das hipóteses, você pode reestruturar a pasta para eliminar os espaços. Não é o que você deseja, mas pode ser a única maneira de fazê-lo funcionar.
Doltknuckle
Obrigado Doltknuckle - eu sei que também poderia fazê-lo com um arquivo .bat (e usar "" em torno do parâmetro (como você faz no script Powershell. Tenho certeza de que é um bug na interface do usuário do editor de tarefas do Windows ... (I sou o criador do .exe;) - Ele funciona muito bem através de um equipamento de teste e para o prompt de comando, mas não através da interface do usuário do Windows ...
Rodney
1
Se você fez o exe, isso pode ser uma pergunta para o stackoverflow. Sinto que você pode precisar modificar o tratamento de parâmetros quando esse exe é usado com tarefas agendadas. Uma sugestão é que o exe registre os parâmetros recebidos em um arquivo para que você possa ver o que está sendo passado. Pelo menos, você poderá ver se os parâmetros da tarefa agendada são iguais aos da linha de comando.
Doltknuckle
6
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"

Observe o uso de 'no caminho de um arquivo a ser executado.

Aman Mehra
fonte
3

Nesse caso, você pode solucionar o problema passando o parâmetro path no formato 8.3.

Você pode descobrir o formato 8.3 para o seu caminho abrindo um prompt de comando e emitindo o comando dir /xna raiz da sua unidade.

Você deve ver uma entrada semelhante a

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

para o diretório Arquivos de Programas.

Em seguida, altere o diretório para Arquivos de programas com cd "Program Files"seguido de cd xyz e emita dir /xnovamente para encontrar o nome do formato 8.3 para" A interface "e assim por diante.

Seu caminho final para o exemplo que você deu seria algo como:

C:\PROGRA~1\XYZ\THEINT~1\FOLDER~1
Keith
fonte
Obrigado, agradeço a resposta, no entanto, isso causa mais problemas. Basicamente, estou chamando um aplicativo EXE .NET que escrevi que usa esse caminho da pasta param para algo - ele não gosta do formato 8.3 e não consegue encontrar o caminho. Então, existe alguma outra maneira de fazer isso?
Rodney #
ps - Então isso é um bug no aplicativo Tarefa agendada do Windows? Os espaços são muito comuns!
Rodney #
Um teste rápido no Windows 7 funciona para mim. Você pode nos guiar pelas etapas que você tomou para configurar a tarefa, como existem de várias maneiras. Obrigado pela edição lá Gareth, parece muito melhor.
21711 Keith
Portanto, a tarefa é executada bem com essa formatação, mas meu programa .NET (que aceita o caminho como uma seqüência de caracteres arg) não descompacta o caminho do formato 8.3. Então talvez seja uma questão de programação - como lidar com caminhos 8.3?
Rodney
Eu sei que isso é velho, mas você tentou hífen (-)?
Chibueze Opata
1

Eu tive um problema semelhante com o VLC, que estava usando no Windows XP. O truque é colocar o argumento do cmdcomando entre aspas duplas.

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

às 15:00 cmd / c "" C: \ Programmi \ VideoLAN \ VLC \ vlc.exe dvb-t: // frequência = 698000000: program = 4006: tempo de execução = 5 --sout "C: \ Documents and Settings \ Nome_do_Usuário \ Documentos \ Vídeo \ VLC \ test.mpg "" "

Observe o uso de aspas duplas logo após /ce no final do comando (depois .mpg). O argumento com espaços neste caso é"C:\Documents and Settings\..."

tomatoma
fonte
1

Uma maneira de conseguir isso é usar o PowerShell na linha de comando.

Adicione esse código a um arquivo 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-*"

Em seguida, na linha de comando OU em um arquivo ps1, você pode 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 da tarefa seria passado como $ (Arg0), $ (Arg1) e $ (Arg2).

SpaceGhost440
fonte
0

Defina sua tarefa agendada da seguinte maneira

cmd / c C: \ Arquivos de programas \ xyz \ Transferência de arquivos FTP \ FTPFileTransferTask.exe "C: \ Arquivos de programas \ xyz \ O caminho da interface \ pasta"

incógnito
fonte
0

Pode ajudar a entender o problema de uma perspectiva diferente. Digamos que você seja o programador encarregado de adicionar um agendador de tarefas ao Windows. Como você faria? Você tem vários problemas para enfrentar: Se a tarefa for executada como alguém que não seja o usuário conectado, você deve incomodar o usuário conectado com algum erro de pop-up? E se não houver usuário conectado no momento em que a tarefa for executada? E a diferença entre um programa GUI e um programa de console? As GUIs não possuem stdin, stdout e stderr; o conceito não tem sentido neles. E os programas internos ou externos ao COMMAND.COM/CMD.EXE? Ou outros mecanismos de script? E os caminhos com espaços no nome do comando? Ou nos parâmetros (opções / argumentos)? (Como você está tentando lidar agora ..)

Embora eu não tenha 100% de certeza sobre os detalhes internos ou técnicos completos neste caso, as respostas parecem ser .. As tarefas são executadas em uma sessão isolada e não interativa, que não pode interagir com o usuário conectado no momento (se houver) ); É executado esperando que não haja saída do console, uma vez que não é interativo, não pode simplesmente interromper qualquer usuário conectado para mostrar a saída de qualquer maneira (e se houver saída, stdin é o bitbucket / NULL, stdout e stderr são registrados no o recurso de registro do sistema); Os espaços são tratados ignorando o problema: o nome do comando é obtido EXATAMENTE como está e os parâmetros passados ​​para o comando são especificados em outra caixa de entrada nas propriedades da Tarefa.

Todos os meios são que sua tarefa precisa ser executada como se fosse um daemon (no mundo Un * x). Tudo é estático e preciso. O nome do comando é o nome do comando real, sem nenhum parâmetro. Isso geralmente inclui a execução de intérpretes de comando / script, como o CMD.EXE! Os parâmetros, se houver, são especificados em outro lugar e devem ser conhecidos quando você configura a tarefa (ou seja, não é possível alterar os parâmetros "on-the-fly"). E assim por diante.

Portanto, se você deseja incluir parâmetros, é necessário usar a seção de parâmetros para especificar os parâmetros. O Agendador de tarefas nãotente analisar o nome do comando para dividi-lo em "command" e "args", como fazem os programas de linha de comando. Apenas o trata como um grande nome completo de comando. Da mesma forma, se você deseja parâmetros variáveis, como usar% 1 ..% n em arquivos BATCH, não pode fazê-lo no próprio Agendador de tarefas; Você terá que encontrar outro caminho. (Observe que você também não pode usar variáveis ​​de ambiente, pois o ambiente passado para o programa depende do ambiente em que a tarefa foi iniciada, NÃO do ambiente "atual".) Você pode usar um arquivo temporário para salvar os parâmetros, mas desde que você deve especificar um nome de arquivo estático nas propriedades da tarefa, o que acontece quando você está em uma rede com 5000 usuários e quatro deles tentam executar a mesma tarefa ao mesmo tempo? Todos eles se atrapalham tentando gravar no mesmo arquivo temporário ao mesmo tempo, provavelmente também não é o que você queria. (Existem soluções para esse problema também, mas isso está muito além do escopo desta pergunta e resposta ..)

Resposta final: no caso simples - o caminho que você deseja passar como parâmetro é estático e não muda - é necessário especificar os parâmetros na propriedade Task apropriada (Arguments), em vez de na caixa Program / Script ou use um arquivo em lotes. Em um caso mais complexo - você precisará fazer a pergunta certa ou pesquisar como os daemons funcionam e como usar bloqueios / semáforos e outros para comunicação entre processos (IPC).

Boa sorte.

CM
fonte