Übergeben eines Arguments an einen geplanten Windows-Task mit Leerzeichen

15

Ich muss eine geplante Windows-Aufgabe einrichten. Es akzeptiert 1 Parameter / Argument, das ein Pfad ist und Leerzeichen enthalten kann. Meine geplante Aufgabe funktioniert nicht - sie "bricht" den Parameter beim ersten Leerzeichen auf.

Wenn ich es in der Eingabeaufforderung ausführe, kann ich das Argument einfach in "" einschließen und es funktioniert einwandfrei. Dies funktioniert jedoch nicht in der Benutzeroberfläche für geplante Tasks.

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

Ich habe versucht, das Argument mit "" '' [] () zu umschließen und habe versucht, die Leerzeichen mit% 20, ~ 1 usw. zu füllen, ohne Erfolg.

Ich kenne eine Lösung, um eine Fledermausdatei zu erstellen und "" um mein Argument herum zu verwenden, aber ich möchte nicht mehr Komplexität hinzufügen.

Ich habe es unter Windows 7 und Windows 2008 Server versucht und beide sind fehlgeschlagen. Es scheint keine Diskussionen darüber zu geben?

Rodney
quelle
1
Fügen Sie das Argument in den Abschnitt Programm / Skript oder in den Abschnitt Argumente hinzufügen (optional) ein, wenn Sie die geplante Aufgabe bearbeiten?
William Jackson
Es wäre hilfreich, wenn Sie genau angeben, welches Programm Sie verwenden, da das korrekte Umschließen von Argumenten im Ermessen des Programms und nicht von Scheduled Taks liegt. WinSCP erwartet beispielsweise doppelte Anführungszeichen ("" ... ""), wenn Sie Anführungszeichen verschachteln müssen.
Tobias Plutat
Es ist ziemlich unklar, 1) was fehlschlägt, die Aufgabe oder Ihre .exe, und 2) genau, was Sie eingegeben haben und wo in der TaskSched-Benutzeroberfläche. Könnte es sein, dass Sie, wenn TaskSched nach einem Befehl fragt (vollständiger Pfad zur ausführbaren Datei), versuchen, ihm eine Befehlszeile zu geben (etwas ganz anderes)?
Kreemoweet
Warum gegen Batch-Datei? Es macht die Dinge so einfach! Oder Sie können für Powershell-Skript schießen, wenn Sie abenteuerlustig sind ..
Tumchaaditya

Antworten:

6

Ich habe mit geplanten Aufgaben gearbeitet und Sie haben die Argumente im Allgemeinen in ein eigenes Texteingabefeld eingegeben. Dies bedeutet, dass Sie die Aktion auf das Programm- / Skriptfeld verweisen und dass das Feld "Argumente hinzufügen" alle Parameter enthalten sollte. ( Quelle )

Blog-Bild

Ich glaube, dieses Verhalten wurde hinzugefügt, um zu verhindern, dass Leerzeichen im Dateipfad zur exe Probleme verursachen.

Ich mache das die ganze Zeit mit PowerShell-Skripten. Hier ist ein Beispiel:

  • Programm / Skript: powershell.exe
  • Fügen Sie folgende Argumente hinzu : -Befehl "& 'C: \ HSD - Copy \ logoffstudents.ps1'" -NonInteractive
  • Beginnen Sie in: Blank
