gpt4 book ai didi

windows - Windows 控制台中的 Tcl 和 Ctrl-C

转载 作者:可可西里 更新时间:2023-11-01 11:18:11 25 4
gpt4 key购买 nike

我在 Windows Tcl 8.5 应用程序中拦截 Ctrl-C 时遇到问题。我在我开发的扩展库中添加了一个控制台处理程序,但它并不总是有效。

如果某些 Tcl 代码正在执行,则一切正常。但是,如果应用程序正在等待用户输入,则按 Ctrl-C 可终止它。我的处理程序被调用,但同时(在不同的线程中?)Tcl REPL 调用 Tcl_Exit。这真的把一切都搞砸了。

据我所知,调用 REPL 调用 Tcl_Exit 是因为它错误地认为 stdin 遇到了 EOF。反过来,这是由于当按下 Ctrl-C 时,读取例程返回,它返回读取的字节数,即零。 REPL 将这种情况解释为 EOF。

有解决这个问题的简单方法吗?我知道我可以放弃 Tcl 内置 channel 并提供我自己的 channel ,但这对于这个简单的问题来说似乎有点矫枉过正。

我试过 twapi::set_console_control_handler 但它似乎根本不起作用。按 Ctrl-C 始终会终止应用程序,并且永远不会调用处理程序。

最佳答案

SetConsoleCtrlHandler 的 MSDN 文档指出 CTRL_C 处理是单独处理的,但这可以通过将控制台模式设置为 ENABLE_PROCESSED_INPUT 来禁用。然后将 Ctrl-C 事件报告为键盘输入。

将以下关键代码加载到解释器中(使用 load ctrl_c.dll ctrl_c; win32::SetCtrlHandler 让我在不退出的情况下拦截 Control-C 键盘输入:

package require critcl

namespace eval win32 {
critcl::ccode {
#define STRICT
#define WIN32_LEAN_AND_MEAN
#define _WIN32_WINNT 0x0502
#include <windows.h>

BOOL CtrlHandler(DWORD dwEvent)
{
switch (dwEvent)
{
case CTRL_C_EVENT:
fprintf(stderr, "ctrl_c\n");
return TRUE;
default:
return FALSE;
}
}
}

# Quick and dirty test CTRL_C interception in windows.
critcl::cproc SetCtrlHandler {} ok {
BOOL b = SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), ENABLE_PROCESSED_INPUT);
if (b)
b = SetConsoleCtrlHandler((PHANDLER_ROUTINE)CtrlHandler, TRUE);
return b ? TCL_OK : TCL_ERROR;
}
}

使用 critcl -lib ctrl_c.tcl 编译。

但是!一旦看到 Ctrl-C,控制台输入就不再回显用户键入的任何内容。它确实读取输入并对其进行操作,但不回显该输入。作为示例 session :

% load ctrl_c.dll ctrl_c
% win32::SetCtrlHandler
% ctrl_c
8.6.1
% -blocking 1 -buffering line -buffersize 4096 -encoding unicode -eofchar → -translation auto
% -blocking 1 -buffering line -buffersize 4096 -encoding unicode -eofchar {} -translation crlf
%

未显示的是我输入 fconfigure stdinfconfigure stdout 的位置。希望这可以帮助您寻找解决方案。

关于windows - Windows 控制台中的 Tcl 和 Ctrl-C,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27903208/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com