方法一
优点:跨平台
缺点:Windows下调用时会闪出控制台窗口
#include <stdio.h>
#include <string.h>
/**
* @brief 使用popen调用终端并获取执行结果
*
* @param[in] cmd 命令内容
* @param[out] result 保存结果的地址
* @return 0或1 执行状态,失败或成功
*/
int exec_cmd(const char *cmd, char *result)
{
FILE *pipe = popen(cmd, "r");
if(!pipe)
return 0;
char buffer[128] = {0};
while(!feof(pipe))
{
if(fgets(buffer, 128, pipe))
strcat(result, buffer);
}
pclose(pipe);
return 1;
}
方法二(Windows下推荐)
优点:后台进程执行,无控制台窗口
缺点:仅适用Windows
#include <windows.h>
#include <string.h>
/**
* @brief 通过创建进程的方式无控制台窗口执行cmd
*
* @param[in] cmd 命令
* @param[out] result 执行结果
* @return 1|0|-1 成功|管道创建失败|进程创建失败
*/
int exec_cmd_1(char* cmd, char* result)
{
SECURITY_ATTRIBUTES sa; // 此结构体包含一个对象的安全描述符,并指定检索到制定这个结构的句柄是否是可继承的
sa.nLength = sizeof(SECURITY_ATTRIBUTES); // 结构体大小
sa.lpSecurityDescriptor = NULL; // 安全描述符
sa.bInheritHandle = TRUE; // 安全描述的对象能否被创建的进程继承,TRUE表示能被继承
HANDLE h_read, h_write;
if (!CreatePipe(&h_read, &h_write, &sa, 0)) // 创建匿名管道
return 0;
STARTUPINFO si = { sizeof(STARTUPINFO) }; // 此结构体用于指定新进程的主窗口特性 //si.cb = sizeof(STARTUPINFO);
GetStartupInfo(&si);
si.wShowWindow = SW_HIDE; // 窗口设为隐藏
si.hStdError = NULL;//h_write; // 标识控制台窗口的缓存,可指定管道
si.hStdOutput = h_write; // 同上
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;// 使用wShowWindow成员,使用hStdInput、hStdOutput、hStdError成员
PROCESS_INFORMATION pi; // 此结构返回有关新进程及其主线程的信息
if (!CreateProcess(NULL, cmd, NULL, NULL, TRUE, NULL, NULL, NULL, &si, &pi)) // 创建进程
return -1;
CloseHandle(h_write);
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
char buffer[1024] = { 0 };
DWORD i = 0, bytes_read;
while (i < 2048)
{
if (ReadFile(h_read, buffer, 1023, &bytes_read, NULL) == NULL)
break;
strcat(result, buffer);
}
CloseHandle(h_read);
return 1;
}
/**
* @brief 通过创建进程的方式无控制台窗口执行cmd
*
* @param[in] cmd 命令
* @return 1|0|-1 成功|管道创建失败|进程创建失败
*/
int exec_cmd_2(char* cmd)
{
STARTUPINFO si = { sizeof(STARTUPINFO) }; // 此结构体用于指定新进程的主窗口特性 //si.cb = sizeof(STARTUPINFO);
GetStartupInfo(&si);
si.wShowWindow = SW_HIDE;
si.dwFlags = STARTF_USESHOWWINDOW;
PROCESS_INFORMATION pi; // 此结构包含有关新进程及其主线程的信息
if (!CreateProcess(NULL, cmd, NULL, NULL, TRUE, NULL, NULL, NULL, &si, &pi))
return -1;
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
return 1;
}
main
#include <stdio.h>
void main()
{
char result[65535];
exec_cmd_1("curl https://pan.wengcx.top", result);
printf("%s", result);
}