为什么我的命令提示在Windows 10上冻结?

发布于 2025-01-27 08:00:40 字数 123 浏览 3 评论 0 原文

在花了一整天的时间搏斗之后,我添加了这个问题,这是Windows 10命令提示的这一令人沮丧的功能,这使我认为控制台应用程序代码有问题。我希望这会帮助某人。

问题:我的控制台应用程序似乎随机停止运行。到底是怎么回事?

I'm adding this question after spending an entire day wrestling with this incredibly frustrating feature of the Windows 10 command prompt which made me think there was something wrong with my console application code. I hope it will help someone.

Issue: My console application seems to randomly stop running. What is going on?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

樱花落人离去 2025-02-03 08:00:40

该问题最终成为Windows 10控制台的新功能。在默认配置下,每当您单击Windows 10中的命令窗口时,它都会在尝试写入控制台时立即停止应用程序过程。发生这种情况时,命令窗口已进入“选择”模式。

您可以说它发生了,因为它将在命令窗口的标题栏上以“ select”:

<< img src =“ https://i.sstatic.net/dwimt.png” alt =“冷冻命令窗口”>

要使程序再次运行,您必须按Escape或单击其他地方。

要摆脱这种奇怪的行为,您可以禁用QuickEdit模式:

“

The issue ended up being a new feature of the windows 10 console. Under the default config, whenever you click on a command window in windows 10, it immediately halts the application process when it attempts to write to the console. When this happens, the command window has gone into "selection" mode.

You can tell it has happened because it will prefix the title bar of the command window with the word "Select" :

frozen command window

To get your program running again, you have to press escape or click somewhere else.

To get rid of this strange behavior, you can disable QuickEdit mode:

disable QuickEdit Mode

蛮可爱 2025-02-03 08:00:40

我想在此处添加到Shaun Rowan的答案中的内容是,要在 all> all 控制台窗口中使用它,您必须单击“默认”,而不是“属性”,然后在此进行更改,如上所述在此帖子

What I'd like to add here to Shaun Rowan's answer is that for it to work in all console windows you have to click "Defaults", instead of "Properties" and make your changes there, as described in this post.

无人问我粥可暖 2025-02-03 08:00:40

最近,我遇到了这个问题,其中一位用户(在他的命令提示符上配置了QuickEdit配置)正在使用我在Java中开发的工具,并且在从命令提示符下运行该工具时将其冻结。

最后,解决问题的是将批处理脚本内的登录重定向到一个文件,如下所示:

@echo off
...
java.exe -jar mytool.jar

需要更新为

java.exe -jar mytool.jar > log.txt

I faced this problem very recently where one of the users (who had Quickedit configured on his Command Prompt) was using a tool I developed in Java, and was getting the tool frozen while running it from command prompt.

Finally what solved the problem was to redirect the logging inside the batch script to a file as shown below:

@echo off
...
java.exe -jar mytool.jar

needed to be updated to

java.exe -jar mytool.jar > log.txt
鲸落 2025-02-03 08:00:40

可以通过导入Windows' kernel32.dll 库并使用Console API函数来编程。 com/en-us/windows/console/getstdhandle'R =“ nofollow noreferrer”> getStdhandle getConsolemode ,and setConsolemode 通过您的语言的本机接口(例如,Java的Jni,Python ctypes)。

带有 ctypes 的python:

short(禁用除Extended_flags以外的所有内容)。阅读 setConsolemode 文档以获取更多详细信息。

import ctypes

kernel32 = ctypes.windll.kernel32
kernel32.SetConsoleMode(kernel32.GetStdHandle(-10), 0x80)

更长(禁用Quick_edit_mode而不更改其他设置)

import ctypes
import time
import threading

# Constants
STD_INPUT_HANDLE = -10

