【问题标题】:How to embed an icon in a PowerShell GUI executable?如何在 PowerShell GUI 可执行文件中嵌入图标?
【发布时间】:2018-11-19 14:13:29
【问题描述】:

我创建了一个 powershell gui,我想在我的 windows.form 中插入一个图标。
我是这样做的,我用 ps2exe 生成了一个 exe 文件。

Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.Application]::EnableVisualStyles()

#region begin GUI{ 

$Form                            = New-Object system.Windows.Forms.Form
$Form.ClientSize                 = '400,230'
$Form.text                       = "Test"
$Form.TopMost                    = $false
$Icon                            = New-Object system.drawing.icon (".\icon\test.ico")
$Form.Icon                       = $Icon

如果我将带有图标 test.ico 的 dir 图标与我的 exe 一起使用,一切都会很好,但现在我会将图标合并到我的代码中,而不必将图标目录与我的 exe 一起带来。

有可能吗?如果有,怎么做?

【问题讨论】:

    标签: powershell


    【解决方案1】:

    您可以使用 base64 编码图像在代码中嵌入图形信息,如下所示:

    Add-Type -AssemblyName System.Windows.Forms
    [System.Windows.Forms.Application]::EnableVisualStyles()
    
    $Form            = New-Object system.Windows.Forms.Form
    $Form.ClientSize = '400,230'
    $Form.text       = "Test"
    $Form.TopMost    = $false
    
    # This base64 string holds the bytes that make up the orange 'G' icon (just an example for a 32x32 pixel image)
    $iconBase64      = 'iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAZdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuMTnU1rJkAAAB50lEQVRIS7WWzytEURTHZ2FhaWFhYWFhYWFhaWFh6c+wsGCapJBJU0hRSrOgLBVSmkQoSpqyUJISapIFJU0i1KQp1PG9826vO9+Z97Pr22dz3pxzv/PO/fUSkvxfOLYOx9bh2DocBzPZKlPtku2VuS7JtMlwIydUw7EnGO50Rd4ehPRdlru87GWUMZVU4LgOqLza0cP56PdHNga4NthgsUc+i3qIQOH9qDzAYLZTyiVd7Ah/8/lGztclNyLbY5JfksKxeuiKRvAzwOy93OsyR+9Pam6HajLHm5UfXhTQT34GqDH1eCGjTZxjkmqQmQ5+6Gdgth5NQLsoIRwca7AoTZ1k1UM0p7Y/QXCsof4sdOvRrRlgeZgyu49eY/0cTDO76ShzcJnTQ0O0NvA2XioWqjIrcKy5PdQ1kLl90CKsVC9F2GiYVVPuiQaDiRb1TzGWw9eHzoEiGGwO6hpHWFRe04vuu4pggCPIFPwowSWmAXa/qdKr5zaOaQBwyps6W+UEh/gGtasFlrjCKC2+ATia15WucHpf76vna/2ylVLntnmeRzbApsUQ4RXZwAFnAC7eMMLNSrWhDEC6RfUac1D3+sRew87HhVzvC4PjYLBecRxhDsByn/qEoYRqOLYOx9bh2DocWyaZ+APgBBKhVfsHwAAAAABJRU5ErkJggg=='
    $iconBytes       = [Convert]::FromBase64String($iconBase64)
    # initialize a Memory stream holding the bytes
    $stream          = [System.IO.MemoryStream]::new($iconBytes, 0, $iconBytes.Length)
    $Form.Icon       = [System.Drawing.Icon]::FromHandle(([System.Drawing.Bitmap]::new($stream).GetHIcon()))
    
    # PowerShell versions older than 5.0 use this:
    # $stream        = New-Object IO.MemoryStream($iconBytes, 0, $iconBytes.Length)
    # $Form.Icon     = [System.Drawing.Icon]::FromHandle((New-Object System.Drawing.Bitmap -Argument $stream).GetHIcon())
    
    [void]$Form.ShowDialog()
    
    # when done, dispose of the stream and form
    $stream.Dispose()
    $Form.Dispose()
    

    要将您自己的图像转换为 base64 字符串,有很多在线转换器,例如 this one

    反过来(将base64图像数据转换回图形图像)他们也有一个here的页面

    当然你也可以使用 Powershell 进行 Base64 的转换:

    [Convert]::ToBase64String((Get-Content ".\icon\test.ico" -Encoding Byte))
    

    【讨论】:

    • 为什么要声明 $iconImage 却不在任何地方使用它?它应该被使用吗?
    • 有什么理由我们不需要在最后调用 $stream.Dispose() 吗?还是会与表格一起处理?如果没有 $Stream.Write() 行,它似乎也可以正常工作 - 这是做什么的?
    • @SteveTaylor 你说得对。现在改变了(自从我发布这个答案以来已经很久了)。我还更新了对 .Net 对象使用 ::new() 构造函数,并注释掉了旧 PowerShell 版本的 New-Object 方法。
    猜你喜欢
    • 2011-01-08
    • 1970-01-01
    • 2011-03-29
    • 2014-03-11
    • 1970-01-01
    • 2011-11-09
    • 1970-01-01
    相关资源
    最近更新 更多