Перенаправление вывода консоли в файл

339
09 ноября 2021, 11:20

Как перенаправить вывод cmd в файл

#include <iostream>
#include "AtlBase.h"
#include "AtlConv.h"
void windows_system(const char* cmd);
int main()
{
    windows_system("ping 192.168.0.1 > C:\\Windows\\Temp\\sys.log");
}
void windows_system(const char* cmd) 
{
    PROCESS_INFORMATION p_info;
    STARTUPINFO s_info;
    DWORD ReturnValue;
    CA2T programpath(cmd);
    memset(&s_info, 0, sizeof(s_info));
    memset(&p_info, 0, sizeof(p_info));
    s_info.cb = sizeof(s_info);
    if (CreateProcess(programpath, NULL, NULL, NULL, 0, 0, NULL, NULL, &s_info, &p_info)) {
        WaitForSingleObject(p_info.hProcess, INFINITE);
        GetExitCodeProcess(p_info.hProcess, &ReturnValue);
        CloseHandle(p_info.hProcess);
        CloseHandle(p_info.hThread);
    }
}
Answer 1
  • Создайте ваш файл при помощи CreateFile. В результате вы получите хэндл этого файла.

  • При создании файла надо будет указать ему SECURITY_ATTRIBUTES, в которых поле bInheritHandle должно быть выставлено в TRUE.

    Альтернативно, можно создать файл с нулевыми SECURITY_ATTRIBUTES, а потом применить к его хэндлу

    SetHandleInformation(хэндл, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT)
    
  • В простейшем случае (просто сохранить результат в файл) ненулевые атрибуты FILE_SHARE_... в аргументах CreateFile не нужны. В более сложных случаях, возможно, они понадобятся.

  • Поместите хэндл этого файла в поле s_info.hStdOutput (и, наверное, s_info.hStdError) перед вызовом CreateProcess.

    В поле s_info.hStdInput поместите значение GetStdHandle(STD_INPUT_HANDLE).

    Выставьте флаг STARTF_USESTDHANDLES в s_info.dwFlags.

  • Через параметр bInheritHandles функции CreateProcess передавайте аргумент TRUE.

  • Также, если вы собираетесь передавать единую командную строку с именем выполнимого файла и аргументами в CreateProcess, то делать это нужно через второй параметр CreateProcess.

Примерный код для "узких" строк

HANDLE h_file = CreateFile("ping.log", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
SetHandleInformation(h_file, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT);
PROCESS_INFORMATION p_info = {};
STARTUPINFO s_info = { sizeof(s_info) };
s_info.dwFlags |= STARTF_USESTDHANDLES;
s_info.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
s_info.hStdError = h_file;
s_info.hStdOutput = h_file;
char programpath[256] = "ping 192.168.0.1";
if (CreateProcess(NULL, programpath, NULL, NULL, TRUE, 0, NULL, NULL, &s_info, &p_info)) 
{
  WaitForSingleObject(p_info.hProcess, INFINITE);
  CloseHandle(p_info.hProcess);
  CloseHandle(p_info.hThread);
}
CloseHandle(h_file);

Этот код прекрасно работает, а "примерный" он только в том смысле, что вам нужно будет адаптировать его к своему окружению.

READ ALSO
Почему не корректно срабатывает ZBuffer

Почему не корректно срабатывает ZBuffer

Помогите, уже второй день не могу понять, почему у меня не корректно отображается 3d сцена, плоскости не перекрываются, почему, не понятно

157
Сортировка по алфавиту

Сортировка по алфавиту

Собственно говоря мне нужно отсортировать " string name;" по алфавитуЖелательно без указателей и векторов

67
Как запустить команду в cmd

Как запустить команду в cmd

Как можно запустить команду cmd через system(""); что бы при этом не открывалась консоль именно при вызове system("");

189
Разные типы параметров у std::ios_base::width и std::setw

Разные типы параметров у std::ios_base::width и std::setw

Почему потоковый width для изменения принимает параметр типа std::streamsize, в то время как манипулятор setw принимает простой int? Насколько я понимаю,...

99