В Windows системная команда cmd или другие готовые исполняемые программы командной строки обычно используются для выполнения некоторых операций, таких как вызов команды ping для проверки работоспособности сети, вызов команды ffmpeg для перекодирования видео и т. д. Чтобы обеспечить лучший интерактивный вывод в интерфейсе программного обеспечения, необходимо получить процесс выполнения команды, обработать его, а затем отобразить на интерфейсе, чтобы пользователь знал, что программа работает нормально. Вот несколько способов получить. выход. .
Текущая среда разработки: 64-разрядная версия Win10 IDE-MSVC2017.
Откройте процесс для выполнения через _popen и получите выходные данные процесса через fgets.
#include <stdio.h>
#include <string.h>
int run_cmd(const char * cmd)
{
char MsgBuff[1024];
int MsgLen=1020;
FILE * fp;
if (cmd == NULL)
{
return -1;
}
if ((fp = _popen(cmd, "r")) == NULL)
{
return -2;
}
else
{
memset(MsgBuff, 0, MsgLen);
//Читаем вывод во время выполнения команды
while (fgets(MsgBuff, MsgLen, fp) != NULL)
{
printf("MsgBuff: %s\n", MsgBuff);
}
//Закрываем исполняемый процесс
if(_pclose(fp) == -1)
{
return -3;
}
}
return 0;
}
int main()
{
//const char *cmd = "ffmpeg -i D:\\123.mp4 -vf reverse D:\\out\\out1.mp4";
const char *cmd = "ping www.baidu.com";
int ret = 0;
ret = run_cmd(cmd);
printf("Результат выполнения команды: %d\r\n",ret);
getchar();
return 0;
}
Затем используйте CreateProcess, чтобы вызвать подпроцесс для запуска, сохранить выходные данные в файле и заблокировать ожидание завершения выполнения процесса.
int my_CreateProcess()
{
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(sa);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;
_unlink("D:/out/output.log");
HANDLE h = CreateFile((L"D:/out/output.log"),
FILE_APPEND_DATA,
FILE_SHARE_WRITE | FILE_SHARE_READ,
&sa,
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
PROCESS_INFORMATION pi;
STARTUPINFO si;
BOOL ret = FALSE;
DWORD flags = CREATE_NO_WINDOW;
ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
ZeroMemory(&si, sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
si.dwFlags |= STARTF_USESTDHANDLES;
si.hStdInput = NULL;
si.hStdError = h;
si.hStdOutput = h;
TCHAR cmd[] = TEXT("ping www.baidu.com");
ret = CreateProcess(NULL, cmd, NULL, NULL, TRUE, flags, NULL, NULL, &si, &pi);
if (ret)
{
WaitForSingleObject(pi.hProcess, INFINITE);
printf("Выполнение успешно....\n");
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
//Закрыть файл
CloseHandle(h);
return 0;
}
//Закрыть файл
CloseHandle(h);
printf("Выполнение не удалось....\n");
return -1;
}
Чтобы получить выходные результаты CreateProcess в реальном времени, когда процесс открыт и запущен, вы можете перенаправить выходные данные CreateProcess в файл канала. CreateProcess записывает данные в записывающий конец канала, а затем считывает их в реальном времени. время от конца чтения канала в родительском процессе.
int my_CreateProcess()
{
BOOL run_pipe;
PROCESS_INFORMATION pi;
STARTUPINFO si;
BOOL ret = FALSE;
DWORD flags = CREATE_NO_WINDOW;
_unlink("D:/out/output.log");
char pBuffer[210];
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;
HANDLE hReadPipe, hWritePipe;
run_pipe=CreatePipe(&hReadPipe, &hWritePipe, &sa, 0);
printf("run_pipe=%d\n", run_pipe);
ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
ZeroMemory(&si, sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
si.dwFlags |= STARTF_USESTDHANDLES;
si.hStdInput = NULL;
si.hStdError = hWritePipe;
si.hStdOutput = hWritePipe;
TCHAR cmd[] = TEXT("ffmpeg -i D:\\123.mp4 -vf reverse D:\\out\\out1.mp4");
ret = CreateProcess(NULL, cmd, NULL, NULL, TRUE, flags, NULL, NULL, &si, &pi);
if (ret)
{
while (true)
{
DWORD ExitCode = 0;
//Определяем, завершился ли процесс
GetExitCodeProcess(pi.hProcess, &ExitCode);
if (ExitCode == STILL_ACTIVE) //Бег
{
DWORD RSize=0;
BOOL run_s=0;
run_s =ReadFile(hReadPipe, pBuffer,200,&RSize,NULL);
pBuffer[RSize] = '\0';
printf("Результат возврата:%d,%d,%s\n", run_s, RSize, pBuffer);
}
else //Заканчивать
{
printf("Выполнение завершено...\n");
break;
}
}
//WaitForSingleObject(pi.hProcess, INFINITE);
printf("Выполнение успешно....\n");
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return 0;
}
printf("Выполнение не удалось....\n");
return -1;
}