" /> " />

目 录CONTENT

文章目录

advanced installer保姆级做包教程[包含注册码操作及程序联动]

Octal
2025-06-01 / 0 评论 / 0 点赞 / 30 阅读 / 0 字
温馨提示:
部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

特别说明:本教程使用advanced installer 19.0版本,所打包的程序为Qt程序

基础操作

一、生成项目

001-ijrg.png

二、添加产品基本信息以及图标(控制面板)

002-vcsm.png

三、添加项目文件(.exe以及运行所需文件)

003-uxhq.png

添加完文件后:

三、添加桌面快捷方式

005-picz.png

选择应用文件中的.exe文件,点击OK

006-xhhl.png

007-xrys.png

008-jutw.png

构建

点击build->选择存储路径->确定

009-hboj.png

此处已完成一个简单的安装包

010-raqh.png

在setupfiles文件夹中就是生成的安装包。

011-ylhq.png

可选操作

一、修改安装包类型

.msi、.exe类型可自行修改

012-behv.png

二、调用批处理文件

如项目文件夹内无该批处理文件,则需手动添加

013-dfaa.png

014-iqmv.png

如项目文件夹内已有该批处理文件,直接进行此步

015-ldlo.png

三、设置开机自动启动

首先,开机自动启动是通过写注册表的方法实现的,我们先找到开机启动的注册表位置,本机开机启动项如下:

016-jxjt.png

正式操作如下

017-mdir.png

018-ulys.png

019-wmnr.png

四、安装包位数

020-lhym.png

五、运行环境限制(系统+硬件+软件)

021-upwc.png

六、运行环境监测及指定安装文件

022-iyrj.png

023-fpyl.png

咱们目前是限制最小版本、以及未安装时进行安装,贴心的是软件已经给我们设置好了版本限制,但是并未设置好未安装时进行安装,需要我们自行设置,设置步骤如下

025-vstf.png

VC++注册表键值地址

制作安装包时,想查看相关环境是否安装,以及版本是否符合,比如VC++环境,需要通过查看注册表的方式进行查看。

方式一

以Microsoft Visual C++ 2015-2019 Redistributable 为例

32位

64位

VC++ Redistributable各个版本是否安装的注册表键值可查看下图

方式二

还是以Microsoft Visual C++ 2015-2019 Redistributable 为例


注:vc++ 2015-2019与vc++2017注册表查看方式类似

方式一查看方式更为简单直接,推荐第一种查看方式。

七、安装完成自动启动程序
027-bryi.png

八、安装前卸载旧版本

028-hkhi.png

UninstallPreviousVersions操作是通过 UpgradeCode来查找旧版本的,所以只要确保新旧版本的UpgradeCode一致(product Code千万不能一致)就可以在安装新版本的时候自动卸载旧版本了。

UpgradeCode:

029-rgwk.png

九、更换主题等

用户可根据需要进行主题的切换、自绘对话框、安装过程(全屏显示)的幻灯片、以及语言选项,可玩性比较高,读者们自行测试吧

030-aqho.png

十、在线升级

该功能最好去看官方文档,这里简单介绍一下该功能:

031-nunx.png

主要思路就是:

1.将最新的exe路径和版本信息等以固定的格式放在网上

2.绿色包也要放在网上

3.调用安装后在软件根目录的updater.exe进行检查下载。

这一套都是该软件做好的,我们提供网上资源和资源信息就好了。补丁包会更加麻烦一些,需要做msi包,进行本版本和下一版本比较生成补丁文件~

升级操作

作为公司类的产品,当然少不了加密授权的操作,软硬加密狗诸如此类,每次想从网上下载资源或者软件进行白嫖,但是人家都能蹦出个授权码、密码啥的,或者带有试用期,真是不给活路。好吧,咱们也不能让别人直接白嫖不是,罪(zhen)过(shuang)~

一、安装包的加密

032-qenr.png

然后安装过程中....033-tjke.png

二、软件试用期限制

034-umzt.png

035-byfr.png

036-qsnn.png

038-rhxa.png

040.png

生成的动态库:

041.png

接下来需要在咱们的程序里添加联动代码

