执⾏脚本的C程序
这⾥我使⽤CreateProcess来运⾏脚本,使⽤管道将脚本输出重定向到⽂件中,执⾏脚本基本上都可以执⾏,要判断执⾏结果,就需要对从管道返回的执⾏结果进⾏分析,判断此次是否执⾏成功。
我⽐较习惯使⽤C的⽂件操作,另使⽤⼀个程序对脚本进⾏管理,对创建的虚拟机名称和IP进⾏分配,并将结果写进Redis和配置⽂件及log ⽂件。
部分操作不是线程安全的,我在使⽤的过程中对执⾏脚本这部分⼀直是单线程操作的,⽽且⼀些⽂件在操作后并不会关闭⽂件指针,使⽤fflush来进⾏刷新来节省效率。
#include <Windows.h>
#include <stdio.h>
createprocessa#include <string>
bool PowerShellService::JudgeFileIsExist(std::string &path) //判断脚本⽂件是否存在
{
if((_access(path.c_str(), 0)) == -1)
{
std::cout << "powershell file " << path << " is not exist!" << std::endl;
return false;
}
return true;
}
std::wstring S2WS(cosnt std::string &s)
{
std::wstring wstrResult;
wstrResult.assign(s.begin(), s.end());
return wstrResult;
}
bool ExecuteDosCommond(std::string &cmd){
SECURITY_ATTRIBUTES sa;
HANDLE hRead,hWrite;
std::wstring command = PowerShellService::S2WS(cmd); //将string转为宽字节wstring
wchar_t *commander = new wchar_t[command.size()+2];  //这⾥注意,款字节以\0\0结尾,所以要多两个字节
memset(commander, 0, command.size()*sizeof(wchar_t)+2);
memcpy(commander, command.c_str(), command.size()*sizeof(wchar_t));
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;
if(!CreatePipe(&hRead, &hWrite, &sa, 0))  //创建管道
{
return false;
}
STARTUPINFO si;
PROCESS_INFORMATION pi;
si.cb = sizeof(STARTUPINFO);
GetStartupInfo(&si);
si.hStdError = hWrite;
si.hStdOutput = hWrite;
si.wShowWindow = SW_HIDE;
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
if(!CreateProcess(NULL, commander, NULL, NULL, TRUE, NULL, NULL, NULL, &si, &pi)) //执⾏脚本
{
CloseHandle(hWrite);
CloseHandle(hRead);
return false;
}
CloseHandle(hWrite);
CloseHandle(hWrite);
char buffer[4096];
DWORD bytesRead;
AddLogToRecordDetail(cmd);
while(true){
if(ReadFile(hRead, buffer, 4095, &bytesRead, NULL) == NULL)
{
break;
}
else
{
//logFileP是⼀个类内的⽂件指针,指向log⽂件,当然直接写是不合适的,还需要对结果进⾏判断,将判断的结果写⼊    fwrite(buffer,bytesRead, 1, logFileP);
}
}
CloseHandle(hRead);
return true;
}
bool ExcutePowerShellScript(const char *path)
{
std::string pathStr = path;
std::string strCmd;
//judge file path
if(pathStr.find("/") == -1) pathStr = filePath + pathStr; //⾃⼰设置的路径
//judge file is exist
if(!JudgeFileIsExist(pathStr)) return false;
strCmd = strCmdPowerShell /*"powershell "*/ + pathStr /*ps1⽂件*/;
if(ExecuteDosCommond(strCmd)) return true;
return false;
}

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。