美文网首页Qt学习Qt学习Qt
Qt之打包发布程序 (NSIS)

Qt之打包发布程序 (NSIS)

作者: 玖零儛 | 来源:发表于2018-07-02 16:24 被阅读17次

写好了程序之后要关心的就是怎么将程序打包成一个安装包发给用户了,这里就推荐一个功能比较全面的打包脚本NSIS。在一般情况下,只要不是特别傻逼的需求 (纠结安装包字符串显示的大爷惹不起惹不起....) 都是能实现的。

Qt程序处理

编译程序的release版

1.IDE版
构建方式换成Release,点击Qt Creator的运行按钮

2.命令行版(方便自动化构建)

set PATH=c:\Qt\Qt5.7.0\5.7\mingw53_32\bin;%PATH%
set PATH=c:\Qt\Qt5.7.0\Tools\mingw530_32\bin;%PATH%
cd %~dp0
mingw32-make.exe clean
qmake.exe Demo.pro -spec win32-g++ "CONFIG+=release" && mingw32-make.exe qmake_all
mingw32-make.exe -j4

查找Qt程序需要的动态库文件

直接将Qt的release目录拷贝到一个没装Qt的电脑里,会发现无法运行,这是因为有的Qt核心的动态库并不会在构建的时候放到该目录下,需要额外添加,Qt给我们提供了一个方便的工具来查找程序需要的相关dll,windeployqt.exe。

  1. widget版:
set PATH=c:\Qt\Qt5.7.0\5.7\mingw53_32\bin;%PATH%
set PATH=c:\Qt\Qt5.7.0\Tools\mingw530_32\bin;%PATH%
windeployqt.exe Demo.exe --dir %PRODUCT_DIR%

2.含有qml界面版:

set PATH=c:\Qt\Qt5.7.0\5.7\mingw53_32\bin;%PATH%
set PATH=c:\Qt\Qt5.7.0\Tools\mingw530_32\bin;%PATH%
windeployqt.exe --qmldir   %QML_FILE_DIR% Demo.exe  --dir %PRODUCT_DIR%

3.莫名其妙缺少dll版:
上面通过windeployqt.exe查找后还是缺失的话,直接去Qt放dll的目录,把所有dll拷贝到release目录下,把你的程序运行起来,然后删除所有dll,提示占用不能删除留下来的就是你需要的。

NSIS打包

NSIS有界面化的工具HM VNISEdit,不过一般都得改,就直接用文本编辑器手敲好了。可以先用工具生成一个默认的模板看看,下面主要讲下特殊需求怎么通过脚本实现。

1.安装/卸载程序互斥:同时只能开启一个安装/卸载程序:

;安装程序互斥
!define Mutex_Install     "Demo_Mutex_Install"
!define Mutex_UnInstall   "Demo_Mutex_UnInstall"


Function CreateMutex
;检查安装互斥
ReCheck:
System::Call 'kernel32::CreateMutexA(i 0, i 0, t "${Mutex_Install}") i .R1 ?e'
Pop $R0
System::Call 'kernel32::CloseHandle(i R1) i.s'
;检查卸载互斥
System::Call 'kernel32::CreateMutexA(i 0, i 0, t "${Mutex_UnInstall}") i .R3 ?e'
Pop $R2
System::Call 'kernel32::CloseHandle(i R3) i.s'
;判断安装/卸载互斥的存在
${If} $R0 != 0
MessageBox MB_RetryCancel|MB_ICONEXCLAMATION "$(MutexInstallMessage)" IdRetry ReCheck
Quit
${ElseIf} $R2 != 0
MessageBox MB_RetryCancel|MB_ICONEXCLAMATION "$(MutexUninstallMessage)" IdRetry ReCheck
Quit
${Else}
;创建安装互斥
System::Call 'kernel32::CreateMutexA(i 0, i 0, t "${Mutex_Install}") i .R1 ?e'
Pop $R0
StrCmp $R0 0 +2
Quit
${EndIf}
FunctionEnd

Function Un.CreateMutex
;检查安装互斥
ReCheck:
System::Call 'kernel32::CreateMutexA(i 0, i 0, t "${Mutex_Install}") i .R1 ?e'
Pop $R0
System::Call 'kernel32::CloseHandle(i R1) i.s'
;检查卸载互斥
CheckUnInstall:
System::Call 'kernel32::CreateMutexA(i 0, i 0, t "${Mutex_UnInstall}") i .R3 ?e'
Pop $R2
System::Call 'kernel32::CloseHandle(i R3) i.s'
;判断安装/卸载互斥的存在
${If} $R0 != 0
MessageBox MB_RetryCancel|MB_ICONEXCLAMATION "$(MutexInstallMessage)" IdRetry ReCheck
Quit
${ElseIf} $R2 != 0
MessageBox MB_RetryCancel|MB_ICONEXCLAMATION "$(MutexUninstallMessage)" IdRetry ReCheck
Quit
${Else}
;创建卸载互斥
System::Call 'kernel32::CreateMutexA(i 0, i 0, t "${Mutex_UnInstall}") i .R1 ?e'
Pop $R0
StrCmp $R0 0 +2
Quit
${EndIf}
FunctionEnd

Function .onInit
Call CreateMutex
...
FunctionEnd
  1. 检测所安装的程序是否有在运行,在的话弹个框提示杀进程:
