c_cpp 在执行命令之前设置控制台模式

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c_cpp 在执行命令之前设置控制台模式相关的知识,希望对你有一定的参考价值。

#include <stdio.h>
#include <tchar.h>
#include <string.h>

#include <Windows.h>
#include <wincon.h>

#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004
#define DISABLE_NEWLINE_AUTO_RETURN 0x0008
#define ENABLE_LVB_GRID_WORDWIDE 0x0010

void Check(BOOL b)
{
    if (!b)
    {
        throw GetLastError();
    }
}

DWORD ParseOutputMode(const TCHAR* s)
{
    DWORD mode = 0;
    while (*s != _T('\0'))
    {
        switch (*s)
        {
        case _T('p'): case _T('P'): mode |= ENABLE_PROCESSED_OUTPUT; break;
        case _T('w'): case _T('W'): mode |= ENABLE_WRAP_AT_EOL_OUTPUT; break;
        case _T('v'): case _T('V'): mode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING; break;
        case _T('n'): case _T('N'): mode |= DISABLE_NEWLINE_AUTO_RETURN; break;
        case _T('l'): case _T('L'): mode |= ENABLE_LVB_GRID_WORDWIDE; break;
        }
        ++s;
    }
    return mode;
}

DWORD MyCreateProcess(TCHAR* cmd, STARTUPINFO sa = STARTUPINFO { sizeof(STARTUPINFO) })
{
    PROCESS_INFORMATION pi = {};
    DWORD Flags = 0;
    Check(CreateProcess(nullptr, cmd, nullptr, nullptr, TRUE, Flags, nullptr, nullptr, &sa, &pi));
    WaitForSingleObject(pi.hProcess, INFINITE);
    DWORD exit = 0;
    GetExitCodeProcess(pi.hProcess, &exit);
    CloseHandle(pi.hProcess);
    return exit;
}

int _tmain(int argc, const TCHAR* argv[])
{
    //HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
    HANDLE hConsole = CreateFile(_T("CONOUT$"), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);

    try
    {
        for (int i = 1; i < argc; ++i)
        {
            const TCHAR* arg = argv[i];
            if (_tcsncmp(arg, _T("/e:"), 3) == 0)
            {
                DWORD mode = 0;
                Check(GetConsoleMode(hConsole, &mode));

                const TCHAR* s = arg + 3;
                mode |= ParseOutputMode(s);
                Check(SetConsoleMode(hConsole, mode));
            }
            else if (_tcsncmp(arg, _T("/t:"), 3) == 0)
            {
                DWORD mode = 0;
                GetConsoleMode(hConsole, &mode);

                const TCHAR* s = arg + 3;
                return (mode & ParseOutputMode(s)) ? 0 : 1;
            }
            else if (_tcscmp(arg, _T("/r")) == 0)
            {
                TCHAR cmd[1024] = _T("");
                ++i;
                // TODO Escape characters like '%', '\'
                while (i < argc)
                {
                    arg = argv[i];
                    if (cmd[0] != _T('\0'))
                        _tcscat_s(cmd, _T(" "));;
                    if (_tcschr(arg, _T(' ')) == nullptr)
                    {
                        _tcscat_s(cmd, arg);
                    }
                    else
                    {
                        _tcscat_s(cmd, _T("\""));
                        _tcscat_s(cmd, arg);
                        _tcscat_s(cmd, _T("\""));
                    }
                    ++i;
                }
                return MyCreateProcess(cmd);
            }
            else
            {
                _ftprintf(stderr, _T("Unknown arg: %s\n"), arg);
            }
        }

        return 0;
    }
    catch (DWORD e)
    {
        _ftprintf(stderr, _T("Error: %d\n"), e);
        return e;
    }
}

以上是关于c_cpp 在执行命令之前设置控制台模式的主要内容,如果未能解决你的问题,请参考以下文章

c_cpp 控制平面:推送命令和获取结果

c_cpp 执行命令并获取输出

如何检测 Topshelf 是不是在控制台模式下运行

iOS使用openSSL加密应该怎么做

如何在 Windows 下编译 OpenSSL

设计模式之命令模式