Ressy 1.0.0

There is a newer version of this package available.
See the version list below for details.
dotnet add package Ressy --version 1.0.0                
NuGet\Install-Package Ressy -Version 1.0.0                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Ressy" Version="1.0.0" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Ressy --version 1.0.0                
#r "nuget: Ressy, 1.0.0"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install Ressy as a Cake Addin
#addin nuget:?package=Ressy&version=1.0.0

// Install Ressy as a Cake Tool
#tool nuget:?package=Ressy&version=1.0.0                

Ressy

Build Coverage Version Downloads Discord Donate

Project status: active.

Ressy is a library for reading and writing native resources stored in portable executable images (i.e. EXE and DLL files). It offers a high-level abstraction model for working with resource functions provided by the Windows API.

⚠️ This library relies on Windows API and, as such, works only on Windows.

💬 If you want to chat, join my Discord server.

Download

📦 NuGet: dotnet add package Ressy

Usage

Ressy's functionality is provided entirely through the PortableExecutable class. You can create an instance of this class by passing a string that specifies the path to a PE file:

using Ressy;

var portableExecutable = new PortableExecutable("C:/Windows/System32/notepad.exe");

// ...

Reading resources

Enumerating identifiers

To get the list of resources in a PE file, use the GetResourceIdentifiers() method:

using Ressy;

var portableExecutable = new PortableExecutable("C:/Windows/System32/notepad.exe");

var identifiers = portableExecutable.GetResourceIdentifiers();

Returned list should contain:

- Type: 16 (RT_VERSION), Name: 1, Language: 1033
- Type: 24 (RT_MANIFEST), Name: 1, Language: 1033
- Type: 3 (RT_ICON), Name: 1, Language: 1033
- Type: 3 (RT_ICON), Name: 2, Language: 1033
- Type: 3 (RT_ICON), Name: 3, Language: 1033
- Type: 14 (RT_GROUP_ICON), Name: 2, Language: 1033
- Type: 4 (RT_MENU), Name: 1, Language: 1033
- Type: 5 (RT_DIALOG), Name: 1, Language: 1033
- Type: 5 (RT_DIALOG), Name: 2, Language: 1033
- Type: 5 (RT_DIALOG), Name: 3, Language: 1033
- Type: "EDPENLIGHTENEDAPPINFOID", Name: "MICROSOFTEDPENLIGHTENEDAPPINFO", Language: 1033
- Type: "EDPPERMISSIVEAPPINFOID", Name: "MICROSOFTEDPPERMISSIVEAPPINFO", Language: 1033
- Type: "MUI", Name: 1, Language: 1033
- ...
Retrieving data

To resolve a specific resource, you can call the GetResource(...) method. This returns an instance of the Resource class, which contains the resource data:

using Ressy;

var portableExecutable = new PortableExecutable("C:/Windows/System32/notepad.exe");

var resource = portableExecutable.GetResource(new ResourceIdentifier(
    ResourceType.Manifest,
    ResourceName.FromCode(1),
    new Language(1033)
));

var resourceData = resource.Data; // byte[]
var resourceString = resource.ReadAsString(Encoding.UTF8); // string

If you aren't sure if the requested resource exists in the PE file, you can also use the TryGetResource(...) method instead. It returns null in case the resource is missing:

using Ressy;

var portableExecutable = new PortableExecutable("C:/Windows/System32/notepad.exe");

var resource = portableExecutable.TryGetResource(new ResourceIdentifier(
    ResourceType.Manifest,
    ResourceName.FromCode(100),
    new Language(1033)
)); // resource is null

Modifying resources

Setting resource data

To add or overwrite a resource, call the SetResource(...) method:

using Ressy;

var portableExecutable = new PortableExecutable("C:/Windows/System32/notepad.exe");

portableExecutable.SetResource(
    new ResourceIdentifier(
        ResourceType.Manifest,
        ResourceName.FromCode(1),
        new Language(1033)
    ),
    new byte[] { 0x01, 0x02, 0x03 }
);
Removing a resource

To remove a resource, call the RemoveResource(...) method:

using Ressy;

var portableExecutable = new PortableExecutable("C:/Windows/System32/notepad.exe");

