在使用Go语言开发应用程序时,有个非常方便的地方就是编译得到的可执行文件可以不依赖任何动态链接库、并且不需要任何运行环境即可运行,这一点Java就没那么方便了。
不过在Windows上编译得到的exe
文件,默认是不带图标和任何属性信息的,那么怎么才能让我们编译得到的可执行文件带上图标和属性信息呢?
事实上,借助go-winres这款命令行工具即可很方便地实现。
1,安装go-winres
命令
执行下列命令即可安装go-winres
命令到电脑中:
bash
go install github.com/tc-hib/go-winres@latest
2,创建配置模板
我们首先需要一个配置文件来指定我们的图标文件和属性信息,然后将它们编译得到资源文件,最后将资源文件和Go源代码一起编译即可得到带有图标的可执行文件了!
我们可以先生成一个配置模板,然后进行修改即可,执行下列命令:
bash
go-winres init
然后在当前目录下,你会发现多了个winres
目录,其中winres.json
就是配置文件,而两个png
文件则是它自带的图标文件:
3,修改配置
使用文本编辑器打开winres.json
文件,其中有一些初始内容:
其中的大致结构我们不需要修改,基本上就是修改指定其中部分字段值即可。
下面,我们来单独看一下每个部分。
(1) 图标指定
我们来看看图标部分,声明在json
文件中的RT_GROUP_ICON
属性中:
json
"RT_GROUP_ICON": {
"APP": {
"0000": [
"icon.png",
"icon16.png"
]
}
}
上述APP
表示一组图标,其中还有一个0000
,表示语言,不过这两个属性名称都不需要怎么动,重点是看0000
这个属性,它是一个数组,而很显然数组中记录着一组图标,在其中可以指定不同分辨率的图标。在这里指定的图标就会被应用到最终编译的可执行文件上去。
图标文件可以就是png
文件,将它和winres.json
放在同一目录下,然后在这个0000
数组中指定图标文件名即可。
假设我现在需要自定义图标,并且只需要一个文件,那么我可以先删除里面自带的两个png
文件,然后把我的图标放在和winres.json
同级目录下:
然后修改图标部分配置如下:
json
"RT_GROUP_ICON": {
"APP": {
"0000": [
"my-icon.png"
]
}
}
这样,图标就指定完成了!
需要注意的是,图片文件尺寸不能大于256 x 256
!
(2) 软件清单
软件清单部分声明在RT_MANIFEST
属性中:
json
"RT_MANIFEST": {
"#1": {
"0409": {
"identity": {
"name": "",
"version": ""
},
"description": "",
"minimum-os": "win7",
"execution-level": "as invoker",
"ui-access": false,
"auto-elevate": false,
"dpi-awareness": "system",
"disable-theming": false,
"disable-window-filtering": false,
"high-resolution-scrolling-aware": false,
"ultra-high-resolution-scrolling-aware": false,
"long-path-aware": false,
"printer-driver-isolation": false,
"gdi-scaling": false,
"segment-heap": false,
"use-common-controls-v6": false
}
}
}
上述并非所有属性都需要填写和修改,这里将重要的部分讲解一下:
description
文件的描述信息minimum-os
最低要求操作系统,可以是以下值:"vista"
"win7"
"win8"
"win8.1"
"win10"
execution-level
应用程序所需的权限,可以是:"as invoker"
不需要任何权限"highest"
使用当前用户的可用最高权限"administrator"
强制要求管理员权限才能运行
对于identify
属性,普通应用程序建议留空即可,也可以将其删除。
(3) 元数据信息
这部分定义在RT_VERSION
属性中:
json
"RT_VERSION": {
"#1": {
"0000": {
"fixed": {
"file_version": "0.0.0.0",
"product_version": "0.0.0.0"
},
"info": {
"0409": {
"Comments": "",
"CompanyName": "",
"FileDescription": "",
"FileVersion": "",
"InternalName": "",
"LegalCopyright": "",
"LegalTrademarks": "",
"OriginalFilename": "",
"PrivateBuild": "",
"ProductName": "",
"ProductVersion": "",
"SpecialBuild": ""
}
}
}
}
}
这里也并非所有属性都需要填写和修改,这里将重要的部分讲解一下:
fixed
属性中的两个属性,主要是声明文件版本和程序版本,按照x.y.z.w
的格式自己填写即可info
主要是属性信息,其中0409
是英语的语言代码,表示在英文环境下显示其中的属性,在info
中可以定义多个语言环境下的属性信息,具体大家可以查看官方项目示例,在其中:CompanyName
公司名称FileDescription
文件描述FileVersion
文件版本ProductVersion
程序版本LegalCopyright
版权信息OriginalFilename
原始文件名ProductName
程序名称
(4) 简易winres.json
模板
可见上述有许多属性是我们大多数时候不需要进行设定的,可以删除,因此这里我提供一个模板 ,大家可以复制作为自己的winres.json
文件使用:
json
{
"RT_GROUP_ICON": {
"APP": {
"0000": [
"my-icon.png"
]
}
},
"RT_MANIFEST": {
"#1": {
"2052": {
"description": "我的Go示例程序",
"minimum-os": "win7",
"execution-level": "highest",
"ui-access": false,
"auto-elevate": false,
"dpi-awareness": "system",
"disable-theming": false,
"disable-window-filtering": false,
"high-resolution-scrolling-aware": false,
"ultra-high-resolution-scrolling-aware": false,
"long-path-aware": false,
"printer-driver-isolation": false,
"gdi-scaling": false,
"segment-heap": false,
"use-common-controls-v6": false
}
}
},
"RT_VERSION": {
"#1": {
"0000": {
"fixed": {
"file_version": "1.0.0.0"
},
"info": {
"2052": {
"CompanyName": "公司名称",
"FileDescription": "我的Golang示例程序",
"LegalCopyright": "© 版权",
"OriginalFilename": "demo.exe",
"ProductName": "Go示例",
"ProductVersion": "1.0.0.0"
}
}
}
}
}
}
大家修改其中信息为自己的即可。
4,编译资源
在winres
文件夹所在目录下执行命令:
bash
go-winres make
此时你会发现多了这几个syso
文件,这就是编译得到的资源:
需要注意的是,上述命令的运行路径是在winres
文件夹所在目录下,而不是winres
文件夹里面。
当然,你也可以使用--in
参数指定json
文件位置,如果你的运行路径不在winres
文件夹的所在目录下的话:
bash
# 指定json配置文件在上一级目录的res目录中
go-winres make --in "../res/winres.json"
还可以使用--out
参数指定输出的资源文件位置,具体大家可以通过命令go-winres make --help
查看帮助。
5,编译Go程序
首先确保上述编译得到的两个syso
资源文件和Go语言模块配置go.mod
在同级目录下:
然后像平时一样,在go.mod
所在目录下执行构建命令即可:
bash
go build -ldflags "-w -s"
这样,我们得到的可执行文件就有图标和属性信息了!
上述命令中,ldflags
参数指定的是去除调试和符号信息以减小构建产物文件大小,这个参数可以省略。
可见我们编译得到的资源文件都有着类似_windows_amd64
这样的后缀,这个后缀是用于go build
命令链接资源时,根据架构判断链接哪个资源用的,例如当我们编译64位程序时,go build
就会自动寻找名为xxx_windows_amd64.syso
的资源文件进行链接,同样地如果是编译为32位程序,则是寻找名为xxx_windows_386.syso
的资源文件,因此syso
资源文件的文件名必须是xxx_windows_amd64.syso
这样的形式,不可以修改其后缀。
与此同时,在进行go build
时,go.mod
文件必须要和syso
文件在同一目录下,如果没有go.mod
文件,那主程序文件(被编译的)就需要和syso
文件在同一目录下。