控制台选择停止应用程序

问题描述 投票:0回答:2

我正在我的服务器上运行套接字服务器,我醒来时收到有关其无法访问的消息。原来,在我睡觉之前,我已经在窗口中选择了文本。我忘记按 Enter 键来恢复该过程。

这就是我现在在控制台中禁用选择的方法,但我仍然希望能够在应用程序不暂停的情况下进行选择。

    #region Disable Quick-Edit Mode
    [DllImport("kernel32.dll")]
    static extern bool SetConsoleMode(IntPtr hConsoleHandle, int mode);

    [DllImport("kernel32.dll")]
    static extern bool GetConsoleMode(IntPtr hConsoleHandle, out int mode);

    [DllImport("kernel32.dll")]
    static extern IntPtr GetStdHandle(int handle);

    const int STD_INPUT_HANDLE = -10;
    const int ENABLE_EXTENDED_FLAGS = 0x80;
    
    public static void DisableQuickEditMode()
    {
        int mode;
        IntPtr handle = GetStdHandle(STD_INPUT_HANDLE);
        GetConsoleMode(handle, out mode);
        mode |= ENABLE_EXTENDED_FLAGS;
        SetConsoleMode(handle, mode);
        mode &= ~ENABLE_QUICK_EDIT;
        SetConsoleMode(handle, mode);
    }

我真的不想回到命令提示符的旧模式,因为它确实有助于拥有新的控制台功能,但我需要找到一种方法来防止应用程序在暂停控制台时停止。

有趣的是,当我今天早上按 Enter 时,所有尝试过的连接都被接受,然后在它们取消排队后,它们被丢弃。这让我怀疑,也许我写的应用程序是错误的;我需要有一个“控制台”线程和一个“服务器”线程。我不确定这是否会有所作为。

c# console dllimport
2个回答
8
投票

在选择模式下,Windows 控制台中的任何线程在写入

stdout
stderr
时都会阻塞。哪个线程并不重要。

您可以将控制台写入与服务器操作分开,并确保服务器线程永远不会写入控制台,但随后您会引入额外的线程管理和消息队列问题。

您可以做大多数人做的事情:使用日志文件。如果您不想构建写入应用程序的文件,只需将

stdout
stderr
传输到文件并使用
tail
的某些 Windows 等效项来监视文件(或像 Sublime 这样的文本编辑器,它会自动监视打开的文件)文件)。

server.exe > server.log 2>&1

澄清一下:

2>&1
表示
stderr
(文件句柄2)应该“合并到”
stdout
(文件句柄1)。


1
投票

对于简单的工具,在不同的线程中执行控制台写入可能确实是最简单的。 示例代码:

    static BlockingCollection<string> messageQueue = new BlockingCollection<string>(new ConcurrentQueue<string>());
    static Task messagePrinterTask;
    private static void ConsoleWriteLine(string s)
    {
        messageQueue.Add(s);
    }
    private static void StartMessageQueuePrinter()
    {
        messagePrinterTask = Task.Run(() =>
        {
            try { while(true) Console.WriteLine(messageQueue.Take()); }
            catch (InvalidOperationException) { } //CompleteAdding called.
        });
    }
    private static void StopMessageQueuePrinter()
    {
        messageQueue.CompleteAdding();
        messagePrinterTask.Wait();
    }
© www.soinside.com 2019 - 2024. All rights reserved.