ANSI颜色设置图形渲染在批处理中途中断并在继续进行后继续工作 [英] ANSI color Set Graphics Rendition breaking mid-batch and working after it proceeds

查看:118
本文介绍了ANSI颜色设置图形渲染在批处理中途中断并在继续进行后继续工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个批处理,该批处理具有一个小节,该小节遍历文件的各个行以供EXE尝试运行,然后该批处理根据其退出代码对EXE进行排序.

I've got a batch that has a sub-section which iterates through lines of a file for EXEs to try running, and then the batch sorts the EXEs based on their exit codes.

由于某些原因,在设置前一个图形表示而不是重新呈现它之后,ANSI SGR似乎破坏或回显了文字文本.

For some reason, the ANSI SGR seems to break or echo the literal text after setting the graphics rendition of the previous one instead of re-rendering it.

我回过头来重新引用此问题和原始文档,但是我不确定为什么我的批处理中的这一特定区域在回显第一行之后会在控制台内部破坏ANSI的颜色.

I went back to re-reference this question and the original documentation, but I'm not sure why this specific area of my batches is mangling the ANSI coloration inside the console after the first line is echoed.

我只用记事本交换了工具,您可以手动将其关闭以实现零退出,或使用控制面板结束该过程以获取非零退出.

I swapped my tool with just Notepad, which you can manually close for a zero-exit, or use the Control Panel to end the process to get a non-zero exit.

test_map.log的内容不要紧,因为您实际上只是使用记事本并将其发送一些参数.这就是我的设置:

The contents of test_map.log shouldn't matter too much since you're actually using just Notepad and sending it some args. This is what mine are set to:

C:\temp\qt_selftest.exe
C:\temp\sub_test.exe
C:\temp\cmd_module_test.exe
C:\temp\failing_qt_test.exe
C:\temp\passing_qt_test.exe
C:\temp\random_qt_test.exe
C:\temp\fail_module.exe
C:\temp\pass_module.exe

从屏幕截图中可以看到,这些行将按字面意义处理.在我从中提取的实际批处理中,它确实又可以恢复工作了……但是在该块中,并且在该块中仅 处,它已损坏.

And as you can see from the screenshot, the lines are being treated literally. Within the actual batch that I pulled this from, it does go back to working again... but within that block and only in that block, it's broken.

有什么想法我可能会搞砸吗?

Any idea where I might be messing this up?

由于ESC序列已转换,我不能直接共享代码,所以这里是要点:

I can't share the code directly due to ESC sequences being converted, so here is the gist: https://gist.github.com/the-nose-knows/1bebce2719e020188c6307cff736f951

如果需要在[之前重新添加它们,请使用alt代码027,例如 alt 0 2 7

If you need to re-add them before the [, use the alt-code of 027, as alt 0 2 7

推荐答案

正如erykson所说,可以通过确保启用虚拟终端模式来解决此问题.如果您仅在意 PowerShell的颜色,则可以在对CMD.exe的调用中添加/A开关,否则,您将需要一个小的进程来像处理垫片一样处理这种情况,但是还可以确保启用了VTM.这并不是一件坏事,因为这个抽象层可能会在将来的用例和错误中派上用场.

As erykson said, this can be solved by making sure Virtual Terminal Mode is enabled. If you only care about PowerShell's color, you can add the /A switch to your call to CMD.exe, otherwise you're going to want a small process that handles this kind of like a shim, but one that also makes sure VTM is enabled. This isn't wholly a bad thing, as this abstraction layer could come in handy for future use cases and bugs.

此片段中唯一的怪异"部分是我的rel-path用法.该代码段是一个子目录中的进程shim,可从一个目录中运行批处理shim.

The only "weird" part of this snippet would be my rel-path usage. This snippet is a process shim from a sub-directory to run a batch shim from up one directory.

代码的重要部分是要包含的标头,并在获取控制台句柄后为StdOut启用VTM.

The important parts of the code are the headers to include and enabling VTM for StdOut after getting the console handle.

#include <iostream>
#include <string>
#include <vector>
#include <iterator>
#include <Windows.h>

#ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING
#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004
#endif

bool uses_whitespace(std::string test_string)
{
    size_t path_white_space_query = test_string.find(' ', 0);

    if (path_white_space_query != std::string::npos)
    {
        return true;
    }

    return false;
}

int main(int argc, char* argv[])
{
    std::string this_app_path = std::string(argv[0]);

    auto it = this_app_path.find_last_of("\\", std::string::npos);

    std::string path(this_app_path, 0, it);

    // Just forwarding the args that were sent to this shim to a batch in a known location,
    // making sure whitespace arguments keep their quotes when forwarded.

    // CMD.exe will need proper quote-handling, or the call will get mangled.
    std::string str = "C:\\Windows\\System32\\cmd.exe /C \"\"" + path + "\\..\\app_shim.bat\"";
    std::vector<std::string> args;
    std::copy(argv + 1, argv + argc, std::back_inserter(args));

    for (auto const& arg : args)
    {
        if (uses_whitespace(arg))
        {
            str += (" \"" + arg + "\"");
        }
        else
        {
            str += (" " + arg);
        }
    }

    // end-of-CMD-call final wrapping quote
    str += "\"";

    HANDLE stdOutHandle = GetStdHandle(STD_OUTPUT_HANDLE);

    DWORD mode = 0;
    GetConsoleMode(stdOutHandle, &mode);
    SetConsoleMode(stdOutHandle, mode | ENABLE_VIRTUAL_TERMINAL_PROCESSING);

    int exit_code = system(str.c_str());

    CloseHandle(stdOutHandle);

    return exit_code;
}

这篇关于ANSI颜色设置图形渲染在批处理中途中断并在继续进行后继续工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