123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309 |
- #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<wstring, wstring> 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<wstring, wstring> 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
|