Làm thế nào để ngăn chặn dấu nhắc lệnh đóng sau khi thực hiện?


54

Vấn đề của tôi là trong Windows, có các cửa sổ dòng lệnh đóng ngay sau khi thực thi. Để giải quyết điều này, tôi muốn hành vi mặc định là cửa sổ được giữ mở. Thông thường, hành vi này có thể tránh được với ba phương pháp xuất hiện trong đầu tôi:

  1. Đặt một pausedòng sau các chương trình hàng loạt để nhắc người dùng nhấn phím trước khi thoát
  2. Chạy các tệp bó này hoặc các công cụ thao tác dòng lệnh khác (ngay cả khi bắt đầu dịch vụ, khởi động lại, v.v. có net start xyhoặc bất cứ thứ gì tương tự) trong cmd.exe(Bắt đầu - Chạy - cmd.exe)
  3. Chạy các chương trình cmd /knhư thế này: cmd /k myprogram.bat

Nhưng có một số trường hợp khác trong đó người dùng:

  1. Chạy chương trình lần đầu tiên và không biết rằng chương trình đã cho sẽ chạy trong Dấu nhắc lệnh (Bộ xử lý lệnh Windows), ví dụ như khi chạy một phím tắt từ menu Bắt đầu (hoặc từ một nơi khác), HOẶC
  2. Tìm thấy một chút không thoải mái khi chạy cmd.exe mọi lúc không có thời gian / cơ hội để viết lại mã của các lệnh này ở mọi nơi để tạm dừng sau chúng hoặc tránh thoát ra một cách rõ ràng.

Tôi đã đọc một bài viết về việc thay đổi hành vi mặc định cmd.exekhi mở nó một cách rõ ràng, với việc tạo một mục AutoRun và thao tác nội dung của nó ở những vị trí này:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Command Processor\AutoRun
HKEY_CURRENT_USER\SOFTWARE\Microsoft\Command Processor\AutoRun

(Các mục AutoRun là _String values_...)

Tôi đặt cmd /d /kgiá trị của nó để dùng thử, nhưng điều này không thay đổi hành vi của những thứ được đề cập ở trên ... Nó chỉ thay đổi hành vi của cửa sổ dòng lệnh khi mở một cách rõ ràng (Start-Run- cmd.exe).

Vì vậy, làm thế nào nó hoạt động? Bạn có thể cho tôi bất kỳ ý tưởng để giải quyết vấn đề này?


10
Câu hỏi của bạn với tất cả những lời giải thích khiến đầu tôi muốn nổ tung. Bạn có thể nói điều gì đó như: Tôi muốn chạy một tệp bó với lệnh "ví dụ" này và tôi muốn hộp lệnh vẫn mở khi kết thúc. đó có phải là điều mà bạn đang hỏi? Vui lòng đặt trong một mẫu gần của mã.
KCotreau

1
Đồng ý +1. Một chút để dài dòng, xin vui lòng xem xét lại câu hỏi của bạn và, nếu có thể, sử dụng một ví dụ và soạn một câu hỏi ngắn gọn hơn.
slotishtype

2
Đây là hành vi bình thường và trong khi câu hỏi của bạn chắc chắn là hợp lệ, bạn nên đặt câu hỏi tại sao bạn cần giữ dấu nhắc lệnh mở sau (hầu hết các tiện ích được tạo ra với lưu ý này).
Đột phá

1
Theo tôi, đây không phải là một câu hỏi thực sự. Thay vào đó, bạn chỉ cần hướng dẫn người dùng sử dụng một tệp bó. Nếu đó không phải là mục đích của câu hỏi, vui lòng làm rõ câu hỏi của bạn bằng cách xóa mọi thông tin khó hiểu và giải thích mục tiêu thực sự của bạn là gì. Thật khó để đưa ra câu trả lời đúng nếu không rõ ràng ...
Tamara Wijsman

1
@Randolf Richardson, đó là bởi vì những công cụ này không phải được nhìn thấy bởi một người dùng cuối bao giờ (sau khi tất cả, đó là lý do tại sao chúng tôi sử dụng giao diện đồ họa bây giờ). Nếu bạn cần thông tin như vậy, hầu hết các nhóm CNTT sẽ gửi các tệp bó để thu thập cho họ thông tin hệ thống phù hợp và hiển thị thông tin đó. Tôi có thể thấy không có cách nào khả thi nếu tìm ra giải pháp cho câu hỏi này, nó sẽ gây ra ít vấn đề hơn sau đó giải quyết - rất nhiều điều được gửi đến stdouttrên cơ sở liên tục mà không bao giờ được nhìn thấy vì một lý do chính đáng.
Đột phá

