Command line tool for adding Windows resources to executable files

go-winres

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

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

Usage

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

Typical usage would be:

  • Run go-winres init to create a winres directory
  • Modify the contents of winres.json
  • Before go build, run go-winres make

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:

  • go-winres simply is a simpler make that does not rely on a json file.
  • go-winres extract extracts resources from an exe file or a dll.
  • go-winres patch replaces resources directly in an exe file or a dll. For example, to enhance a 7z self extracting archive, you may change its icon, and add a manifest to make it look better on high DPI screens.

JSON format

The JSON file follows this hierarchy:

  • Resource type (e.g. "RT_GROUP_ICON" or "#42" or "MY_TYPE")
    • Resource name (e.g. "MY_ICON" or "#1")
      • Language ID (e.g. "0409" for en-US)
        • Actual resource: a filename or a json structure

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:

  • "APP"
  • "OTHER"
  • 42

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.

  • "APP" is made of 4 png files.
  • "OTHER" will be generated from one png file. It will be resized to 256x256, 64x64, 48x48, 32x32, and 16x16.
  • 42 is a native icon, it probably already contains several images.

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

  • "0409" means en-US, which is the default.
  • "040C" means fr-FR.

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:

  • "ARROW" contains two images (one for higher DPI). It is a json array.
  • "MOVE" uses cur files directly. It is different in French. It is a string.
  • 1 contains one image. It is an object.

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":
  • "" (default)
  • "highest": elevates to the highest level available to the current user
  • "administrator": require the user to be an administrator and elevate to this level
Values for "minimum-os":
  • "vista"
  • "win7" (default)
  • "win8"
  • "win8.1"
  • "win10"
Values for "dpi-awareness":
  • "unaware"
  • "system" (default)
  • "per monitor"
  • "per monitor v2" (recommended)

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:

  • Multilingual resources
  • Multilingual VersionInfo that works in Windows Explorer
  • Explicitly named resources, by ID or by string (so you can use them in runtime)
  • Extracting resources from exe or dll files
  • Replacing resources in exe or dll files
  • Simplified VersionInfo definition
  • Simplified manifest definition
  • Support for custom information in VersionInfo
  • Making an icon or a cursor from a PNG file
  • Embedding custom resources

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:

  • ACCELERATORS
  • DIALOGEX
  • MENUEX
  • POPUP

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

  • rc.exe and cvtres.exe from Visual Studio
  • windres from GNU Binary Utilities
  • llvm-rc and llvm-cvtres from LLVM tools

See Resource Compiler for more information.

Thanks

Many thanks to akavel for his help.

This project uses these very helpful libs:

Comments
  • How to add an icon for task bar?

    How to add an icon for task bar?

    Hi, I use go-winres in own Go Qt UI project. I added an icon for the app, and the icon display anywhere but task bar. How to fix that? If create lnk file for binary file, the icon will be display. But if run binary directly the icon will not be display. My res config for icon:

    "RT_GROUP_ICON": {
        "APP": {
          "0000": [
            "icon.png",
            "icon.png",
            "icon.png",
            "icon.png"
          ]
        },
        "#42": {
          "0409": "icon.ico",
          "040C": "icon.ico"
        },
        "MAINICON": {
          "0409": "icon.ico"
        },
        "OTHER": {
          "0000": "icon.ico"
        }
      }
    

    Result:

    Безымянный111

  • Large icon view not using 256px png

    Large icon view not using 256px png

    Hi,

    Love this project and how easy it makes embedding Windows resources.

    I might be hitting some really obscure Windows bug, but for some reason my 256px icon embedded with go-winres is not being displayed at full resolution (ie. when using (Extra) Large icons in Explorer).

    You can see the comparisons with go-winres here in Explorer using Extra Large icons: Capture

    My winres/ folder here: https://github.com/optix2000/totsugeki/tree/v0.2.0/winres Running Windows 10.0.19043.1110

    I've even tried adding all the "required" sizes (16px, 32px, 48px, 256px) to no avail. https://github.com/optix2000/totsugeki/tree/16xicon/winres

    Is there some limitation or option that needs to be set for the 256px icon to be used at full resolution?

  • support for rsrc_windows_arm64.syso

    support for rsrc_windows_arm64.syso

  • fix(init subCommand): permission denied when on Unix platform

    fix(init subCommand): permission denied when on Unix platform

    I tried to run go-winres init on my Mac, however, it just kept telling me:

    ❯ go-winres init
    2022/11/10 15:34:29 open winres/winres.json: permission denied
    ❯ ls -alh .
    total 120
    drwxr-xr-x  18 kmahyyg  staff   576B Nov 10 15:25 .
    drwxr-xr-x   7 kmahyyg  staff   224B Oct 15 19:47 ..
    -rw-r--r--@  1 kmahyyg  staff   6.0K Oct 27 12:50 .DS_Store
    drwxr-xr-x  16 kmahyyg  staff   512B Nov 10 15:34 .git
    -rw-r--r--   1 kmahyyg  staff   4.2K Oct 28 20:03 .gitignore
    -rw-r--r--   1 kmahyyg  staff   154B Oct 31 14:16 .gitmodules
    drwxr-xr-x   8 kmahyyg  staff   256B Nov 10 15:29 .idea
    <REDACTED HERE>
    drw-r--r--   5 kmahyyg  staff   160B Nov 10 15:34 winres
    

    Then I just realized what went wrong. On unix platform, folder default permission should be 755, files should have 644. (You will not like any others write your own files, right?) Since Windows doesn't use the same method for access control, 755 and 644 will work on Windows platform too.

    So this PR will allow more user to run this develop their apps on MacOS / Linux without effecting any existing users.

  • git-tag not working with simply

    git-tag not working with simply

    Hi, I've just installed your tool with "go get github.com/tc-hib/go-winres@latest". I'm trying to generate resources with "simply" command this way:

    go-winres simply --product-version=git-tag --file-version=git-tag --file-description="MKey process" --icon=winres/#1_0409.ico

    But when I compile de .exe file, It takes correctly the file description and ico but it shows "git-tag" texts as Product Version and "0.0.0.0" as File-Version.

    If I generate the res file with go-winres make --product-version=git-tag --file-version=git-tag it works fine. What could I be doing wrong with the Simply command?

  • Provide more verbose error on failed git tag resolution

    Provide more verbose error on failed git tag resolution

    The error when doing this in a shallow clone is simply "exit 128", which makes it very difficult to determine that the problem is the lack of git tag data. This change just makes that error more clear.

Watcher - A simple command line app to watch files in a directory for changes and run a command when files change!

Watcher - Develop your programs easily Watcher watches all the files present in the directory it is run from of the directory that is specified while

Mar 27, 2022
mlp is a comman line tool responsible for creating, updating and deleting kubernetes resources based on files generated by Mia-Platform Console.

mlp is a comman line tool responsible for creating, updating and deleting kubernetes resources based on files generated by Mia-Platform Console.

Apr 28, 2022
An open-source GitLab command line tool bringing GitLab's cool features to your command line
An open-source GitLab command line tool bringing GitLab's cool features to your command line

GLab is an open source GitLab CLI tool bringing GitLab to your terminal next to where you are already working with git and your code without switching

Dec 30, 2022
A command line tool to prompt for a value to be included in another command line.

readval is a command line tool which is designed for one specific purpose—to prompt for a value to be included in another command line. readval prints

Dec 22, 2021
Command-line tool to customize the official Spotify client. Supports Windows, MacOS and Linux.
Command-line tool to customize the official Spotify client. Supports Windows, MacOS and Linux.

Command-line tool to customize the official Spotify client. Supports Windows, MacOS and Linux. Features Change colors whole UI Inject CSS for advanced

Jan 2, 2023
This command line converts .webarchive file to resources embed .html file

webarchive-to-singlefile This command line converts Safari's .webarchive file to complete .html. Notice Only tested on MacOS. Google Chrome required.

Dec 30, 2022
go-editor is the clean go module that refractors from Kubernetes to help you edit resources in a command-line way.

go-editor The source code of go-editor comes from Kubernetes and refractor as the clean Go module. You can embed go-editor in your command-line tool l

Dec 5, 2021
donLoader is a shellcode loader creation tool that uses donut to convert executable payloads into shellcode to evade detection on disk.

donLoader WARNING: This is WIP, barely anything was tested properly. Use at your own risk. Description donLoader is a shellcode loader creation tool t

Sep 20, 2022
Command-line tool to load csv and excel (xlsx) files and run sql commands
Command-line tool to load csv and excel (xlsx) files and run sql commands

csv-sql supports loading and saving results as CSV and XLSX files with data processing with SQLite compatible sql commands including joins.

Nov 2, 2022
Command line tool makeing working with remote files esier.

Command line tool makeing working with remote files esier.

Jul 27, 2022
mass-binding-target is a command line tool for generating binding target list by search plot files from disk.

mass-binding-target mass-binding-target is a command line tool for generating binding target list by search plot files from disk. Build Go 1.13 or new

Nov 5, 2021
Command-line tool to organize large directories of media files recursively by date, detecting duplicates.

go-media-organizer Command-line tool written in Go to organise all media files in a directory recursively by date, detecting duplicates.

Jan 6, 2022
F2 is a cross-platform command-line tool for batch renaming files and directories quickly and safely. Written in Go!
F2 is a cross-platform command-line tool for batch renaming files and directories quickly and safely. Written in Go!

F2 is a cross-platform command-line tool for batch renaming files and directories quickly and safely.

Dec 31, 2022
A simple single-file executable to pull a git-ssh repository and serve the web app found to a self-contained browser window

go-git-serve A simple single-file executable to pull a git-ssh repository (using go-git library) and serve the web app found to a self-contained brows

Jan 19, 2022
git-xargs is a command-line tool (CLI) for making updates across multiple Github repositories with a single command.
git-xargs is a command-line tool (CLI) for making updates across multiple Github repositories with a single command.

Table of contents Introduction Reference Contributing Introduction Overview git-xargs is a command-line tool (CLI) for making updates across multiple

Dec 31, 2022
git-xargs is a command-line tool (CLI) for making updates across multiple GitHub repositories with a single command
git-xargs is a command-line tool (CLI) for making updates across multiple GitHub repositories with a single command

git-xargs is a command-line tool (CLI) for making updates across multiple GitHub repositories with a single command. You give git-xargs:

Feb 5, 2022
A command line tool for simplified docker volume command built with go

dockervol A command line tool for simplified docker volume command built with go. Features: Remove anonymous volume (beta) Remove volume by matching n

Dec 18, 2021
fofax is a fofa query tool written in go, positioned as a command-line tool and characterized by simplicity and speed.
fofax is a fofa query tool written in go, positioned as a command-line tool and characterized by simplicity and speed.

fofaX 0x00 Introduction fofax is a fofa query tool written in go, positioned as

Jan 8, 2023
Go package to make lightweight ASCII line graph ╭┈╯ in command line apps with no other dependencies.
Go package to make lightweight ASCII line graph ╭┈╯ in command line apps with no other dependencies.

asciigraph Go package to make lightweight ASCII line graphs ╭┈╯. Installation go get github.com/guptarohit/asciigraph Usage Basic graph package main

Jan 8, 2023