web-dev-qa-db-ja.com

スペースを含むWindowsスケジュールタスクに引数を渡す方法

Windowsスケジュールタスクを設定する必要があります。パスであり、スペースを含めることができる1つのパラメーター/引数を受け入れます。スケジュールされたタスクが機能しません-最初のスペースでパラメーターが「分割」されます。

コマンドプロンプトで実行すると、引数を ""で囲むだけで問題なく機能しますが、これはスケジュールされたタスクのUIでは機能しません。

例えばC:\Program Files\xyz\FTP File Transfer\FTPFileTransferTask.exe "C:\Program Files\xyz\The Interface\Folder Path"

引数を "" '' []()でラップしてみましたが、スペースに%20、〜1などを埋めることができませんでした。

私はbatファイルを作成し、引数を ""で囲む1つの解決策を知っていますが、さらに複雑にしたくありません。

Windows 7とWindows 2008 Serverで試してみましたが、どちらも失敗しました。これに関する議論はないようですか?

15
Rodney
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"

実行するファイルのパスで'を使用していることに注意してください。

6
Aman Mehra

私はスケジュールされたタスクを扱ってきましたが、通常、引数は独自のテキスト入力ボックスに入力します。つまり、アクションをプログラム/スクリプトフィールドがexeにポイントし、[引数の追加]フィールドにすべてのパラメーターが含まれている必要があります。 ( ソース

Blog image

この動作は、exeへのファイルパス内のスペースが問題を引き起こすのを防ぐために追加されたと思います。

私はいつもPowerShellスクリプトを使ってこれを行っています。次に例を示します。

  • プログラム/スクリプト:powershell.exe
  • 引数を追加:-command "& 'C:\ HSD-Copy\logoffstudents.ps1'" -NonInteractive
  • 開始:空白
6
Doltknuckle

この場合、8.3形式でパスパラメータを渡すことで問題を回避できます。

パスの8.3形式を見つけるには、コマンドプロンプトを開き、ドライブのルートでdir /xコマンドを発行します。

次のようなエントリが表示されます

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

program Filesディレクトリ。

次に、ディレクトリをcd "Program Files "の後にcd xyzが続くProgram Filesに変更し、再度dir /xを発行して、「The Interface」などの8.3形式の名前を探します。

与えた例の最終的なパスは次のようになります。

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

Windows XPで使用していたVLCにも同様の問題がありました。トリックは、二重引用符でcmdコマンドの 引数を囲む にすることです。

これは私が使用した例です(15:00に録音をスケジュールします)。

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

/cの直後とコマンドの最後(.mpgの後)での二重引用符の使用に注意してください。この場合のスペースを含む引数は"C:\Documents and Settings\..."です

1
tomatoma

これを実現する1つの方法は、コマンドラインからPowerShellを使用することです。

このコードを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-*"

次に、コマンドラインからOR実行できるps1ファイル:

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)

Taskparameters配列のそれぞれの項目は、$(Arg0)、$(Arg1)、および$(Arg2)として渡されます。

1
SpaceGhost440

スケジュールされたタスクを次のように設定します

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

0
incognito

別の観点から問題を理解するのに役立つかもしれません。あなたがWindowsにタスクスケジューラを追加する責任を負っているプログラマであるとしましょう。どうしますか対処する必要のある問題がいくつかあります。タスクがログインしているユーザー以外のユーザーとして実行されている場合、ログインしているユーザーをエラーポップアップで困らせますか?タスクの実行時にログインしているユーザーがいない場合はどうなりますか? GUIプログラムとコンソールプログラムの違いは何ですか? GUIには、stdin、stdout、およびstderrはありません。概念はそれらで無意味です。 COMMAND.COM/CMD.EXEの内部または外部のプログラムについてはどうですか?または他のスクリプトエンジン?コマンド名にスペースを含むパスはどうですか?またはパラメーター(オプション/引数)で? (あなたが今対処しようとしているように..)

この場合、内部または完全な技術的詳細については100%確実ではありませんが、答えはあるようです。タスクは、現在ログインしているユーザー(存在する場合)と対話できない、分離された非対話型セッションで実行されます。 );コンソール出力がないことを期待して実行されます。非インタラクティブであるため、ログインしているユーザーを中断して出力を表示することはできません。システムのロギング機能);スペースは問題を回避することで処理されます。コマンド名が使用されます[〜#〜] exactly [〜#〜]そのままで、コマンドに渡されるパラメーターはタスクの別の入力ボックスで指定されますプロパティ。

つまり、タスクはデーモンのように(Un * xの世界では)実行する必要があるということです。すべてが静的で正確です。コマンド名は、パラメータなしの実際のコマンド名です。これには、CMD.EXEなどのコマンド/スクリプトインタープリターの実行も含まれます。パラメータがある場合は、それを別の場所で指定し、タスクを設定するときに知っておく必要があります(つまり、「オンザフライ」でパラメータを変更することはできません)。等々。

したがって、パラメーターを含める場合は、パラメーターセクションを使用してパラメーターを指定する必要があります。タスクスケジューラはnotコマンド名を解析して、コマンドラインプログラムが行うように「コマンド」と「引数」に分割します。それを1つの大きな完全なコマンド名として扱うだけです。同様に、BATCHファイルで%1 ..%nを使用するなど、可変パラメーターが必要な場合は、タスクスケジューラ自体からは実行できません。別の方法を見つける必要があります。 (プログラムに渡される環境は、「現在の」環境ではなく、タスクが開始される環境に依存するため、環境変数も使用できないことに注意してください。)一時ファイルを使用してパラメーターを保存できますが、タスクのプロパティで静的ファイル名を指定する必要があります。5000人のユーザーがいるネットワークで、4人が同時に同じタスクを実行しようとするとどうなりますか?それらはすべて、おそらく同じ目的のファイルに同時に書き込みを試みて、互いにやりとりします。 (この問題には解決策もありますが、それはこの質問と回答の範囲をはるかに超えています。)

だから最後の答え:単純なケースでは-パラメーターとして渡すパスは静的で変更されません-プログラム/スクリプトボックスではなく、適切なタスクプロパティ(引数)でパラメーターを指定する必要があります、またはバッチファイルを使用します。より複雑なケースでは、適切な質問をするか、デーモンがどのように機能するか、およびプロセス間通信(IPC)でロック/セマフォなどを使用する方法を調査する必要があります。

幸運を。

0
C. M.