using Autodesk.AutoCAD.Runtime;
using System;
using System.IO;
using System.Runtime.InteropServices;
// This line is not mandatory, but improves loading performances
[assembly: CommandClass(typeof(GetIconFromAcadXMX.MyCommands))]
namespace GetIconFromAcadXMX
{
static class NativeResourceManager
{
public const uint LOAD_LIBRARY_AS_DATAFILE = 0x00000002;
public const uint LOAD_LIBRARY_AS_IMAGE_RESOURCE = 0x00000020;
public static IntPtr RC_RCDATA = (IntPtr)((UInt16)10);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr LoadLibraryEx(string lpFileName, IntPtr hFile, uint dwFlags);
[DllImport("Kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr LoadLibrary(string lpFileName);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr FindResource(IntPtr hModule, string lpName, IntPtr lpType);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr LoadResource(IntPtr hModule, IntPtr hResInfo);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr LockResource(IntPtr hResData);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern uint SizeofResource(IntPtr hModule, IntPtr hResInfo);
public static MemoryStream GetIcon(string lpFileName, string lpName, IntPtr lpType)
{
IntPtr hModule = LoadLibraryEx(lpFileName, IntPtr.Zero,
LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE);
if (hModule == IntPtr.Zero) return null;
IntPtr hResource = FindResource(hModule, lpName, lpType);
if (hResource == IntPtr.Zero) return null;
uint resSize = SizeofResource(hModule, hResource);
IntPtr resData = LoadResource(hModule, hResource);
if (resData == IntPtr.Zero) return null;
byte[] uiBytes = new byte[resSize];
IntPtr ipMemorySource = LockResource(resData);
Marshal.Copy(ipMemorySource, uiBytes, 0, (int)resSize);
return new MemoryStream(uiBytes);
}
public static void SaveIcon(string lpFileName, string lpName, IntPtr lpType, string toFolder)
{
using (MemoryStream ico = GetIcon(lpFileName, lpName, lpType)) {
if (ico == null) return;
using (FileStream file = File.Create(Path.Combine(toFolder, lpName) + ".ico"))
file.Write(ico.ToArray(),0, (int)ico.Length);
}
}
}
public class MyCommands
{
[CommandMethod("IconTest")]
public static void IconTestCommand()
{
NativeResourceManager.SaveIcon(@"c:\Program Files\Autodesk\AutoCAD 2021\acadbtn.xmx",
"RCDATA_16_2DOPTIM",
NativeResourceManager.RC_RCDATA,
@"Z:\test"
);
}
}
}