Jak przekazać argument do zaplanowanego zadania systemu Windows ze spacjami

15

Muszę skonfigurować zaplanowane zadanie systemu Windows. Przyjmuje 1 parametr / argument, który jest ścieżką i może zawierać spacje. Moje zaplanowane zadanie nie działa - „rozbija” parametr w pierwszym miejscu.

Jeśli uruchomię go w wierszu polecenia, mogę po prostu zawinąć argument w „” i działa dobrze, jednak nie działa to w interfejsie Zaplanowanego Zadania.

na przykład C:\Program Files\xyz\FTP File Transfer\FTPFileTransferTask.exe "C:\Program Files\xyz\The Interface\Folder Path"

Próbowałem zawinąć argument za pomocą „” „” [] () i bez powodzenia próbowałem wypełnić spacje% 20, ~ 1 itd.

Znam jedno rozwiązanie, aby utworzyć plik nietoperza i użyć argumentu „” wokół mojego argumentu, ale nie chcę dodawać większej złożoności.

Wypróbowałem to na Windows 7 i Windows 2008 Server i oba zakończyły się niepowodzeniem. Wydaje się, że nie ma dyskusji na ten temat?

Rodney
źródło
1
Czy umieszczasz argument w sekcji Program / skrypt lub Dodaj argumenty (opcjonalnie) podczas edycji Zaplanowanego zadania?
William Jackson
Byłoby pomocne, gdybyś określił dokładnie, którego programu używasz, ponieważ prawidłowe zawijanie argumentów zależy od programu, a nie od Zaplanowanych Taksów. Na przykład WinSCP oczekuje podwójnych cudzysłowów („” ... ”), gdy trzeba zagnieżdżać cudzysłowy.
Tobias Plutat
Nie jest jasne, co do 1) niepowodzenia, zadania lub pliku .exe oraz 2) dokładnie tego, co wpisałeś i gdzie w interfejsie TaskSched. Czy to możliwe, że gdy TaskSched prosi o polecenie (pełna ścieżka do pliku wykonywalnego), próbujesz nadać mu wiersz polecenia (coś zupełnie innego)?
kreemoweet
Dlaczego przeciwko plikowi wsadowemu? To sprawia, że ​​wszystko jest takie proste! Lub możesz strzelać do skryptu PowerShell, jeśli masz ochotę na przygodę ...
tumchaaditya

Odpowiedzi:

6

Pracowałem z zaplanowanymi zadaniami i zwykle umieszczasz argumenty we własnym polu wprowadzania tekstu. Oznacza to, że skierujesz akcję na pole programu / skryptu, które wskazuje na plik exe, a pole „Dodaj argumenty” powinno mieć wszystkie parametry. ( źródło )

Obraz bloga

Myślę, że to zachowanie zostało dodane, aby zapobiec spacjom w ścieżce pliku do pliku exe powodującym problemy.

Robię to cały czas za pomocą skryptów PowerShell. Oto przykład:

  • Program / skrypt: powershell.exe
  • Dodaj argumenty : -command "& 'C: \ HSD - Copy \ logoffstudents.ps1'" -NonInteractive
  • Rozpocznij za: Puste
Doltknuckle
źródło
Dzięki, ale problem polega na tym, że jeden z moich parametrów JEST ścieżką do pliku (i ma w nim spację). Więc w twoim przykładzie 100 będzie działać, ale co jeśli chcesz przekazać „C: \ Start Folder”?
Rodney
Po prostu używam cytatów w moich programach i to działa. Znak ampersand jest wymagany tylko w przypadku PowerShell. Ten symbol jest operatorem CALL i pozwala mi wywołać polecenie PowerShell. W większości przypadków potrzebne są cytaty. W tym momencie możesz chcieć skontaktować się z twórcą exe, aby sprawdzić, czy obsługują zaplanowane zadania. Natknąłem się na kilka rzadkich programów, które po prostu odmawiają uruchomienia jako zaplanowane zadanie. Myślę, że istnieją subtelne różnice w sposobie przekazywania parametrów, które mogą powodować problemy. Przepraszam, nie mogę pomóc więcej.
Doltknuckle
W najgorszym przypadku możesz zmienić strukturę folderu, aby wyeliminować spacje. To nie jest to, czego chcesz, ale może to być jedyny sposób, aby to zadziałało.
Doltknuckle
Dzięki Doltknuckle - wiem, że mógłbym to zrobić również z plikiem .bat (i używać „” wokół parametrów (tak jak w skrypcie Powershell. Jestem pewien, że jest to błąd w interfejsie edytora zadań Windows ... jestem twórcą .exe;) - Działa dobrze przez wiązkę testową i z wiersza polecenia, ale nie przez interfejs użytkownika Windows ...
Rodney
1
Jeśli stworzyłeś exe, może to być pytanie o przepełnienie stosu. Mam wrażenie, że może być konieczne zmodyfikowanie obsługi parametrów, gdy ten plik exe jest używany z zaplanowanym zadaniem. Jedną z sugestii jest, aby twój exe rejestrował parametry otrzymane do pliku, abyś mógł zobaczyć, co jest przekazywane. Pozwoliłoby to przynajmniej sprawdzić, czy parametry zaplanowanego zadania są takie same jak parametry wiersza poleceń.
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"

Zwróć uwagę na użycie 'w ścieżce pliku do uruchomienia.

Aman Mehra
źródło
3

W takim przypadku można obejść problem, przekazując parametr ścieżki w formacie 8.3.

Możesz odkryć format 8.3 swojej ścieżki, otwierając wiersz polecenia i wydając polecenie dir /xw katalogu głównym dysku.

Powinieneś zobaczyć wpis podobny do

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

dla katalogu Program Files.

Następnie zmień katalog na Program Files with cd "Program Files”, a następnie cd xyz i wydaj dir /xponownie, aby znaleźć nazwę formatu 8.3 dla„ The Interface ”i tak dalej.

Ostateczna ścieżka do podanego przykładu wyglądałaby mniej więcej tak:

C:\PROGRA~1\XYZ\THEINT~1\FOLDER~1
Keith
źródło
Dziękuję, doceniam odpowiedź, jednak powoduje to dalsze problemy. Zasadniczo nazywam aplikację EXE .NET, którą napisałem, która do czegoś używa tej ścieżki folderu parametrów - nie lubi formatu 8.3 i nie może znaleźć ścieżki. Czy jest więc jakiś inny sposób?
Rodney
ps - czy to jest błąd w aplikacji Windows Scheduled Task? Miejsca są bardzo powszechne!
Rodney
Szybki test na Windows 7 działa dla mnie. Czy możesz przeprowadzić nas przez kroki, które wykonałeś, aby skonfigurować zadanie, ponieważ istnieją różne sposoby. Dzięki za edycję, Gareth, wygląda o wiele ładniej.
Keith
Tak więc zadanie działa poprawnie z tym formatowaniem, ale mój program .NET (który akceptuje ścieżkę jako ciąg arg) nie dekompresuje ścieżki z formatu 8.3. Więc może jest to pytanie programistyczne - jak obsługiwać ścieżki 8.3?
Rodney
Wiem, że to stare, ale czy próbowałeś łącznika (-)?
Chibueze Opata,
1

Miałem podobny problem z VLC, którego używałem w systemie Windows XP. Sztuką jest, aby ująć argument w cmdkomendzie w cudzysłowach.

Oto przykład tego, czego użyłem (planując nagranie o 15:00):

o 15:00 cmd / c "" C: \ Programmi \ VideoLAN \ VLC \ vlc.exe dvb-t: // frequency = 698000000: program = 4006: run-time = 5 --out "C: \ Documents and Settings \ UserName \ Documents \ Video \ VLC \ test.mpg „”

Zwróć uwagę na użycie podwójnych cudzysłowów tuż po /ci na końcu polecenia (po .mpg). Argument spacji w tym przypadku to"C:\Documents and Settings\..."

Pomidor
źródło
1

Jednym ze sposobów na osiągnięcie tego jest użycie PowerShell z wiersza poleceń.

Dodaj ten kod do pliku o nazwie 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-*"

Następnie z wiersza polecenia LUB pliku ps1 możesz uruchomić:

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)

Każdy odpowiedni element w tablicy parametrów zadania byłby przekazywany jako $ (Arg0), $ (Arg1) i $ (Arg2).

SpaceGhost440
źródło
0

Ustaw zaplanowane zadanie w następujący sposób

cmd / c C: \ Program Files \ xyz \ FTP File Transfer \ FTPFileTransferTask.exe „C: \ Program Files \ xyz \ Interfejs \ Ścieżka folderu”

incognito
źródło
0

