最近在运行编译好的exe文件时,发现了一个现象,就是通过cmd运行exe文件或者双击执行运行exe文件,偶尔会出现程序没有执行的情况。最开始发现这个现象时,还以为是程序出现了什么Bug。后面经过网上查询才知道,原始这一切都是控制台(cmd)模式下快速编辑模式捣的鬼。可能大家平常没有接触到,或者是没有留意。

接下来我们就一起看看什么是控制台(cmd)模式下快速编辑模式、如果解决这个问题以及简单的了解下背后的原理。

1、现象

我们先编写一段简单的代码,来复现上面说的现象。

package main

import (
"fmt"
"time"
) func main() {
for {
fmt.Println("-------------------")
fmt.Println(time.Now())
time.Sleep(time.Second)
}
}

代码很简单,就是定时向标准输出(这里就是屏幕)输出指定的内容。现象如下:

现象也如我们期望的那样。这个时候,我们用鼠标点击下控制台黑色范围,会发现屏幕没有输出内容了,程序仿佛没有执行了。现象如下:

这个时候就很奇怪了,程序运行好好的,怎么突然这样子呢?

这个时候我们将鼠标移动到黑色范围呢,然后按下 enter 键,会发现程序又开始往下执行了。现象如下:

了解了上面的现象,接下来我们看看如何解决这个问题。

2、解决办法

2.1、手动设置法

windows cmd -> 窗口白色部分,点击右键 ->默认值 -> 取消掉快速编辑模式(Q)

注意:

将cmd设置之后,cmd是禁用了,但运行一个exe终端,发现它还是启动快速编辑模式。所以每个新exe都需手动设置。

2.2、通过命令修改windows默认配置方式

这个方式,我没有测试过,大家可以自行网上搜索或看下面链接测试。

windows cmd批处理终端 快速编辑模式bug 程序运行阻塞 标题栏提示选择 需要回车继续执行

2.3、代码中禁用

package main

import (
"fmt"
"golang.org/x/sys/windows"
"os"
"time"
) func init() {
//输入模式
var inMode uint32
inHandle := windows.Handle(os.Stdin.Fd())
if err := windows.GetConsoleMode(inHandle, &inMode); err != nil {
return
}
inMode &^= windows.ENABLE_QUICK_EDIT_MODE
inMode &^= windows.ENABLE_INSERT_MODE
inMode &^= windows.ENABLE_MOUSE_INPUT
windows.SetConsoleMode(inHandle, inMode) //输出模式
var outMode uint32
out := windows.Handle(os.Stdout.Fd())
if err := windows.GetConsoleMode(out, &outMode); err != nil {
return
}
outMode |= windows.ENABLE_PROCESSED_OUTPUT | windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING
_ = windows.SetConsoleMode(out, outMode)
} func main() {
for {
fmt.Println("-------------------")
fmt.Println(time.Now())
time.Sleep(time.Second)
}
}

运行编译后的文件,这个时候再去点击用鼠标点击下控制台黑色范围,发现并不会影响程序的正常运行。

3、简单聊一聊代码中的功能以及 bitmask 的设置技巧

init 函数代码简介:

func init() {
//输入模式
var inMode uint32 //通过os.Stdin.Fd()获取标准输入的文件描述符,然后将其转换为windows.Handle类型的句柄inHandle
inHandle := windows.Handle(os.Stdin.Fd()) //使用windows.GetConsoleMode函数获取与inHandle相关联的控制台输入模式,并将结果存储在inMode中
if err := windows.GetConsoleMode(inHandle, &inMode); err != nil {
return
} //通过按位异或清除控制台的快速编辑模式
inMode &^= windows.ENABLE_QUICK_EDIT_MODE
inMode &^= windows.ENABLE_INSERT_MODE
inMode &^= windows.ENABLE_MOUSE_INPUT
//使用windows.SetConsoleMode函数将修改后的输入模式应用到标准输入句柄上
windows.SetConsoleMode(inHandle, inMode) //输出模式
var outMode uint32
out := windows.Handle(os.Stdout.Fd())
//使用windows.GetConsoleMode函数获取与out相关联的控制台输出模式,并将结果存储在outMode中
if err := windows.GetConsoleMode(out, &outMode); err != nil {
return
}
//设置控制台输出模式,包括控制台的标准输出处理模式和启用虚拟终端处理
outMode |= windows.ENABLE_PROCESSED_OUTPUT | windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING
_ = windows.SetConsoleMode(out, outMode)
}

