วิธีส่งอาร์กิวเมนต์ไปยัง Windows Scheduled Task ด้วยช่องว่าง


15

ฉันต้องตั้งค่า Windows Scheduled Task ยอมรับ 1 พารามิเตอร์ / อาร์กิวเมนต์ซึ่งเป็นเส้นทางและสามารถมีช่องว่าง งานที่กำหนดเวลาไว้ของฉันไม่ทำงาน - จะ "แยก" พารามิเตอร์ที่ช่องว่างแรก

หากฉันเรียกใช้ในพรอมต์คำสั่งฉันสามารถใส่อาร์กิวเมนต์ใน "" ได้ แต่ก็ใช้งานได้ดี แต่สิ่งนี้จะไม่ทำงานใน UI ที่กำหนดเวลาไว้

เช่น C:\Program Files\xyz\FTP File Transfer\FTPFileTransferTask.exe "C:\Program Files\xyz\The Interface\Folder Path"

ฉันลองตัดอาร์กิวเมนต์ด้วย "" '' [] () และลองเติมช่องว่างด้วย% 20, ~ 1 ฯลฯ โดยไม่มีโชค

ฉันรู้วิธีแก้ปัญหาข้อหนึ่งในการสร้างไฟล์แบ็ตและใช้อาร์กิวเมนต์รอบตัว แต่ไม่ต้องการเพิ่มความซับซ้อน

ฉันลองใน Windows 7 และ Windows 2008 Server และทั้งคู่ล้มเหลว ดูเหมือนจะไม่มีการพูดคุยเกี่ยวกับเรื่องนี้?


1
คุณกำลังใส่อาร์กิวเมนต์ในส่วนโปรแกรม / สคริปต์หรือส่วนเพิ่มอาร์กิวเมนต์ (เป็นทางเลือก)เมื่อคุณแก้ไขภารกิจที่กำหนดเวลาไว้หรือไม่
William Jackson

มันจะมีประโยชน์หากคุณระบุว่าโปรแกรมใดที่คุณกำลังใช้งานอยู่เนื่องจากการตัดอาร์กิวเมนต์ที่ถูกต้องขึ้นอยู่กับดุลยพินิจของโปรแกรมและไม่ใช่ Taks ที่กำหนดเวลาไว้ ตัวอย่างเช่น WinSCP คาดว่าอัญประกาศคู่ ("" ... "") เมื่อคุณต้องซ้อนคำพูด
Tobias Plutat

มันไม่ชัดเจนว่า 1) สิ่งที่ล้มเหลวงานหรือ. exe และ 2) สิ่งที่คุณป้อนและที่อยู่ใน TaskSched UI เป็นไปได้ไหมที่ที่ TaskSched ขอคำสั่ง (พา ธ เต็มไปสู่การปฏิบัติการ) คุณพยายามที่จะให้บรรทัดคำสั่ง (สิ่งที่แตกต่างกันมาก)?
kreemoweet

ทำไมกับไฟล์แบทช์ มันทำให้สิ่งต่าง ๆ ง่ายมาก! หรือคุณสามารถถ่ายทำสคริปต์ PowerShell ถ้าคุณรู้สึกผจญภัย ..
tumchaaditya

คำตอบ:


6

ฉันได้ทำงานกับงานที่กำหนดเวลาไว้แล้วและโดยทั่วไปคุณจะใส่อาร์กิวเมนต์ลงในกล่องป้อนข้อความของตัวเอง ซึ่งหมายความว่าคุณชี้การดำเนินการไปที่ฟิลด์โปรแกรม / สคริปต์ชี้ไปที่ exe และฟิลด์ "เพิ่มอาร์กิวเมนต์" ควรมีพารามิเตอร์ทั้งหมด ( แหล่งที่มา )

ภาพบล็อก

ฉันเชื่อว่าพฤติกรรมนี้ได้รับการเพิ่มเพื่อป้องกันช่องว่างในเส้นทางของไฟล์ไปยัง exe ทำให้เกิดปัญหา

ฉันทำสิ่งนี้ตลอดเวลาด้วยสคริปต์ PowerShell นี่คือตัวอย่าง:

  • โปรแกรม / สคริปต์: powershell.exe
  • เพิ่มอาร์กิวเมนต์ : -command "& 'C: \ HSD - คัดลอก \ logoffstudents.ps1'" -NonInteractive
  • เริ่มใน:ว่างเปล่า