Doltknuckle
quelle
Danke, aber das Problem ist, dass einer meiner Parameter ein Dateipfad ist (und ein Leerzeichen enthält). In Ihrem Beispiel funktionieren also 100, aber was ist, wenn Sie "C: \ Start Folder" übergeben möchten?
Rodney
Ich benutze nur Anführungszeichen in meinen Programmen und es funktioniert. Das kaufmännische Und wird nur mit Powershell benötigt. Dieses Symbol ist der CALL-Operator und ermöglicht es mir, einen Powershell-Befehl aufzurufen. In den meisten Fällen genügen Anführungszeichen. Zu diesem Zeitpunkt möchten Sie möglicherweise den Ersteller der Exe kontaktieren, um festzustellen, ob er geplante Aufgaben unterstützt. Ich bin auf einige seltene Programme gestoßen, die sich einfach weigern, als geplante Aufgabe ausgeführt zu werden. Ich denke, es gibt subtile Unterschiede bei der Übergabe der Parameter, die Probleme verursachen können. Entschuldigung, ich kann nicht mehr helfen.
Doltknuckle
Im schlimmsten Fall können Sie den Ordner neu strukturieren, um die Leerzeichen zu entfernen. Es ist nicht das, was Sie wollen, aber es könnte der einzige Weg sein, es zum Laufen zu bringen.
Doltknuckle
Danke Doltknuckle - ich weiß, ich könnte es auch mit einer .bat - Datei machen (und "" um den Parameter herum verwenden (wie Sie es im Powershell - Skript tun. Ich bin sicher, es ist ein Fehler in der Benutzeroberfläche des Windows - Task - Editors ... (I bin der Schöpfer der .exe;) - Es funktioniert gut über ein Testkabel und über die Eingabeaufforderung, aber nicht über die Windows-Benutzeroberfläche ...
Rodney
1
Wenn Sie die Exe gemacht haben, kann dies eine Frage für den Stackoverflow sein. Ich habe das Gefühl, dass Sie möglicherweise Ihre Parameterbehandlung ändern müssen, wenn diese exe mit geplanten Task verwendet wird. Ein Vorschlag ist, dass Ihre Exe-Datei die empfangenen Parameter in einer Datei protokolliert, damit Sie sehen können, was übergeben wird. Zumindest können Sie sehen, ob die geplanten Task-Parameter mit den Befehlszeilenparametern übereinstimmen.
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"

Beachten Sie die Verwendung von 'im Pfad einer auszuführenden Datei.

Aman Mehra
quelle
3

In diesem Fall können Sie das Problem umgehen, indem Sie Ihren Pfadparameter im 8.3-Format übergeben.

Sie können das 8.3-Format für Ihren Pfad ermitteln, indem Sie eine Eingabeaufforderung öffnen und den Befehl dir /xim Stammverzeichnis Ihres Laufwerks eingeben.

Sie sollten einen ähnlichen Eintrag sehen wie

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

für Ihr Programmverzeichnis.

Wechseln Sie dann mit cd "Program Files"gefolgt von cd xyz" in das Verzeichnis "Programme " und geben Sie es dir /xerneut aus, um den 8.3-Formatnamen für "The Interface" usw. zu finden.

Ihr letzter Pfad für das Beispiel, das Sie gegeben haben, würde ungefähr so ​​aussehen:

C:\PROGRA~1\XYZ\THEINT~1\FOLDER~1
Keith
quelle
Vielen Dank, ich freue mich über die Antwort, aber dies verursacht weitere Probleme. Grundsätzlich rufe ich eine von mir geschriebene EXE .NET-App auf, die diesen param-Ordnerpfad für etwas verwendet - das 8.3-Format gefällt ihr nicht und der Pfad kann nicht gefunden werden. Gibt es eine andere Möglichkeit, dies zu tun?
Rodney
ps - Ist das ein Fehler in der Windows Scheduled Task App? Leerzeichen sind sehr verbreitet!
Rodney
Ein schneller Test unter Windows 7 funktioniert bei mir. Können Sie uns die Schritte erklären, die Sie unternommen haben, um die Aufgabe einzurichten? Es gibt verschiedene Möglichkeiten. Vielen Dank für die Bearbeitung dort Gareth, sieht viel schöner aus.
Keith
Die Aufgabe wird mit dieser Formatierung ordnungsgemäß ausgeführt, aber dann dekomprimiert mein .NET-Programm (das den Pfad als Argumentzeichenfolge akzeptiert) den Pfad aus dem 8.3-Format nicht. Vielleicht ist es also eine Programmierfrage - wie geht man mit 8.3-Pfaden um?
Rodney
Ich weiß, dass wir alt sind, aber haben Sie versucht, Bindestrich (-)?
Chibueze Opata
1

Ich hatte ein ähnliches Problem mit VLC, das ich unter Windows XP verwendete. Der Trick besteht darin, das Argument des cmdBefehls in doppelte Anführungszeichen zu setzen.

Hier ist ein Beispiel dessen, was ich verwendet habe (Planen einer Aufnahme um 15:00 Uhr):

um 15:00 cmd / c "" C: \ Programmi \ VideoLAN \ VLC \ vlc.exe dvb-t: // Frequenz = 698000000: Programm = 4006: Laufzeit = 5 --sout "C: \ Dokumente und Einstellungen \ Benutzername \ Dokumente \ Video \ VLC \ test.mpg "" "

Beachten Sie die Verwendung von doppelten Anführungszeichen unmittelbar nach /cund am Ende des Befehls (nach .mpg). Das Argument mit Leerzeichen ist in diesem Fall"C:\Documents and Settings\..."

Tomate
quelle
1

Eine Möglichkeit, dies zu erreichen, ist die Verwendung von Powershell über die Befehlszeile.

Fügen Sie diesen Code einer Datei mit dem Namen MyModule.psm1 hinzu.

$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-*"

Dann können Sie über die Befehlszeile ODER eine ps1-Datei ausführen:

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)

Jedes entsprechende Element im taskparameters-Array wird als $ (Arg0), $ (Arg1) und $ (Arg2) übergeben.

SpaceGhost440
quelle
0

Stellen Sie Ihre geplante Aufgabe wie folgt ein

cmd / c C: \ Programme \ xyz \ FTP-Dateiübertragung \ FTPFileTransferTask.exe "C: \ Programme \ xyz \ Die Benutzeroberfläche \ Ordnerpfad"

inkognito
quelle
0

Es könnte hilfreich sein, das Problem aus einer anderen Perspektive zu verstehen. Nehmen wir an, Sie sind der Programmierer, der damit beauftragt wurde, Windows einen Taskplaner hinzuzufügen. Wie würdest du es machen? Sie haben verschiedene Probleme: Wenn die Aufgabe nicht als angemeldeter Benutzer ausgeführt wird, sollten Sie den angemeldeten Benutzer mit Fehler-Popups belästigen? Was ist, wenn zum Zeitpunkt der Taskausführung kein Benutzer angemeldet ist? Was ist mit dem Unterschied zwischen einem GUI-Programm und einem Konsolenprogramm? GUIs haben kein stdin, kein stdout und kein stderr; Das Konzept ist in ihnen bedeutungslos. Was ist mit internen oder externen Programmen für COMMAND.COM/CMD.EXE? Oder andere Scripting Engines? Was ist mit Pfaden mit Leerzeichen im Befehlsnamen? Oder in den Parametern (Optionen / Argumente)? (Wie Sie versuchen, jetzt zu beschäftigen ..)

Obwohl ich in diesem Fall nicht 100% sicher bin, ob es sich um interne oder technische Details handelt, scheinen die Antworten zu lauten. Aufgaben werden in einer isolierten, nicht interaktiven Sitzung ausgeführt, die nicht mit dem derzeit angemeldeten Benutzer (falls vorhanden) interagieren kann ); Es läuft in der Erwartung, dass es keine Konsolenausgabe gibt, da es nicht interaktiv ist. Es kann jeden angemeldeten Benutzer sowieso nicht unterbrechen, um die Ausgabe anzuzeigen die Systemprotokollierungsanlage); Leerzeichen werden behandelt, indem das Problem umgangen wird: Der Befehlsname wird EXAKT so wie er ist verwendet, und Parameter, die an den Befehl übergeben werden, werden in einem anderen Eingabefeld in den Task-Eigenschaften angegeben.

