索引
DotNet4应用程序打包工具->升级版【三】宿主程序分析+全部源码下载
DotNet4应用程序打包工具->升级版【二】安装工具分析
DotNet4应用程序打包工具(把DotNet4安装程序打包进你的应用程序;WINAPI开发,无dotNet环境也可顺利执行)【一】整体思路
废话少说
入口函数
入口函数是所有逻辑的集合体
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);
---------------------------
打包工具源码下载:BagDotNet_code.zip
宿主程序源码下载:CheckDotNet_code.zip
--------------------------------------------------------
如果您喜欢我的文章,请您推荐我的文章吧~谢谢~