【问题标题】:SetConsoleMode fails with zero, lasterror = 0SetConsoleMode 失败为零,lasterror = 0
【发布时间】:2017-06-15 18:14:56
【问题描述】:

这不是重复的! - 嗯,看完了cmets,也许是吧。

我正在寻找一种在控制台应用程序的控制台输出中斜体文本的方法,使用 c#、Visual Studio 2015、Targeting .NET Framework 4.5.2、OS = Windows 7。

微软文档很清楚

它是here - 它非常具有误导性,它是错误的。这是一个操作系统问题。

Vladimir Reshetnikov 用我想要的解决方案找到了以下问题,

adding text decorations to console output

在 3 月 28 日 19:52 回答了其中一个答案,并在 git 和其他地方编写了类似的代码......我的问题是 - 自然 - 它对我不起作用。

我将作者的代码和小修改复制到以下控制台应用程序中

using System;
using System.Runtime.InteropServices;

namespace ConsoleApplication1
{
    class Program
    {
        const int STD_OUTPUT_HANDLE = -11;
        const uint ENABLE_VIRTUAL_TERMINAL_PROCESSING = 4;

        [DllImport("kernel32.dll", SetLastError = true)]
        static extern IntPtr GetStdHandle(int nStdHandle);

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

        [DllImport("kernel32.dll")]
        static extern bool SetConsoleMode(IntPtr hConsoleHandle, uint dwMode);

        static void Main()
        {
            var handle = GetStdHandle(STD_OUTPUT_HANDLE);
            uint mode;
            GetConsoleMode(handle, out mode);
            mode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
            SetConsoleMode(handle, mode);

            const string UNDERLINE = "\x1B[4m";
            const string RESET = "\x1B[0m";
            Console.WriteLine("Some " + UNDERLINE + "underlined" + RESET + " text");
            Console.ReadLine();
        }
    }
}

我在窗口中得到了 VT 命令,而不是文章中的下划线。

这是我的控制台窗口:

我已经捕获了 ConsoleSetMode 的返回值 - 它为零。我已经看到了 lasterror = 6 的失败,但这里的 lasterror 是 0。

认为这是最近的更新? ... 或者其他的东西? [编辑] 这是一个 Windows 版本问题 - 显然需要 Windows 10 AU。

【问题讨论】:

  • 这仅适用于 W8 或更高版本。
  • @Gusman 在 Windows 8.1 上对我不起作用。你是说 Windows 10 吗?
  • 对不起,错了,只有W10,看附件。
  • 在 Win10 的控制台上做了很多工作来支持 ENABLE_VIRTUAL_TERMINAL_PROCESSING 选项,使其表现得更像是 1970 年的东西。已完成支持新 Linux 子系统的工作。

标签: c# formatting console-application


【解决方案1】:

确保未设置控制台属性底部附近的“使用旧版控制台”复选框:

如果您没有看到此复选框,那么您可能使用的 Windows 版本太旧。

您可以使用注册表项HKCU\Console\ForceV2 以编程方式操作此复选框,如this answer 中所述。

【讨论】:

    【解决方案2】:

    好的。这是一个重复的 - 排序。在 Gusman 提到的问题的答案中,SetConsoleMode() and ENABLE_VIRTUAL_TERMINAL_PROCESSING?(我找不到,但应该有) - 此功能仅在 Windows 10 上可用(并且进一步......根据 Tamás Deme 'tomzorz',仅在 Windows 10 AU 上或之后),尽管 Microsoft 声称它在 Windows 2000“及更高版本”上可用。

    所以,答案是:它不起作用,除了在 Windows 10 上也不会起作用,在 Windows 7 被从地球上移除之前,这是一条死胡同,而且它不可能通过 QC视窗 7。

    届时,控制台应用程序将被法律禁止。

    【讨论】:

    • “在 Windows 2000 及更高版本上”可用的是 SetConsoleMode 函数 - 这几乎是正确的,因为 Windows 2000 是当前最早的“支持”里程碑,甚至对于函数也会显示从 Windows 95 开始就存在了。所以这部分是正确的,但他们确实忘记为各个常量指明不同的支持级别,就像他们对例如SystemParametersInfo。可能被报告为文档错误。
    【解决方案3】:

    需要更多的错误检查。

    private static readonly IntPtr InvalidHandle = new IntPtr(-1);
    

    handle = GetStdHandle(STD_OUTPUT_HANDLE);
    if (handle == InvalidHandle) {
        throw new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error());
    }
    if (!GetConsoleMode(handle, out uint mode)) {
        throw new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error());
    }
    mode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
    if (!SetConsoleMode(handle, mode)) {
        throw new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error());
    }
    

    【讨论】:

      猜你喜欢
      • 2011-12-07
      • 1970-01-01
      • 2013-04-18
      • 2013-07-23
      • 2016-12-10
      • 1970-01-01
      • 1970-01-01
      • 2019-10-22
      • 2022-10-16
      相关资源
      最近更新 更多