Создание консольного канала вместо файлового канала - PullRequest
0 голосов
/ 22 февраля 2019

Я пытаюсь перехватить вывод из cmd.exe при запуске команд.Я пытаюсь захватить вывод Unicode для поддержки других языков.Мой код работает прямо сейчас для возврата юникода из встроенных команд в cmd.exe.Таких как Dir.Но если я попытаюсь выполнить внешние команды, такие как «net user» или «ipconfig», он не выведет юникод.

Я прочитал и обнаружил, что это из-за того, что мои каналы являются файловыми каналами.Ipconfig.exe определяет, печатает ли он на консоль или нет.Если он печатает на консоль, он использует WriteFileW и выводит Unicode.Иначе он просто печатает ANSI, и я получаю ????????для любого Unicode.

#include <winsock.h>
#include <Windows.h>
#include <stdio.h>

void ExecCmd() {
    HANDLE hPipeRead;
    HANDLE hPipeWrite;
    SECURITY_ATTRIBUTES saAttr = { sizeof(SECURITY_ATTRIBUTES) };
    STARTUPINFO si = { sizeof(STARTUPINFO) };
    PROCESS_INFORMATION pi = { 0 };
    BOOL fSuccess;
    BOOL bProcessEnded = FALSE;
    size_t total = 0;

    saAttr.bInheritHandle = TRUE;
    saAttr.lpSecurityDescriptor = NULL;

    if (!CreatePipe(&hPipeRead, &hPipeWrite, &saAttr, 0)) {
        return;
    }

    si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
    si.hStdOutput = hPipeWrite;
    si.hStdError = hPipeWrite;
    si.wShowWindow = SW_HIDE; 

    WCHAR k[] = L"cmd.exe /u /c net user";
    fSuccess = CreateProcessW(NULL, k, NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);
    if (!fSuccess) {
        CloseHandle(hPipeWrite);
        CloseHandle(hPipeRead);
        return;
    }


    for (; !bProcessEnded;) {
        bProcessEnded = WaitForSingleObject(pi.hProcess, 50) == WAIT_OBJECT_0;

        while (TRUE) {
            DWORD dwRead = 0;
            DWORD dwAvail = 0;
            WCHAR *buffer = NULL;

            if (!PeekNamedPipe(hPipeRead, NULL, NULL, NULL, &dwAvail, NULL)) {
                break;
            }

            if (!dwAvail) {
                break;
            }

            buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (dwAvail + 2));
            if (buffer == NULL) {
                break;
            }

            if (!ReadFile(hPipeRead, buffer, dwAvail, &dwRead, NULL) || !dwRead) {
                break;
            }

            total += dwRead;

        }

    }
    CloseHandle(hPipeWrite);
    CloseHandle(hPipeRead);
    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);
    return;

} 

int main() {
    ExecCmd();
    return 0;
}

Мой вопрос: как я могу изменить способ, которым мои каналы получают информацию от внешних команд, таких как ipconfig, чтобы он поддерживал Unicode.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...