Câu trả lời:


27

Tôi có một giải pháp chỉ có thể áp dụng trên .cmd.batcác tệp:

Mở regeditvà đi đến từng người trong số:

[HKEY_CLASSES_ROOT\batfile\shell\open\command]
[HKEY_CLASSES_ROOT\cmdfile\shell\open\command] 

Bây giờ thay đổi "Giá trị khóa mặc định" thành cmd.exe /k "%1" %*. Bây giờ, mọi cửa sổ tập lệnh bó sẽ vẫn mở sau khi thực thi.

Lưu ý rằng điều này giống như sử dụng cmd.exe /c cmd.exe /k program.bat, có nghĩa là một phiên bản CMD khác sẽ được khởi chạy vào phiên bản gốc. Tôi không thể tìm cách ghi đè lên /cđối số đầu tiên .

Bạn cũng có thể làm như vậy với [exefile], nhưng bây giờ nó sẽ hiển thị một hộp điều khiển trống nếu tệp thực thi có GUI.


4
+1 để có giải pháp duy nhất ở đây thực sự trả lời câu hỏi được đưa ra. Thật không may, tôi nghĩ rằng đây có thể là một rò rỉ bộ nhớ đang chờ để xảy ra. Điều gì xảy ra khi một dịch vụ khởi chạy một tệp bó mới mà không chỉ định CMD.EXE trong dòng CMD? Mã này sẽ không được sử dụng trong trường hợp đó? Đây không phải là sẽ tạo một cửa sổ mới trên máy tính để bàn không tương tác và để nó mở cho đến khi bạn khởi động lại?
krowe2

@APerson Chỉnh sửa của bạn đã phá vỡ lệnh bằng cách không bao gồm *. Hãy cẩn thận hơn khi chỉnh sửa!
not2qubit

@ not2qubit Xin lỗi, tôi không nhận thấy rằng tôi đã xóa ba dấu sao thay vì hai. Sẽ làm.
APerson

17

Trích dẫn Microsoft :

Một giao diện điều khiển được đóng lại khi quá trình cuối cùng gắn liền với nó chấm dứt hoặc gọi FreeConsole.

Nói cách khác, cửa sổ bảng điều khiển Win32 sẽ luôn bị đóng khi chương trình cuối cùng chạy bên trong nó thoát ra và bạn không thể thay đổi điều này.


(Đối với các chương trình MS-DOS 16 bit, Windows cung cấp tùy chọn "Đóng khi thoát" trong hộp thoại thuộc tính, nhưng đây không phải là ngoại lệ đối với hành vi trên: đó là quy trình NTVDM giữ cửa sổ mở. Ngoài ra, tùy chọn này là một lần nữa cho mỗi chương trình.)


13
+1 để hiểu cách thứclý do cửa sổ bảng điều khiển đóng (trái ngược với hầu hết những người chỉ nói "OMG TẠI SAO KHÔNG THỂ NÓ MỞ !!!!!!!!!!! 1111one"). Nó hoạt động như thiết kế, và nó nên giữ nguyên như vậy IMHO. Đây là lý do chính tại sao chúng tôi có các luồng và tệp chuẩn ở vị trí đầu tiên.
Đột phá

27
@BreakENC Câu hỏi là How can I do X, không In your opinion, should I do X. Câu trả lời này là không có ích, nó ngụ ý X là không thể, khi các giải pháp một phần đã được trình bày ở nơi khác. (-1)
Tuyệt vời nhất

7

Chỉ cần mở một dấu nhắc lệnh tại vị trí tệp bó của bạn và nhập thủ công tên tệp bó của bạn để chạy nó trong cửa sổ đó.

1.Navigate vào thư mục nơi thực thi của bạn cư trú
2.Shift-Nhấp chuột phải và chọn "Cửa sổ lệnh từ đây"
3. Nhập tên của tệp thực thi và nhấn enter
4. Quá trình sẽ chạy, nhưng cửa sổ sẽ mở


