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