Das heißt, Ihre Aufgabe muss wie ein Dämon ausgeführt werden (in der Un * x-Welt). Alles ist statisch und präzise. Der Befehlsname ist der tatsächliche Befehlsname ohne Parameter. Dies beinhaltet häufig das Ausführen von Befehls / Skript-Interpretern, wie z. B. CMD.EXE! Die Parameter, falls vorhanden, werden an anderer Stelle angegeben und müssen beim Einrichten der Task bekannt sein (dh, Sie können die Parameter nicht "on-the-fly" ändern). Und so weiter.

Wenn Sie also Parameter einbeziehen möchten, müssen Sie den Parameterabschnitt verwenden, um die Parameter anzugeben. Der Taskplaner funktioniert nichtVersuchen Sie, den Befehlsnamen zu analysieren, um ihn in "command" und "args" zu unterteilen, wie dies Befehlszeilenprogramme tun. Es wird nur als ein großer, vollständiger Befehlsname behandelt. Wenn Sie variable Parameter möchten, z. B.% 1 ..% n in BATCH-Dateien, können Sie dies nicht über den Taskplaner selbst tun. Du musst einen anderen Weg finden. (Beachten Sie, dass Sie auch keine Umgebungsvariablen verwenden können, da die an das Programm übergebene Umgebung von der Umgebung abhängt, mit der der Task gestartet wird, NICHT von der "aktuellen" Umgebung.) Sie könnten eine temporäre Datei verwenden, um die Parameter zu speichern In den Task-Eigenschaften muss ein statischer Dateiname angegeben werden. Was passiert, wenn Sie sich in einem Netzwerk mit 5000 Benutzern befinden und vier von ihnen versuchen, denselben Task gleichzeitig auszuführen? Sie alle quälen sich gegenseitig und versuchen gleichzeitig, in dieselbe temporäre Datei zu schreiben. wahrscheinlich auch nicht das, was du wolltest. (Es gibt auch Lösungen für dieses Problem, aber das geht zu weit über den Rahmen dieser Frage und Antwort hinaus.)

Endgültige Antwort: Im einfachen Fall - der Pfad, den Sie als Parameter übergeben möchten, ist statisch und ändert sich nicht - müssen Sie die Parameter entweder in der entsprechenden Task-Eigenschaft (Argumente) und nicht im Feld Programm / Skript angeben oder verwenden Sie eine Batch-Datei. In einem komplexeren Fall müssen Sie die richtige Frage stellen oder untersuchen, wie Dämonen funktionieren und wie Sperren / Semaphoren und dergleichen für die prozessübergreifende Kommunikation (IPC) verwendet werden.

Viel Glück.

CM
quelle