ขอบคุณ แต่ปัญหาคือหนึ่งในพารามิเตอร์ของฉันคือเส้นทางของไฟล์ (และมีที่ว่างในนั้น) ดังนั้นในตัวอย่าง 100 จะใช้งานได้ แต่ถ้าคุณต้องการส่งผ่าน "C: \ Start Folder"
ร็อดนีย์

ฉันแค่ใช้เครื่องหมายคำพูดในโปรแกรมและทำงานได้ เครื่องหมายแอมเปอร์แซนด์จำเป็นต้องใช้กับ PowerShell เท่านั้น สัญลักษณ์นี้เป็นตัวดำเนินการ CALL และอนุญาตให้ฉันเรียกคำสั่ง powershell ในกรณีส่วนใหญ่คำพูดเป็นสิ่งที่คุณต้องการ ณ จุดนี้คุณอาจต้องการติดต่อผู้สร้าง exe เพื่อดูว่าพวกเขาสนับสนุนงานที่กำหนดหรือไม่ ฉันทำงานเป็นโปรแกรมหายากไม่กี่แห่งที่เพิ่งปฏิเสธที่จะทำงานตามกำหนดเวลา ฉันคิดว่ามีความแตกต่างเล็กน้อยเกี่ยวกับวิธีการส่งผ่านพารามิเตอร์ที่อาจทำให้เกิดปัญหา ขอโทษฉันไม่สามารถช่วยได้มากขึ้น
Doltknuckle

ที่แย่ที่สุดคุณสามารถจัดโครงสร้างโฟลเดอร์ใหม่เพื่อกำจัดช่องว่าง ไม่ใช่สิ่งที่คุณต้องการ แต่อาจเป็นวิธีเดียวที่จะทำให้มันทำงาน
Doltknuckle

