Skip to content

Instantly share code, notes, and snippets.

@Rottweiler
Last active June 13, 2020 09:10
Show Gist options
  • Save Rottweiler/583f12b4ed83001d020a7c46d902a882 to your computer and use it in GitHub Desktop.
Save Rottweiler/583f12b4ed83001d020a7c46d902a882 to your computer and use it in GitHub Desktop.
Win32ResourceManager - A native resource manager in a managed flavor
using System;
using System.ComponentModel;
using System.IO;
using System.Runtime.InteropServices;
/// <summary>
/// Win32ResourceManager - A native resource manager in a managed flavor
/// </summary>
internal class Win32ResourceManager
{
[DllImport("kernel32.dll")]
private static extern IntPtr LockResource(IntPtr hResData);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern IntPtr FindResource(IntPtr hModule, IntPtr lpName, IntPtr lpType);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern IntPtr FindResource(IntPtr hModule, uint lpName, uint lpType);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern IntPtr FindResource(IntPtr hModule, uint lpName, string lpType);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern IntPtr FindResource(IntPtr hModule, string lpName, uint lpType);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern IntPtr FindResource(IntPtr hModule, string lpName, string lpType);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern IntPtr LoadResource(IntPtr hModule, IntPtr hResInfo);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern IntPtr SizeofResource(IntPtr hModule, IntPtr hResInfo);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern IntPtr GetModuleHandle(string filename);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern IntPtr LoadLibrary(string filename);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern IntPtr FreeLibrary(IntPtr hModule);
public string FileName { get; set; }
public bool ThrowOnFail { get; set; }
private bool ShouldFree { get; set; }
public IntPtr Handle { get; set; }
public Win32ResourceManager(string filename)
{
FileName = Path.GetFullPath(filename);
Handle = GetModuleHandle(FileName);
if (Handle == IntPtr.Zero)
{
Handle = LoadLibrary(FileName);
if (Handle == IntPtr.Zero)
{
if(ThrowOnFail)
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
}
else
{
ShouldFree = true;
}
}
}
~Win32ResourceManager()
{
if (ShouldFree)
{
FreeLibrary(Handle);
}
}
private IntPtr LockResourceData(IntPtr hResData)
{
var handle = LockResource(hResData);
if (handle == IntPtr.Zero)
{
if (ThrowOnFail)
{
throw new ApplicationException("Could not get a pointer to the resource data.");
}
}
return handle;
}
private byte[] GetResource(IntPtr res)
{
var loaded = LoadResource(Handle, res);
if (loaded == IntPtr.Zero)
{
if (ThrowOnFail)
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
}
var size = SizeofResource(Handle, res).ToInt32();
var data = new byte[size];
try
{
Marshal.Copy(loaded, data, 0, size);
}
catch
{
if (ThrowOnFail)
{
throw;
}
}
return data;
}
public byte[] GetObject(string name)
{
return GetObject(name, ResourceType.RT_RCDATA);
}
public byte[] GetObject(IntPtr name, IntPtr type)
{
var res = FindResource(Handle, name, type);
return GetResource(res);
}
public byte[] GetObject(string name, string type)
{
var res = FindResource(Handle, name, type);
return GetResource(res);
}
public byte[] GetObject(uint name, uint type)
{
var res = FindResource(Handle, name, type);
return GetResource(res);
}
public byte[] GetObject(uint name, string type)
{
var res = FindResource(Handle, name, type);
return GetResource(res);
}
public byte[] GetObject(string name, uint type)
{
var res = FindResource(Handle, name, type);
return GetResource(res);
}
public byte[] GetObject(string name, ResourceType type)
{
var res = FindResource(Handle, name, (uint)type);
return GetResource(res);
}
public byte[] GetObject(uint name, ResourceType type)
{
var res = FindResource(Handle, name, (uint)type);
return GetResource(res);
}
}
internal enum ResourceType : uint
{
RT_ACCELERATOR = 9,
RT_ANICURSOR = 21,
RT_ANIICON = 22,
RT_BITMAP = 2,
RT_CURSOR = 1,
RT_DIALOG = 5,
RT_DLGINCLUDE = 17,
RT_DLGINIT = 240,
RT_TOOLBAR = 241,
RT_FONT = 8,
RT_FONTDIR = 7,
RT_GROUP_CURSOR = RT_CURSOR + 11,//12,
RT_GROUP_ICON = RT_ICON + 11,//14,
RT_HTML = 23,
RT_ICON = 3,
RT_MANIFEST = 24,
RT_MENU = 4,
RT_MESSAGETABLE = 11,
RT_PLUGPLAY = 19,
RT_RCDATA = 10,
RT_STRING = 6,
RT_VERSION = 16,
RT_VXD = 20
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment