Code stops executing when a user clicks on the console window
我有一个控制台应用程序,无需用户干预即可执行我的代码。如果用户有意或无意中在控制台窗口中单击,所有执行将停止。
这与从控制台窗口复制文本有关。应用程序再次开始执行的唯一方法是用户选择文本,然后在控制台窗口上单击鼠标右键,然后将其复制到剪贴板。
要查看实际效果,请创建一个控制台应用程序并添加以下代码。
1 | class Program |
当您单击控制台窗口时,任务线程将停止执行。这根本不是理想的行为,我想防止这种情况在我的控制台应用程序中发生。
我该如何预防?据我所知,控制台窗口上的所有属性/事件都与控制此行为无关。
如您所见,当我在窗口中单击时出现光标。当我按任意键时-光标消失并且应用程序继续工作
相关讨论
- 什么是"工作区应用程序"?输出结果如何?产生输出的代码是什么样的?
- 工作区表示控制台窗口,应用程序输出-处理操作的日志,例如"将文件A移至存储B ..."
- "医生,我这样做会很痛!""那么,那就不要那样做!"
- 请停止编辑,我已经重写了,希望可以弄清楚发生了什么。 @ShannonHolsinger的问题是,您不能确切地告诉用户不要意外单击控制台窗口...
- @ShannonHolsinger哦,真聪明。它的客户的愿望。
- 我不确定,但是这可能是Windows 10中的新功能。如果您在客户端计算机上运行了长时间运行的控制台应用程序,并且尝试聚焦窗口时,它们意外地停止了执行,则此行为将不是最佳选择。而且没有迹象表明发生了什么,或者如何使应用程序再次运行。
- 看到这个,可能不是一个确切的例子,但是包含有用的提示。
- @将感谢您的编辑。就像您说的那样,客户不小心在窗口中单击,并认为该应用程序已冻结。在解释了应用程序刚刚暂停后,客户希望禁用此行为以避免此类情况
- 我无法复制。您提供的代码可以正常工作。
- @Mahdi是什么操作系统?我相信此更改是Windows 10的新功能。
- @Sinatr多数民众赞成在绝对相同的问题。
- @将Windows 10专业版。
- @Mahdi还是一样,我绝对可以复制。
- 您还可以使用System.Diagnostics从另一个进程运行该进程,并完全隐藏控制台窗口。
- 这是如何通过互操作调用将其关闭stackoverflow.com/q/13656846/1997232
如果在控制台窗口上启用了"快速编辑模式",则会发生这种情况。如果右键单击标题栏并选择"属性",然后选择"选项"选项卡,则可以检查是否启用了"快速编辑模式"。如果禁用快速编辑模式,则在窗口中单击时滚动不会停止。
滚动停止的原因是因为在窗口中单击鼠标可以选择文本。
您可以在程序的控制台上禁用"快速编辑模式",但是需要调用GetConsoleMode和SetConsoleMode API函数。这是您的处理方式:
1 | [DllImport("kernel32.dll", SetLastError=true)] |
如果沿这条路线走,最好在程序启动时保存原始控制台模式设置,并在程序退出时恢复原来的控制台模式设置。因此,在启动时:
1 | GetConsoleMode(GetConsoleWindow(), ref saveConsoleMode); |
当程序终止时:
1 | SetConsoleMode(GetConsoleWindow(), saveConsoleMode); |
当然,通过适当的错误处理。如果对GetConsoleMode的调用失败,则您不想恢复控制台模式。
相关讨论
- 这似乎仅在从Visual Studio进行调试时运行。 单独启动程序时,即使以管理员身份运行,也仍然会出现问题。 有任何想法吗?
- @tayoung-检查每个系统调用返回的错误,并在发生错误时尝试调用Marshal.GetLastWin32Error(),例如:var error = Marshal.GetLastWin32Error(); var errorMessage = new Win32Exception(error).Message;
- @tayoung:即使独立运行,这也对我有用。 如果您可以用其他方式说明,请通过示例发表问题。
- @jimMischel Im面临类似问题。 我检查了您的两种解决方案(该解决方案可在您的旧帖子中找到)。 我检查了快速编辑模式的开和关。 (两者都得到相同的结果)。 我还没有找到解决方案。 有什么解决方法,我该如何解决这个错误。
我只是看到OP的问题评论中链接的这个答案包含了我自己发现的内容。我会保留我的答案,因为人们可能不会像我一样看到它,这将使他们节省很多时间。
吉姆的答案对我不起作用,我不知道为什么。
我四处寻找并找到了可行的解决方案,因此我将分享我的发现,希望能帮助处于相同情况的某人。
问题出在我从GetConsoleWindow()获得的手柄上,它给出了Win32错误(0x6),其中当我尝试使用它时手柄无效。对SetConsoleMode()的调用没有执行任何操作。
为了获得有效的句柄,我使用了GetStdHandle()来获取控制台的Input句柄。将此添加到Jim的代码中:
1 | public const int STD_INPUT_HANDLE = -10; |
然后在Jim的代码中将GetConsoleWindow()替换为DisableQuickEdit()中的GetStdHandle(STD_INPUT_HANDLE)和EnableQuickEdit()。
调用DisableQuickEdit()后,将在控制台中禁用选择。
正确代码:
在控制台中:
private static void OnTimedEvent(object source, ElapsedEventArgs e)
{
Console.WriteLine(DateTime.Now);
}
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr GetConsoleWindow();
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool GetConsoleMode(
IntPtr hConsoleHandle,
out int lpMode);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool SetConsoleMode(
IntPtr hConsoleHandle,
int ioMode);
/// <summary>
/// This flag enables the user to use the mouse to select and edit text. To enable
/// this option, you must also set the ExtendedFlags flag.
/// </summary>
const int QuickEditMode = 64;
public const int STD_INPUT_HANDLE = -10;
[DllImport("Kernel32.dll", SetLastError = true)]
public static extern IntPtr GetStdHandle(int nStdHandle);
// ExtendedFlags must be combined with
// InsertMode and QuickEditMode when setting
/// <summary>
/// ExtendedFlags must be enabled in order to enable InsertMode or QuickEditMode.
/// </summary>
const int ExtendedFlags = 128;
static void DisableQuickEdit()
{
IntPtr conHandle = GetStdHandle(STD_INPUT_HANDLE);
int mode;
if (!GetConsoleMode(conHandle, out mode))
{
// error getting the console mode. Exit.
return;
}
mode = mode & ~(QuickEditMode | ExtendedFlags);
if (!SetConsoleMode(conHandle, mode))
{
// error setting console mode.
}
}
static void EnableQuickEdit()
{
IntPtr conHandle = GetConsoleWindow();
int mode;
if (!GetConsoleMode(conHandle, out mode))
{
// error getting the console mode. Exit.
return;
}
mode = mode | (QuickEditMode | ExtendedFlags);
if (!SetConsoleMode(conHandle, mode))
{
// error setting console mode.
}
}
Main函数调用: DisableQuickEdit();//禁止快捷编辑
do something
EnableQuickEdit()//启用快捷编辑