我们debug看看程序的执行过程,前面两步如下:

执行完windows.GetConsoleMode后,inMode=503,对应二进制为:1,1111,0111。

执行完inMode &^= windows.ENABLE_QUICK_EDIT_MODE,inMode=439,对应二进制为:1,1011,0111。

1,1111,0111 = 503
0,0100,0000 = 64
异或
1,1011,0111 = 439

异或:相同为0,不同为1

这样通过异或操作,可以将bitmask(标志位)修改。

对于ENABLE_QUICK_EDIT_MODE等标志位的设定,我对它的感悟是:如果使用一个变量来控制一个软件的不用作用,比如这里是否开启快速编辑模式。我们可以使用 bitmask 来控制,bitmask 最好是按照1, 2, 4, 8 ... 这样设置,只要对应位上的数字是1表示开启,为0则表示关闭。

这样方便后续通过异或操作,设置功能是否开启,这样既简单,又直观。

https://learn.microsoft.com/en-us/windows/console/setconsolemode

Windows中控制台(cmd)模式下运行程序卡死/挂起现象解决方案(快速编辑模式)的更多相关文章

  1. C#下控制台程序窗口下启用快速编辑模式运行线程会阻止线程运行

    最近做一个小的功能,使用C#控制台程序开启一个线程进行无限循环没5秒处理一次程序,发现控制台窗口在开启快速编辑模式情况下,进行选择程序打印 出来的文字后发现线程不走了,将快速编辑模式去除后,线程就不会 ...

  2. IntelliJ IDEA在Local模式下Spark程序消除日志中INFO输出

    在使用Intellij IDEA,local模式下运行Spark程序时,会在Run窗口打印出很多INFO信息,辅助信息太多可能会将有用的信息掩盖掉.如下所示 要解决这个问题,主要是要正确设置好log4 ...

  3. MySQL-Front 出现“程序注册时间到期 程序将被限制模式下运行”解决方式

    MySQL-Front 出现“程序注册时间到期 程序将被限制模式下运行”解决方式 在用mysql-front的时候遇到显示:程序注册时间到期程序将被限制模式下运行.可以在“帮助”菜单下的点“登记”-- ...

  4. 在C#中,Windows Console控制台 设置控制台标题、禁用关闭按钮、关闭快速编辑模式、插入模式

    设置控制台标题 禁用关闭按钮 关闭快速编辑模式 关闭插入模式 设置控制台标题.禁用关闭按钮 #region 设置控制台标题 禁用关闭按钮 [DllImport("user32.dll&quo ...

  5. 非GUI模式下运行JMeter和远程启动JMeter

    JMeter是一款非常不错的免费开源压力测试工具,越来越多的公司在使用.不过,在使用过程中可能会存在一些问题,比如:GUI模式非常消耗资源,单个客户端测试无法达到目标压力.而使用非 GUI 模式,即命 ...

  6. 《机器学习实战-KNN》—如何在cmd命令提示符下运行numpy和matplotlib

    问题背景:好吧,文章标题是瞎取得.平常用cmd运行python代码问题不大,我在学习<机器学习实战>这本书时,发现cmd无法运行import numpy as np以及import mat ...

  7. OLE DB访问接口“MICROSOFT.JET.OLEDB.4.0”配置为在单线程单位模式下运行,所以该访问接口无法用于分布式

    OLE DB访问接口"MICROSOFT.JET.OLEDB.4.0"配置为在单线程单位模式下运行,所以该访问接口无法用于分布式 数据库操作excel时遇到的以上问题的解决方法 解 ...

  8. 报错解决:DENIED Redis正在保护模式下运行

    DENIED Redis正在保护模式下运行,因为已启用保护模式,未指定绑定地址,也未向客户端请求身份验证密码.在此模式下,仅接受环回接口的连接.如果您想从外部计算机连接到Redis,您可以采用以下解决 ...

  9. 教你50招提升ASP.NET性能(十一):避免在调试模式下运行网站

    (17)Avoid running sites in debug mode 招数17: 避免在调试模式下运行网站 When it comes to ASP.NET, one of the most c ...

  10. [Selenium]Grid模式下运行时打印出当前Case在哪台node机器上运行

    当Case在本地运行成功,在Grid模式下运行失败时,我们需要在Grid模式下进行调试,同时登录远程的node去查看运行的情况. Hub是随机将case分配到某台node上运行的,怎样知道当前的cas ...

随机推荐

  1. .NET周刊【2月第1期 2024-02-04】

    祝大家新年快乐,龙年大吉~ 国内文章 C#/.NET/.NET Core优秀项目和框架2024年1月简报 https://www.cnblogs.com/Can-daydayup/p/18000401 ...

  2. 【Unity3D】花瓣特效

    1 花瓣绘制原理 ​ 如下图是实现的花瓣特效效果,为方便描述,我们将每个红色的扁状长条称为花瓣,每个花瓣中心的绿点称为花蕊,花朵的正中心称为花心. ​ 我们在 xOz 平面上绘制花朵,假设花心为 O ...

  3. springboot和jquery.form.js实现监听文件上传进度

    说明 文件上传作为程序开发最常用的功能之一,上传进度展示也是必须的.但是有时候进度并不准,进度100%了实际上后台尚未接收完毕,本篇就介绍如何利用jquery的form插件来实时反馈文件上传进度. 实 ...

  4. Oracle正则表达式实战

    原文链接:http://oracle-base.com/articles/misc/regular-expressions-support-in-oracle.php Introduction Exa ...

  5. 2020-11-18 原生js实现自动打字效果

    原理 使用定时器,对要输出的文字进行遍历,每遍历一次,都增加一个字以及在段尾加上"|"暗示别人正在打字. js代码 const fangWrite = (theString, qu ...

  6. 【LeetCode栈与队列#03】删除字符串中所有的相邻重复项

    删除字符串中所有的相邻重复项 力扣题目链接(opens new window) 给出由小写字母组成的字符串 S,重复项删除操作会选择两个相邻且相同的字母,并删除它们. 在 S 上反复执行重复项删除操作 ...

  7. 【API Management】使用 APIM Inbound Policy 来修改Content‐Type Header的值

    问题描述 在使用APIM提供API服务管理的场景中,遇见了客户端请求时候发送的请求Header中的Content-Type不满足后台服务器的要求,但是在客户端要求客户修改代码难度较高. 所以面对这样的 ...

  8. 【Azure 事件中心】向Event Hub发送数据异常 : partitionId[null]: Sending messages timed out

    问题描述 在使用Java 代码向 Azure Event Hub发送数据时,先后遇见了如下两种异常消息: 1)ERROR c.t.d.h.s.source.EventHubLogConsumer - ...

  9. 八: Mysql配置文件的使用

    # Mysql配置文件的使用 1. 配置文件格式 与在命令行中指定启动选项不同的是,配置文件中的启动选项被划分为若干个组,丽个组有一个组名, 用中括号 [ ]扩起来,像这样: 像这个配置文件里就定义了 ...

  10. Mysql基础目录

    尚硅谷Mysql课程笔记 课程链接: https://www.bilibili.com/video/BV1iq4y1u7vj?p=1 第01章_数据库概述 第02章_MySQL环境搭建 第03章_基本 ...