...
 Push $R0
 CheckProc:
    Push "${PRODUCT_MAIN_APP_EXE}"
    ProcessWork::existsprocess
    Pop $R0
    IntCmp $R0 0 Done
    ; MessageBox MB_OKCANCEL|MB_ICONSTOP $(InstallWarningMessage) IDCANCEL Exit
    MessageBox MB_OKCANCEL|MB_ICONSTOP "$(InstallWarningMessage)" IDCANCEL Exit
    Push "${PRODUCT_MAIN_APP_EXE}"
    Processwork::KillProcess
    Sleep 1000
    Goto CheckProc
 Exit:
     Abort
 Done:
    Pop $R0
...
  1. 检测是否安装过旧版本,有的话提示卸载:
...
var /GLOBAL UNINSTALL_PROG
var /GLOBAL OLD_VER
var /GLOBAL OLD_PATH
    
ClearErrors
  ReadRegStr $UNINSTALL_PROG ${PRODUCT_UNINST_ROOT_KEY} ${PRODUCT_UNINST_KEY} "UninstallString"
  IfErrors  FinishInit
  
  ReadRegStr $OLD_VER ${PRODUCT_UNINST_ROOT_KEY} ${PRODUCT_UNINST_KEY} "DisplayVersion"
  MessageBox MB_YESNOCANCEL|MB_ICONQUESTION "$(Uninstall_Old_Message)" /SD IDYES IDYES UninstallOld IDNO FinishInit
  Abort
  
UninstallOld:
  StrCpy $OLD_PATH $UNINSTALL_PROG -10

  ExecWait '"$UNINSTALL_PROG" /S _?=$OLD_PATH' $0
  DetailPrint "uninst.exe returned $0"
  Delete "$UNINSTALL_PROG"
  RMDir $OLD_PATH

FinishInit:
...
  1. 安装包多语言:
; 语言选择窗口常量设置
!define MUI_LANGDLL_REGISTRY_ROOT "${PRODUCT_UNINST_ROOT_KEY}"
!define MUI_LANGDLL_REGISTRY_KEY "${PRODUCT_UNINST_KEY}"
!define MUI_LANGDLL_REGISTRY_VALUENAME "NSIS:Language"

!define MUI_LANGDLL_WINDOWTITLE "$(LangDialog_Title)"
!define MUI_LANGDLL_INFO "$(LangDialog_Text)"
!define MUI_LANGDLL_ALLLANGUAGES
...
; 安装界面包含的语言设置
!insertmacro MUI_LANGUAGE "English" ;first language is the default language
!insertmacro MUI_LANGUAGE "SimpChinese"
...

; 安装预释放文件
!insertmacro MUI_RESERVEFILE_LANGDLL
;!insertmacro MUI_RESERVEFILE_INSTALLOPTIONS
...
Function .onInit
 !insertmacro MUI_LANGDLL_DISPLAY 
...
FunctionEnd
  1. 界面美化
    如果制作的安装包不需要多语言的设置的话,可以通过一些别人写好的插件进行界面美化,如:nsNiuniuSkin
    下载下来就带了2个demo,改改就能自己用了,比较方便。Demo图示:
    Demo1.png
Demo2.png

相关文章

  • Qt之打包发布程序 (NSIS)

    写好了程序之后要关心的就是怎么将程序打包成一个安装包发给用户了,这里就推荐一个功能比较全面的打包脚本NSIS。在一...

  • Linux下打包发布Qt应用程序

    Linux下打包发布Qt应用程序 Linux下打包发布Qt应用程序 Linux下使用Qt进行开发的程序,如果想要在...

  • QT程序打包发布

    当你历尽艰辛终于把"bug"写完,兴致勃勃的发给基友炫耀时,结果你的"bug"在基友电脑上跑不起来,提示缺少一堆d...

  • qt程序打包发布

    qt程序打包发布 目标: 我想安装自己开发的程序 1.打包依赖库 a.使用qtcreator编译生成程序demo....

  • NSIS制作安装包笔记(二):NSIS使用NSIS+Qt界面制作

    前言   Nsis可以使用duilib也可以使用qt界面,笔者主要qt,本文章梳理nsis+qt制作安装包的基本流...

  • 程序打包教程

    QT5程序打包问题 问题描述:为了方便不同电脑之间QT程序的移植,简单介绍QT5打包方式打包工具:QT5自带的wi...

  • 在Linux 下如何打包免安装的QT程序?

    如题,近期因为项目需求,得打包QT程序,并将程序放到没有安装QT库的电脑上运行。网上索罗了下,打包QT程序的方式很...

  • 使用NSIS打包程序

    使用****NSIS****打包安装程序教程 1、前言 程序设计好以后会生成若干可执行文件和依赖文件。为了方便程序...

  • Qt5.12.5 静态编译以及裁剪大小对比

    最近在研究用静态编译的 Qt 做个 Qt 的安装包程序,因为 nsis 在界面自定义还有多语言适配等问题上不太理想...

  • QT打包发布

    设置执行文件的图标 图片格式需要用工具转成 .ico 格式。把该图片放到QT的工程目录下,也就是包含pro文件的目...

网友评论

    本文标题:Qt之打包发布程序 (NSIS)

    本文链接:https://www.haomeiwen.com/subject/ocxluftx.html