tc-hib / go-winres

Command line tool for adding Windows resources to executable files
BSD Zero Clause License
319 stars 16 forks source link
golang icon manifest rsrc windows

go-winres

A simple command line tool for embedding usual resources in Windows executables built with Go:

You might want to directly use winres as a library too: github.com/tc-hib/winres

Installation

To install the go-winres command, run:

go install github.com/tc-hib/go-winres@latest

Usage

Please type go-winres help to get a list of commands and options.

Typical usage would be:

go-winres make creates files named rsrc_windows_*.syso that go build automatically embeds in the executable.

The suffix _windows_amd64 is very important. Thanks to it, go build knows it should not include that object in a Linux or 386 build.

Automatic version from git

The --file-version and --product-version flags can take a special value: git-tag. This will retrieve the current tag with git describe --tags and add it to the file properties of the executable.

Using go generate

You can use a //go:generate comment as well:

//go:generate go-winres make --product-version=git-tag

Subcommands

There are other subcommands:

JSON format

The JSON file follows this hierarchy:

Standard resource types can be found there. But please never use RT_ICON or RT_CURSOR. Use RT_GROUP_ICON and RT_GROUP_CURSOR instead.

Icon JSON

{
  "RT_GROUP_ICON": {
    "APP": {
      "0000": [
        "icon_64.png",
        "icon_48.png",
        "icon_32.png",
        "icon_16.png"
      ]
    },
    "OTHER": {
      "0000": "icon.png"
    },
    "#42": {
      "0409": "icon_EN.ico",
      "040C": "icon_FR.ico"
    }
  }
}

This example contains 3 icons:

Windows Explorer will display "APP" because it is the first one. Icons are sorted by name in case sensitive ascending order, then by ID.

42 is an ID, not a name, this is why it comes last.

Finally, 42 will display a different icon for french users.

You can find other language IDs there.

Cursor JSON

{
  "RT_GROUP_CURSOR": {
    "ARROW": {
      "0000": [
        {
          "image": "arrow_32.png",
          "x": 28,
          "y": 4
        },
        {
          "image": "arrow_48.png",
          "x": 40,
          "y": 6
        }
      ]
    },
    "MOVE": {
      "0409": "move_EN.cur",
      "040C": "move_FR.cur"
    },
    "#1": {
      "0000": {
        "image": "cross.png",
        "x": 16,
        "y": 16
      }
    }
  }
}

This example contains 3 cursors:

When a cursor is made with a png file, you have to provide the coordinates of the "hot spot", that is, the pixel that clicks.

Manifest

The manifest should be defined as resource 1 with language 0409.

As a JSON object

{
  "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
      }
    }
  }
}

All boolean values default to false.

It is recommended to omit identity if your program is a plain application, not meant to be a side-by-side dependency.

Values for "execution-level":
Values for "minimum-os":
Values for "dpi-awareness":

As an XML file

{
  "RT_MANIFEST": {
    "#1": {
      "0409": "my_manifest.xml"
    }
  }
}

VersionInfo JSON

Here is an example JSON file containing every standard info field, a French translation, and every possible flag. "0409" and "040C" are language code identifiers (LCID) for en-US and fr-FR respectively.

{
  "RT_VERSION": {
    "#1": {
      "0000": {
        "fixed": {
          "file_version": "1.2.3.4",
          "product_version": "1.2.3.42",
          "flags": "Debug,Prerelease,Patched,PrivateBuild,SpecialBuild",
          "timestamp": "2020-12-18T23:00:00+01:00"
        },
        "info": {
          "0409": {
            "Comments": "Comments",
            "CompanyName": "Company",
            "FileDescription": "A description",
            "FileVersion": "1.2.3.4",
            "InternalName": "",
            "LegalCopyright": "© You",
            "LegalTrademarks": "",
            "OriginalFilename": "X.EXE",
            "PrivateBuild": "",
            "ProductName": "Product",
            "ProductVersion": "1.2.3.42 beta",
            "SpecialBuild": ""
          },
          "040C": {
            "Comments": "Commentaire",
            "CompanyName": "Compagnie",
            "FileDescription": "Une description",
            "FileVersion": "1.2.3.4",
            "InternalName": "",
            "LegalCopyright": "© Vous",
            "LegalTrademarks": "",
            "OriginalFilename": "X.EXE",
            "PrivateBuild": "",
            "ProductName": "Produit",
            "ProductVersion": "1.2.3.42 bêta",
            "SpecialBuild": ""
          }
        }
      }
    }
  }
}

Alternatives

This project is similar to akavel/rsrc and josephspurrier/goversioninfo.

Additional features are:

It might be closer to Microsoft specifications too.

Limitations

go-winres is not a real resource compiler, which means it won't help you embed these UI templates:

If you ever need them, you can use one of those tools instead:

See Resource Compiler for more information.

Thanks

Many thanks to akavel for his help.

This project uses these very helpful libs: