从 DLL 中提取位图以在 PowerShell 脚本中使用



我正在使用Powershell构建一个小实用程序,并且花了很多时间自学如何使用Powershell构建Windows窗体和控件。 为了使我的部署占用空间较小,我使用第三方实用程序(绿鱼图标编辑器专业版,我强烈推荐(将所有图形图标(.ico(和图像(.bmp(打包到动态链接库(*.dll(中。我现在遇到的问题是我无法加载程序集,因为生成的 *.dll 缺少清单。我已经搜索了所有内容,但找不到有关如何在不使用添加类型 cmdlet 加载 *.dll的情况下访问资源的任何简洁答案。

我能够在 Kazun 对这篇文章的回答中找到一种从 dll 加载图标的方法。 然后利用 technet,我能够在 dll 中找到提取位图的方法的相应入口点。 请参阅下面的脚本,该脚本结合了IconExtractor和我新创建的BitmapExtractor类。

$code = @"
using System;
using System.Drawing;
using System.Runtime.InteropServices;
namespace System {
    public class IconExtractor  { #Credit to Kazun from https://social.technet.microsoft.com/Forums/windows/en-US/16444c7a-ad61-44a7-8c6f-b8d619381a27/using-icons-in-powershell-scripts?forum=winserverpowershell
        public static Icon Extract(string file, int number, bool largeIcon) {
            IntPtr large;
            IntPtr small;
            ExtractIconEx(file, number, out large, out small, 1);
            try {
                return Icon.FromHandle(largeIcon ? large : small);
            } catch {
                return null;
            }
        }
        [DllImport("Shell32.dll", EntryPoint = "ExtractIconExW", CharSet = CharSet.Unicode, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
        private static extern int ExtractIconEx(string sFile, int iIndex, out IntPtr piLargeVersion, out IntPtr piSmallVersion, int amountIcons);
    }
    public class BitmapExtractor { #Credit to Chad Estes (chadwestes@gmail.com)
        public static Bitmap Extract(string file, string resourceID) {
            IntPtr hModule = LoadLibraryEx(file,IntPtr.Zero,0x00000020);
            Bitmap bmp = null;
            IntPtr hBitmap = IntPtr.Zero;
            try {
                if (hModule != IntPtr.Zero) {
                    hBitmap = LoadBitmap(hModule, resourceID);
                    if (hBitmap != IntPtr.Zero) {
                        bmp = Bitmap.FromHbitmap(hBitmap);
                    }
                }
            } catch {
                bmp = null;
            } finally {
                DeleteObject(hBitmap);
                FreeLibrary(hModule);
            }
            return bmp;
        }
        [DllImport("kernel32.dll", SetLastError = true)]
        static extern IntPtr LoadLibraryEx(string lpFileName, IntPtr hReservedNull, uint dwFlags);
        [DllImport("kernel32.dll", SetLastError=true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool FreeLibrary(IntPtr hModule);
        [DllImport("user32.dll")]
        static extern IntPtr LoadBitmap(IntPtr hInstance, string lpBitmapName);
        [DllImport("gdi32.dll", EntryPoint="DeleteObject", CharSet = CharSet.Unicode, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
        private static extern bool DeleteObject(IntPtr hBitmap);
    }
}
"@
Add-Type -TypeDefinition $code -ReferencedAssemblies System.Drawing
$myImage = [System.BitmapExtractor]::Extract("C:SomePathSome.dll", "LOGO")
$myIcon = [System.IconExtractor]::Extract("C:SomePathSome.dll", 1, $true)

最新更新