web-dev-qa-db-fra.com

Comment passer un argument à une tâche planifiée Windows contenant des espaces

Je dois configurer une tâche planifiée Windows. Il accepte 1 paramètre/argument qui est un chemin et peut contenir des espaces. Ma tâche planifiée ne fonctionne pas - elle "rompt" le paramètre dans le premier espace.

Si je l'exécute dans l'invite de commande, je peux simplement envelopper l'argument dans "" et tout fonctionne correctement. Toutefois, cela ne fonctionne pas dans l'interface utilisateur de tâche planifiée.

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

J'ai essayé de résumer l'argument avec "" '' [] () et j'ai essayé de remplir les espaces avec% 20, ~ 1, etc. sans succès.

Je connais une solution pour créer un fichier chauve-souris et utiliser "" autour de mon argument, mais je ne veux pas ajouter de complexité supplémentaire.

Je l'ai essayé sur Windows 7 et Windows 2008 Server et les deux ont échoué. Il semble n'y avoir aucune discussion à ce sujet?

14
Rodney

J'ai travaillé avec des tâches planifiées et vous avez généralement placé les arguments dans sa propre zone de saisie de texte. Cela signifie que vous pointez l'action sur le champ programme/script, pointez sur l'exe et que le champ "Ajouter des arguments" doit contenir tous les paramètres. ( source )

Blog image

Je crois que ce comportement a été ajouté pour empêcher les espaces dans le chemin du fichier de créer des problèmes.

Je le fais tout le temps avec les scripts PowerShell. Voici un exemple:

  • Programme/script: powershell.exe
  • Ajouter des arguments : -commande "& 'C:\HSD - Copier\logoffstudents.ps1" "-NonInteractive
  • Commencez par: Blanc
6
Doltknuckle
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"

Notez l'utilisation de ' dans le chemin d'un fichier à exécuter.

5
Aman Mehra

Dans ce cas, vous pouvez contourner le problème en transmettant votre paramètre de chemin d'accès au format 8.3.

Vous pouvez découvrir le format 8.3 de votre chemin en ouvrant une invite de commande et en émettant la commande dir /x à la racine de votre lecteur.

Vous devriez voir une entrée semblable à

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

pour votre répertoire Program Files.

Puis changez de répertoire en Program Files avec cd "Program Files "suivi de cd xyz et relancez dir /x pour trouver le nom de format 8.3 pour" The Interface ", etc.

Votre chemin final pour l'exemple que vous avez donné ressemblerait à quelque chose comme:

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

J'ai eu un problème similaire avec VLC, que j'utilisais sous Windows XP. L'astuce consiste à mettre l'argument de la commande cmd entre guillemets.

Voici un exemple de ce que j'ai utilisé (programmer un enregistrement à 15h00):

à 15:00 cmd/c "" C:\Programmi\VideoLAN\VLC\vlc.exe dvb-t: // fréquence = 698000000: programme = 4006: run-time = 5 --sout "C:\Documents et paramètres\Nom d'utilisateur\Documents\Vidéo\VLC\test.mpg "" "

Notez l'utilisation de guillemets juste après /c et à la fin de la commande (après .mpg). L'argument avec des espaces dans ce cas est "C:\Documents and Settings\..."

1
tomatoma

Pour ce faire, utilisez l'une des méthodes suivantes: powershell, à partir de la ligne de commande.

Ajoutez ce code à un fichier appelé 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-*"

Ensuite, à partir de la ligne de commande OR, un fichier ps1 que vous pouvez exécuter:

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)

Chaque élément respectif du tableau taskparameters serait passé sous la forme $ (Arg0), $ (Arg1) et $ (Arg2).

1
SpaceGhost440