portableExecutable.RemoveResource(
    new ResourceIdentifier(
        ResourceType.Manifest,
        ResourceName.FromCode(1),
        new Language(1033)
    )
);

To remove all resources in a PE file, call the ClearResources() method:

using Ressy;

var portableExecutable = new PortableExecutable("C:/Windows/System32/notepad.exe");

portableExecutable.ClearResources();

High-level operations

Ressy provides extensions for PortableExecutable that enable you to directly read and manipulate known resources types, such as icons, manifests, versions, etc.

Manifest resources

A manifest resource (type 24) contains XML data that describes and identifies assemblies that an application should bind to at run time. It may also contain other information, such as application settings, requested execution level, and more.

To learn more about application manifests, see this article.

Reading the manifest

To read the manifest resource as an XML text string, call the GetManifest() extension method:

using Ressy;
using Ressy.HighLevel;

var portableExecutable = new PortableExecutable("C:/Windows/System32/notepad.exe");

var manifest = portableExecutable.GetManifest();
// -or-
// var manifest = portableExecutable.TryGetManifest();

💡 If there are multiple manifest resources, this method retrieves the one with the lowest ordinal name (ID), while giving preference to resources in the neutral language. If there are no matching resources, this method retrieves the first manifest resource it finds.

Setting the manifest

To add or overwrite a manifest resource, call the SetManifest(...) extension method:

using Ressy;
using Ressy.HighLevel;

var portableExecutable = new PortableExecutable("C:/Windows/System32/notepad.exe");

portableExecutable.SetManifest("<assembly>...</assembly>"); 
Removing the manifest

To remove all manifest resources, call the RemoveManifest() extension method:

using Ressy;
using Ressy.HighLevel;

var portableExecutable = new PortableExecutable("C:/Windows/System32/notepad.exe");

portableExecutable.RemoveManifest();
Icon resources

Icon resources (type 3) and icon group resources (type 14) are used by the operating system to visually identify an application in the shell and other places. Each portable executable file may contain multiple icon resources (usually in different sizes or color configurations), which are grouped together by the corresponding icon group resource.

Setting the icon

To add or overwrite icon resources based on an ICO file, call the SetIcon(...) extension method:

using Ressy;
using Ressy.HighLevel;

var portableExecutable = new PortableExecutable("C:/Windows/System32/notepad.exe");

portableExecutable.SetIcon("new_icon.ico");

⚠️ Calling this method does not remove existing icon and icon group resources, except for those that are overwritten directly. If you want to clean out redundant icon resources (e.g. if the previous icon group contained more icons), call the RemoveIcon() method first.

Additionally, you can also set the icon by passing a stream that contains ICO-formatted data:

using Ressy;
using Ressy.HighLevel;

var portableExecutable = new PortableExecutable("C:/Windows/System32/notepad.exe");

using var iconFileStream = File.Open("new_icon.ico");
portableExecutable.SetIcon(iconFileStream);
Removing the icon

To remove all icon and icon group resources, call the RemoveIcon() extension method:

using Ressy;
using Ressy.HighLevel;

var portableExecutable = new PortableExecutable("C:/Windows/System32/notepad.exe");

portableExecutable.RemoveIcon();
Version info resources

A version info resource (type 16) contains file's version numbers, compatibility flags, and arbitrary string attributes. Some of these attributes (such as, for example, ProductName and Copyright) are recognized by the operating system and may be displayed in some places.

Reading version info

To get the version info resource, call the GetVersionInfo() extension method. This returns a VersionInfo object that represents the deserialized binary data stored in the resource:

using Ressy;
using Ressy.HighLevel;

var portableExecutable = new PortableExecutable("C:/Windows/System32/notepad.exe");

var versionInfo = portableExecutable.GetVersionInfo();
// -or-
// var versionInfo = portableExecutable.TryGetVersionInfo();

Returned object should contain:

{
  "FileVersion": "10.0.19041.1",
  "ProductVersion": "10.0.19041.1",
  "FileFlags": "None",
  "FileOperatingSystem": "Windows32, WindowsNT",
  "FileType": "Application",
  "FileSubType": "Unknown",
  "AttributeTables": [
    {
      "Language": {
        "Id": 1033
      },
      "CodePage": {
        "Id": 1200
      },
      "Attributes": {
        "CompanyName": "Microsoft Corporation",
        "FileDescription": "Notepad",
        "FileVersion": "10.0.19041.1 (WinBuild.160101.0800)",
        "InternalName": "Notepad",
        "LegalCopyright": "© Microsoft Corporation. All rights reserved.",
        "OriginalFilename": "NOTEPAD.EXE.MUI",
        "ProductName": "Microsoft® Windows® Operating System",
        "ProductVersion": "10.0.19041.1"
      }
    }
  ]
}

💡 If there are multiple version info resources, this method retrieves the one with the lowest ordinal name (ID), while giving preference to resources in the neutral language. If there are no matching resources, this method retrieves the first version info resource it finds.

When working with version info resources that include multiple attribute tables (bound to different language and code page pairs), you can use the GetAttribute(...) method to query a specific attribute. This method searches through all attribute tables (while giving priority to tables in the neutral language) and returns the first matching value it finds:

// ...

var companyName = versionInfo.GetAttribute(VersionAttributeName.CompanyName); // Microsoft Corporation
// -or-
// var companyName = versionInfo.TryGetAttribute(VersionAttributeName.CompanyName);
Removing version info

To remove all version info resources, call the RemoveVersionInfo() extension method:

using Ressy;
using Ressy.HighLevel;

var portableExecutable = new PortableExecutable("C:/Windows/System32/notepad.exe");

portableExecutable.RemoveVersionInfo();
Setting version info

To add or overwrite a version info resource, call the SetVersionInfo(...) extension method. You can use the VersionInfoBuilder class to drastically simplify the creation of a new VersionInfo instance:

using Ressy;
using Ressy.HighLevel;

var portableExecutable = new PortableExecutable("C:/Windows/System32/notepad.exe");

var versionInfo = new VersionInfoBuilder()
    .SetFileVersion(new Version(1, 2, 3, 4))
    .SetProductVersion(new Version(1, 2, 3, 4))
    .SetFileType(FileType.Application)
    .SetAttribute(VersionAttributeName.FileDescription, "My new description")
    .SetAttribute(VersionAttributeName.CompanyName, "My new company")
    .SetAttribute("Custom Attribute", "My new value")
    .Build();

portableExecutable.SetVersionInfo(versionInfo);

You can also use an alternative overload of this method, which lets you selectively modify only a subset of properties in a version info resource, leaving the rest intact. Properties that are not provided are pulled from the existing version info resource or resolved to their default values in case the resource does not exist:

using Ressy;
using Ressy.HighLevel;

var portableExecutable = new PortableExecutable("C:/Windows/System32/notepad.exe");

portableExecutable.SetVersionInfo(v => v
    .SetFileVersion(new Version(1, 2, 3, 4))
    .SetAttribute("Custom Attribute", "My new value")
);

💡 When using the SetAttribute(...) method on VersionInfoBuilder, you can optionally specify the language and code page of the table that you want to add the attribute to. If you choose to omit these parameters, Ressy will set the attribute in all attribute tables. In case there are no existing attribute tables, this method creates a new one bound to the neutral language and Unicode code page.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 is compatible. 
.NET Framework net461 is compatible.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • .NETFramework 4.6.1

  • .NETStandard 2.0

    • No dependencies.
  • .NETStandard 2.1

    • No dependencies.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on Ressy:

Package Downloads
RPA.AtualizaDrivers

Package Description

GitHub repositories (3)

Showing the top 3 popular GitHub repositories that depend on Ressy:

Repository Stars
Abdelrhman-AK/WinPaletter
Advanced Windows Appearance Editor
INotGreen/SharpThief
一键提取exe的图标、嵌入图标、资源信息、版本信息、修改时间、数字签名,降低程序熵值
Tyrrrz/DotnetRuntimeBootstrapper
Bootstrapped framework-dependent deployment for .NET applications
Version Downloads Last updated
1.0.3 4,640 4/27/2023
1.0.0 7,023 11/25/2021