คุณจะ 'หยุดชั่วคราว' ด้วย PowerShell 2.0 ได้อย่างไร


114

ตกลงฉันแพ้แล้ว PowerShell ทำให้ฉันรำคาญ ฉันต้องการให้กล่องโต้ตอบหยุดชั่วคราวปรากฏขึ้น แต่จะไม่ปรากฏ

PS W:\>>> $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
Exception calling "ReadKey" with "1" argument(s): "The method or operation is not implemented."
At line:1 char:23
+ $host.UI.RawUI.ReadKey <<<< ("NoEcho")
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : DotNetMethodException

1
ฉันมีปัญหาเดียวกันใน PowerShell ISE ทำงานได้ดีในคอนโซล PowerShell มาตรฐานแม้ว่า
Charles Anderson

3
ฉันแค่ยุ่งกับ powershell และมันก็ยังน่ารำคาญเหมือนนรกแม้ 2 1/2 ปีต่อมา!
Bill K

ถ้าคุณอ่านลิงค์เทคอดัมหรือรหัสในการตอบ @Michael Sorens (ประมาณครึ่งหนึ่งลงหน้าที่ผมเขียนนี้ในปี 2020) if (!$psise) { <# pause #> }คุณอาจค้นพบเทคนิคการห่อหยุดของคุณใน หากคุณชอบฉันและ 99% ของเหตุผลที่คุณต้องการหยุดชั่วคราวคือเพื่อที่คุณจะได้อ่านหน้าจอก่อนที่จะกระพริบไปสิ่งนี้จะช่วยได้เพราะถ้าคุณอยู่ใน ISE มันจะไม่กระพริบตาและคุณจะไม่ ไม่จำเป็นต้องหยุดชั่วคราว
john v kumpf

คำตอบ:


89
cmd /c pause | out-null

(ไม่ใช่วิธี PowerShell แต่สวยงามกว่ามาก)

บันทึกต้นไม้ ใช้ one-liners


7
/ c ดำเนินการตามคำสั่งที่ระบุโดยสตริงจากนั้นจึงยุติ | out-null วางเอาต์พุตเป็นค่าว่างเปล่าโดยที่คุณจะไม่เห็นหากคุณต้องการเห็นข้อความ "กดปุ่มใด ๆ เพื่อดำเนินการต่อ ... " ให้นำท่อออก นอกจากนี้ดูเหมือนว่าจะไม่ทำงานใน PowerShell ISE ขั้นตอนนี้ติดขัดและคุณไม่สามารถกดปุ่มใด ๆ ได้ วิธีใดก็ได้
Wouter


7
@ คลิกใช่ 47 บรรทัดของโค้ดเพื่อแทนที่ "cmd / c pause | out-null" ซึ่งฟังดูเหมือนวิธี PowerShell
Bill K

@BillK โพสต์ที่ฉันเชื่อมโยงเพื่อตอบคำถามของ Wouter คุณไม่เห็นด้วย?
นิค

6
ไม่ใช่คำอธิบายสำหรับคำตอบของคุณฉันคิดว่าคุณพูดถูกทั้งหมด เป็นคำอธิบายเกี่ยวกับ PowerShell ฉันรู้สึกขยะแขยงพอสมควร - ฉันไม่เคยเห็นการใช้คำฟุ่มเฟือยที่คลุมเครืออย่างไร้จุดหมายขนาดนี้ตั้งแต่ฉันตั้งโปรแกรมใน Cobol
Bill K

234

ฉันคิดว่ามันคุ้มค่าที่จะสรุป / สรุปตัวเลือกที่นี่เพื่อความชัดเจน ... จากนั้นเสนอรูปแบบใหม่ที่ฉันเชื่อว่าให้ประโยชน์สูงสุด

<1> ReadKey (System.Console)

write-host "Press any key to continue..."
[void][System.Console]::ReadKey($true)
  • ข้อได้เปรียบ: ยอมรับคีย์ใด ๆ แต่ไม่รวมคีย์ตัวปรับแต่ง Shift, Alt, Ctrl อย่างเหมาะสม
  • ข้อเสีย: ไม่ทำงานใน PS-ISE

<2> ReadKey (RawUI)

Write-Host "Press any key to continue ..."
$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
  • ข้อเสีย: ไม่ทำงานใน PS-ISE
  • ข้อเสีย: ไม่รวมคีย์ตัวปรับแต่ง

<3> ซม

cmd /c Pause | Out-Null
  • ข้อเสีย: ไม่ทำงานใน PS-ISE
  • ข้อเสีย: เปิดตัวเชลล์ / หน้าต่างใหม่อย่างเห็นได้ชัดเมื่อใช้งานครั้งแรก ไม่สังเกตเห็นได้ในการใช้งานครั้งต่อไป แต่ยังคงมีค่าใช้จ่าย

<4> อ่านโฮสต์

Read-Host -Prompt "Press Enter to continue"
  • ข้อได้เปรียบ: ทำงานใน PS-ISE
  • ข้อเสีย: ยอมรับเฉพาะคีย์ Enter

<5> คอมโพสิต ReadKey

นี่เป็นส่วนประกอบของ <1> ด้านบนพร้อมด้วยวิธีแก้ปัญหา ISE / kludge ที่ดึงมาจากข้อเสนอในบล็อกด้านเทคนิคของ Adam (ได้รับความอนุเคราะห์จาก Nick จากความคิดเห็นก่อนหน้านี้ในหน้านี้) ฉันได้ทำการปรับปรุงเล็กน้อยสองครั้งในช่วงหลัง: เพิ่ม Test-Path เพื่อหลีกเลี่ยงข้อผิดพลาดหากคุณใช้Set-StrictMode (คุณทำใช่ไหม!) และโฮสต์การเขียนขั้นสุดท้ายเพื่อเพิ่มบรรทัดใหม่หลังจากการกดแป้นพิมพ์ของคุณเพื่อวาง แจ้งในสถานที่ที่เหมาะสม

Function Pause ($Message = "Press any key to continue . . . ") {
    if ((Test-Path variable:psISE) -and $psISE) {
        $Shell = New-Object -ComObject "WScript.Shell"
        $Button = $Shell.Popup("Click OK to continue.", 0, "Script Paused", 0)
    }
    else {     
        Write-Host -NoNewline $Message
        [void][System.Console]::ReadKey($true)
        Write-Host
    }
}
  • ข้อได้เปรียบ: ยอมรับคีย์ใด ๆ แต่ไม่รวมคีย์ตัวปรับแต่ง Shift, Alt, Ctrl อย่างเหมาะสม
  • ข้อได้เปรียบ: ทำงานใน PS-ISE (แม้ว่าจะใช้ Enter หรือคลิกเมาส์เท่านั้น)
  • ข้อเสีย: ไม่ใช่ซับเดียว!

9
คำตอบที่ดีที่สุดโดยเฉพาะอย่างยิ่งเนื่องจากมีโซลูชันที่ใช้งานได้ทุกที่
Petr

ตอบโจทย์มาก! ฉันต้องการทราบว่าการเพิ่มAllowCtrlCพารามิเตอร์ในตัวเลือก 2 ทำให้ผู้ใช้สามารถคลิก Ctrl + C ได้โดยไม่ต้องยกเลิกสคริปต์ อย่างไรก็ตามตัวเลือกนี้ยังไม่รวมคีย์ตัวปรับแต่ง Ctrl อย่างเหมาะสม (ทำหน้าที่เหมือนกับว่าผู้ใช้คลิกที่ปุ่ม Ctrl เท่านั้น) อ้างอิง: Microsoft TechNet - Windows PowerShell เคล็ดลับ: กดปุ่มใด ๆ เพื่อดำเนินการต่อ
Oz Edri

2
ตัวเลือกที่ 3 และ 5 มีข้อเสียอีกประการหนึ่ง: ไม่ทำงานบน linux
bitbonk

43

ฉันคิดว่าคุณต้องการอ่านอินพุตจากคอนโซล ถ้าใช่ให้ใช้Read-Host.


3
Ditto - อาจจะเพิ่มข้อความแจ้งที่ขโมยจากด้านล่าง .. Read-Host -Prompt "กด Enter เพื่อดำเนินการต่อ"
Jon H

21

วิธีแก้ปัญหาเช่นcmd /c pauseทำให้ตัวแปลคำสั่งใหม่เริ่มต้นและทำงานในพื้นหลัง แม้ว่าจะยอมรับได้ในบางกรณี แต่ก็ไม่เหมาะอย่างยิ่ง

การแก้ปัญหาโดยใช้การRead-Hostบังคับให้ผู้ใช้กดEnterและไม่ใช่ "คีย์ใด ๆ " จริงๆ

โซลูชันนี้จะให้อินเทอร์เฟซ "กดปุ่มใด ๆ เพื่อดำเนินการต่อ" ที่แท้จริงและจะไม่เริ่มต้นล่ามใหม่ซึ่งจะเลียนแบบpauseคำสั่งเดิมเป็นหลัก

Write-Host "Press any key to continue..."
[void][System.Console]::ReadKey($true)

ในทางเทคนิค ISE อยู่นอกขอบเขตเนื่องจากคำถามเดิมถามเฉพาะเกี่ยวกับ Powershell 2.0 และไม่รวม ISE หากคุณใช้ ISE ให้ใช้เบรกพอยต์
Ro Yo Mi

4
1. ฉันไม่เห็นด้วยว่า ISE อยู่นอกขอบเขต แต่ตอนนี้ไม่เกี่ยวข้อง 2. ฉันสังเกตว่ามันใช้ไม่ได้ใน ISE เพื่อช่วยเหลือผู้สัญจรในคำถามนี้
Bill_Stewart

2

นอกจากคำตอบของ Michael Sorens :

<6> ReadKey ในกระบวนการใหม่

Start-Process PowerShell {[void][System.Console]::ReadKey($true)} -Wait -NoNewWindow
  • ข้อได้เปรียบ: ยอมรับคีย์ใด ๆ แต่ไม่รวมคีย์ตัวปรับแต่ง Shift, Alt, Ctrl อย่างเหมาะสม
  • ข้อได้เปรียบ: ทำงานใน PS-ISE

วิธีนี้ใช้งานได้ดี แต่จะปรากฏหน้าต่างใหม่ของ powershell เว้นแต่จะ-NoNewWindowมีการเพิ่ม :)
jeuxjeux20

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