Cela peut aider de comprendre le problème sous un angle différent. Supposons que vous soyez le programmeur chargé d’ajouter un planificateur de tâches à Windows. Comment le ferais-tu? Vous devez faire face à plusieurs problèmes: Si la tâche est exécutée en tant que personne autre que l'utilisateur connecté, devez-vous ennuyer l'utilisateur connecté avec des fenêtres contextuelles d'erreur? Que se passe-t-il s'il n'y a pas d'utilisateur connecté au moment de l'exécution de la tâche? Qu'en est-il de la différence entre un programme graphique et un programme console? Les interfaces graphiques n'ont pas stdin, stdout et stderr; le concept n'a pas de sens en eux. Qu'en est-il des programmes internes ou externes à COMMAND.COM/CMD.EXE? Ou d'autres moteurs de script? Qu'en est-il des chemins avec des espaces dans le nom de la commande? Ou dans les paramètres (options/arguments)? (Comme vous essayez de traiter maintenant ..)

Bien que je ne sois pas tout à fait sûr des détails internes ou techniques complets dans ce cas, les réponses semblent être .. Les tâches sont exécutées dans une session isolée et non interactive, qui ne peut pas interagir avec l'utilisateur actuellement connecté (le cas échéant). ) Il s'attend à ce qu'il n'y ait aucune sortie de console, car non interactif, il ne peut interrompre aucun utilisateur connecté pour afficher la sortie, de toute façon (et s'il existe une sortie, stdin est le bitbucket/NULL, stdout et stderr sont consignés la fonction de journalisation du système); Les espaces sont gérés en contournant le problème: le nom de la commande est pris EXACTEMENT tel quel, et les paramètres transmis à la commande sont spécifiés dans une autre zone de saisie. dans les propriétés de la tâche.

Cela signifie que votre tâche doit être exécutée comme s'il s'agissait d'un démon (dans le monde Un * x). Tout est statique et précis. Le nom de la commande est le nom actuel de la commande, sans aucun paramètre. Cela inclut souvent l'exécution d'interprètes de commande/script, tels que CMD.EXE! Les paramètres éventuels sont spécifiés ailleurs et doivent être connus lors de la configuration de la tâche (autrement dit, vous ne pouvez pas modifier les paramètres "à la volée"). Etc.

Donc, si vous souhaitez inclure des paramètres, vous devez utiliser la section des paramètres pour spécifier les paramètres. Le planificateur de tâches n'essaie pas d'analyser le nom de la commande pour le scinder en "commande" et "argument" comme le font les programmes en ligne de commande. Il la traite simplement comme un grand nom de commande complet. De même, si vous voulez des paramètres variables, comme utiliser% 1 ..% n dans les fichiers BATCH, vous ne pouvez pas le faire à partir du planificateur de tâches lui-même; Vous devrez trouver un autre moyen. (Notez que vous ne pouvez pas utiliser de variables d’environnement non plus, car l’environnement transmis au programme dépend de l’environnement avec lequel la tâche est démarrée, PAS de l’environnement "actuel".) Vous pouvez utiliser un fichier temporaire pour enregistrer les paramètres. devez spécifier un nom de fichier statique dans les propriétés de la tâche, que se passe-t-il lorsque vous êtes sur un réseau de 5 000 utilisateurs et que quatre d'entre eux essaient d'exécuter la même tâche au même moment? Ils vont tous s'embrasser en essayant d'écrire dans le même fichier temporaire en même temps, probablement pas ce que vous vouliez, non plus. (Il y a aussi des solutions à ce problème, mais cela sort du cadre de la question et de la réponse.)

Donc réponse finale: dans le cas simple - le chemin que vous voulez passer en tant que paramètre est statique et ne change pas - vous devez soit spécifier les paramètres dans la propriété de tâche appropriée (arguments) plutôt que dans la zone programme/script ou utilisez un fichier de commandes. Dans un cas plus complexe, vous devrez poser la bonne question ou rechercher le fonctionnement des démons et l'utilisation du verrouillage/des sémaphores, par exemple pour la communication inter-processus (IPC).

Bonne chance.

1
C. M.

Définissez votre tâche planifiée comme suit

cmd/c C:\Program Files\xyz\Transfert de fichier FTP\FTPFileTransferTask.exe "C:\Program Files\xyz\Le chemin de l’interface \"

0
incognito