🌎

Goで作ったWindowsアプリのアイコン埋め込みはgo-winresが良さげな件

2024/12/15に公開

序論

以前WindowsのパッケージマネージャーであるScoop[1]のアップデートからキャッシュ削除までを一括で実施してくれる自作ツールについて紹介いたしました。

https://zenn.dev/yuta28/articles/windows-scoopupdate-go-lang

このアプリはGoで作成したツールですが、特にアイコンとかを意識せずビルドしたのでWindows標準アイコンのままツールが作成されました。


ちょっと味気ない

デザイン自体は生成AIとかで適当に作ってもいいので何かアイコンを設定したいなと思い色々調べてみましたが、GNU Binutils[2]の中にwindresというWindowsリソースを操作できるツールを見つけました。

https://web.sfc.wide.ad.jp/~sagawa/gnujdoc/binutils-2.14/binutils-ja_12.html

windresは画像ファイルをアプリケーションに埋め込むことができるリソースファイル(.res)[3]へ変換してくれるツールです。
ただリソースファイルへ変換するためにリソーススクリプトファイル(.rc)というものが必要で、C++の知識もある程度ないとトラブルシューティングも難しく私には使い込ませんでした。

もう少しシンプルなツールがないものか悩みましたが、go-winresというGoでビルドされたアプリケーションにアイコンを埋め込めるだけの機能を持ったシンプルなツールを見つけ、簡単にアイコンを設定できましたので今回はこのgo-winresというツールについて紹介いたします。

対象読者

  • WindowsアプリをGoで作っている人
  • Windows実行ファイルにアイコンを設定したい人

go-winresについて

https://github.com/tc-hib/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

winres.json
{
  "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.sysorsrc_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_versionproduct_versionでバージョン管理できるプロパティがあります。
Goの機能にあるgo generate[4]を使って作業中のGitタグをプロダクトバージョンに埋め込むことで作業中のGit情報を基にプロダクトバージョンと紐づけられます。

https://github.com/Yuhta28/Scoop-update-to-cleanup/blob/main/scoop-update-to-cleanup.go#L1-L12

所感

Goで作られたWindowsアプリに簡単にアイコンを埋め込んでくれるgo-winresについて紹介いたしました。
最初にwindresを使ってアイコン埋め込みを試みましたが、リソーススクリプトファイルやリソースファイルの理解が足りず、うまく埋め込みできなくて困っていたのでシンプルな代替ツールを見つけることができて良かったです。
皆さんも自作のGo製のWindowsアプリに好きなアイコンを入れたい要望が出てきましたらぜひ使ってみてください。

参考文献

https://zenn.dev/yusei_wy/articles/853ac3f909edb4

脚注
  1. https://scoop.sh/ ↩︎

  2. https://www.gnu.org/software/binutils/ ↩︎

  3. https://learn.microsoft.com/ja-jp/cpp/windows/resource-files-visual-studio?view=msvc-170 ↩︎

  4. https://go.dev/blog/generate ↩︎

GitHubで編集を提案

Discussion