DotNet4应用程序打包工具可以打包dotNet2.0 3.5 4乃至所有在注册表中添加过注册表项的应用程序。
DotNet4应用程序打包工具源码分析
入口函数:
int WinMain(HINSTANCE hInstance,HINSTANCE hPreInstance,LPSTR lpCmdLine,int nCmdShow)
{
DialogBox(hInstance,MAKEINTRESOURCE(MainWinDL),0,DlgProc);
return 0;
}
好吧,入口函数很简单,只是创建了一个窗体,并注册了窗口过程函数
-----------------------------
窗口过程
//窗口过程
BOOL CALLBACK DlgProc (HWND hDlg, UINT message,WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG :
OnInitDlg(hDlg);
return TRUE ;
case WM_COMMAND :
switch (LOWORD(wParam))
{
case IDC_STATIC_Name:
ShellExecute(hDlg,"open","http://www.cnblogs.com/liulun",NULL,NULL,SW_SHOWNORMAL);
break;
case IDC_BUTTON1:
GetFile(hDlg,IDC_EDIT1);
break;
case IDC_BUTTON3:
GetFile(hDlg,IDC_EDIT3);
break;
case IDC_RADIO1:
CheckRadio(hDlg,IDC_RADIO1,"SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v2.0.50727");
break;
case IDC_RADIO2:
CheckRadio(hDlg,IDC_RADIO2,"SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v3.5");
break;
case IDC_RADIO3:
CheckRadio(hDlg,IDC_RADIO3,"SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v4");
break;
case IDC_RADIO_ELSE:
CheckRadio(hDlg,IDC_RADIO_ELSE,"");
break;
case IDOK:
ReleaseTar(hDlg);
ReplaceICO(hDlg);
BagTar(hDlg,IDC_EDIT3);
BagTar(hDlg,IDC_EDIT1);
BagStr(hDlg);
Alert("打包成功");
break;
case IDCANCEL:
EndDialog (hDlg, 0) ;
return TRUE ;
}
break;
}
return FALSE ;
}
在这个过程函数里
接收到的每个消息都执行了一个或几个函数
那么,我们就一个函数一个函数的讲
-------------------------------------------------------
窗口初始化消息里
我们默认选中了dotNet4的单选按钮
void OnInitDlg(HWND hwnd)
{
HWND cld = ::GetDlgItem(hwnd,IDC_RADIO3);
::SendMessage(cld,BM_SETCHECK,1,0);
::SetDlgItemText(hwnd,IDC_EDIT2,"SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v4");
LastCheckRdioId = IDC_RADIO3;
}
---------------------------------------------------------
四个单选按钮的单击事件
设置了文本框的内容,
并记录了当前选中的是哪个单选按钮
void CheckRadio(HWND hwnd,int rdioID,LPCSTR val)
{
if(rdioID == LastCheckRdioId)
{
return;
}
::SetDlgItemText(hwnd,IDC_EDIT2,val);
LastCheckRdioId = rdioID;
}
------------------------------------------------------------
选择文件
把选中的文件路径赋值给相应的文本框
//得到文件
void GetFile(HWND hwnd,int EDITId)
{
char szFile[MAX_PATH] = {0};
OPENFILENAME ofn;
memset(&ofn, 0, sizeof(OPENFILENAME));
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.lpstrFile = szFile;
ofn.nMaxFile = MAX_PATH;
ofn.lpstrFilter = "应用程序 (.exe)\0*.exe\0\0";
ofn.lpstrDefExt = "exe";
ofn.lpstrTitle = "选择exe文件";
ofn.nFilterIndex = 1;
ofn.lpstrFileTitle = NULL;
ofn.nMaxFileTitle = 0;
ofn.lpstrInitialDir = NULL;
if(GetOpenFileName(&ofn))
{
SetDlgItemText(hwnd,EDITId,szFile);
}
}
--------------------------------------------------------------------
从资源中读取宿主程序,并按指定的文件名,释放到当前目录下
//释放资源
int ReleaseTar(HWND hwnd)
{
::GetDlgItemText(hwnd,IDC_EDIT1,szFilePath,MAX_PATH);
::strcat(szFilePath,".bag.exe");
HMODULE hInstance = ::GetModuleHandle(NULL);
HRSRC hResID = ::FindResource(hInstance,(LPCSTR)IDR_BIN1,"bin");
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;
}
---------------------------------------------------------------------------
替换宿主程序的ICO图标资源
这里需要重点说明一下:
要想更新一个应用程序的资源
必须先知道这个资源的ID
GetIcoIndex函数的工作就是获取资源ID的
因为一般的应用程序图标资源都会有两个
所以获取了两个图表资源的ID
其他的WINAPI就不多解释了~~
int GetIcoIndex(HMODULE hExe,int index[])
{
HRSRC hRes;
int iLoop;
int i = 0;
for(iLoop = 1;;iLoop++)
{
hRes = FindResource(hExe, MAKEINTRESOURCE(iLoop), RT_ICON);
if (NULL == hRes)
{
if(iLoop == 60)
{
break;
}
continue ;
}
else
{
index[i] = iLoop;
i +=1;
if(i == 2)
{
break;
}
}
}
return 1;
}
int ReplaceICO(HWND hwnd)
{
HMODULE hSrcExe,hDestExe;
HANDLE hUpdateRes;
HRSRC hRes;
HRSRC hResLoad;
char *lpResLock;
int result;
char szFile[MAX_PATH+1] = {0};
int hSrcIndex[2] = {0};
int hDestIndex[2] = {0};
::GetDlgItemText(hwnd,IDC_EDIT1,szFile,MAX_PATH);
hSrcExe = LoadLibrary(szFile);
hDestExe = LoadLibrary(szFilePath);
GetIcoIndex(hSrcExe,hSrcIndex);
GetIcoIndex(hDestExe,hDestIndex);
for(int i=0;i<2;i++)
{
hRes = FindResource(hSrcExe, MAKEINTRESOURCE(hSrcIndex[i]), RT_ICON);
hResLoad=(HRSRC)LoadResource(hSrcExe,hRes);
lpResLock=(char*)LockResource(hResLoad);
FreeLibrary(hDestExe);
hUpdateRes=BeginUpdateResource(szFilePath,FALSE);
result=UpdateResource(hUpdateRes,RT_ICON,MAKEINTRESOURCE(hDestIndex[i]),MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL),lpResLock,SizeofResource(hSrcExe,hRes));
EndUpdateResource(hUpdateRes, FALSE);
}
FreeLibrary(hSrcExe);
return result;
}
---------------------------------------
为宿主程序增加目标程序资源和dotNet安装包资源
增加的资源也是需要标明ID的
因为宿主程序会根据约定好的ID来得到这些资源
EditId参数就是这些资源的ID
int BagTar(HWND hwnd,int EditId)
{
HANDLE hFile;
DWORD dwFileSize,dwBytesRead;
LPBYTE lpBuffer;
char szFile[MAX_PATH+1] = {0};
::GetDlgItemText(hwnd,EditId,szFile,MAX_PATH);
hFile = CreateFile(szFile,GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
dwFileSize = GetFileSize(hFile, NULL);
lpBuffer = new BYTE[dwFileSize];
ReadFile(hFile, lpBuffer, dwFileSize, &dwBytesRead, NULL);
HANDLE hResource = BeginUpdateResource(szFilePath, FALSE);
UpdateResource(hResource,RT_RCDATA,MAKEINTRESOURCE(EditId),MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),(LPVOID)lpBuffer,dwFileSize);
EndUpdateResource(hResource, FALSE);
delete [] lpBuffer;
CloseHandle(hFile);
return 1;
}
--------------------------------------------------------
把注册表项的路径也当作资源打包进宿主程序
我们约定这个资源的ID为1039
int BagStr(HWND hwnd)
{
char szFile[MAX_PATH+1] = {0};
::GetDlgItemText(hwnd,IDC_EDIT2,szFile,MAX_PATH);
HANDLE hUpdateRes=BeginUpdateResource(szFilePath,FALSE);
int result=UpdateResource(hUpdateRes,RT_RCDATA,MAKEINTRESOURCE(1039),MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL),(LPVOID)szFile,::strlen(szFile));
EndUpdateResource(hUpdateRes, FALSE);
return 0;
}
-------------------------------------------------------------
其他的一些代码如下
#include <Windows.h>
#include <ShlObj.h>
#include "resource.h"
TCHAR szFilePath[MAX_PATH + 1];
int LastCheckRdioId;
//提示
void Alert(LPCSTR msg)
{
MessageBox(NULL,msg,"系统提示",MB_OK);
}
- PC官方版
- 安卓官方手机版
- IOS官方手机版