Pomoże to zrozumieć problem z innej perspektywy. Powiedzmy, że jesteś programistą, którego zadaniem jest dodanie harmonogramu zadań do systemu Windows. Jak byś to zrobił? Masz kilka problemów, z którymi musisz się zmierzyć: Jeśli zadanie jest uruchamiane jako osoba inna niż zalogowany użytkownik, czy powinieneś denerwować zalogowanego użytkownika jakimś wyskakującym okienkiem błędu? Co jeśli nie ma zalogowanego użytkownika w momencie uruchamiania zadania? Co z różnicą między programem GUI a programem konsoli? GUI nie mają stdin, stdout i stderr; koncepcja jest w nich bez znaczenia. Co z programami wewnętrznymi lub zewnętrznymi do COMMAND.COM/CMD.EXE? Lub inne silniki skryptowe? Co ze ścieżkami ze spacjami w nazwie polecenia? Lub w parametrach (opcje / argumenty)? (Gdy próbujesz sobie teraz poradzić ...)

Chociaż w tym przypadku nie jestem w 100% pewien co do wewnętrznych elementów ani pełnych szczegółów technicznych, odpowiedzi wydają się być… Zadania są uruchamiane w odizolowanej, nieinteraktywnej sesji, która nie może wchodzić w interakcje z aktualnie zalogowanym użytkownikiem (jeśli w ogóle ); Uruchamia się, oczekując, że nie będzie żadnego wyjścia konsoli, ponieważ jest nieinteraktywny, nie może po prostu przerwać zalogowanego użytkownika, aby pokazać wyjście, w każdym razie (a jeśli jest wyjście, stdin jest bitbucket / NULL, stdout i stderr zostają zalogowane do funkcja logowania do systemu); Spacje są obsługiwane przez pominięcie problemu: nazwa polecenia jest pobierana DOKŁADNIE w takiej postaci, w jakiej jest, a parametry przekazywane do polecenia są określone w innym polu wejściowym we właściwościach zadania.

Oznacza to, że twoje zadanie musi być uruchomione tak, jakby było demonem (w świecie Un * x). Wszystko jest statyczne i precyzyjne. Nazwa polecenia jest faktyczną nazwą polecenia, bez żadnych parametrów. Często obejmuje to uruchamianie interpreterów poleceń / skryptów, takich jak CMD.EXE! Parametry, jeśli istnieją, są określone gdzie indziej i muszą być znane podczas konfigurowania zadania (tzn. Nie można zmieniać parametrów „w locie”). I tak dalej.

Tak więc, jeśli chcesz dołączyć parametry, musisz użyć sekcji parametrów, aby określić parametry. Harmonogram zadań niespróbuj parsować nazwę polecenia, aby podzielić go na „polecenie” i „argumenty”, tak jak robią to programy wiersza poleceń. Po prostu traktuje to jako jedną wielką, pełną nazwę polecenia. Podobnie, jeśli chcesz parametrów zmiennych, takich jak użycie% 1 ..% n w plikach BATCH, nie możesz tego zrobić z poziomu samego Harmonogramu zadań; Musisz znaleźć inny sposób. (Należy pamiętać, że nie można również używać zmiennych środowiskowych, ponieważ środowisko przekazane do programu zależy od środowiska, w którym uruchamiane jest zadanie, a NIE od środowiska „bieżącego”.) Można użyć pliku tymczasowego do zapisania parametrów, ale ponieważ musisz określić statyczną nazwę pliku we właściwościach zadania, co dzieje się, gdy jesteś w sieci z 5000 użytkownikami i czterech z nich próbuje uruchomić to samo zadanie w tym samym czasie? Wszyscy będą się wzajemnie zaciskać, próbując jednocześnie zapisać w tym samym pliku tymczasowym, prawdopodobnie też nie to, czego chciałeś. (Istnieją również rozwiązania tego problemu, ale wykracza to zbyt daleko poza zakres tego pytania i odpowiedzi ..)

Ostateczna odpowiedź: w prostym przypadku - ścieżka, którą chcesz przekazać jako parametr, jest statyczna i nie zmienia się - albo musisz podać parametry w odpowiedniej właściwości Zadania (Argumenty), a nie w polu Program / Skrypt lub użyj pliku wsadowego. W bardziej złożonym przypadku - musisz zadać właściwe pytanie lub zbadać, w jaki sposób działają demony i jak używać blokowania / semaforów i tym podobnych do komunikacji międzyprocesowej (IPC).

Powodzenia.

CM
źródło