【问题标题】:Extract Bitmap from DLL for use in PowerShell Script从 DLL 中提取位图以在 PowerShell 脚本中使用
【发布时间】:2018-01-18 04:58:48
【问题描述】:

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

【问题讨论】:

    标签: powershell dll


    【解决方案1】:

    在this post from 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:\SomePath\Some.dll", "LOGO")
    $myIcon = [System.IconExtractor]::Extract("C:\SomePath\Some.dll", 1, $true)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-02-11
      • 1970-01-01
      • 2019-12-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多