在很多情况下,不得不调用cmd命令行,去实现一系列功能,总结靠谱方法两种如下:
方法一:可接受cmd命令行黑框一闪(推荐星数::可传值几乎任何cmd命令)
string
string getCmdResult(const string &strCmd)//传参string格式命令,返回值string格式;
{
char buf[10240] = { 0 };
FILE *pf = NULL;
if ((pf = _popen(strCmd.c_str(), "r")) == NULL)
{
return "";
}
string strResult;
while (fgets(buf, sizeof buf, pf))
{
strResult += buf;
}
_pclose(pf);
unsigned int iSize = strResult.size();
if (iSize > 0 && strResult[iSize - 1] == '\n')
{
strResult = strResult.substr(0, iSize - 1);
}
return strResult;
}
方法二:隐藏CMD黑窗 (推荐星数::可传值大部分cmd命令,如ipconfig、ping等,具体请自测)
直接调用此函数string ExeCmd(string pszCmd)即可,传命令为string格式,返回值仍为 string格式。
重点:部分命令,传形参命令时必须加入 cmd.exe /c 具体请自测。(这个让我走了好几天弯路百思不得其解,最后意外发现此方法可解决,免去了把文件导出来,一行读取判断的麻烦!)
例如:改变文件编码格式命令 type 1.txt>2.txt
传形参时应该这样传参 cmd.exe /c type 1.txt>2.txt
#include <iostream>
#include <string>
//#pragma comment( linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"" )//隐藏命令行
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
using namespace std;
wstring Str2Wstr(string str)
{
unsigned len = str.size() * 2;// 预留字节数
setlocale(LC_CTYPE, ""); //必须调用此函数
wchar_t *p = new wchar_t[len];// 申请一段内存存放转换后的字符串
mbstowcs(p, str.c_str(), len);// 转换
std::wstring str1(p);
delete[] p;// 释放申请的内存
return str1;
}
string ExeCmd(string pszCmd)
{
wstring pszCmd_w = Str2Wstr(pszCmd);
wcout << "pszCmd_w is " << pszCmd_w << endl;
// 创建匿名管道,write->read;
SECURITY_ATTRIBUTES sa = { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE };
HANDLE hRead, hWrite;
if (!CreatePipe(&hRead, &hWrite, &sa, 0))
{
cout << "@ CreatePipe failed!" << endl;
return (" ");
}
cout << "@0" << endl;
// 设置命令行进程启动信息(以隐藏方式启动命令并定位其输出到hWrite
STARTUPINFO si = { sizeof(STARTUPINFO) }; // Pointer to STARTUPINFO structure;
GetStartupInfo(&si);
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
//si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = SW_HIDE; //隐藏窗口;
si.hStdError = hWrite;
si.hStdError = hWrite;
si.hStdOutput = hWrite; //管道的输入端口连接命令行的输出;
// 启动命令行
PROCESS_INFORMATION pi;// Pointer to PROCESS_INFORMATION structure;
if (!CreateProcess(NULL,
(LPWSTR)pszCmd_w.c_str(),
NULL,
NULL,
TRUE,
//FALSE, // Set handle inheritance to FALSE
NULL,
//0, // No creation flags
NULL,
NULL,
&si,
&pi))
{
cout << "@ CreateProcess failed!" << endl;
return ("Cannot create process");
}
CloseHandle(hWrite);//关闭管道的输入端口;
// 读取命令行返回值
string strRetTmp;
char buff[1024] = { 0 };
DWORD dwRead = 0;
strRetTmp = buff;
while (ReadFile(hRead, buff, 1024, &dwRead, NULL))//从管道的输出端获取命令行写入的数据;
{
cout << "buff = " << buff << endl;
strRetTmp += buff;
}
CloseHandle(hRead);//关闭管道的输出端口;
cout << "strRetTmp:"<<strRetTmp << endl;
return strRetTmp;
}
方法三:调用vbs脚本,可隐藏黑框(推荐星数:)
vbs脚本:
Set ws= CreateObject("Wscript.shell")
ws.run "cmd /c test.bat",vbhide
另做test.bat填充功能代码
set objShell=wscript.createObject("wscript.shell")
iReturn=objShell.Run("你的程序.exe", 0, FALSE)
'Run()
'第一个参数是你要执行的程序的路径,
'第二个参数是窗口的形式,0后台运行;1正常运行;2最小化;3最大化;缺省的话表示正常运行
'第三个参数是表示这个脚本是等待还是继续执行,如果设为了True,脚本就会等待调用的程序退出后再向后执行。
方法四: WinExec函数(推荐星数:,黑框可隐藏)
WinExec(cmd.c_str(),SW_HIDE);//cmd(string类型)中为我们要调用的程序名及其参数, 如 “dir *.exe ”
其第一个参数相当于system函数的参数,
其第二个参数可以设置窗口是否显示,SW_HIDE这个宏表示隐藏窗口。
重点:部分命令,传形参命令时也必须加入 cmd.exe /c 具体请自测。
但是这个函数有一个问题,函数创建完这个进程后就返回了,也就是说它返回后,该进程不一定已经结束。
^-^自由 开源因你更精彩^-^ 。