英文:
How do you set the application icon in golang?
问题
你好!以下是你要翻译的内容:
我刚在Windows上创建了我的第一个Go应用程序。
我该如何为它添加一个图标?
似乎没有任何构建标志可以做到这一点,而且我知道Go语言不支持资源。
英文:
I've just created my first go application on Windows.
How do I give it an icon?
There doesn't seem to be any build flags to do this, and I know golang doesn't support resources.
答案1
得分: 41
你可以使用类似akavel/rsrc的工具来生成一个包含指定资源的.syso文件,这些资源被嵌入到.rsrc
部分中,用于在构建Win32可执行文件时由Go链接器使用。
以lxn/walk应用程序为例,它在可执行文件中嵌入了其他元数据。
rsrc [-manifest FILE.exe.manifest] [-ico FILE.ico[,FILE2.ico...]] -o FILE.syso
-ico=""
:要嵌入的.ico文件的逗号分隔路径列表
这与将二进制数据嵌入到Go程序中不同。
对于这个,可以使用jteeuwen/go-bindata。
> 要访问资源数据,我们使用生成的输出中包含的Asset(string) []byte
函数。
data := Asset("pub/style/foo.css")
if len(data) == 0 {
// 未找到资源。
}
// 使用资源数据
更新于2021年:如John N的答案中所述,你还可以使用:
> 一个简单的命令行工具,用于在使用Go构建的Windows可执行文件中嵌入常规资源:
>
> - 一个清单
> - 一个应用程序图标
> - 版本信息(文件属性中的详细信息选项卡)
> - 其他图标和光标
它也可以作为库使用。
英文:
You can use a tool like akavel/rsrc in order to generate a .syso file with specified resources embedded in .rsrc
section, aimed for consumption by Go linker when building Win32 excecutables.
See as an example the lxn/walk application, which embeds other metadata in its executable.
rsrc [-manifest FILE.exe.manifest] [-ico FILE.ico[,FILE2.ico...]] -o FILE.syso
-ico=""
: comma-separated list of paths to .ico files to embed
This differs from embedding binary data into a go program.
For that, use jteeuwen/go-bindata.
> To access asset data, we use the Asset(string) []byte
function which is included in the generated output.
data := Asset("pub/style/foo.css")
if len(data) == 0 {
// Asset was not found.
}
// use asset data
Update 2021: as noted in John N's answer, you can also use:
> A simple command line tool for embedding usual resources in Windows executables built with Go:
>
> - A manifest
> - An application icon
> - Version information (the Details tab in file properties)
> - Other icons and cursors
It can be used as a library too.
答案2
得分: 10
主题是长时间,实际上mingw
只是一个要求,我们不需要第三方依赖。此外,资源文件*.rc
对于Win32可执行应用程序是必需的。最后,你可以在rc-demo中找到演示。
1)使用Chocolatey安装mingw:choco install mingw
2)创建main.exe.manifest
文件
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity
version="1.0.0.0"
processorArchitecture="x86"
name="controls"
type="win32"
/>
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="*"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>
</assembly>
3)创建main.rc
文件
100 ICON "main.ico"
100 24 "main.exe.manifest"
101 RCDATA "content.zip"
4)构建
在git-bash窗口执行以下命令:
windres -o main-res.syso main.rc && go build -i
英文:
The topic is long time, in fact mingw
is only requirement, we don't need 3rd party dependency. In addition, resource file *.rc
is mandatory for win32 executable application. At last, you can find the demo in rc-demo
-
Install mingw using Chocolatey:
choco install mingw
-
Create
main.exe.manifest
file<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity
version="1.0.0.0"
processorArchitecture="x86"
name="controls"
type="win32"
/>
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture=""
publicKeyToken="6595b64144ccf1df"
language=""
/>
</dependentAssembly>
</dependency>
</assembly> -
Create
main.rc
file100 ICON "main.ico"
100 24 "main.exe.manifest"
101 RCDATA "content.zip" -
Build
In git-bash windows perform the following command:
windres -o main-res.syso main.rc && go build -i
1: https://gitlab.com/gozoo/rc-demo "demo"
答案3
得分: 5
以上的答案都对我没用。我唯一能够将ico嵌入到GO exe中的方法是使用Resource Hacker。
- 安装并打开Resource Hacker。
- 在Resource Hacker中打开编译后的exe文件。
- 选择操作 > 添加图像或其他二进制资源。
- 选择ICO文件 > 添加资源。
- 保存并关闭。
如果需要将其添加到构建脚本中,你也可以直接从命令行运行。
ResourceHacker -open main.exe -save output.exe -action addskip -res main.ico -mask ICONGROUP,MAIN,
英文:
None of the above answers worked for me. The only way I could get an ico embedded into a GO exe was with Resource Hacker.
http://www.angusj.com/resourcehacker/
- Install and open Resource Hacker
- Open compiled exe in Resource Hacker
- Action > Add an image or other binary resource
- Select ICO > Add Resource
- Save and Close
You can also run it directly from the command line if you need to add it to your build scripts.
ResourceHacker -open main.exe -save output.exe -action addskip -res main.ico -mask ICONGROUP,MAIN,
答案4
得分: 3
有一个由Joseph Spurrier创建的GitHub包GoVersionInfo:
> 用于Go语言的Microsoft Windows文件属性/版本信息和图标资源生成器
>
> 该包创建一个包含Microsoft Windows版本信息和可选图标的syso文件。当你运行"go build"时,Go语言将在可执行文件中嵌入版本信息、可选图标和可选清单。如果syso文件与main()函数在同一个目录中,Go语言将自动使用该syso文件。
英文:
There is a github package GoVersionInfo by Joseph Spurrier:
> Microsoft Windows File Properties/Version Info and Icon Resource Generator for the Go Language
>
> Package creates a syso file which contains Microsoft Windows Version Information and an optional icon. When you run "go build", Go will embed the version information and an optional icon and an optional manifest in the executable. Go will automatically use the syso file if it's in the same directory as the main() function.
答案5
得分: 2
这对我来说很有效。
去获取 github.com/akavel/rsrc
rsrc -ico YOUR_ICON_FILE_NAME.ico
go build
英文:
This worked out for me
go get github.com/akavel/rsrc
rsrc -ico YOUR_ICON_FILE_NAME.ico
go build
答案6
得分: 2
这个很好用:
go install github.com/tc-hib/go-winres@latest
go-winres simply --icon youricon.png
go build
如果你的应用有图形界面:
go-winres simply --icon icon.png --manifest gui
英文:
This works well:
go install github.com/tc-hib/go-winres@latest
go-winres simply --icon youricon.png
go build
If your app has a GUI:
go-winres simply --icon icon.png --manifest gui
答案7
得分: 1
我为了满足我的需求深入研究了这个问题,但是John N和Coconut提到的简单方法并没有按预期工作。
经过更深入的研究,我找出了问题所在,并分享出来,希望对其他人有用。
- syso文件需要是应用程序使用的一个包的一部分。
- 当存在用于构建的
cmd/main.go
文件时,syso文件不能放在项目的根目录中。 - 当构建
cmd/main.go
文件时,syso文件不能放在应用程序的主包中(即将syso放在cmd
下面不会起作用)。
以下是对我有效的几个示例:
扁平项目结构
...\test1
│ go.mod
│ main.go
│ rsrc.syso
其中go.mod文件内容为:
module test1
go 1.19
main.go文件内容为:
package main
import (
"fmt"
)
func main() {
fmt.Println("test1")
}
然后运行go build
命令,会按预期创建test1.exe
。
空包
将syso文件放在一个新的包文件夹中,并创建一个空文件与包名相同,使用_
强制导入该包。
...\test2
│ go.mod
│
├───cmd
│ main.go
│
└───rsrc
rsrc.go
rsrc.syso
其中go.mod文件内容为:
module test2
go 1.19
rsrc.go文件内容为:
package rsrc
main.go文件内容为:
package main
import (
"fmt"
_ "test2/rsrc"
)
func main() {
fmt.Println("test2")
}
然后运行go build -o test2.exe cmd\main.go
命令,会按预期创建test2.exe
。
借用现有包
将syso文件放在项目应用程序已经使用的一个包文件夹中(注意:不同的应用程序如果使用了该包,将会有相同的syso文件)。
...\test3
│ go.mod
│
├───cmd
│ main.go
│
└───other
other.go
rsrc.syso
其中go.mod文件内容为:
module test3
go 1.19
other.go文件内容为:
package other
func Foo() string {
return "bar"
}
main.go文件内容为:
package main
import (
"fmt"
"test3/other"
)
func main() {
fmt.Println("test3")
fmt.Println(other.Foo())
}
然后运行go build -o test3.exe cmd\main.go
命令,会按预期创建test3.exe
。
使用Docker构建流程
基于借用现有包的Docker化构建
因为,嘿,其他人可能也需要这个...<br>
使用arch参数将其设置为适当的ARCH,如果你有多平台/架构的构建流程。
...
ARG TARGETARCH
ARG TARGETOS
RUN go install github.com/tc-hib/go-winres@latest
RUN go-winres simply --icon images/icon.png --out other/rsrc --arch ${TARGETARCH}
...
GOOS=${TARGETOS} GOARCH=${TARGETARCH} go build -o test3.exe cmd/main.go
...
希望这对那些遇到困难的人有所帮助。
英文:
I delved into this issue for my requirements and the simple methods mentioned by John N and Coconut did not work as expected.
After more delving i figure out what was the problem and I share it so it might be useful for others.
- the syso file need to be part of a package used by the application.
- the syso file cant be placed in the root of the project when there is a
cmd/main.go
file used for the build. - the syso file cant be placed in the main package of your application (i.e. placing the syso under
cmd
when buildingcmd/main.go
file wont make it).
couple examples that worked for me:
flat project structure
...\test1
│ go.mod
│ main.go
│ rsrc.syso
where go.mod
module test1
go 1.19
and main.go
package main
import (
"fmt"
)
func main() {
fmt.Println("test1")
}
then go build
created test1.exe
as expected
empty package
put syso file in a new folder package and create empty file with the package name, force import this package using _
...\test2
│ go.mod
│
├───cmd
│ main.go
│
└───rsrc
rsrc.go
rsrc.syso
where go.mod
module test2
go 1.19
rsrc.go
package rsrc
and main.go
package main
import (
"fmt"
_ "test2/rsrc"
)
func main() {
fmt.Println("test2")
}
then go build -o test2.exe cmd\main.go
created test2.exe
as expected
piggyback on existing package
place the syso file in a folder package that already used by the project app (Note: that different apps would have the same syso in case they use that package)
...\test3
│ go.mod
│
├───cmd
│ main.go
│
└───other
other.go
rsrc.syso
where go.mod
module test3
go 1.19
other.go
package other
func Foo() string {
return "bar"
}
and main.go
package main
import (
"fmt"
"test3/other"
)
func main() {
fmt.Println("test3")
fmt.Println(other.Foo())
}
then go build -o test3.exe cmd\main.go
created test3.exe
as expected
using docker build flow
Dockerized build based on piggybacking on existing package
because, hey someone else probably needs this as well....<br>
use the arch to set it to the proper ARCH if you have multi platform/architecture build flow
...
ARG TARGETARCH
ARG TARGETOS
RUN go install github.com/tc-hib/go-winres@latest
RUN go-winres simply --icon images/icon.png --out other/rsrc --arch ${TARGETARCH}
...
GOOS=${TARGETOS} GOARCH=${TARGETARCH} go build -o test3.exe cmd/main.go
...
hope this helps anyone who got stuck
答案8
得分: 0
你可以首先了解setIcon()
方法,它只允许使用byte[]
格式。所以你需要先创建图像,然后将其转换为byte[]
格式。按照以下步骤进行操作:
// 使用os.Open()定义图标路径
iconFile, err := os.Open("/home/user/image/icon.png")
if err != nil {
log.Fatal(err)
}
defer iconFile.Close()
// 使用png.Decode()将图像路径转换为图像
img, err := png.Decode(iconFile)
if err != nil {
log.Fatal(err)
}
// 然后使用bytes.Buffer将图像转换为byte[]格式
buf := new(bytes.Buffer)
err1 := jpeg.Encode(buf, img, nil)
_ = err1
// 将转换后的byte[]保存到变量中
img_buf := buf.Bytes()
// 使用systray.SetTemplateIcon()方法设置转换后的byte[]图标
systray.SetTemplateIcon(img_buf, img_buf)
谢谢!
英文:
you ant change a icon first think you know setIcon() method
it only alow byte[]
format so you first create image and convert into byte[]. so do following procedure.
// define icon path using os.Open()
iconFile, err := os.Open("/home/user/image/icon.png")
if err != nil {
log.Fatal(err)
}
defer iconFile.Close()
// png.Decode() to convert image path to image
img, err := png.Decode(iconFile)
if err != nil {
log.Fatal(err)
}
// Then convert the image to byte[] format using bytes.Buffer
buf := new(bytes.Buffer)
err1 := jpeg.Encode(buf, img, nil)
_ = err1
// save the converted byte[] to variable
img_buf := buf.Bytes()
// set the coverted byte[] icon using systray.SetTemplateIcon() method
systray.SetTemplateIcon(img_buf, img_buf)
Thank you!!!
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论