Làm cách nào để bạn thực hiện 'Tạm dừng' với PowerShell 2.0?


113

OK, tôi đang mất nó. PowerShell đang làm phiền tôi. Tôi muốn một hộp thoại tạm dừng xuất hiện nhưng nó sẽ không xuất hiện.

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
Tôi đã gặp sự cố tương tự trong PowerShell ISE. Mặc dù vậy, hoạt động tốt trong bảng điều khiển PowerShell tiêu chuẩn.
Charles Anderson,

3
Tôi chỉ làm phiền với powershell và nó vẫn khó chịu như địa ngục, thậm chí 2 năm rưỡi sau!
Bill K

Nếu bạn đọc liên kết Công nghệ của Adam hoặc mã trong câu trả lời @Michael Sorens (khoảng nửa trang khi tôi viết bài này vào năm 2020), bạn có thể khám phá ra một kỹ thuật giúp bạn tạm dừng if (!$psise) { <# pause #> }. Nếu bạn giống tôi và 99% lý do bạn muốn tạm dừng là để bạn có thể đọc màn hình trước khi nó nhấp nháy, thì điều này sẽ hữu ích, bởi vì nếu bạn đang ở trong ISE, nó không nhấp nháy và bạn không không cần tạm dừng
John v kumpf

Câu trả lời:


88
cmd /c pause | out-null

(Đó không phải là cách PowerShell, nhưng nó thanh lịch hơn nhiều.)

Cứu cây. Sử dụng một lớp lót.


7
/ c Thực hiện lệnh được chỉ định bởi chuỗi và sau đó kết thúc | out-null chuyển kết quả đầu ra đến out-null, nơi bạn sẽ không bao giờ nhìn thấy nó Nếu bạn muốn thấy thông báo "Nhấn phím bất kỳ để tiếp tục ...", hãy xóa ống dẫn. Ngoài ra, điều này dường như không hoạt động trong PowerShell ISE. Quá trình này chỉ đơn giản là bị kẹt và bạn không thể nhấn bất kỳ phím nào. Bất kỳ cách nào xung quanh điều đó?
Wouter

1
@Wouter Xem bài đăng trên blog này: Cách tạm dừng đúng cách một tập lệnh PowerShell
Nick

7
@Nick yes, 47 dòng mã để thay thế "cmd / c pause | out-null", nghe giống như cách của PowerShell.
Bill K

@BillK Bài đăng tôi đã liên kết để trả lời câu hỏi của Wouter. Bạn không đồng ý?
Nick

6
Đó không phải là một bình luận về câu trả lời của bạn, tôi nghĩ bạn hoàn toàn đúng. Đó là một bài bình luận về PowerShell. Tôi hơi ghê tởm - Tôi chưa từng thấy sự dài dòng vô nghĩa như thế này kể từ khi tôi lập trình trong Cobol.
Bill K

234

Tôi nghĩ rất đáng để tóm tắt / tóm tắt các lựa chọn ở đây cho rõ ràng ... sau đó đưa ra một biến thể mới mà tôi tin rằng cung cấp tiện ích tốt nhất.

<1> ReadKey (System.Console)

write-host "Press any key to continue..."
[void][System.Console]::ReadKey($true)
  • Ưu điểm: Chấp nhận bất kỳ phím nào nhưng loại trừ đúng các phím bổ trợ Shift, Alt, Ctrl.
  • Nhược điểm: Không hoạt động trong PS-ISE.

<2> ReadKey (RawUI)

Write-Host "Press any key to continue ..."
$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
  • Nhược điểm: Không hoạt động trong PS-ISE.
  • Nhược điểm: Không loại trừ các phím bổ trợ.

<3> cmd

cmd /c Pause | Out-Null
  • Nhược điểm: Không hoạt động trong PS-ISE.
  • Nhược điểm: Dễ thấy sẽ khởi chạy trình bao / cửa sổ mới trong lần sử dụng đầu tiên; không đáng chú ý khi sử dụng tiếp theo nhưng vẫn có chi phí

<4> Máy chủ đọc

Read-Host -Prompt "Press Enter to continue"
  • Ưu điểm: Hoạt động trong PS-ISE.
  • Nhược điểm: Chỉ chấp nhận phím Enter.

<5> hỗn hợp ReadKey

Đây là kết hợp của <1> ở trên với cách giải quyết ISE / k bùn được trích xuất từ ​​đề xuất trên Blog Công nghệ của Adam (được sự cho phép của Nick từ các nhận xét trước đó trên trang này). Tôi đã thực hiện hai cải tiến nhỏ cho cái sau: thêm Đường dẫn kiểm tra để tránh lỗi nếu bạn sử dụng Chế độ đặt-Nghiêm ngặt (đúng không?!) Và Máy chủ ghi cuối cùng để thêm một dòng mới sau lần nhấn phím của bạn để đặt nhắc nhở đúng chỗ.

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
    }
}
  • Ưu điểm: Chấp nhận bất kỳ phím nào nhưng loại trừ đúng các phím bổ trợ Shift, Alt, Ctrl.
  • Ưu điểm: Hoạt động trong PS-ISE (mặc dù chỉ với Enter hoặc nhấp chuột)
  • Nhược điểm: Không phải là một lớp lót!

9
Câu trả lời tốt nhất, đặc biệt là vì nó cung cấp giải pháp mà làm việc ở khắp mọi nơi
Petr

Câu trả lời chính xác! Tôi muốn lưu ý rằng việc thêm AllowCtrlCtham số vào lựa chọn 2 cho phép người dùng nhấp vào Ctrl + C mà không kết thúc tập lệnh. Tuy nhiên, lựa chọn này vẫn không loại trừ đúng phím bổ trợ Ctrl. (nó hoạt động cũng giống như khi người dùng nhấp chuột duy nhất trên phím Ctrl) Tham khảo: Microsoft TechNet - Windows PowerShell Mẹo: Nhấn phím bất kỳ để tiếp tục
Oz Edri

2
Lựa chọn 3 và 5 có nhược điểm khác: không làm việc trên Linux
bitbonk

43

Tôi giả sử rằng bạn muốn đọc đầu vào từ bảng điều khiển. Nếu vậy, hãy sử dụng Read-Host.


3
Ditto - Có thể thêm văn bản lời nhắc bị đánh cắp từ bên dưới .. Đọc-Máy chủ lưu trữ-Nhắc "Nhấn Enter để tiếp tục"
Jon H

21

Các giải pháp như cmd /c pause khiến một trình thông dịch lệnh mới khởi động và chạy trong nền. Mặc dù có thể chấp nhận được trong một số trường hợp, nhưng điều này không thực sự lý tưởng.

Các giải pháp sử dụng Read-Hostbuộc người dùng phải nhấnEnter và không thực sự là "phím bất kỳ".

Giải pháp này sẽ cung cấp cho bạn giao diện "nhấn phím bất kỳ để tiếp tục" thực sự và sẽ không khởi động trình thông dịch mới, về cơ bản sẽ bắt chước pauselệnh gốc .

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

Về mặt kỹ thuật, ISE nằm ngoài phạm vi vì câu hỏi ban đầu chỉ hỏi về Powershell 2.0 và loại trừ ISE. Nếu bạn đang sử dụng ISE, thì chỉ cần sử dụng một điểm ngắt.
Ro Yo Mi

4
1. Tôi không đồng ý ISE đã nằm ngoài phạm vi, nhưng điều đó không còn phù hợp nữa. 2. Tôi đã lưu ý rằng nó không hoạt động trong ISE để hỗ trợ người qua đường về câu hỏi này.
Bill_Stewart

2

Ngoài câu trả lời của Michael Sorens :

<6> ReadKey trong một quy trình mới

Start-Process PowerShell {[void][System.Console]::ReadKey($true)} -Wait -NoNewWindow
  • Ưu điểm: Chấp nhận bất kỳ phím nào nhưng loại trừ đúng các phím bổ trợ Shift, Alt, Ctrl.
  • Ưu điểm: Hoạt động trong PS-ISE.

Này hoạt động tuyệt vời, nhưng bật lên một cửa sổ mới của PowerShell, trừ khi -NoNewWindowđã được thêm :)
jeuxjeux20

@ jeuxjeux20, cảm ơn bạn đã gợi ý, tôi đã thêm điều này vào lệnh trong câu trả lời.
iRon
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.