// 试用功能签名
typedef UINT (__stdcall * TrialFcn)(LPCSTR, HWND);

// 注册函数签名
typedef UINT (__stdcall * RegisterFcn)(LPCSTR, LPCWSTR);

int InitLicensingSupport(LPCSTR aKeyCode, HWND aHWnd)
{
  HMODULE hModule = ::LoadLibrary("suibian.dll");
  if(hModule == NULL)
    return -1; // 缺少试用版 DLL;

  TrialFcn readSettingsProc = reinterpret_cast<TrialFcn>(
    ::GetProcAddress(hModule, "ReadSettingsStr"));

  if(readSettingsProc == NULL)
    return -1; // 缺少试用版 DLL;

  // Return values:
  // "0" - 应用已注册(找到有效的许可证密钥);
  // "2" - 应用处于试用模式;
  // 如果应用试用期已过,且用户未输入
  // 有效的许可证密钥,则该函数将终止该进程,而不是返回上述代码之一。
  int ret = readSettingsProc(aKeyCode, aHWnd);

  return ret;
}

int DisplayRegistrationDlg(LPCSTR aKeyCode, HWND aHWnd)
{
  HMODULE hModule = ::LoadLibrary("suibian.dll");
  if(hModule == NULL)
    return -1; // Missing Trial DLL;

  TrialFcn displayRegProc = reinterpret_cast<TrialFcn>(
    ::GetProcAddress(hModule, "DisplayRegistrationStr"));

  if(displayRegProc == NULL)
    return -1; // Missing Trial DLL;

  // Return values:
  // "0" - 应用程序已注册(找到/输入了有效的许可证密钥);
  // "2" - 应用程序处于试用模式;
  int ret = displayRegProc(aKeyCode, aHWnd);

  ::FreeLibrary(hModule);

  return ret;
}

int RegisterLicense(LPCSTR aKeyCode, LPCWSTR aLicense)
{
  HMODULE hModule = ::LoadLibrary("suibian.dll");
  if(hModule == NULL)
    return -1; // Missing Trial DLL;

  RegisterFcn registerLicense = reinterpret_cast<RegisterFcn>(
    ::GetProcAddress(hModule, "RegisterStr"));

  if(registerLicense == NULL)
    return -1; // Missing Trial DLL;

  // Return values:
  // “0” - 许可证已成功保存在本地机器上;请注意,使用“RegisterStr”函数时不会进行许可证验证
  // “不同于 0” - 许可证无法保存在本地机器上
  int ret = registerLicense(aKeyCode, aLicense);

  ::FreeLibrary(hModule);

  return ret;
}

在刚进程序的地方添加调用函数即可


#define kLibraryKey "52C55AA6D662A785EE887C42D403486B7401D62E32AF681B7E2E12BBEA5E9BC342013F48A2D2"

// 主应用程序启动后立即初始化许可支持
void OnInit(...)
{
  // 您可以选择为许可消息指定一个父窗口
  HWND parentWnd = m_hWnd; // can be NULL

  int ret = InitLicensingSupport(kLibraryKey, parentWnd);

  // 试用版 DLL 缺少退出功能以保护应用程序
  // (您可以选择其他处理方式 - 正常退出应用程序)
  if(ret == -1)
    exit(0);

  // 您可以保存并使用返回码 (ret) 显示应用程序注册状态

  // 继续加载您的应用程序...
  // ...

}

// 当客户端想要注册你的应用程序时,你应该这样处理
LRESULT OnRegister(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL & /*bHandled*/)
{
  // 显示试用对话框。
  int ret = DisplayRegistrationDlg(kLibraryKey, m_hWnd);

 // 您可以保存并使用返回代码(ret)来更新应用程序注册状态
  return 0;
}

加入联动代码后,记得生成最新的exe程序

三、最终效果

run一下,查看效果

042.png

043.png

044.png

045.png

046.png

047.png

048.png

049.png

050.png

有问题请留言(配上问题界面截图)笔者会积极回复你,感谢!

0
  1. 支付宝打赏

    qrcode alipay
  2. 微信打赏

    qrcode weixin
  3. QQ打赏

    qrcode qq

评论区