1
Tôi không biết về Shift + Nhấp chuột phải. Tuy nhiên, tuy nhiên, bạn có thể kéo thả exe vào cửa sổ cmd, tự động đặt đường dẫn cho bạn.
Tuyệt vời nhất

1
Điều này thường làm việc cho tôi, nhưng dường như nó không phải là một điều chắc chắn bởi vì tôi ở đây đang tìm kiếm một giải pháp chính xác bởi vì nó không hoạt động trong tình huống hiện tại của tôi.
RenniePet

đây là giải pháp dễ nhất và phải được đánh dấu là câu trả lời đúng
Vicky Kapadia

4

cmd.exe /ksẽ cung cấp cho bạn rắc rối với một số lô. Nếu lô exit 1(không có /B) bàn điều khiển của bạn sẽ bị đóng. Một mẹo nhỏ là sử dụng:

cmd.exe /k cmd /c ...

Để sử dụng điều này theo mặc định cho tất cả các tệp bó, đặt HKEY_CLASSES_ROOT\cmdfile\shell\open\command\(default)HKEY_CLASSES_ROOT\batfile\shell\open\command\(default)thành "%windir%\system32\cmd.exe" /k "%windir%\system32\cmd" /c "%1" %*.


1
Tôi nghĩ rằng nó "%*"vượt qua danh sách tham số đầy đủ, vì vậy điều này sẽ không vượt qua tham số đầu tiên hai lần, một lần "%1"và một lần nữa như tham số đầu tiên của "%*"?
Kevin Fegan

1
@KevinFegan Tôi chưa kiểm tra lý do nhưng% 1 nên giữ nguyên các trích dẫn có nghĩa là nó có thể được trích dẫn gấp đôi trong một số trường hợp. Cũng có một sự khác biệt giữa %1 %2 %3 ..%*tôi không nhớ ngay bây giờ nhưng %1 %2 %3công việc trong một số trường hợp %*không thành công.
Wernight

3

Tôi chỉ nhấn vào một giải pháp ngu ngốc sau khi đọc grawitycâu trả lời.

Trường hợp sử dụng của tôi là thiết lập môi trường giao diện điều khiển tại nơi làm việc, nơi tất cả các giải pháp hợp lý hơn đều bị chặn. Tất cả những gì tôi cần là đặt PATH và cấu hình một số bí danh doskey và được đổ vào trình bao.

Giải pháp của tôi (vừa được thử nghiệm trên Win7) là thêm cmddòng cuối cùng trong tệp bó. Điều này chạy một dấu nhắc lệnh lồng nhau kế thừa môi trường của cha mẹ của nó. Vỏ con đó giữ quy trình lô mở cho đến khi bạn THOÁT, tại thời điểm đó, lô đó không có quy trình con và cũng thoát.


2

Thay vì sử dụng PAUSE (tôi thích LỰA CHỌN hoặc THỜI GIAN hơn là sử dụng PAUSE khi cần thiết), bạn có thể sử dụng giải pháp tại đây: 886848 / how-to-make-windows-batch-file-pause-when-double-click .

Bằng cách này, nếu bạn nhấp vào tệp bó hoặc liên kết (phím tắt) từ trong Windows Explorer, bạn có thể tạm dừng chương trình tệp bó trước khi thoát để bạn có thể xem đầu ra chương trình và bất kỳ thông báo lỗi nào.

Sử dụng CHOICE, bạn có thể lập trình khả năng cho người dùng chọn nhiều hành động cần thực hiện và sử dụng TIMEOUT có thể để cửa sổ đóng lại sau một khoảng thời gian trễ (không giám sát). Nếu bạn chạy tệp bó từ trong cửa sổ nhắc lệnh, các tạm dừng này có thể gây khó chịu.

Giải pháp được liên kết sẽ cho phép bạn quyết định xem bạn có muốn bỏ qua các tạm dừng nếu tệp bó được chạy từ cửa sổ nhắc lệnh hay không.

Bạn có thể đọc thêm tại liên kết được cung cấp, nhưng điều cơ bản của nó là nó sử dụng biến môi trường:

%cmdcmdline%

để xác định xem tệp bó có được chạy từ cửa sổ lệnh hay không.

Vì vậy, bạn sử dụng nó như thế này:

Tại điểm mà tệp bó sẽ thoát, bạn thêm một số mã như thế này:

echo %cmdcmdline:"=-% | find /i "cmd /c --%~dpf0%-"
if %errorlevel% NEQ 0 goto :EOF
pause
goto :EOF

rem if %errorlevel% EQU 0 batch-file: %~dpf0 was executed from Windows Explorer, ...
rem if %errorlevel% NEQ 0 batch-file: %~dpf0 was executed from within a Command Prompt

1

Cách tốt nhất mà tôi đã tìm thấy để giải quyết vấn đề này là gọi các tệp bó của bạn từ một tệp bó khác bằng cách sử dụng start.

Vì vậy, nếu bạn thường chạy một tệp có tên go.bat, thì bạn sẽ tạo một tệp bó thứ hai có tên là go2.bat

nội dung của go2.bat sẽ chỉ là

start go.bat

cửa sổ đầu tiên đóng lại ngay lập tức, nhưng cửa sổ đang chạy go.bat vẫn mở


Điều này hoạt động, tôi chỉ cần đặt tên của dấu nhắc lệnh thực thi trong một tập tin bat (1.bat) được gọi bằng cách sử dụng lệnh start từ một tập tin bat thứ hai "start 1.bat". Cửa sổ lệnh vẫn mở.
ejectamenta

1

Điều này hoạt động cho phiên bản 5,00 của Windows Registry Editor.

[HKEY_CLASSES_ROOT\batfile\shell\open\command]
@="cmd.exe /k \"%1\" %*"

[HKEY_CLASSES_ROOT\cmdfile\shell\open\command]
@="cmd.exe /k \"%1\" %*"

Lưu các cmds trên trong một tệp gọi là một cái gì đó như cmdbatfile-open.regvà thực hiện nó!


2
Chào mừng bạn đến với Sàn giao dịch Stack! Tôi đã sửa định dạng trong câu trả lời của bạn cho bạn. Xem ở đây để giúp định dạng. Ngoài ra, khi bạn đăng mã, hãy nhớ giải thích chính xác những gì nó làm. Bạn cũng có thể muốn đọc cách trả lời .
Blacklight Shining

1

Giả sử bạn có hai tệp bó mà bạn muốn khởi chạy trong trường hợp riêng của chúng và tiếp tục mở nếu thoát thực thi của chúng. Hãy gọi hai đợt đó A.batB.bat.

Bây giờ để đơn giản, bạn có thể có một tệp bó để khởi chạy cả hai, hãy gọi nó launch_both.batvới nội dung:

start cmd /k "A.bat & cmd /c"
start cmd /k "B.bat & cmd /c"

Nó có thể không hoạt động như mong đợi nếu bạn gọi exitmột trong hai tệp bó. Điều đó sẽ cần phải được kiểm tra.


0

Đối với người dùng sử dụng Windows 10, lưu ý rằng không có câu trả lời nào ở trên hiện đang hoạt động cho Windows 10.

Đối với Windows 10, nếu bạn có quyền truy cập vào tập lệnh, bạn cần thêm đoạn mã sau vào cuối:

read

Mã đó sẽ đợi một đầu vào trước khi đóng.


Hãy nhớ câu hỏi đã được hỏi trước Windows 10 (5 năm trước), vui lòng chỉnh sửa câu trả lời của bạn với nhiều thông tin hơn
vào

0

Đáp lại việc hạ thấp PSIXO - "Câu trả lời này đã được đề cập trong câu hỏi. - Ro Yo Mi ngày 20 tháng 1 năm 16 lúc 5:06" - KHÔNG, nó KHÔNG. Các câu trả lời trước đó là: "tạm dừng", không hoạt động. Câu trả lời của PSIXO là: "& tạm dừng", điều này KHÔNG hoạt động. Vui lòng phân tích kỹ hơn trước khi hạ cấp. Tôi đã chạy nó từ một dấu nhắc IDLE và nó đã hoạt động:

    >>> os.system('dir ^ & pause')
    0
    >>> 

Mặt khác:

    >>> os.system('dir ^ pause')
    1
    >>>

KHÔNG hoạt động (dấu nhắc cmd bị xóa và trên thực tế đã trả về lỗi (1)). Cảm ơn PSIXO cho câu trả lời mà tôi cần. Henry.

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.