#include "CCmd.h" #pragma region cmd指令说明 // 【/k】:调用cmd进程时,必须调用此参数 // // 【x:】:x为x盘符,cd到不同盘符下的文件夹路径之前,必须要要调用此参数,否则cd指令不生效; // 【cd xxx】:切换到指定的文件夹xxx路径 // 【start/wait】:start启动进程,wait等待指令调用结束 //【APPDIR】: 安装路径 // 【qb】:cmd后台静默执行 //【qn】:无安装界面运行,静默安装指令参数 //【norestart】:安装后不启动App,默认为不启动(目前已经去掉该参数) //vba不支持带空格路径安装,即便用路径标识符也不行,例如%cd% #pragma endregion CCmd::CCmd() { } BOOL CCmd::Installcmd() { std::wstring cmd = L""; //防止目标路径与当前进程所在盘符不一致,所以在cd之前,要指定目标路径的盘符cdDisk auto cdDisk = PathCore::smPath_Install.substr(0, 1) + L": & "; cmd = L"/k " + cdDisk + L"cd \"" + PathCore::smPath_Install + L"\"" + L" & start/wait " + Product::smName_InstallPackage + L" APPDIR=\"" + PathCore::smPath_Install + L"\" /qb /qn"; LogIni::GetLogToIni("Install cmd", cmd); TCHAR* tc = (TCHAR*)(&cmd[0]); return Executecmd(tc); } //环境检测,如果没有就安装NET Framework BOOL CCmd::InstallNetcmd() { wstring systemLetter = DiskCore::GetSystemDriveLetter();//获取系统盘符 SYSTEM_INFO si; GetNativeSystemInfo(&si);//获取系统信息 std::wstring netframe; bool isSystem64 = true; if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64 || si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64) { isSystem64 = true; } else { isSystem64 = false; } if (systemLetter == L"") { systemLetter = L"C"; } //安装NET Framework工具所在路径是固定的 if (isSystem64) { netframe = systemLetter + L":\\Windows\\Microsoft.NET\\Framework64\\v4.0.30319"; } else { netframe = systemLetter + L":\\Windows\\Microsoft.NET\\Framework\\v4.0.30319"; } std::wstring cmd = L""; //cmd = L"dism /online /enable-feature /featurename:IIS-ASPNET45 /all";//win8需要启动ASPNET4.5服务,目前暂时没用到; //检测当前系统为win8或更高版本 if (IsWindows8OrGreater()) { cmd = L"/k " + systemLetter + L": & cd " + netframe + L" & aspnet_regiis.exe -i /qb /qn"; std::map map{ {L"InstallNetFramwork", cmd}, { L"WindowsVersion", L"Win8,10.." }}; LogIni::GetLogToIniMaps(map); m_IsWin8InstallNet = true; } else { cmd = L"/k " + systemLetter + L": & cd " + netframe + L" & aspnet_regiis.exe -i /qb /qn"; std::map map{ {L"InstallNetFramwork", cmd}, { L"WindowsVersion", L"Win7" } }; LogIni::GetLogToIniMaps(map); } TCHAR* tc = (TCHAR*)(&cmd[0]); return Executecmd(tc); } BOOL CCmd::InstallVcPlusPluscmd() { std::wstring cmd = L""; wchar_t downloadsPath[MAX_PATH]; DWORD bufferSize = ::GetEnvironmentVariable(L"USERPROFILE", downloadsPath, MAX_PATH); std::wstring wstrPath_Install(downloadsPath); wstrPath_Install += L"\\Downloads"; //防止目标路径与当前进程所在盘符不一致,所以在cd之前,要指定目标路径的盘符cdDisk auto cdDisk = wstrPath_Install.substr(0, 1) + L": & "; cmd = L"/k " + cdDisk + L"cd \"" + wstrPath_Install + L"\"" + L" & curl -o vc_redist.x64.exe https://download.visualstudio.microsoft.com/download/pr/eaab1f82-787d-4fd7-8c73-f782341a0c63/917C37D816488545B70AFFD77D6E486E4DD27E2ECE63F6BBAAF486B178B2B888/VC_redist.x64.exe && start /wait vc_redist.x64.exe /install /quiet /norestart && del vc_redist.x64.exe"; //LogIni::GetLogToIni("Install cmd", cmd); TCHAR* tc = (TCHAR*)(&cmd[0]); return Executecmd(tc); } BOOL CCmd::OpenAppcmd() { //Todo:目前不使用该函数 std::wstring cmd = L""; auto cdDisk = PathCore::smPath_Install.substr(0, 1) + L": & "; cmd = L"/k " + cdDisk + L"cd \"" + PathCore::smPath_Install + L"\"" + L" & start/wait " + Product::smName_Application; LogIni::GetLogToIni("Start App cmd", cmd); TCHAR* tc = (TCHAR*)(&cmd[0]); return Executecmd(tc); } BOOL CCmd::Executecmd(TCHAR pszCmdLine[], bool isVBA) { char Buffer[4096]; STARTUPINFO sInfo;//新进程的主窗口特性 PROCESS_INFORMATION pInfo; SECURITY_ATTRIBUTES sa; HANDLE hRead, hWrite; DWORD bytesRead; //读取代码的长度 sa.nLength = sizeof(SECURITY_ATTRIBUTES); //结构体的大小,可用SIZEOF取得 sa.lpSecurityDescriptor = NULL;//安全描述符 sa.bInheritHandle = TRUE;; //安全描述的对象能否被新创建ÆÆ的进程继承 if (!CreatePipe(&hRead, &hWrite, &sa, 0)) { return GetLastError(); } GetStartupInfo(&sInfo); sInfo.cb = sizeof(sInfo); sInfo.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; sInfo.wShowWindow = SW_HIDE; sInfo.hStdError = hWrite; //将管道的写端交给子进程 sInfo.hStdOutput = hWrite; memset(&pInfo, 0, sizeof(pInfo)); wstring cmdPath = L""; if (isVBA == false) { cmdPath = L"c:\\windows\\system32\\cmd.exe"; } else { wstring Installpath = PathCore::smPath_Install + L"\\install.bat"; cmdPath = Installpath; } if (!CreateProcessW(cmdPath.c_str(), pszCmdLine, NULL, NULL, TRUE, 0, NULL, NULL, &sInfo, &pInfo)) { CloseHandle(hWrite); CloseHandle(hRead); return GetLastError(); } for (int i = 0;; ++i) { //执行cmd结束之后,则读取文件结束 if (!ReadFile(hRead, Buffer, sizeof(Buffer) - 1, &bytesRead, NULL)) { break; Buffer[bytesRead] = 0; } else { WaitForSingleObject(pInfo.hProcess, 1000); CloseHandle(hWrite); CloseHandle(hRead); return TRUE; } } CloseHandle(hWrite); CloseHandle(hRead); return TRUE; } #pragma region VBA脚本指令(备用方案) //编辑vba脚本内容-》生成文件vba文件到安装路径-》执行vba文件 // // //因时间有限,暂时不进行排查修复UTF-16的vba脚本执行没反应的问题 bool CCmd::GetVBA_UTF16() { std::wstring cmdd = L""; std::wstring echoc = L"ECHO."; //vba脚本内容 cmdd = L"@echo off\n" + echoc + L"\n" + PathCore::smPath_Install.substr(0, 1) + L": & " + L"cd " + L"%~dp0" + L"\n" + echoc + L"\n" + echoc + L"\n" + L"start/wait " + Product::smName_InstallPackage + L" APPDIR=\"" + PathCore::smPath_Install + L"\" /qb /qn" + L"\n" + echoc + L"\n" + L"EXIT"; wstring Installpath = PathCore::smPath_Install + L"\\install.bat"; HANDLE hDevice = CreateFileW(Installpath.c_str(), GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); if (hDevice == INVALID_HANDLE_VALUE) { DWORD errorCode = GetLastError(); return false; } DWORD dwWriteSize = 0; auto chBuffer = cmdd.c_str(); DWORD nBytes; WORD a = 0xFEFF; WriteFile(hDevice, &a, sizeof(a), &nBytes, NULL); BOOL bRet = WriteFile(hDevice, chBuffer, lstrlen(chBuffer) * sizeof(wchar_t), &nBytes, NULL); //BOOL bRet = WriteFile(hDevice, chBuffer, cmdd.length(), &dwWriteSize, NULL); //BOOL bRet = WriteFile(hDevice, chBuffer, cmdd.length(), &dwWriteSize, NULL); if (bRet) { } FlushFileBuffers(hDevice); //将缓冲区数据写入磁盘 LONG IDistance = 0; DWORD dwPtr = SetFilePointer(hDevice, IDistance, NULL, FILE_BEGIN); //调整文件指针到文件开头 DWORD dwSize = GetFileSize(hDevice, NULL); //bRet = ReadFile(hDevice, chBuffer, dwSize, &dwSize, NULL); //if (bRet) //{ // //printf("chbuffer is %s /n", chBuffer); //} CloseHandle(hDevice); Executecmd(nullptr, true); } //含有中文空格的路径,调用UTF8 VBA脚本会失败(安装到一半,就自动回退到安装前状态) bool CCmd::GetVBA_UTF8() { wstring Installpath = PathCore::smPath_Install + L"\\install.bat"; LPCWSTR Installpathstr = Installpath.c_str(); wchar_t* rootptr = _wcsdup(PathCore::smPath_Install.substr(0, 1).c_str()); auto rootch = CharConvert::GetMultiByteW(rootptr); wchar_t* rootptr22 = _wcsdup(PathCore::smPath_Install.c_str()); auto rootch22 = CharConvert::GetMultiByteW(rootptr22); wchar_t* ptrInstallPackage = _wcsdup(Product::smName_InstallPackage.c_str()/*.substr(0, 1).c_str()*/); auto InstallPackagech = CharConvert::GetMultiByteW(ptrInstallPackage); std::string cmdd = ""; std::string echoc = "ECHO."; cmdd = "@echo off\n" + echoc + "\n" + rootch + ": & " + "cd " + "%~dp0" + "\n" + echoc + "\n" + echoc + "\n" + "start/wait " + InstallPackagech + " APPDIR=%cd%" + +" /qb /qn" + "\n" + echoc + "\n" + "EXIT"; char* chBuffer = &cmdd[0]; HANDLE hDevice = CreateFile(Installpathstr, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); if (hDevice == INVALID_HANDLE_VALUE) { DWORD errorCode = GetLastError(); return false; } DWORD dwSize = GetFileSize(hDevice, NULL); DWORD dwWriteSize = 0; WORD a = 0xFEFF; WriteFile(hDevice, &a, sizeof(a), &dwWriteSize, NULL); BOOL bRet = WriteFile(hDevice, chBuffer, lstrlenA(chBuffer) * sizeof(char), &dwWriteSize, NULL); //BOOL bRet = WriteFile(hDevice, chBuffer, cmdd.length(), &dwWriteSize, NULL); if (bRet) { return false; } FlushFileBuffers(hDevice); LONG IDistance = 0; DWORD dwPtr = SetFilePointer(hDevice, IDistance, NULL, FILE_BEGIN); DWORD dwReadSize = 0; /*bRet = ReadFile(hDevice, chBuffer, 10, &dwReadSize, NULL); if (bRet) { printf("chbuffer is %s /n", chBuffer); }*/ CloseHandle(hDevice); return Executecmd(nullptr, true);; } #pragma endregion