# Enum for ConsoleModes
class ConsoleModes(ctypes.c_uint):
    ENABLE_PROCESSED_INPUT = 0x1
    ENABLE_LINE_INPUT = 0x2
    ENABLE_ECHO_INPUT = 0x4
    ENABLE_WINDOW_INPUT = 0x8
    ENABLE_MOUSE_INPUT = 0x10
    ENABLE_INSERT_MODE = 0x20
    ENABLE_QUICK_EDIT_MODE = 0x40
    ENABLE_EXTENDED_FLAGS = 0x80
    ENABLE_AUTO_POSITION = 0x100

# Import kernel32.dll functions
kernel32 = ctypes.windll.kernel32
GetStdHandle = kernel32.GetStdHandle
GetConsoleMode = kernel32.GetConsoleMode
SetConsoleMode = kernel32.SetConsoleMode

def disable_quick_edit_mode():
    std_in = GetStdHandle(STD_INPUT_HANDLE)
    mode = ctypes.c_uint()
    if GetConsoleMode(std_in, ctypes.byref(mode)):
        if mode.value & ConsoleModes.ENABLE_QUICK_EDIT_MODE:
            mode.value ^= ConsoleModes.ENABLE_QUICK_EDIT_MODE
            SetConsoleMode(std_in, mode)

def print_numbers():
    i = 0
    while True:
        time.sleep(0.3)
        print(i)
        i += 1

def main():
    disable_quick_edit_mode()
    threading.Thread(target=print_numbers).start()

if __name__ == "__main__":
    main()

请记住,此代码仅在Windows上运行。如果您正在编写要在多个操作系统上运行的软件,请确保保护错误。


阅读更多

C#:
batch:

It's possible to disable the annoying QuickEdit Mode programmatically by importing Windows' Kernel32.dll library and using the console API functions GetStdHandle, GetConsoleMode, and SetConsoleMode through your language's native interface (e.g., Java's JNI, Python ctypes).

Python with ctypes:

Short (disables everything except EXTENDED_FLAGS). Read SetConsoleMode documentation for more detail.

import ctypes

kernel32 = ctypes.windll.kernel32
kernel32.SetConsoleMode(kernel32.GetStdHandle(-10), 0x80)

Longer (disables QUICK_EDIT_MODE without altering other settings)

import ctypes
import time
import threading

# Constants
STD_INPUT_HANDLE = -10

# Enum for ConsoleModes
class ConsoleModes(ctypes.c_uint):
    ENABLE_PROCESSED_INPUT = 0x1
    ENABLE_LINE_INPUT = 0x2
    ENABLE_ECHO_INPUT = 0x4
    ENABLE_WINDOW_INPUT = 0x8
    ENABLE_MOUSE_INPUT = 0x10
    ENABLE_INSERT_MODE = 0x20
    ENABLE_QUICK_EDIT_MODE = 0x40
    ENABLE_EXTENDED_FLAGS = 0x80
    ENABLE_AUTO_POSITION = 0x100

# Import kernel32.dll functions
kernel32 = ctypes.windll.kernel32
GetStdHandle = kernel32.GetStdHandle
GetConsoleMode = kernel32.GetConsoleMode
SetConsoleMode = kernel32.SetConsoleMode

def disable_quick_edit_mode():
    std_in = GetStdHandle(STD_INPUT_HANDLE)
    mode = ctypes.c_uint()
    if GetConsoleMode(std_in, ctypes.byref(mode)):
        if mode.value & ConsoleModes.ENABLE_QUICK_EDIT_MODE:
            mode.value ^= ConsoleModes.ENABLE_QUICK_EDIT_MODE
            SetConsoleMode(std_in, mode)

def print_numbers():
    i = 0
    while True:
        time.sleep(0.3)
        print(i)
        i += 1

def main():
    disable_quick_edit_mode()
    threading.Thread(target=print_numbers).start()

if __name__ == "__main__":
    main()

Keep in mind that this code only runs on Windows. If you are writing software to be run on multiple operating systems, make sure to safeguard against errors.


Read More

C#:
Batch:
本宫微胖 2025-02-03 08:00:40

我知道这是一个古老的问题,但是提供的答案过于复杂。可以使用单个注册表值更改此行为。

在CMD提示中键入以下内容:

