/**************************************************
作者: DS小龙哥
功能: 执行命令
参数解释:
CallBackFunction_p func_p :回调函数,用于通知进度执行过程
char *text //进度的转码过程,详细描述.描述当前这个操作是做什么.
char *total_time //执行的总时间
char *cmd //执行的命令
**************************************************/
int file_down_func(CallBackFunction_p func_p, const char *text, const char *total_time, const char *cmd)
{
BOOL run_pipe;
PROCESS_INFORMATION pi;
STARTUPINFO si;
BOOL ret = FALSE;
DWORD flags = CREATE_NO_WINDOW;
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);
if (run_pipe != 1)
{
printf("创建匿名管道文件失败=%d\n", run_pipe);
return -1;
}
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;
wchar_t cmd_wchar[1024];
CharToWchar(cmd, cmd_wchar);
//TCHAR cmd[] = TEXT("ffmpeg -i D:\\123.mp4 -vf reverse D:\\out\\out1.mp4");
ret = CreateProcess(NULL, cmd_wchar, NULL, NULL, TRUE, flags, NULL, NULL, &si, &pi);
if (ret)
{
while (true)
{
DWORD ExitCode = 0;
//判断进程是否执行结束
printf("正在执行...GetExitCodeProcess\r\n");
GetExitCodeProcess(pi.hProcess, &ExitCode);
printf("ExitCode:%d\r\n", ExitCode);
if (ExitCode == STILL_ACTIVE) //正在运行
{
DWORD RSize = 0;
BOOL run_s = 0;
printf("正在执行...ReadFile\r\n");
run_s = ReadFile(hReadPipe, pBuffer, sizeof(pBuffer), &RSize, NULL);
pBuffer[RSize - 1] = '\0';
printf("执行过程:%s,%d,%d,%s\n", version_str, run_s, RSize, pBuffer);
char number_buff[10]="\0"; //存放百分比
printf("pBuffer=%s\r\n", pBuffer);
//通过回调函数向外部返回进度提示
for (size_t i = 0; i < 10 && pBuffer[i]!='\0'; i++)
{
if (pBuffer[i] >= '0' && pBuffer[i] <= '9')
{
//得到百分比值
for (size_t j = 0; j < 9 && pBuffer[i+j] != '\0'; j++)
{
//printf("@@%c@@\r\n", pBuffer[i + j]);
if (pBuffer[i+j] >= '0' && pBuffer[i+j] <= '9')
{
number_buff[j] = pBuffer[i + j];
}
else
{
number_buff[j] = '\0';
break;
}
}
break;
}
}
// 0 926M 0 6463k 0 0 7378k 0 0:02:08 --:--:-- 0:02:08 7386
//如果找到进度的位置
if (strlen(number_buff)>0)
{
std::string out_str;
out_str = text;
out_str += ",";
out_str += "100";
out_str += ",";
out_str += number_buff;
printf("回调:%s\r\n", out_str.c_str());
//将执行的结果再回调出去
if (func_p)
{
func_p(out_str.c_str());
}
}
}
else //结束
{
printf("执行完毕,ExitCode=%d\r\n", ExitCode);
break;
}
}
printf("正在等待子进程结束....\n");
//等待结束
WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
printf("子进程执行完毕....\n");
return 0;
}
printf("子进程创建失败:%d\n", ret);
return -1;
}
int main()
{
string VideoCacheFilePath = "D:\\out";
//下载的文件名称
string file_path = "http://192.168.1.110:8001/Uploads/1/哈哈哈.MP4";
//如果返回为真就表示是网络地址
if (strstr(file_path.c_str(), "http:") ||
strstr(file_path.c_str(), "https:"))
{
//1.获取不带路径的文件名
string::size_type iPos;
if (strstr(file_path.c_str(), "\\"))
{
iPos = file_path.find_last_of('\\') + 1;
}
else
{
iPos = file_path.find_last_of('/') + 1;
}
//得到文件名称
string base_file = file_path.substr(iPos, file_path.length() - iPos);
//得到完整的文件下载存储路径
string VideoPath_tmp = VideoCacheFilePath;
VideoPath_tmp += "\\";
VideoPath_tmp += base_file;
//判断文件是否存在
printf("文件存储路径:%s\r\n", VideoPath_tmp.c_str());
FILE *file_p = fopen(VideoPath_tmp.c_str(),"rb");
//不存在就下载
if (file_p == nullptr)
{
//切换目录,进入到curl命令所在的目录
_chdir(VideoCacheFilePath.c_str());
string cmd = "curl -O ";
cmd += file_path;
//启动下载文件
file_down_func(NULL, base_file.c_str(),"100",cmd.c_str());
}
else
{
printf("文件存在不需要下载.\r\n");
fclose(file_p);
}
}
return 0;
}
评论