QT使用QtIFW打包带简单安装脚本演示

发布于 21 天前  14 次阅读


QT使用QtIFW打包带简单安装脚本演示

提前下载好

QtIFW国内镜像站

下载后找个版本安装

dll补全

编译好的动态链接程序移动到任意一个非中文路径下

使用windeployqt补全要用到的dll

windeployqt去到编译所使用的qt路径下面找 例如C:\Qt\Qt5.14.2\5.14.2\msvc2017_64\bin

如果有其它的环境干扰可以进入

image-20260205001239471

例如C:\Windows\System32\cmd.exe /A /Q /K C:\Qt\Qt5.14.2\5.14.2\msvc2017_64\bin\qtenv2.bat

这样确保没有conda之类的里面有干扰

image-20260205001328532

cd过去后使用windeployqt .\你编译的程序.exe

image-20260205001403541

然后我们稍微瘦身(

把程序运行起来后删除一遍,把没用到的dll删除

image-20260205001543428

目录构建

然后到QtIFW安装目录下

C:\Qt\QtIFW-4.8.1\examples

有示例,以里面的startmenu为模板,也找个非中文路径移出来

把前面补全的全部文件 对应的目录全部转移到

packages\org.qtproject.ifw.xxx\data下面

这里xxx自己命名

image-20260205002803049

config.xml配置

详细的跳转到文后看官方文档对照

先看到config\config.xml的配置

我这里要注意的就

InstallerApplicationIcon使用的ico要为多尺寸windows ico

以及管理工具MaintenanceToolName的命名我改为了Uninstall

这是我的配置

config\config.xml

<?xml version="1.0" encoding="UTF-8"?>
<Installer>
    <Name>Audio Control</Name>
    <Version>1.0.0</Version>
    <Title>Audio Control安装向导</Title>
    <Publisher>Ranfey</Publisher>
    <!-- Directory name is used in component.xml -->
    <StartMenuDir>Audio Control</StartMenuDir>
    <TargetDir>@ApplicationsDir@/Audio Control</TargetDir>
    <InstallerApplicationIcon>favicon</InstallerApplicationIcon>
    <MaintenanceToolName>Uninstall</MaintenanceToolName>
</Installer>

组件package.xml

然后是package.xml的配置

在结构packages\org.qtproject.ifw.xxxx\meta\package.xml

简单修改了以下

主要就是指定了Script

packages\org.qtproject.ifw.xxxx\meta\package.xml

<?xml version="1.0" encoding="UTF-8"?>
<Package>
    <DisplayName>Audio Control</DisplayName>
    <Description>Audio Control</Description>
    <Version>1.0.0-1</Version>
    <ReleaseDate>2026-02-03</ReleaseDate>
    <Default>true</Default>
    <Script>installscript.qs</Script>
</Package>

其中Script也是meta\里面

下面是我使用的脚本

packages\org.qtproject.ifw.xxxx\meta\installscript.qs

function Component()
{
    // 默认构造函数:
}

Component.prototype.createOperations = function()
{
    /*
     *  调用默认实现(非常重要)
     */
    component.createOperations();

    /*
     *  判断操作系统
     */
    if (systemInfo.productType === "windows") {

        /*
         *  创建开始菜单快捷方式:主程序 Audio_control.exe
         *
         * component.addOperation(opName, arg1, arg2, ...)
         * 用于向操作队列追加一条操作。
         * 
         * 这里使用了预定义变量(@...@),会在运行时展开为实际路径:
         *   - @TargetDir@   : 用户选择的安装目标目录(最终安装位置)
         *   - @StartMenuDir@: 开始菜单目录(由 config.xml 的 StartMenuDir 等决定)
         *
         */
        component.addOperation(
            "CreateShortcut",
            "@TargetDir@/Audio_control.exe",              // 快捷方式指向的可执行文件
            "@StartMenuDir@/Audio Control.lnk",           // 生成的 .lnk 快捷方式位置
            "workingDirectory=@TargetDir@",               // 快捷方式“起始位置/工作目录”
            "iconPath=@TargetDir@/Audio_control.exe",     // 图标来源文件(这里直接取 exe 内嵌图标)
            "iconId=0",                                   // exe 内图标索引(通常 0 是主图标)
            "description=Start Audio Control"             // 快捷方式描述
        );

        /*
         *  创建开始菜单快捷方式:卸载入口 Uninstall.exe
         *
         *  把卸载器也放进开始菜单,方便用户从开始菜单卸载。
         *
         * 注意:iconPath 仍然使用 Audio_control.exe 的图标,
         * 这样 Uninstall.lnk 的图标更美观/统一;否则卸载器可能是默认图标。
         */
        component.addOperation(
            "CreateShortcut",
            "@TargetDir@/Uninstall.exe",                  // 卸载程序注意是在前面的MaintenanceToolName
            "@StartMenuDir@/Uninstall.lnk",               // 卸载快捷方式
            "workingDirectory=@TargetDir@",               // 工作目录同安装目录
            "iconPath=@TargetDir@/Audio_control.exe",     // 我使用主程序的图标作为卸载快捷方式图标
            "iconId=0",
            "description=Uninstall"
        );

        /*
         *  弹窗询问:是否创建桌面快捷方式
         *
         * QMessageBox.question(...) 会弹出一个“是/否”对话框。
         *
         * 参数含义:
         *   - "AskDesktop"                     : 对话框内部标识(可用于一些自动化/翻译系统)
         *   - "桌面快捷方式"                   : 标题
         *   - "是否在桌面创建快捷方式?"       : 文本
         *   - QMessageBox.Yes | QMessageBox.No : 按钮组合
         *   - QMessageBox.Yes                  : 默认选中的按钮
         *
         * 返回值:用户点了哪个按钮(Yes/No)。
         */
        if (QMessageBox.question(
                "AskDesktop",
                "桌面快捷方式",
                "是否在桌面创建快捷方式?",
                QMessageBox.Yes | QMessageBox.No,
                QMessageBox.Yes
            ) == QMessageBox.Yes)
        {
            /*
             * 6) 如果用户选择“是”:创建桌面快捷方式
             *
             * @DesktopDir@ 是预定义变量,代表当前用户的桌面目录。
             *
             * 说明:
             * - 你创建的是 “Audio Control.lnk” 在桌面上。
             * - 参数与开始菜单那个一致(工作目录/图标/描述)。
             */
            component.addOperation(
                "CreateShortcut",
                "@TargetDir@/Audio_control.exe",
                "@DesktopDir@/Audio Control.lnk",
                "workingDirectory=@TargetDir@",
                "iconPath=@TargetDir@/Audio_control.exe",
                "iconId=0",
                "description=Start Audio Control"
            );
        }
    }
};

到这里配置完成

生成

使用C:\Qt\QtIFW-4.8.1\bin下的binarycreator打包

binarycreator -c config\config.xml -p packages Installer -v

懒得添加C:\Qt\QtIFW-4.8.1\bin到环境就直接用

& "C:\Qt\QtIFW-4.8.1\bin\binarycreator.exe"  -c config\config.xml -p packages Installer -v

image-20260205011337984

image-20260205011354889

打包完成

效果演示

image-20260205011600999

image-20260205011621323

image-20260205011643554

官方文档对照

config.xml语法示例

https://doc.qt.io/qtinstallerframework/ifw-globalconfig.html

<?xml version="1.0"?>
<Installer>
    <Name>Some Application</Name>
    <Version>1.0.0</Version>
    <Title>Some Application Setup</Title>
    <Publisher>Your Company</Publisher>
    <ProductUrl>http://www.your-fantastic-company.com</ProductUrl>
    <InstallerWindowIcon>installericon</InstallerWindowIcon>
    <InstallerApplicationIcon>installericon</InstallerApplicationIcon>
    <Logo>logo.png</Logo>
    <Watermark>watermark.png</Watermark>
    <RunProgram>@TargetDir@/YourAppToRun</RunProgram>
    <RunProgramArguments>
        <Argument>Argument 1</Argument>
        <Argument>Argument 2</Argument>
    </RunProgramArguments>
    <RunProgramDescription>My nice application</RunProgramDescription>
    <StartMenuDir>Some Application Entry Dir</StartMenuDir>
    <MaintenanceToolName>SDKMaintenanceTool</MaintenanceToolName>
    <AllowNonAsciiCharacters>true</AllowNonAsciiCharacters>
    <Background>background.png</Background>

    <TargetDir>@HomeDir@/testinstall</TargetDir>
    <AdminTargetDir>@RootDir@/testinstall</AdminTargetDir>
    <RemoteRepositories>
        <Repository>
            <Url>http://www.your-repo-location/packages/</Url>
        </Repository>
    </RemoteRepositories>
    <AliasDefinitionsFile>aliases.xml</AliasDefinitionsFile>
</Installer>
  • 建议:将所有在配置文件中引用到的文件(图片、样式表、脚本等)放在同一个目录下。也可以使用相对路径;工具会以 config.xml 所在位置为基准解析相对路径。
  • 文件名必须唯一:被引用的文件名不能重名。比如你想让 <Logo><Watermark> 用同一张图片,也需要准备两份文件,但文件名必须不同(例如 logo.pngwatermark.png)。

配置项的值中可以使用用 @...@ 包裹的预定义变量(例如 @TargetDir@@HomeDir@)。

元素(Element) 中文说明(翻译+解释)
Name 要安装的产品名称。必填
Version 产品版本号,格式:`[0-9]+((.
Title 安装程序窗口标题栏显示的名称。
Publisher 软件发布者(在 Windows 控制面板等位置显示)。
ProductUrl 指向产品信息页面的 URL。
InstallerApplicationIcon 自定义安装器应用图标文件名。实际文件会按平台自动拼接后缀:macOS 用 .icns、Windows 用 .ico;Unix 上无功能。
InstallerWindowIcon 安装器窗口图标(PNG)。用于 Windows 和 Linux;macOS 上无功能。
Logo Logo 图片(PNG),用作 QWizard::LogoPixmap
Watermark 水印图片(PNG),用作 QWizard::WatermarkPixmap。若 WizardShowPageList 设为 true,则水印会被隐藏。
Banner 横幅图片(PNG),用作 QWizard::BannerPixmap(仅 ModernStyle 使用)。
Background 背景图片(PNG),用作 QWizard::BackgroundPixmap(仅 MacStyle 使用)。若 WizardShowPageList 设为 true,则背景会被隐藏。
PageListPixmap 安装器页面列表顶部显示的图片(PNG)。仅当 WizardShowPageList 也设为 true 时显示。
WizardStyle Wizard 风格:Modern / Mac / Aero / Classic
StyleSheet 样式表文件。
WizardDefaultWidth Wizard 默认宽度(像素)。设置 Banner 图片会覆盖该值。支持 em / ex 后缀(类似 CSS 单位)。
WizardDefaultHeight Wizard 默认高度(像素)。设置 Watermark 图片会覆盖该值。支持 em / ex 单位。
WizardMinimumWidth Wizard 最小宽度(像素)。支持 em / ex 单位。
WizardMinimumHeight Wizard 最小高度(像素)。支持 em / ex 单位。
WizardShowPageList 是否显示左侧“页面列表”控件。设为 false 表示不显示;默认 true。若显示,该控件在 ClassicStyle + WatermarkPixmapModernStyle + BackgroundPixmapMacStyle 等情形下会有不同隐藏/显示行为(原文提到会在某些页面/样式下隐藏)。
ProductImages PerformInstallationPage 显示的一组图片列表。可包含多个 <ProductImage>,每个包含 <Image>(PNG 文件名)与可选 <Url>。点击图片会打开 <Url>;若 <Url> 指向本地文件,则会用合适的应用打开而不是浏览器。
TitleColor 标题/副标题颜色(HTML 色值,如 #88FF33)。
RunProgram 安装完成后,若用户接受“立即运行”的操作,则执行该命令。应提供程序完整路径。
RunProgramArguments 传给 RunProgram 的参数列表。可以有多个 <Argument> 子元素。
RunProgramDescription “安装完成后运行程序”的复选框旁显示的文字。若设置了 RunProgram 但没提供该描述,UI 将显示类似 Run <Name> now.
StartMenuDir Windows 开始菜单中默认程序组(文件夹)名称。
TargetDir 默认安装目标目录。Linux 上通常是用户家目录。
AdminTargetDir 需要管理员权限安装时的默认目标目录。仅在 Linux 可用(通常不希望装到管理员用户的 home 下)。
LocalCacheDir 元数据缓存目录名(不含前置路径)。实际缓存根路径由平台自动选择(合适的 cache 位置)。用户可在安装器设置中覆盖该路径。默认值是基于产品名生成的 UUID。
PersistentLocalCache 设为 false:安装器退出时清理已获取的元数据缓存;否则保留缓存以加速后续获取。默认 true
RemoteRepositories 远程仓库列表。可包含多个 <Repository>,每个含 <Url> 指定仓库地址。
RepositoryCategories 仓库分类名称,可包含多个子 <RemoteRepositories>(原文提示“更多信息见 Configuring Repository Categories”)。
MaintenanceToolName 生成的维护工具(maintenancetool)文件名。默认 maintenancetool,会自动追加平台可执行文件扩展名。
MaintenanceToolIniFile 维护工具的配置文件名。默认 MaintenanceToolName.ini
MaintenanceToolAlias 维护工具在 Applications 目录下创建的别名文件名。可选,仅 macOS 使用。
RemoveTargetDir 设为 false:卸载时不删除目标目录。
AllowNonAsciiCharacters 设为 true:允许安装路径包含非 ASCII 字符。
DisableAuthorizationFallback 设为 true:遇到授权错误时不提示用户使用“授权回退(fallback)”,而是直接中止安装。
DisableCommandLineInterface 设为 true:禁用命令行接口功能,防止用户对 installer 传 consumer 命令(如 install / update / remove 等);其他选项仍可用。默认 false
RepositorySettingsPageVisible 设为 false:隐藏设置对话框中的“仓库设置”页面。
AllowRepositoriesForOfflineInstaller 设为 false:对离线安装器禁用临时或用户配置的仓库;但离线安装器写出的 maintenance tool 仍可访问仓库。默认 true
AllowSpaceInPath 设为 false:安装路径不允许包含空格。
DependsOnLocalInstallerBinary 设为 true:禁止从外部资源(如网络盘)运行安装,以避免大体积安装器在网络环境的风险;仅 Windows 使用。
TargetConfigurationFile 安装到目标机器上的配置文件名。默认 components.xml
AliasDefinitionsFile 组件别名定义 XML 文件名。用于声明组件别名(更多信息见 Alias Definition File)。
Translations UI 翻译文件列表。可包含多个 <Translation> 子元素。用于覆盖/配置默认翻译(更多信息见 Translating Pages 等)。
UrlQueryString 形如 "key=value" 的字符串,会追加到归档下载请求中,用于向托管仓库的 Web 服务器传递信息。
ControlScript 自定义安装器控制脚本文件名(见 Controller Scripting)。
CreateLocalRepository 设为 true:在安装目录内创建本地仓库。对在线安装器无效;本地仓库会自动加入默认仓库列表。
InstallActionColumnVisible 设为 true:在组件树增加一列显示“安装动作”(安装/卸载/保持)。
SupportsModify 设为 false:产品不支持“修改已有安装(Modify)”。
SaveDefaultRepositories 设为 false:不把默认仓库保存到 MaintenanceToolName.ini。默认会保存;不保存意味着运行 maintenancetool 时没有默认仓库可用。
AllowUnstableComponents 设为 true:允许安装包含“不稳定组件”。不稳定指缺依赖、脚本错误等;这类组件在树中会灰显且不可选。默认 false(即发现不稳定组件会中止安装)。

Package Directory(包目录)

https://doc.qt.io/qtinstallerframework/ifw-component-description.html

安装器由多个 Component(组件)组成。组件可以:

  • 嵌入(embedded)在安装器里;或
  • 远程仓库(remote repository)按需下载。

无论哪种方式,你都需要把组件组织为安装器能识别的固定目录结构元数据格式

包目录结构(Package Directory Structure)

把所有组件放在同一个根目录下,这个根目录称为 package directory(包目录)

  • 包目录下的第一层子目录名充当一种“域名式标识符(domain-like identifier)”,用于识别组件,例如:com.vendor.root
  • 该目录名不能包含 :-
    因为这些字符被保留用于把“版本号”和“标识符”分隔开(即标识符与版本的解析会冲突)。

在每个组件目录内,必须包含两个子目录:

  • data/:安装时会被解包/释放的内容
  • meta/:组件元信息(不会被解包)
-packages
    - com.vendor.root
        - data
        - meta
    - com.vendor.root.component1
        - data
        - meta
    - com.vendor.root.component1.subcomponent1
        - data
        - meta
    - com.vendor.root.component2
        - data
        - meta

Meta Directory(meta 目录)

meta/ 目录包含“部署与安装流程配置”相关文件:

  • 这些文件 不会被安装器解压到目标目录;
  • meta/ 至少必须包含:
    1. package 信息文件(通常是 package.xml
    2. package.xml 引用到的所有文件(例如脚本、UI 文件、翻译文件等)

package.xml语法示例

https://doc.qt.io/qtinstallerframework/ifw-component-description.html

<?xml version="1.0"?>
<Package>
    <DisplayName>QtGui</DisplayName>
    <Description>Qt gui libraries</Description>
    <Description xml:lang="de_de">Qt GUI Bibliotheken</Description>
    <Version>1.2.3</Version>
    <ReleaseDate>2009-04-23</ReleaseDate>
    <Name>com.vendor.root.component2</Name>
    <Dependencies>com.vendor.root.component1</Dependencies>
    <Virtual>false</Virtual>
    <Licenses>
        <License name="License Agreement" file="license.txt" />
    </Licenses>
    <Script>installscript.qs</Script>
    <UserInterfaces>
        <UserInterface>specialpage.ui</UserInterface>
        <UserInterface>errorpage.ui</UserInterface>
    </UserInterfaces>
    <Translations>
        <Translation>sv_se.qm</Translation>
        <Translation>de_de.qm</Translation>
    </Translations>
    <DownloadableArchives>component2.7z, component2a.7z</DownloadableArchives>
    <AutoDependOn>com.vendor.root.component3</AutoDependOn>
    <SortingPriority>123</SortingPriority>
    <UpdateText>This changed compared to the last release</UpdateText>
    <Default>false</Default>
    <ForcedInstallation>false</ForcedInstallation>
    <ForcedUpdate>false</ForcedUpdate>
    <Essential>false</Essential>
    <Replaces>com.vendor.root.component2old</Replaces>

    <Operations>
        <Operation name="AppendFile">
            <Argument>@TargetDir@/A.txt</Argument>
            <Argument>lorem ipsum</Argument>
        </Operation>
        <Operation name="Extract">
            <Argument>@TargetDir@/Folder1</Argument>
            <Argument>content.7z</Argument>
        </Operation>
        <Operation name="Extract">
            <Argument>@TargetDir@/Folder2</Argument>
        </Operation>
    </Operations>

    <TreeName moveChildren="true">com.vendor.subcomponent</TreeName>
</Package>
元素 中文说明
DisplayName 组件对用户可见的名称(可读名称)。必填。可用多个 DisplayName 并用 xml:lang="xx_xx" 提供多语言。
Description 组件描述文本。必填。多语言方式同 DisplayName。若找不到匹配语言但存在无语言版本,则使用无语言版本;否则该语言环境下不显示描述。可在描述中加入用户可点击的外部链接:{external-link}='https://www.qt.io/'(URL 必须有效且包含完整路径)。
Version 组件版本号,格式:`[0-9]+((.
ReleaseDate 当前组件版本的发布日期。必填
Name 组件的域名式唯一标识符。必填
Dependencies 依赖组件列表(逗号分隔)。可选支持“带版本约束”(见下文“Component Dependencies”)。可使用比较运算符 =, >, <, >=, <=;注意 XML 中 < 要写成 <<= 要写成 <=
AutoDependOn 自动依赖列表(逗号分隔)。语义是:只有当这些依赖全部满足时,该组件才会被安装。同时该组件在组件树中通常不会显示可选复选框(用户不能直接勾选),但在 updater 视图里可能仍能被手动选为更新。包管理模式下会自动选择:未安装过时,只有当列表中的组件也被选中安装时才会选中它;已安装时,若列表中任一组件被选中卸载/更新,它也会相应被选中卸载/更新。
Virtual 设为 true 将组件从安装器中隐藏(并且会隐藏其所有子孙组件)。注意:对“根组件”设置可能不起作用(原文明确提醒)。
SortingPriority 组件在树中的排序优先级:从高到低排序,数值越高越靠上。
Licenses 许可协议列表:安装时用户必须接受。可添加多个 <License>,每个指定 namefile,可选 priority。许可文件支持 ASCII/UTF-8。若组件有翻译文件,安装器还会寻找“翻译版许可文件”:例如原许可 license.txt,德语翻译则为 license_de_de.txt(并在德语系统安装时展示)。
Script 安装脚本文件名(可选)。postLoad="true" 表示脚本只会在“该组件被选中安装/更新”时加载;还可用另一个属性(原文提到“With the attribute...”但你这段被截断了)来控制脚本加载时机,以减少大量带脚本组件时的加载开销。要确保脚本不依赖于“安装树视图显示之前”必须求值的东西。
UserInterfaces 需要加载的 UI 页面列表(可选)。多个 <UserInterface> 子元素。
Translations 需要加载的翻译文件列表(可选)。安装器会加载与当前系统 locale 匹配的 .qm 文件(例如系统为德语时加载 de.qm)。
UpdateText 当该组件作为“更新”时,追加到组件描述中的更新说明(可选)。
Default 组件默认选中策略:true / false / script。设为 true 会在安装器里预选该组件,但仅对“没有可见子组件”的组件生效。script 表示运行时由脚本决定;脚本名通过本文件的 <Script> 指定。
Essential 标记为“关键组件”。若该组件有更新可用,会强制 MaintenanceTool 重启;且在更新完成前包管理器保持禁用。新引入的 essential 组件在运行 updater 时会自动安装。
ForcedInstallation 强制安装:最终用户不能在安装器中取消勾选(必须安装)。但在更新视图里该组件仍可被取消某次更新。
ForcedUpdate 强制更新:类似 Essential,会强制 MaintenanceTool 重启;若有 ForcedUpdate 组件待更新,包管理器在更新前保持禁用。
Replaces 替换列表(逗号分隔):声明当前组件替代哪些旧组件(可选)。
DownloadableArchives 在线安装器要下载的数据归档文件列表(逗号分隔)。如果组件目录下存在数据文件且 package.xml/脚本未指定 DownloadableArchivesrepogen 会自动注册发现的数据。
RequiresAdminRights 设为 true 表示该组件需要提升权限(管理员权限)安装(可选)。
Checkable 设为 false 隐藏该项的勾选框(可选)。用于“希望用户只选少数子组件,而不是一勾全勾”的场景。更新组件时复选框仍可见,以便用户切换是否更新。
ExpandedByDefault 设为 true 表示该项默认展开(可选)。
Operations 安装时执行的操作列表。可用多个 <Operation name="...">,每个可包含多个 <Argument>。这是“用 XML 定义操作”的替代方式(否则也可在脚本里定义)。
TreeName 指定组件在安装树视图中的展示位置,覆盖基于 Name 自动计算的树位置。NameTreeName 都必须唯一(至少在树位置意义上不能冲突)。moveChildren="true" 会同时移动子组件到新的树节点下,并保持相对路径。若同一分支多个组件都定义了 tree name,则位置变更顺序为:从叶子到根

Component Dependencies(组件依赖)

组件可以依赖一个或多个真实组件或虚拟组件。依赖通过:

  • 组件标识符(如 com.vendor.root.component1
  • 可选 组件版本号约束

来定义。

写法规则

  • 用连字符 -版本号标识符分隔:identifier-version
  • 版本号前可以带比较运算符:=, >, <, >=, <=
  • 若不写运算符,默认是 =(等于)

XML 转义注意

因为 < 是 XML 特殊字符,必须写成实体引用:

  • <<
  • <=<=

Data Directory(data 目录)

data/ 目录包含安装时会被解压到目标机器的内容。

关键点:

  • data 必须被打包为 归档文件(archives)
  • 归档创建方式:
    1. 使用 binarycreator(创建安装器)和 repogen(创建仓库)时自动打包;或
    2. 你也可以手动预先打包,以获得更强的控制

可用归档工具与格式

手动打包时可使用:

  • Qt Installer Framework 自带的 archivegen
  • 或任何能生成以下格式的工具:

支持格式:

  • 7z
  • zip
  • tar.gz
  • tar.bz2
  • tar.xz
QQ:2219349024
最后更新于 2026-02-05