REG add "HKCU\Console" /v QuickEdit /t REG_DWORD /d 0 /f

I know this is an old question, but the provided answers are overcomplicated. This behavior can be changed with a single registry value.

In CMD prompt type the following:

REG add "HKCU\Console" /v QuickEdit /t REG_DWORD /d 0 /f
橙味迷妹 2025-02-03 08:00:40

我必须指出,该应用程序实际上不是“停止”或“暂停”,这仅是因为每当单击命令窗口时,控制台输出流是 blocked ,并且看到整个应用程序暂停,这是因为这些程序无法正确实现多线程和非阻滞IO。

您可以通过编写多线程应用程序来轻松验证这一点。例如,以下Java应用程序显示了一个登录对话框,并继续在控制台上输出文本。当控制台块时,您仍然可以与GUI互动。

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField; 
public class SwingLoginExample {
    
    public static void main(String[] args) { 
        new Thread(() -> {
            var i = 0;
            while (true) {
                i++;
                System.out.println("Hello World! " + i); // System.out.println is a blocking method in java
            }
        }).start();

        JFrame frame = new JFrame("Login Example");
        // Setting the width and height of frame
        frame.setSize(350, 200);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);


        JPanel panel = new JPanel();    
        frame.add(panel);
        placeComponents(panel);

        frame.setVisible(true);
    }

    private static void placeComponents(JPanel panel) {
        panel.setLayout(null);


        JLabel userLabel = new JLabel("User:");

        userLabel.setBounds(10,20,80,25);
        panel.add(userLabel);

        JTextField userText = new JTextField(20);
        userText.setBounds(100,20,165,25);
        panel.add(userText);


        JLabel passwordLabel = new JLabel("Password:");
        passwordLabel.setBounds(10,50,80,25);
        panel.add(passwordLabel);


        JPasswordField passwordText = new JPasswordField(20);
        passwordText.setBounds(100,50,165,25);
        panel.add(passwordText);

        JButton loginButton = new JButton("login");
        loginButton.setBounds(10, 80, 80, 25);
        panel.add(loginButton);
    }

}

您应始终避免直接调用print()或类似方法;如果控制台响应缓慢,则您的程序将因此而放慢。创建一个线程以执行print()任务,或使用非阻止替代方案。

I must point out that the application is actually not "halted" or "paused", it's only because the console output stream is blocked whenever you click on the command window, and if you see the whole application pausing, it's because these programs don't implement multithreading and non-blocking IO correctly.

You can easily verify this by writing a multi-threading application. For example, the following Java application shows a login dialog and continues to output text on the console. When the console blocks, you can still interact with the GUI.

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField; 
public class SwingLoginExample {
    
    public static void main(String[] args) { 
        new Thread(() -> {
            var i = 0;
            while (true) {
                i++;
                System.out.println("Hello World! " + i); // System.out.println is a blocking method in java
            }
        }).start();

        JFrame frame = new JFrame("Login Example");
        // Setting the width and height of frame
        frame.setSize(350, 200);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);


        JPanel panel = new JPanel();    
        frame.add(panel);
        placeComponents(panel);

        frame.setVisible(true);
    }

    private static void placeComponents(JPanel panel) {
        panel.setLayout(null);


        JLabel userLabel = new JLabel("User:");

        userLabel.setBounds(10,20,80,25);
        panel.add(userLabel);

        JTextField userText = new JTextField(20);
        userText.setBounds(100,20,165,25);
        panel.add(userText);


        JLabel passwordLabel = new JLabel("Password:");
        passwordLabel.setBounds(10,50,80,25);
        panel.add(passwordLabel);


        JPasswordField passwordText = new JPasswordField(20);
        passwordText.setBounds(100,50,165,25);
        panel.add(passwordText);

        JButton loginButton = new JButton("login");
        loginButton.setBounds(10, 80, 80, 25);
        panel.add(loginButton);
    }

}

You should always avoid calling print() or similar methods directly; if the console responds slowly, your program will be slowed down as a result. Create a thread to perform the print() task, or use a non-blocking alternative.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文