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で試してみましたが、どちらも失敗しました。これに関する議論はないようですか?
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"
実行するファイルのパスで'
を使用していることに注意してください。
私はスケジュールされたタスクを扱ってきましたが、通常、引数は独自のテキスト入力ボックスに入力します。つまり、アクションをプログラム/スクリプトフィールドがexeにポイントし、[引数の追加]フィールドにすべてのパラメーターが含まれている必要があります。 ( ソース )
この動作は、exeへのファイルパス内のスペースが問題を引き起こすのを防ぐために追加されたと思います。
私はいつもPowerShellスクリプトを使ってこれを行っています。次に例を示します。
この場合、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
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つの方法は、コマンドラインから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)として渡されます。
スケジュールされたタスクを次のように設定します
cmd/c C:\ Program Files\xyz\FTP File Transfer\FTPFileTransferTask.exe "C:\ Program Files\xyz\The Interface\Folder Path"
別の観点から問題を理解するのに役立つかもしれません。あなたがWindowsにタスクスケジューラを追加する責任を負っているプログラマであるとしましょう。どうしますか対処する必要のある問題がいくつかあります。タスクがログインしているユーザー以外のユーザーとして実行されている場合、ログインしているユーザーをエラーポップアップで困らせますか?タスクの実行時にログインしているユーザーがいない場合はどうなりますか? GUIプログラムとコンソールプログラムの違いは何ですか? GUIには、stdin、stdout、およびstderrはありません。概念はそれらで無意味です。 COMMAND.COM/CMD.EXEの内部または外部のプログラムについてはどうですか?または他のスクリプトエンジン?コマンド名にスペースを含むパスはどうですか?またはパラメーター(オプション/引数)で? (あなたが今対処しようとしているように..)
この場合、内部または完全な技術的詳細については100%確実ではありませんが、答えはあるようです。タスクは、現在ログインしているユーザー(存在する場合)と対話できない、分離された非対話型セッションで実行されます。 );コンソール出力がないことを期待して実行されます。非インタラクティブであるため、ログインしているユーザーを中断して出力を表示することはできません。システムのロギング機能);スペースは問題を回避することで処理されます。コマンド名が使用されます[〜#〜] exactly [〜#〜]そのままで、コマンドに渡されるパラメーターはタスクの別の入力ボックスで指定されますプロパティ。
つまり、タスクはデーモンのように(Un * xの世界では)実行する必要があるということです。すべてが静的で正確です。コマンド名は、パラメータなしの実際のコマンド名です。これには、CMD.EXEなどのコマンド/スクリプトインタープリターの実行も含まれます。パラメータがある場合は、それを別の場所で指定し、タスクを設定するときに知っておく必要があります(つまり、「オンザフライ」でパラメータを変更することはできません)。等々。
したがって、パラメーターを含める場合は、パラメーターセクションを使用してパラメーターを指定する必要があります。タスクスケジューラはnotコマンド名を解析して、コマンドラインプログラムが行うように「コマンド」と「引数」に分割します。それを1つの大きな完全なコマンド名として扱うだけです。同様に、BATCHファイルで%1 ..%nを使用するなど、可変パラメーターが必要な場合は、タスクスケジューラ自体からは実行できません。別の方法を見つける必要があります。 (プログラムに渡される環境は、「現在の」環境ではなく、タスクが開始される環境に依存するため、環境変数も使用できないことに注意してください。)一時ファイルを使用してパラメーターを保存できますが、タスクのプロパティで静的ファイル名を指定する必要があります。5000人のユーザーがいるネットワークで、4人が同時に同じタスクを実行しようとするとどうなりますか?それらはすべて、おそらく同じ目的のファイルに同時に書き込みを試みて、互いにやりとりします。 (この問題には解決策もありますが、それはこの質問と回答の範囲をはるかに超えています。)
だから最後の答え:単純なケースでは-パラメーターとして渡すパスは静的で変更されません-プログラム/スクリプトボックスではなく、適切なタスクプロパティ(引数)でパラメーターを指定する必要があります、またはバッチファイルを使用します。より複雑なケースでは、適切な質問をするか、デーモンがどのように機能するか、およびプロセス間通信(IPC)でロック/セマフォなどを使用する方法を調査する必要があります。
幸運を。