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

时间:2018-01-17 20:58:48

标签: powershell dll

我正在使用powershell构建一个小实用程序,并花了很多时间教我自己使用PowerShell构建窗体和控件。为了使我的部署占用空间小,我使用第三方实用程序将所有图形图标( .ico)和图像( .bmp)打包在动态链接库(* .dll)中(greenfish图标编辑亲,我强烈推荐)。 我现在遇到的问题是我无法加载程序集,因为生成的* .dll缺少清单。我已经搜索了所有但无法找到关于如何在不使用add-type cmdlet加载* .dll的情况下访问资源的任何简明答案。

1 个答案:

答案 0 :(得分:0)

我能够在this post from Kazun的答案中找到一种从dll加载图标的方法。然后利用technet,我能够在dll中找到一个相应的入口点,用于提取位图的方法。请参阅下面的kludged together脚本,该脚本结合了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:\SomePath\Some.dll", "LOGO")
$myIcon = [System.IconExtractor]::Extract("C:\SomePath\Some.dll", 1, $true)