ฉันจะเรียกใช้ไฟล์ bat ในพื้นหลังจากไฟล์ bat อื่นได้อย่างไร


92

ฉันมีสคริปต์ "ตั้งค่า" ซึ่งฉันเรียกใช้ในตอนเช้าซึ่งจะเริ่มโปรแกรมทั้งหมดที่ฉันต้องการ ตอนนี้บางคนต้องการการตั้งค่าสภาพแวดล้อมเพิ่มเติมดังนั้นฉันต้องห่อไว้ด้วยสคริปต์ BAT ขนาดเล็ก

ฉันจะเรียกใช้สคริปต์ดังกล่าวบน Windows XP ในพื้นหลังได้อย่างไร

CALL env-script.bat รันพร้อมกันกล่าวคือสคริปต์การตั้งค่าสามารถดำเนินการต่อได้หลังจากที่คำสั่งใน env-script สิ้นสุดลงแล้วเท่านั้น

START/B env-script.bat เรียกใช้อินสแตนซ์อื่นของ CMD.exe ในพรอมต์คำสั่งเดียวกันปล่อยให้อยู่ในสถานะที่ยุ่งเหยิงจริงๆ (ฉันเห็นผลลัพธ์ของ CMD.exe ที่ซ้อนกันแป้นพิมพ์หยุดทำงานชั่วขณะสคริปต์ไม่ทำงาน)

START/B CMD env-script.batให้ผลลัพธ์เดียวกัน ไม่มีแฟล็กใดใน CMD ที่ตรงกับบิลของฉัน

คำตอบ:


72

จริงๆแล้วสิ่งต่อไปนี้ใช้ได้ดีสำหรับฉันและสร้างหน้าต่างใหม่:

test.cmd:

@echo off
start test2.cmd
start test3.cmd
echo Foo
pause

test2.cmd

@echo off
echo Test 2
pause
exit

test3.cmd

@echo off
echo Test 3
pause
exit

รวมสิ่งนั้นเข้ากับพารามิเตอร์startเช่นตาม/minที่ Moshe ชี้ให้เห็นว่าคุณไม่ต้องการให้หน้าต่างใหม่เกิดขึ้นต่อหน้าคุณหรือไม่


1
โอเคใช้งานได้ แต่ไม่สมบูรณ์ 100%: หลังจากที่ฉันกด "RETURN" ใน "Test 2" หน้าต่างนั้นจะไม่ปิดลง ความคิดใด ๆ ?
Aaron Digulla

คุณสามารถเพิ่ม "exit" ลงในแบทช์ที่เกิดเพื่อปิดอีกครั้งในภายหลัง ขออภัยไม่ได้ทดสอบไกลขนาดนั้น :)
Joey

ในความเป็นจริง start script1.bat \ n start script2.bat \ n start scriptN.bat เพียงพอสำหรับฉัน
andrej

142

สองขวบ แต่เพื่อความสมบูรณ์ ...

แนวทางมาตรฐานแบบอินไลน์: (เช่นพฤติกรรมที่คุณจะได้รับเมื่อใช้&ใน Linux)

START /B CMD /C CALL "foo.bat" [args [...]]

หมายเหตุ: 1. CALLจับคู่กับไฟล์. bat เนื่องจากว่ามันจะไปที่ไหน .. (เช่นนี่เป็นเพียงส่วนขยายของCMD /C CALL "foo.bat"แบบฟอร์มเพื่อทำให้เป็นแบบอะซิงโครนัสโดยปกติจะต้องได้รับรหัสออกอย่างถูกต้อง แต่นั่นไม่ใช่ปัญหา ที่นี่); 2. เครื่องหมายคำพูดคู่รอบไฟล์. bat จำเป็นต่อเมื่อชื่อมีช่องว่าง (ชื่ออาจเป็นเส้นทางซึ่งในกรณีนี้มีความเป็นไปได้มากกว่านี้)

หากคุณไม่ต้องการผลลัพธ์:

START /B CMD /C CALL "foo.bat" [args [...]] >NUL 2>&1

หากคุณต้องการให้ค้างคาวทำงานบนคอนโซลอิสระ: (เช่นหน้าต่างอื่น)

START CMD /C CALL "foo.bat" [args [...]]

หากคุณต้องการให้หน้าต่างอื่นค้างอยู่ในภายหลัง:

START CMD /K CALL "foo.bat" [args [...]]

หมายเหตุ: นี่เป็นรูปแบบที่ไม่ดีจริง ๆ เว้นแต่คุณจะมีผู้ใช้ที่ต้องการใช้หน้าต่างที่เปิดเป็นคอนโซลปกติโดยเฉพาะ หากคุณเพียงแค่ต้องการให้หน้าต่างค้างเพื่อดูผลลัพธ์ก็ควรใส่PAUSEที่ท้ายไฟล์ bat หรือแม้กระทั่งเพิ่ม^& PAUSEหลังบรรทัดคำสั่ง:

START CMD /C CALL "foo.bat" [args [...]] ^& PAUSE

10
&เป็นตัวดำเนินการ "แล้ว" (ศัพท์เฉพาะ?) (เช่นcmd1 & cmd2วิธีการทำ "cmd1" แล้ว "CMD2". ซึ่งแตกต่างจาก&&ผู้ประกอบการดำเนินการของ "CMD2" ไม่ได้ขึ้นอยู่กับทางออกที่ประสบความสำเร็จของ "cmd1".) The ^หนี&เพื่อที่จะเข้าสู่การขัดแย้ง CMD แทนการถูกบริโภค และรันโดยคอนโซลเดียวกับที่รัน START
antak

สิ่งนี้มีประโยชน์มากขอบคุณ ฉันกำลังจะพอร์ตสคริปต์บางส่วนไปยัง Linux เนื่องจากคำแนะนำอื่น ๆstartและcmdไม่ได้ให้ฟังก์ชันการทำงานทั้งหมดที่ฉันต้องการ คำตอบของคุณตอกตะปู
Iterator

3
หากคุณไม่ต้องการเอาท์พุทการเปลี่ยนทิศทางจะต้องหลีกเลี่ยงเพื่อให้ส่งผ่านไปยัง CMD นอกจากนี้ยังไม่จำเป็นต้องโทร:START /B "" CMD /C "foo.bat" [args [...]] ^>nul 2^>^&1
dbenham

1
@dbenham: แม้ว่าสิ่งที่คุณพูดจะสมเหตุสมผล แต่START /B "" CMD /C PING 127.0.0.1 >NULดูเหมือนว่าจะทำงานได้โดยไม่คำนึงถึงและไม่มีอะไรส่งออก (อาจเป็นเพราะการจัดการ I / O ของCMDสืบทอดSTART) ฉันเดาSTARTว่าความแตกต่างคือถ้าคุณต้องการให้เอาต์พุต (ข้อผิดพลาด) เหมือนเดิมซึ่งน่าจะเป็นความคิดที่ดี CALLอยู่ที่นั่นเพราะฉันรู้สึกว่ามันเป็นแนวทางปฏิบัติที่ดี (เช่นการไม่ใช้CALLสำหรับการโทรแบบซิงโครนัสแบ็ตจะส่งผลให้เกิดรหัสออกที่ไม่สามารถคาดเดาได้ดังนั้นฉันจึงจับคู่การโทรด้วยค้างคาวอย่างสม่ำเสมอCALLแม้ว่าจะไม่ได้ใช้อย่างเคร่งครัดก็ตามเช่นในกรณีนี้)
antak

7

เนื่องจาก START เป็นวิธีเดียวในการดำเนินการบางอย่างในเบื้องหลังจากสคริปต์ CMD ฉันขอแนะนำให้คุณใช้มันต่อไป แทนที่จะใช้ตัวปรับแต่ง / B ให้ลอง / MIN เพื่อให้หน้าต่างที่สร้างขึ้นใหม่ไม่รบกวนคุณ นอกจากนี้คุณสามารถตั้งค่าลำดับความสำคัญเป็นสิ่งที่ต่ำกว่าด้วย / LOW หรือ / BELOWNORMAL ซึ่งควรปรับปรุงการตอบสนองของระบบของคุณ


-1 ปัญหาคือ START ไม่สร้างหน้าต่างใหม่เมื่อคุณเริ่มไฟล์ BAT แทนที่จะนำหน้าต่างปัจจุบันกลับมาใช้และผสม I / O สองกระบวนการ CMD
Aaron Digulla

4
ไม่ได้สร้างหน้าต่างใหม่เนื่องจากคุณใช้แฟล็ก / B ย้ายมัน.
Moshe

5

นอกเหนือจากคำที่อยู่เบื้องหน้า / พื้นหลัง อีกวิธีหนึ่งในการซ่อนหน้าต่างที่กำลังทำงานอยู่คือผ่าน vbscript หากยังมีอยู่ในระบบของคุณ

DIM objShell
set objShell=wscript.createObject("wscript.shell")
iReturn=objShell.Run("yourcommand.exe", 0, TRUE)

ตั้งชื่อเป็น sth.vbs และเรียกมันจาก bat ใส่งานที่กำหนดไว้เป็นต้นโดยส่วนตัวฉันจะปิดใช้งาน vbs โดยไม่ต้องรีบร้อนในระบบ Windows ใด ๆ ที่ฉันจัดการ :)


สำหรับกรณีการใช้งานโดยเฉพาะของฉันนี่เป็นทางออกเดียวที่ฉันสามารถใช้งานได้ ...
เบ็น

0

สร้างแอปพลิเคชัน C # Windows ใหม่และเรียกวิธีนี้จาก main:

public static void RunBatchFile(string filename)
{
    Process process = new Process();

    process.StartInfo.FileName = filename;

    // suppress output (command window still gets created)
    process.StartInfo.Arguments = "> NULL";

    process.Start();
    process.WaitForExit();
}

2
อืม ... ฉันหวังว่าจะมีบางอย่างที่เรียบง่ายอย่างที่ไม่จำเป็นต้องติดตั้ง Visual Studio ...
Aaron Digulla

1
จนกว่า PowerShell จะพร้อมใช้งาน 100% - C # นั้นมากเกินไป
jim

2
Aaron: คอมไพเลอร์ C # รวมอยู่ใน. NET Framework 2 ดังนั้นคุณสามารถแก้ไขโค้ดบางส่วนในโปรแกรมแก้ไขข้อความและคอมไพล์ได้ อย่างไรก็ตามเนื่องจากสิ่งนี้เป็นไปได้อย่างสมบูรณ์แบบในไฟล์แบตช์ฉันจึงบอกว่า C # นั้นมากเกินไป
Joey

0

สิ่งนี้ใช้ได้กับการติดตั้ง Windows XP Home ของฉันด้วยวิธี Unix:

call notepad.exe & 

7
ฉันคิดว่าสิ่งนี้ใช้ได้ผลโดยบังเอิญเท่านั้นและสิ่งที่ & ไม่จำเป็น
Sam Watkins

2
ใช่ notepad.exe เป็นแบบอะซิงโครนัสที่จะเริ่มต้นด้วย
antak

0

ที่จริงแล้วค่อนข้างง่ายด้วยตัวเลือกนี้ในตอนท้าย:

c: \ start BATCH.bat -WindowStyle Hidden


คำสั่ง Windows startไม่มี-WindowStyleตัวเลือก
Stephan

@Stephan Arreed. เส้นทางแปลก ๆ ( C:` instead of C: \ Windows`) แสดงให้เห็นว่าเขาพบเครื่องมือที่ไหนสักแห่งบนอินเทอร์เน็ตและคัดลอกลงในฮาร์ดไดรฟ์ของเขา
Aaron Digulla
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.