Apifox(Api调试管理工具)2.1.29.1 绿色版
小乌龟代码管理工具(TortoiseGit)2.13.0.1 中文免费版
SoapUI破解版5.7.0 最新版
小皮面板(phpstudy)8.1.1.3 官方最新版
Ruby3.0(ruby运行环境)3.0.2 官方版
gcc编译器( MinGW-w64 9.0.0绿色版)免费下载
宝玉编辑助手0.0.05新版
火花编程软件2.7.2 官方pc版
猿编程少儿班客户端3.1.1 官方版
Restorator 2009中文版单文件汉化版
十六进制阅读小工具
IT码农工具软件1.0 中文免费版
python爬虫实战入门教程pdf免费版
Postman Canary(网页调试软件)官方版7.32.0绿色免费版
大耳猴少儿编程客户端1.1.2 官方免费版
excel批量sql语句(通过excel构建sql工具)1.0 免费版
软件添加弹窗和网址工具1.0 中文免费版
天霸编程助手2.1 单文件中文版
ida pro 中文破解版(反编译工具)7.0 永乐汉化版64位
VBA代码助手3.3.3.1官方版
Node.js开发实战教程百度云完整版【36课】
猿编程电脑端3.9.1.347 官方PC版
蒲公英 Android SDKV4.1.11 官方最新版
蒲公英iOS SDK2.8.9.1 官方最新版
WxPython中文可视化编辑器1.2 简体中文免费版
Python代码生成器1.0 中文免费版
C语言代码实例助手1.0 免费版
c primer plus第6版中文版高清版
C++ Primer Plus 2021电子版最新版
notepad++7.8.2 中文免费版
wpe pro Alpha 0.9a 中文绿色版




Microsoft Spy++9.10 中文绿色版
源代码保护工具(Dotfuscator Professional
MDB数据库管理软件1.0 中文免费版
源码安全监测工具(Fortify SCA 2016)【附cr
RTX ServerSDK 2015官方最新版
阿猫串口调试助手2.4.0.0绿色免费版
精易论坛SQL语句生成器2.1 绿色最新版 【
java开源报表系统(JasperReports Library)6
独立团游戏作坊窗口分析工具【VIP全套教程及