ขอบคุณ Doltknuckle - ฉันรู้ว่าฉันสามารถทำได้ด้วยไฟล์. bat (และใช้ "" รอบ ๆ param (เหมือนที่คุณทำในสคริปต์ Powershell ฉันแน่ใจว่าเป็นข้อผิดพลาดใน UI Task Editor ของ Windows ... (ฉัน เป็นผู้สร้าง. exe;) - ทำงานได้ดีผ่านชุดทดสอบและจากพรอมต์คำสั่ง แต่ไม่สามารถใช้งานผ่าน UI ของ Windows ...
Rodney

1
หากคุณสร้าง exe นี่อาจเป็นคำถามสำหรับ stackoverflow ฉันรู้สึกว่าคุณอาจต้องแก้ไขการจัดการพารามิเตอร์ของคุณเมื่อ exe นี้ใช้กับงานที่กำหนด ข้อเสนอแนะอย่างหนึ่งคือให้บันทึก exe ของคุณพารามิเตอร์ที่ได้รับไปยังไฟล์เพื่อให้คุณสามารถเห็นสิ่งที่กำลังผ่าน อย่างน้อยมันจะช่วยให้คุณดูว่าพารามิเตอร์งานที่กำหนดเวลาไว้เหมือนกับพารามิเตอร์บรรทัดคำสั่งหรือไม่
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"

หมายเหตุการใช้งาน'ในเส้นทางของไฟล์ที่จะเรียกใช้


3

ในกรณีนี้คุณสามารถแก้ไขปัญหาโดยส่งพารามิเตอร์พา ธ ของคุณในรูปแบบ 8.3

คุณสามารถค้นพบรูปแบบ 8.3 สำหรับเส้นทางของคุณโดยการเปิดพรอมต์คำสั่งและออกคำสั่งdir /xในรูทของไดรฟ์ของคุณ

คุณควรเห็นรายการที่คล้ายกับ

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

สำหรับไดเรกทอรี Program Files ของคุณ

จากนั้นเปลี่ยนไดเรกทอรีเป็น Program Files ด้วยcd "Program Files"ตามด้วย cd xyz และออกdir /xอีกครั้งเพื่อค้นหาชื่อรูปแบบ 8.3 สำหรับ" The Interface "และอื่น ๆ

เส้นทางสุดท้ายของคุณสำหรับตัวอย่างที่คุณให้มามีลักษณะดังนี้:

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

ขอบคุณฉันขอบคุณคำตอบ แต่สิ่งนี้ทำให้เกิดปัญหาเพิ่มเติม โดยทั่วไปฉันกำลังเรียกใช้แอป EXE .NET ซึ่งฉันเขียนซึ่งใช้พา ธ โฟลเดอร์ param นี้สำหรับบางสิ่ง - มันไม่ชอบรูปแบบ 8.3 และไม่สามารถค้นหาเส้นทาง ดังนั้นมีวิธีอื่นที่จะทำหรือไม่
ร็อดนีย์

ps - ดังนั้นนี่คือข้อบกพร่องในแอป Windows Scheduled Task หรือไม่ ช่องว่างเป็นเรื่องธรรมดามาก!
ร็อดนีย์

การทดสอบอย่างรวดเร็วของ windows 7 นั้นเหมาะกับฉัน คุณช่วยแนะนำเราผ่านขั้นตอนที่คุณทำเพื่อตั้งค่างานได้อย่างไร ขอบคุณสำหรับการแก้ไขที่นั่น Gareth ดูดีกว่ามาก
Keith

ดังนั้นงานจึงทำงานได้ดีกับการจัดรูปแบบนี้ แต่จากนั้นโปรแกรม. NET ของฉัน (ซึ่งยอมรับพา ธ เป็นสตริงของ ARG) จะไม่คลายการบีบอัดพา ธ จากรูปแบบ 8.3 ดังนั้นอาจเป็นคำถามการเขียนโปรแกรม - วิธีจัดการ 8.3 เส้นทาง
Rodney

ฉันรู้ว่าเราแก่แล้ว แต่คุณลองใช้ยัติภังค์ (-) หรือไม่?
Chibueze Opata

1

ฉันมีปัญหาที่คล้ายกันกับ VLC ซึ่งฉันใช้บน Windows XP เคล็ดลับคือการใส่อาร์กิวเมนต์ของcmdคำสั่งในเครื่องหมายคำพูดคู่

นี่คือตัวอย่างของสิ่งที่ฉันใช้ (กำหนดเวลาการบันทึกเวลา 15:00 น):

ที่ 15:00 cmd / c "" C: \ Programmi \ VideoLAN \ VLC \ vlc.exe dvb-t: // frequency = 698000000: โปรแกรม = 4006: run-time = 5 --sout "C: \ Documents and Settings \ ชื่อผู้ใช้ \ Documents \ วิดีโอ \ 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-*"

จากบรรทัดคำสั่งหรือไฟล์ 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)

แต่ละรายการที่เกี่ยวข้องในอาร์เรย์พารามิเตอร์พารามิเตอร์จะได้รับการส่งผ่านเป็น $ (Arg0), $ (Arg1) และ $ (Arg2)


0

ตั้งค่างานที่กำหนดของคุณดังนี้

cmd / c C: \ Program Files \ xyz \ FTP การถ่ายโอนไฟล์ \ FTPFileTransferTask.exe "C: \ Program Files \ xyz \ เส้นทางส่วนต่อของโฟลเดอร์ \"


0

มันอาจช่วยให้เข้าใจปัญหาจากมุมมองที่ต่างกันสมมติว่าคุณเป็นโปรแกรมเมอร์ที่ถูกคิดค่าใช้จ่ายด้วยการเพิ่มตัวกำหนดตารางเวลางานลงใน Windows คุณจะทำอย่างไร คุณมีปัญหาหลายประการในการต่อสู้กับ: หากงานถูกเรียกใช้ในฐานะบุคคลอื่นที่ไม่ใช่ผู้ใช้ที่เข้าสู่ระบบคุณควรรบกวนผู้ใช้ที่เข้าสู่ระบบด้วยป๊อปอัปข้อผิดพลาดหรือไม่? จะทำอย่างไรถ้าไม่มีผู้ใช้ที่เข้าสู่ระบบในขณะที่มีการเรียกใช้งาน ความแตกต่างระหว่างโปรแกรม GUI และโปรแกรมคอนโซลคืออะไร GUI ไม่มี stdin, stdout และ stderr แนวคิดไม่มีความหมายในพวกเขา สิ่งที่เกี่ยวกับโปรแกรมภายในหรือภายนอกเพื่อ COMMAND.COM/CMD.EXE หรือเอ็นจิ้นสคริปต์อื่น ๆ สิ่งที่เกี่ยวกับเส้นทางที่มีช่องว่างในชื่อคำสั่ง? หรือในพารามิเตอร์ (ตัวเลือก / ข้อโต้แย้ง)? (ตามที่คุณพยายามจัดการกับตอนนี้ .. )

ในขณะที่ฉันไม่แน่ใจ 100% เกี่ยวกับ internals หรือรายละเอียดด้านเทคนิคทั้งหมดในกรณีนี้คำตอบดูเหมือนจะเป็น .. งานถูกเรียกใช้ในเซสชันที่แยกต่างหากและไม่โต้ตอบซึ่งไม่สามารถโต้ตอบกับผู้ใช้ที่เข้าสู่ระบบในปัจจุบัน (ถ้ามี) ); มันทำงานคาดหวังว่าจะไม่มีคอนโซลออกเพราะมันไม่ใช่แบบโต้ตอบมันไม่สามารถขัดจังหวะผู้ใช้ที่เข้าสู่ระบบเพื่อแสดงผลลัพธ์ แต่อย่างใด (และถ้ามีเอาท์พุท stdin คือ bitbucket / NULL, stdout และ stderr ระบบบันทึกการทำงานของระบบ); ช่องว่างที่จะถูกจัดการโดยผ่านปัญหา: ชื่อคำสั่งจะมาตรงตามที่เป็นอยู่และพารามิเตอร์ที่ส่งผ่านไปยังคำสั่งที่ระบุไว้ในกล่องใส่อีกในคุณสมบัติของงาน

สิ่งที่หมายถึงทั้งหมดคืองานของคุณจะต้องถูกเรียกใช้เหมือนเป็นภูต (ในโลก Un * x) ทุกอย่างคงที่และแม่นยำ ชื่อคำสั่งเป็นชื่อคำสั่งจริงโดยไม่มีพารามิเตอร์ใด ๆ ซึ่งมักจะรวมถึงการรันคำสั่ง / สคริปต์ล่ามเช่น CMD.EXE! หากมีการระบุพารามิเตอร์ไว้ที่อื่นและต้องทราบเมื่อคุณตั้งค่างาน (กล่าวคือคุณไม่สามารถเปลี่ยนพารามิเตอร์ "on-the-fly") และอื่น ๆ

ดังนั้นหากคุณต้องการรวมพารามิเตอร์คุณต้องใช้ส่วนพารามิเตอร์เพื่อระบุพารามิเตอร์ ตัวกำหนดเวลางานไม่ทำงานลองแยกชื่อคำสั่งเพื่อแยกมันเป็น "command" และ "args" เช่นเดียวกับที่โปรแกรมบรรทัดคำสั่งทำ มันแค่ถือว่าเป็นชื่อคำสั่งใหญ่เต็ม เช่นเดียวกันหากคุณต้องการพารามิเตอร์ตัวแปรเช่นใช้% 1 .. % n ในไฟล์ BATCH คุณไม่สามารถทำได้จาก Task Scheduler เอง คุณจะต้องหาวิธีอื่น (โปรดทราบว่าคุณไม่สามารถใช้ตัวแปรสภาพแวดล้อมได้เนื่องจากสภาพแวดล้อมที่ส่งผ่านไปยังโปรแกรมขึ้นอยู่กับสภาพแวดล้อมที่งานเริ่มต้นด้วยไม่ใช่สภาพแวดล้อม "ปัจจุบัน") คุณสามารถใช้ไฟล์ชั่วคราวเพื่อบันทึกพารามิเตอร์ แต่เนื่องจากคุณ ต้องระบุชื่อไฟล์คงที่ในคุณสมบัติของงานจะเกิดอะไรขึ้นเมื่อคุณอยู่ในเครือข่ายที่มีผู้ใช้ 5,000 คนและสี่คนพยายามใช้งานเดียวกันในเวลาเดียวกัน พวกเขาจะปิดบังซึ่งกันและกันพยายามที่จะเขียนไปยังไฟล์ temp เดียวกันในเวลาเดียวกัน อาจไม่ใช่สิ่งที่คุณต้องการเช่นกัน (มีวิธีแก้ไขปัญหานี้เช่นกัน แต่มันอยู่ไกลเกินขอบเขตของคำถามและคำตอบนี้ .. )

ดังนั้นคำตอบสุดท้าย: ในกรณีที่ง่าย - เส้นทางที่คุณต้องการผ่านเป็นพารามิเตอร์เป็นแบบคงที่และไม่เปลี่ยนแปลง - คุณต้องระบุพารามิเตอร์ในคุณสมบัติงานที่เหมาะสม (อาร์กิวเมนต์) แทนที่จะเป็นในกล่องโปรแกรม / สคริปต์ หรือใช้ไฟล์แบตช์ ในกรณีที่ซับซ้อนมากขึ้นคุณจะต้องถามคำถามที่ถูกต้องหรือค้นคว้าว่า daemons ทำงานอย่างไรและจะใช้การล็อก / เซมาฟอร์และการสื่อสารระหว่างกระบวนการ (IPC) ได้อย่างไร

โชคดี.


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.