【问题标题】:Changing title bar icon in Powershell script with embedded XAML GUI使用嵌入式 XAML GUI 更改 Powershell 脚本中的标题栏图标
【发布时间】:2020-01-12 05:37:41
【问题描述】:

这是我的第一篇文章。我正在使用用于 GUI 的嵌入式 XAML 代码在 Powershell 中编写脚本启动器应用程序。 XAML 在 Visual Studio 中粗略制作,然后导出到 Powershell 并手动调整。简单且可维护,但我一直在尝试更改应用程序的标题栏图标。更改图标是内部品牌需求。

通用 Powershell 图标确实出现在我的应用程序的标题栏中。而且我想我已经尝试调整本网站和其他地方提到的每一种 XAML 和代码隐藏技术来安装我自己的 ICO 图标。没有喜悦。有些需要使用 Visual Studio,我希望不要再使用了。最简单的建议 XAML 路由似乎是添加这样的一行...

Icon="MyFavicon.ico"

...在下面测试平台的标题行下方。但这会引发此错误:

Exception calling "Load" with "1" argument(s): "Failed to create a 'Icon' from the text 'StribLogoFavicon.ico'."
At M:\Scripting\Saxophone\Test\trivial_xaml_and_ps_for_icon_troubleshooting_v18.ps1:26 char:2
+     $Window = [Windows.Markup.XamlReader]::Load($Reader)
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : XamlParseException

You cannot call a method on a null-valued expression.
At M:\Scripting\Saxophone\Test\trivial_xaml_and_ps_for_icon_troubleshooting_v18.ps1:28 char:1
+ $Window.ShowDialog()
+ ~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull

FWIW,相同的 ICO 文件以前在该项目的 HTA 版本的标题栏中工作。我还尝试了第二个 ICO 文件。

ICO 文件的位置对于我的部署而言并不重要。我尝试编写脚本的根文件夹和子文件夹。

这是我的项目的骨架。任何人都可以提出解决方案吗?也许我们可以使用这个测试平台来记录一个易于确认的测试平台。谢谢!

#Trivial pared-down app GUI for icon troubleshooting
    Add-Type -AssemblyName presentationframework, presentationcore, windowsbase
    #Begin XAML code for GUI
    [xml]$xaml = @"
    <Window
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            x:Name="Demo_WPF_Window"
            Title="How to change icon at left?" Height="150" Width="320" WindowStyle="SingleBorderWindow" Background="#FFECBD5A" ResizeMode="NoResize"
    >
        <Grid x:Name="Grid">
            <Grid Margin="18,64,0,18">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="25*"/>
                <ColumnDefinition Width="126*"/>
                <ColumnDefinition Width="6*"/>
            </Grid.ColumnDefinitions>
        </Grid>
        <Label x:Name="Label_Icon_testbed" Content="Icon is ICO file in same folder as PS1 script" HorizontalAlignment="Left" Height="45" Margin="19,10,0,0" VerticalAlignment="Top" Width="240" FontSize="11" FontWeight="Bold" Grid.ColumnSpan="2"/>
    </Grid>
   </Window>
"@
#Prepare the GUI
    $Reader = New-Object System.Xml.XmlNodeReader $xaml
    $Window = [Windows.Markup.XamlReader]::Load($Reader)
#Render the GUI
    $Window.ShowDialog()

【问题讨论】:

    标签: powershell xaml icons


    【解决方案1】:

    我能够通过在 Window Loaded 事件中设置图标来添加一个图标:

    #region Load the Assemblies
    Add-Type -assemblyName PresentationFramework
    Add-Type -assemblyName PresentationCore
    Add-Type -assemblyName WindowsBase
    #endregion
    
    #region XAML
    [xml]$XAML = @"
    <Window
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="Testing" Height="200" Width="300" >
    
    </Window>
    "@
    #endregion XAML
    
    #Load the XAML and catch a failure
    $reader=(New-Object System.Xml.XmlNodeReader $xaml) 
    try{$Window=[Windows.Markup.XamlReader]::Load( $reader )}
    catch{Write-Host "Unable to load Windows.Markup.XamlReader. Some possible causes for this problem include: .NET Framework is missing PowerShell must be launched with PowerShell -sta, invalid XAML code was encountered."; exit}
    
    ##XAML Should have loaded NOW
    
    #Set all "Names" as Variables
    $xaml.SelectNodes("//*[@*[contains(translate(name(.),'n','N'),'Name')]]") | ForEach-Object{
        Set-Variable -Name ($_.Name) -Value $Window.FindName($_.Name)
    }
    
    #region EVENTS
    $Window.add_Loaded({
        $Window.Icon = "C:\Path\to\Icon.ico"
    })
    #endregion EVENTS
    
    
    ##Show the Window - Wrap ShowDialog in the Async Dispatcher to prevent powershell from crashing on second run
    $async = $window.Dispatcher.InvokeAsync({
        $window.ShowDialog() | Out-Null
    })
    $async.Wait() | Out-Null
    

    【讨论】:

      【解决方案2】:

      这是 Shamus 的有效答案——非常感谢! -- 与上面的testbed代码底部集成:

      $Reader = New-Object System.Xml.XmlNodeReader $xaml
      
      $Window = [Windows.Markup.XamlReader]::Load($Reader)
      
      
      $Window.add_Loaded({
          $Window.Icon = "C:\full\path\to\favicon.ico"
      })
      
      $Window.ShowDialog()
      

      【讨论】:

        猜你喜欢
        • 2018-03-10
        • 1970-01-01
        • 1970-01-01
        • 2019-04-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-12-20
        • 1970-01-01
        相关资源
        最近更新 更多