索引
废话少说
入口函数
入口函数是所有逻辑的集合体
int WinMain(HINSTANCE hInstance,HINSTANCE hPreInstance,LPSTR lpCmdLine,int nCmdShow){ int result; LPCTSTR netName = ".net4.exe"; LPCTSTR tarName = ".tar.exe"; result = CheckDotNet4(); if(result == 0) { result = FreeRC(MAKEINTRESOURCE(1012),netName); if(result == 0) { Alert("没有成功释放预装工具~安装失败"); return 0; } result = CreateInstallProcess(netName); if(result == 0) { Alert("没有成功启动预装工具进程~安装失败"); ClearFile(netName); return 0; } //暂时不支持静默安装 //result = InstallIt(); result = CheckDotNet4(); if(result == 0) { Alert("没有成功安装预装工具~安装失败"); ClearFile(netName); return 0; } } result = FreeRC(MAKEINTRESOURCE(1001),tarName); if(result == 0) { Alert("没有成功释放应用程序~安装失败"); ClearFile(netName); ClearFile(tarName); return 0; } result = CreateInstallProcess(tarName); if(result == 0) { Alert("没有成功启动应用程序进程~安装失败"); } ClearFile(netName); ClearFile(tarName); return 0;}
判断目标环境是否有相关的注册表项
先从资源里提取出注册表项
然后判断
int CheckDotNet4(){ HMODULE hInstance = ::GetModuleHandle(NULL); HRSRC hResID = ::FindResource(hInstance,MAKEINTRESOURCE(1039),RT_RCDATA); HGLOBAL hRes = ::LoadResource(hInstance,hResID); LPVOID pRes = ::LockResource(hRes); DWORD dwResSize = ::SizeofResource(hInstance,hResID); int length = MAX_PATH + 1; if(!dwResSize) { return 0; } length = (int)dwResSize; TCHAR regeditStr[MAX_PATH + 1]; memcpy(regeditStr,pRes,dwResSize); regeditStr[dwResSize] = 0; HKEY ck; int result = 1; if(ERROR_SUCCESS != RegOpenKeyEx(HKEY_LOCAL_MACHINE,regeditStr,0,KEY_ALL_ACCESS,&ck)) { Alert("您的系统中缺少应用程序执行的环境\n现在开始为您搭建该环境"); result = 0; } RegCloseKey(ck); return result;}
如果没有相关的注册表项
就要释放出想要预先安装的程序
读取资源
并把资源写入文件
int FreeRC(LPCTSTR resourceID,LPCTSTR resourceName){ HMODULE hInstance = ::GetModuleHandle(NULL); TCHAR szFilePath[MAX_PATH + 1]; GetPath(szFilePath,resourceName,hInstance); HRSRC hResID = ::FindResource(hInstance,resourceID,RT_RCDATA); HGLOBAL hRes = ::LoadResource(hInstance,hResID); LPVOID pRes = ::LockResource(hRes); DWORD dwResSize = ::SizeofResource(hInstance,hResID); if(!dwResSize) { return 0; } HANDLE hResFile = CreateFile(szFilePath,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL); DWORD dwWritten = 0; WriteFile(hResFile,pRes,dwResSize,&dwWritten,NULL); CloseHandle(hResFile); if(dwResSize == dwWritten); { return 1; } return 0;}
成功释放之后
就执行这个程序
注意WaitForSingleObject的WINAPI
是等待进程退出
//创建进程int CreateInstallProcess(LPCTSTR resourceName){ STARTUPINFO stinfo; ZeroMemory((void*)&stinfo,sizeof(STARTUPINFO)); PROCESS_INFORMATION ProcessInfo; stinfo.cb = sizeof(STARTUPINFO); stinfo.dwFlags = STARTF_USESHOWWINDOW; stinfo.wShowWindow = SW_SHOW;//SW_SHOW SW_HIDE TCHAR szFilePath[MAX_PATH + 1]; GetPath(szFilePath,resourceName);//.dotnet4.exe int result = CreateProcess(szFilePath,NULL,NULL,NULL,false,0,NULL,NULL,&stinfo,&ProcessInfo); WaitForSingleObject(ProcessInfo.hProcess, INFINITE); return result; }
如果进程没有被成功启动
就会删除释放的预安装程序
int ClearFile(LPCTSTR resourceName){ TCHAR szFilePath[MAX_PATH + 1]; GetPath(szFilePath,resourceName);//.dotnet4.exe int result = ::DeleteFile(szFilePath); return result;}
接着再次检查注册表项
result = CheckDotNet4();
如果仍旧没有相关的注册表项
那么说明预安装程序没有安装成功,退出程序
---------------------
至此,检查工作已经完成
入口函数里剩下的代码
是执行目标程序的工作
不在多做解释
result = FreeRC(MAKEINTRESOURCE(1001),tarName); if(result == 0) { Alert("没有成功释放应用程序~安装失败"); ClearFile(netName); ClearFile(tarName); return 0; } result = CreateInstallProcess(tarName); if(result == 0) { Alert("没有成功启动应用程序进程~安装失败"); } ClearFile(netName); ClearFile(tarName);
---------------------------
打包工具源码下载:
宿主程序源码下载:
--------------------------------------------------------
如果您喜欢我的文章,请您推荐我的文章吧~谢谢~