Goで作ったWindowsアプリのアイコン埋め込みはgo-winresが良さげな件
序論
以前WindowsのパッケージマネージャーであるScoop[1]のアップデートからキャッシュ削除までを一括で実施してくれる自作ツールについて紹介いたしました。
このアプリはGoで作成したツールですが、特にアイコンとかを意識せずビルドしたのでWindows標準アイコンのままツールが作成されました。
ちょっと味気ない
デザイン自体は生成AIとかで適当に作ってもいいので何かアイコンを設定したいなと思い色々調べてみましたが、GNU Binutils[2]の中にwindresというWindowsリソースを操作できるツールを見つけました。
windresは画像ファイルをアプリケーションに埋め込むことができるリソースファイル(.res)[3]へ変換してくれるツールです。
ただリソースファイルへ変換するためにリソーススクリプトファイル(.rc)というものが必要で、C++の知識もある程度ないとトラブルシューティングも難しく私には使い込ませんでした。
もう少しシンプルなツールがないものか悩みましたが、go-winresというGoでビルドされたアプリケーションにアイコンを埋め込めるだけの機能を持ったシンプルなツールを見つけ、簡単にアイコンを設定できましたので今回はこのgo-winresというツールについて紹介いたします。
対象読者
- WindowsアプリをGoで作っている人
- Windows実行ファイルにアイコンを設定したい人
go-winresについて
go-winresはGoでビルドされたWindows実行ファイルにリソースを埋め込んでくれるシンプルなCLIベースのツールとなります。
go install github.com/tc-hib/go-winres@latest
使い方
まずはじめにビルド対象となるGoファイルが配置されているフォルダ上でgo-winres init
を実行しwinresフォルダを作成します。
$ go-winres init
Created winres/winres.json
$ ls
Mode LastWriteTime Length Name
---- ------------- ------ ----
d---- 2024/12/11 1:16 winres #winresフォルダが作成される
-a--- 2024/11/13 1:19 499 .gitignore
-a--- 2024/11/13 1:19 361 go.mod
-a--- 2024/11/13 1:19 1853 go.sum
-a--- 2024/11/13 1:19 1084 LICENSE
-a--- 2024/11/13 1:19 198 README.md
-a--- 2024/11/13 1:19 2171 scoop-update-to-cleanup.go
このwinres
フォルダの中にはgo-winresの初期アイコン2つとリソースを定義するJSONファイルが含まれています。
256x256のicon.png
32x32のicon16.png
{
"RT_GROUP_ICON": {
"APP": {
"0000": [
"icon.png",
"icon16.png"
]
}
},
"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
}
}
},
"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": ""
}
}
}
}
}
}
このフォルダの中にアプリのアイコンに使う画像ファイルをセットします。
icon16.pngを置き換え
次にgo-winres make
を実行するとrsrc_windows_386.syso
とrsrc_windows_amd64.syso
というファイルが生成されます。
$ go-winres make
$ ls
Mode LastWriteTime Length Name
---- ------------- ------ ----
d---- 2024/12/11 9:28 winres
-a--- 2024/11/13 1:19 499 .gitignore
-a--- 2024/11/13 1:19 361 go.mod
-a--- 2024/11/13 1:19 1853 go.sum
-a--- 2024/11/13 1:19 1084 LICENSE
-a--- 2024/11/13 1:19 198 README.md
-a--- 2024/12/11 9:29 13020 rsrc_windows_386.syso
-a--- 2024/12/11 9:29 13020 rsrc_windows_amd64.syso
-a--- 2024/11/13 1:19 2171 scoop-update-to-cleanup.go
この状態でGoファイルをビルド(go build .
)しますとWindows実行ファイルにはwinresフォルダに配置した画像ファイルをベースにしたアイコンが埋め込まれてます。
応用編
winres.json
ファイルの中にfile_version
やproduct_version
でバージョン管理できるプロパティがあります。
Goの機能にあるgo generate
[4]を使って作業中のGitタグをプロダクトバージョンに埋め込むことで作業中のGit情報を基にプロダクトバージョンと紐づけられます。
所感
Goで作られたWindowsアプリに簡単にアイコンを埋め込んでくれるgo-winresについて紹介いたしました。
最初にwindresを使ってアイコン埋め込みを試みましたが、リソーススクリプトファイルやリソースファイルの理解が足りず、うまく埋め込みできなくて困っていたのでシンプルな代替ツールを見つけることができて良かったです。
皆さんも自作のGo製のWindowsアプリに好きなアイコンを入れたい要望が出てきましたらぜひ使ってみてください。
参考文献
Discussion