Documentation ¶
Overview ¶
Package winres provides functions to create a resource section for Windows executables. This is where the application's icon, manifest, and version information are stored.
Basic usage ¶
Create an empty ResourceSet, call the Set method to add resources to it and then use the WriteObject method to produce an object file.
Each resource must be named, so it can later be accessed with FindResource, LoadImage, etc. To name a resource, you may use an int that you cast to winres.ID, or a string that you cast to winres.Name.
rs := winres.ResourceSet{} rs.Set(winres.RT_RCDATA, winres.Name("MYDATA"), 0, 0, []byte("some data")) rs.WriteObject(someFile, winres.ArchAMD64) rs.WriteObject(anotherFile, winres.ArchI386)
Embedding resources in a Go built application ¶
winres produces a linkable COFF object. Save it in your project's root directory with extension “syso” and it will be automatically included by “go build”.
It is recommended to name this object with target suffixes, so that the “go build” command automatically links the proper object for each target.
For example:
rsrc_windows_amd64.syso rsrc_windows_386.syso
Example ¶
Embedding an icon, version information, and a manifest:
import ( "image" "log" "os" "github.com/tc-hib/winres" "github.com/tc-hib/winres/version" ) func main() { // First create an empty resource set rs := winres.ResourceSet{} // Make an icon group from a png file f, err := os.Open("icon.png") if err != nil { log.Fatalln(err) } defer f.Close() img, _, err := image.Decode(f) if err != nil { log.Fatalln(err) } f.Close() icon, _ := winres.NewIconFromResizedImage(img, nil) // Add the icon to the resource set, as "APPICON" rs.SetIcon(winres.Name("APPICON"), icon) // Make a VersionInfo structure vi := version.Info{ FileVersion: [4]uint16{1, 0, 0, 0}, ProductVersion: [4]uint16{1, 0, 0, 1}, } vi.Set(0, version.ProductName, "A Windows Application") vi.Set(0, version.ProductVersion, "v1.0.0.1") // Add the VersionInfo to the resource set rs.SetVersionInfo(vi) // Add a manifest rs.SetManifest(winres.AppManifest{ ExecutionLevel: RequireAdministrator, DPIAwareness: DPIPerMonitorV2, UseCommonControlsV6: true, }) // Create an object file for amd64 out, err := os.Create("rsrc_windows_amd64.syso") defer out.Close() if err != nil { log.Fatalln(err) } err = rs.WriteObject(out, winres.ArchAMD64) if err != nil { log.Fatalln(err) } }
Localization ¶
You can provide different resources depending on the user's langage.
To do so, you should provide a language code identifier (LCID) to the Set method.
A list of LCIDs is available there: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-lcid/
As an example, the LCID for en-US is 0x0409.
Other functions ¶
winres can do a few more things: extract resources from an executable, replace resources in an executable, export cursors or icons...
Index ¶
- Constants
- Variables
- func ForceCheckSum() exeOption
- func IsSignedEXE(exe io.ReadSeeker) (bool, error)
- func WithAuthenticode(handling authenticodeHandling) exeOption
- type AppManifest
- type Arch
- type AssemblyIdentity
- type Cursor
- type CursorImage
- type DPIAwareness
- type ExecutionLevel
- type HotSpot
- type ID
- type Icon
- type Identifier
- type Name
- type ResourceSet
- func (rs *ResourceSet) Count() int
- func (rs *ResourceSet) Get(typeID, resID Identifier, langID uint16) []byte
- func (rs *ResourceSet) GetCursor(resID Identifier) (*Cursor, error)
- func (rs *ResourceSet) GetCursorTranslation(resID Identifier, langID uint16) (*Cursor, error)
- func (rs *ResourceSet) GetIcon(resID Identifier) (*Icon, error)
- func (rs *ResourceSet) GetIconTranslation(resID Identifier, langID uint16) (*Icon, error)
- func (rs *ResourceSet) Set(typeID, resID Identifier, langID uint16, data []byte) error
- func (rs *ResourceSet) SetCursor(resID Identifier, cursor *Cursor) error
- func (rs *ResourceSet) SetCursorTranslation(resID Identifier, langID uint16, cursor *Cursor) error
- func (rs *ResourceSet) SetIcon(resID Identifier, icon *Icon) error
- func (rs *ResourceSet) SetIconTranslation(resID Identifier, langID uint16, icon *Icon) error
- func (rs *ResourceSet) SetManifest(manifest AppManifest)
- func (rs *ResourceSet) SetVersionInfo(vi version.Info)
- func (rs *ResourceSet) Walk(f func(typeID, resID Identifier, langID uint16, data []byte) bool)
- func (rs *ResourceSet) WalkType(typeID Identifier, f func(resID Identifier, langID uint16, data []byte) bool)
- func (rs *ResourceSet) WriteObject(w io.Writer, arch Arch) error
- func (rs *ResourceSet) WriteToEXE(dst io.Writer, src io.ReadSeeker, opt ...exeOption) error
- type SupportedOS
Constants ¶
const ( // ErrorIfSigned means winres won't patch a signed executable. ErrorIfSigned authenticodeHandling = 0 // RemoveSignature means winres will patch a signed executable, // and remove the signature. RemoveSignature authenticodeHandling = 1 // IgnoreSignature means winres will patch a signed executable, // and leave the now invalid signature as is. IgnoreSignature authenticodeHandling = 2 )
const ( LCIDNeutral = 0 LCIDDefault = 0x409 // en-US is default )
Variables ¶
var DefaultIconSizes = []int{256, 64, 48, 32, 16}
var ErrNoResources = errors.New(errNoRSRC)
ErrNoResources is the error returned by LoadFromEXE when it didn't find a .rsrc section.
var ErrSignedPE = errors.New(errSignedPE)
ErrSignedPE is the error returned by WriteToEXE when it refused to touch signed code. (Authenticode)
Functions ¶
func ForceCheckSum ¶
func ForceCheckSum() exeOption
ForceCheckSum forces updating the PE checksum, even when the original file didn't have one
func IsSignedEXE ¶
func IsSignedEXE(exe io.ReadSeeker) (bool, error)
IsSignedEXE helps knowing if an exe file is signed before encountering an error with WriteToEXE.
func WithAuthenticode ¶
func WithAuthenticode(handling authenticodeHandling) exeOption
WithAuthenticode allows patching signed executables, either by removing the signature or by ignoring it (and making it wrong)
Types ¶
type AppManifest ¶
type AppManifest struct { Identity AssemblyIdentity `json:"identity"` Description string `json:"description"` Compatibility SupportedOS `json:"minimum-os"` ExecutionLevel ExecutionLevel `json:"execution-level"` UIAccess bool `json:"ui-access"` // Require access to other applications' UI elements AutoElevate bool `json:"auto-elevate"` DPIAwareness DPIAwareness `json:"dpi-awareness"` DisableTheming bool `json:"disable-theming"` DisableWindowFiltering bool `json:"disable-window-filtering"` HighResolutionScrollingAware bool `json:"high-resolution-scrolling-aware"` UltraHighResolutionScrollingAware bool `json:"ultra-high-resolution-scrolling-aware"` LongPathAware bool `json:"long-path-aware"` PrinterDriverIsolation bool `json:"printer-driver-isolation"` GDIScaling bool `json:"gdi-scaling"` SegmentHeap bool `json:"segment-heap"` UseCommonControlsV6 bool `json:"use-common-controls-v6"` // Application requires Common Controls V6 (V5 remains the default) }
AppManifest describes an application manifest.
Its zero value corresponds to the most common case.
func AppManifestFromXML ¶
func AppManifestFromXML(data []byte) (AppManifest, error)
AppManifestFromXML makes an AppManifest from an xml manifest, trying to retrieve as much valid information as possible.
If the xml contains other data, they are ignored.
This function can only return xml syntax errors, other errors are ignored.
type Arch ¶
type Arch string
Arch defines the target architecture. Its value can be used as a target suffix too: "rsrc_windows_"+string(arch)+".syso"
type AssemblyIdentity ¶
AssemblyIdentity defines the side-by-side assembly identity of the executable.
It should not be needed unless another assembly depends on this one.
If the Name field is empty, the <assemblyIdentity> element will be omitted.
func (AssemblyIdentity) MarshalJSON ¶
func (ai AssemblyIdentity) MarshalJSON() ([]byte, error)
func (*AssemblyIdentity) UnmarshalJSON ¶
func (ai *AssemblyIdentity) UnmarshalJSON(b []byte) error
type Cursor ¶
type Cursor struct {
// contains filtered or unexported fields
}
Cursor describes a mouse cursor.
This structure must only be created by constructors: NewCursorFromImages, LoadCUR
func LoadCUR ¶
func LoadCUR(cur io.ReadSeeker) (*Cursor, error)
LoadCUR loads a CUR file and returns a cursor, ready to embed in a resource set.
func NewCursorFromImages ¶
func NewCursorFromImages(images []CursorImage) (*Cursor, error)
NewCursorFromImages makes a cursor from a list of images and hot spots.
type CursorImage ¶
CursorImage defines an image to import into a cursor.
It is an Image with hot spot coordinates.
type DPIAwareness ¶
type DPIAwareness int
DPIAwareness is an enumeration which corresponds to the <dpiAware> and the <dpiAwareness> elements.
When it is set to DPIPerMonitorV2, it will fallback to DPIAware if the OS does not support it.
DPIPerMonitor would not scale windows on secondary monitors.
const ( DPIAware DPIAwareness = iota DPIUnaware DPIPerMonitor DPIPerMonitorV2 )
func (DPIAwareness) MarshalText ¶
func (a DPIAwareness) MarshalText() ([]byte, error)
func (*DPIAwareness) UnmarshalText ¶
func (a *DPIAwareness) UnmarshalText(b []byte) error
type ExecutionLevel ¶
type ExecutionLevel int
ExecutionLevel is used in an AppManifest to set the required execution level.
const ( AsInvoker ExecutionLevel = iota HighestAvailable RequireAdministrator )
func (ExecutionLevel) MarshalText ¶
func (level ExecutionLevel) MarshalText() ([]byte, error)
func (*ExecutionLevel) UnmarshalText ¶
func (level *ExecutionLevel) UnmarshalText(b []byte) error
type ID ¶
type ID uint16
ID is the type of a resource id, or resource type id.
const ( RT_CURSOR ID = 1 RT_BITMAP ID = 2 RT_ICON ID = 3 RT_MENU ID = 4 RT_DIALOG ID = 5 RT_STRING ID = 6 RT_FONTDIR ID = 7 RT_FONT ID = 8 RT_ACCELERATOR ID = 9 RT_RCDATA ID = 10 RT_MESSAGETABLE ID = 11 RT_GROUP_CURSOR ID = 12 RT_GROUP_ICON ID = 14 RT_VERSION ID = 16 RT_PLUGPLAY ID = 19 RT_VXD ID = 20 RT_ANICURSOR ID = 21 RT_ANIICON ID = 22 RT_HTML ID = 23 RT_MANIFEST ID = 24 )
Standard type IDs from https://docs.microsoft.com/en-us/windows/win32/menurc/resource-types
type Icon ¶
type Icon struct {
// contains filtered or unexported fields
}
Icon describes a Windows icon.
This structure must only be created by constructors: NewIconFromImages, NewIconFromResizedImage, LoadICO
func LoadICO ¶
func LoadICO(ico io.ReadSeeker) (*Icon, error)
LoadICO loads an ICO file and returns an icon, ready to embed in a resource set.
func NewIconFromImages ¶
NewIconFromImages makes an icon from a list of images.
This converts every image to 32bpp PNG.
func NewIconFromResizedImage ¶
NewIconFromResizedImage makes an icon from a single Image by resizing it.
If sizes is nil, the icon will be resized to: 256px, 64px, 48px, 32px, 16px.
type Identifier ¶
type Identifier interface {
// contains filtered or unexported methods
}
Identifier is either an ID or a Name.
When you are asked for an Identifier, you can pass an int cast to an ID or a string cast to a Name.
type ResourceSet ¶
type ResourceSet struct {
// contains filtered or unexported fields
}
ResourceSet is the main object in the package.
Create an empty ResourceSet and call Set methods to add resources, then WriteObject to produce a COFF object file.
func LoadFromEXE ¶
func LoadFromEXE(exe io.ReadSeeker) (*ResourceSet, error)
LoadFromEXE loads the .rsrc section of the executable and returns a ResourceSet
func LoadFromEXESingleType ¶
func LoadFromEXESingleType(exe io.ReadSeeker, typeID Identifier) (*ResourceSet, error)
LoadFromEXESingleType loads the .rsrc section of the executable and returns a ResourceSet containing only resources of one type.
func (*ResourceSet) Count ¶
func (rs *ResourceSet) Count() int
Count returns the number of resources in the set.
func (*ResourceSet) Get ¶
func (rs *ResourceSet) Get(typeID, resID Identifier, langID uint16) []byte
Get returns resource data.
Returns nil if the resource was not found.
func (*ResourceSet) GetCursor ¶
func (rs *ResourceSet) GetCursor(resID Identifier) (*Cursor, error)
GetCursor extracts a cursor from a resource set.
func (*ResourceSet) GetCursorTranslation ¶
func (rs *ResourceSet) GetCursorTranslation(resID Identifier, langID uint16) (*Cursor, error)
GetCursorTranslation extracts a cursor from a specific language of the resource set.
func (*ResourceSet) GetIcon ¶
func (rs *ResourceSet) GetIcon(resID Identifier) (*Icon, error)
GetIcon extracts an icon from a resource set.
func (*ResourceSet) GetIconTranslation ¶
func (rs *ResourceSet) GetIconTranslation(resID Identifier, langID uint16) (*Icon, error)
GetIconTranslation extracts an icon from a specific language of the resource set.
func (*ResourceSet) Set ¶
func (rs *ResourceSet) Set(typeID, resID Identifier, langID uint16, data []byte) error
Set adds or replaces a resource.
typeID is the resource type's identifier. It can be either a standard type number (RT_ICON, RT_VERSION, ...) or any type name.
resID is the resource's unique identifier for a given type. It can either be an ID starting from 1, or a Name.
A resource ID can have different data depending on the user's locale. In this case Set can be called several times with the same resID but a different language ID.
langID can be 0 (neutral), or one of those LCID: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-lcid
Warning: the ResourceSet takes ownership of the data parameter. The caller should not write into it anymore after calling this method.
func (*ResourceSet) SetCursor ¶
func (rs *ResourceSet) SetCursor(resID Identifier, cursor *Cursor) error
SetCursor adds the cursor to the resource set.
func (*ResourceSet) SetCursorTranslation ¶
func (rs *ResourceSet) SetCursorTranslation(resID Identifier, langID uint16, cursor *Cursor) error
SetCursorTranslation adds the cursor to a specific language in the resource set.
func (*ResourceSet) SetIcon ¶
func (rs *ResourceSet) SetIcon(resID Identifier, icon *Icon) error
SetIcon adds the icon to the resource set.
The first icon will be the application's icon, as shown in Windows Explorer. That means:
- First name in case-sensitive ascending order, or else...
- First ID in ascending order
func (*ResourceSet) SetIconTranslation ¶
func (rs *ResourceSet) SetIconTranslation(resID Identifier, langID uint16, icon *Icon) error
SetIconTranslation adds the icon to a specific language in the resource set.
The first icon will be the application's icon, as shown in Windows Explorer. That means:
- First name in case-sensitive ascending order, or else...
- First ID in ascending order
func (*ResourceSet) SetManifest ¶
func (rs *ResourceSet) SetManifest(manifest AppManifest)
SetManifest is a simplified way to embed a typical application manifest, without writing xml directly.
func (*ResourceSet) SetVersionInfo ¶
func (rs *ResourceSet) SetVersionInfo(vi version.Info)
SetVersionInfo sets the VersionInfo structure.
This what Windows displays in the Details tab of file properties.
func (*ResourceSet) Walk ¶
func (rs *ResourceSet) Walk(f func(typeID, resID Identifier, langID uint16, data []byte) bool)
Walk walks through the resources in same order as they will be written.
It takes a callback function that takes same parameters as Set and returns a bool that should be true to continue, false to stop.
If you modify the set during a call to Walk, behaviour is undefined.
func (*ResourceSet) WalkType ¶
func (rs *ResourceSet) WalkType(typeID Identifier, f func(resID Identifier, langID uint16, data []byte) bool)
WalkType walks through the resources or a certain type, in same order as they will be written.
It takes a callback function that takes same parameters as Set and returns a bool that should be true to continue, false to stop.
If you modify the set during a call to Walk, behaviour is undefined.
func (*ResourceSet) WriteObject ¶
func (rs *ResourceSet) WriteObject(w io.Writer, arch Arch) error
WriteObject writes a full object file into w.
func (*ResourceSet) WriteToEXE ¶
func (rs *ResourceSet) WriteToEXE(dst io.Writer, src io.ReadSeeker, opt ...exeOption) error
WriteToEXE patches an executable to replace its resources with this ResourceSet.
It reads the original file from src and writes the new file to dst.
src and dst should not point to a same file/buffer.
Options:
ForceCheckSum() // Forces updating the checksum even when it was not set in the original file WithAuthenticode(<how>) // Allows updating the .rsrc section despite the file being signed
type SupportedOS ¶
type SupportedOS int
SupportedOS is an enumeration that provides a simplified way to fill the compatibility element in an application manifest, by only setting a minimum OS.
Its zero value is Win7AndAbove, which matches Go's requirements.
https://github.com/golang/go/wiki/MinimumRequirements#windows
const ( WinVistaAndAbove SupportedOS = iota - 1 Win7AndAbove Win8AndAbove Win81AndAbove Win10AndAbove )
func (SupportedOS) MarshalText ¶
func (os SupportedOS) MarshalText() ([]byte, error)
func (*SupportedOS) UnmarshalText ¶
func (os *SupportedOS) UnmarshalText(b []byte) error