需要帮助以使Powershell脚本具有消息框支持从右到左和多行

问题描述

我具有PowerShell脚本,需要使用消息框来提醒用户我正在使用此[System.Windows.Forms.MessageBox] :: Show(...),但不支持阿拉伯语和多行。 所以我找到了这个Powershell message box

我的问题是使下面的脚本支持多行并支持从右到左的语言,例如阿拉伯语。

    # PowerShell function to display a customizable WPF message Box / window
Function New-WPFMessageBox {

    # For examples for use,see my blog:
    # https://smsagent.wordpress.com/2017/08/24/a-customisable-wpf-messageBox-for-powershell/
    
    # CHANGES
    # 2017-09-11 - Added some required assemblies in the dynamic parameters to avoid errors when run from the PS console host.
    
    # Define Parameters
    [CmdletBinding()]
    Param
    (
        # The popup Content
        [Parameter(Mandatory=$True,Position=0)]
        [Object]$Content,# The window title
        [Parameter(Mandatory=$false,Position=1)]
        [string]$Title,# The buttons to add
        [Parameter(Mandatory=$false,Position=2)]
        [validateset('OK','OK-Cancel','Abort-Retry-Ignore','Yes-No-Cancel','Yes-No','Retry-Cancel','Cancel-TryAgain-Continue','None')]
        [array]$ButtonType = 'OK',Position=3)]
        [array]$CustomButtons,# Content font size
        [Parameter(Mandatory=$false,Position=4)]
        [int]$ContentFontSize = 14,# Title font size
        [Parameter(Mandatory=$false,Position=5)]
        [int]$TitleFontSize = 14,# BorderThickness
        [Parameter(Mandatory=$false,Position=6)]
        [int]$BorderThickness = 0,# CornerRadius
        [Parameter(Mandatory=$false,Position=7)]
        [int]$CornerRadius = 8,# ShadowDepth
        [Parameter(Mandatory=$false,Position=8)]
        [int]$ShadowDepth = 3,# BlurRadius
        [Parameter(Mandatory=$false,Position=9)]
        [int]$BlurRadius = 20,# WindowHost
        [Parameter(Mandatory=$false,Position=10)]
        [object]$WindowHost,# Timeout in seconds,[Parameter(Mandatory=$false,Position=11)]
        [int]$Timeout,# Code for Window Loaded event,Position=12)]
        [scriptblock]$OnLoaded,# Code for Window Closed event,Position=13)]
        [scriptblock]$OnClosed

    )

    # Dynamically Populated parameters
    DynamicParam {
        
        # Add assemblies for use in PS Console 
        Add-Type -AssemblyName System.Drawing,PresentationCore
        
        # ContentBackground
        $ContentBackground = 'ContentBackground'
        $AttributeCollection = New-Object System.Collections.ObjectModel.Collection[System.Attribute]
        $Parameterattribute = New-Object System.Management.Automation.Parameterattribute
        $Parameterattribute.Mandatory = $False
        $AttributeCollection.Add($Parameterattribute) 
        $RuntimeParameterDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary
        $arrSet = [System.Drawing.Brushes] | Get-Member -Static -MemberType Property | Select -ExpandProperty Name 
        $validatesetAttribute = New-Object System.Management.Automation.validatesetAttribute($arrSet)    
        $AttributeCollection.Add($validatesetAttribute)
        $PSBoundParameters.ContentBackground = "White"
        $RuntimeParameter = New-Object System.Management.Automation.RuntimeDefinedParameter($ContentBackground,[string],$AttributeCollection)
        $RuntimeParameterDictionary.Add($ContentBackground,$RuntimeParameter)
        

        # FontFamily
        $FontFamily = 'FontFamily'
        $AttributeCollection = New-Object System.Collections.ObjectModel.Collection[System.Attribute]
        $Parameterattribute = New-Object System.Management.Automation.Parameterattribute
        $Parameterattribute.Mandatory = $False
        $AttributeCollection.Add($Parameterattribute)  
        $arrSet = [System.Drawing.FontFamily]::Families.Name | Select -Skip 1 
        $validatesetAttribute = New-Object System.Management.Automation.validatesetAttribute($arrSet)
        $AttributeCollection.Add($validatesetAttribute)
        $RuntimeParameter = New-Object System.Management.Automation.RuntimeDefinedParameter($FontFamily,$AttributeCollection)
        $RuntimeParameterDictionary.Add($FontFamily,$RuntimeParameter)
        $PSBoundParameters.FontFamily = "Segoe UI"

        # TitleFontWeight
        $TitleFontWeight = 'TitleFontWeight'
        $AttributeCollection = New-Object System.Collections.ObjectModel.Collection[System.Attribute]
        $Parameterattribute = New-Object System.Management.Automation.Parameterattribute
        $Parameterattribute.Mandatory = $False
        $AttributeCollection.Add($Parameterattribute) 
        $arrSet = [System.Windows.FontWeights] | Get-Member -Static -MemberType Property | Select -ExpandProperty Name 
        $validatesetAttribute = New-Object System.Management.Automation.validatesetAttribute($arrSet)    
        $AttributeCollection.Add($validatesetAttribute)
        $PSBoundParameters.TitleFontWeight = "normal"
        $RuntimeParameter = New-Object System.Management.Automation.RuntimeDefinedParameter($TitleFontWeight,$AttributeCollection)
        $RuntimeParameterDictionary.Add($TitleFontWeight,$RuntimeParameter)

        # ContentFontWeight
        $ContentFontWeight = 'ContentFontWeight'
        $AttributeCollection = New-Object System.Collections.ObjectModel.Collection[System.Attribute]
        $Parameterattribute = New-Object System.Management.Automation.Parameterattribute
        $Parameterattribute.Mandatory = $False
        $AttributeCollection.Add($Parameterattribute) 
        $arrSet = [System.Windows.FontWeights] | Get-Member -Static -MemberType Property | Select -ExpandProperty Name 
        $validatesetAttribute = New-Object System.Management.Automation.validatesetAttribute($arrSet)    
        $AttributeCollection.Add($validatesetAttribute)
        $PSBoundParameters.ContentFontWeight = "normal"
        $RuntimeParameter = New-Object System.Management.Automation.RuntimeDefinedParameter($ContentFontWeight,$AttributeCollection)
        $RuntimeParameterDictionary.Add($ContentFontWeight,$RuntimeParameter)
        

        # ContentTextForeground
        $ContentTextForeground = 'ContentTextForeground'
        $AttributeCollection = New-Object System.Collections.ObjectModel.Collection[System.Attribute]
        $Parameterattribute = New-Object System.Management.Automation.Parameterattribute
        $Parameterattribute.Mandatory = $False
        $AttributeCollection.Add($Parameterattribute) 
        $arrSet = [System.Drawing.Brushes] | Get-Member -Static -MemberType Property | Select -ExpandProperty Name 
        $validatesetAttribute = New-Object System.Management.Automation.validatesetAttribute($arrSet)    
        $AttributeCollection.Add($validatesetAttribute)
        $PSBoundParameters.ContentTextForeground = "Black"
        $RuntimeParameter = New-Object System.Management.Automation.RuntimeDefinedParameter($ContentTextForeground,$AttributeCollection)
        $RuntimeParameterDictionary.Add($ContentTextForeground,$RuntimeParameter)

        # TitleTextForeground
        $TitleTextForeground = 'TitleTextForeground'
        $AttributeCollection = New-Object System.Collections.ObjectModel.Collection[System.Attribute]
        $Parameterattribute = New-Object System.Management.Automation.Parameterattribute
        $Parameterattribute.Mandatory = $False
        $AttributeCollection.Add($Parameterattribute) 
        $arrSet = [System.Drawing.Brushes] | Get-Member -Static -MemberType Property | Select -ExpandProperty Name 
        $validatesetAttribute = New-Object System.Management.Automation.validatesetAttribute($arrSet)    
        $AttributeCollection.Add($validatesetAttribute)
        $PSBoundParameters.TitleTextForeground = "Black"
        $RuntimeParameter = New-Object System.Management.Automation.RuntimeDefinedParameter($TitleTextForeground,$AttributeCollection)
        $RuntimeParameterDictionary.Add($TitleTextForeground,$RuntimeParameter)

        # BorderBrush
        $BorderBrush = 'BorderBrush'
        $AttributeCollection = New-Object System.Collections.ObjectModel.Collection[System.Attribute]
        $Parameterattribute = New-Object System.Management.Automation.Parameterattribute
        $Parameterattribute.Mandatory = $False
        $AttributeCollection.Add($Parameterattribute) 
        $arrSet = [System.Drawing.Brushes] | Get-Member -Static -MemberType Property | Select -ExpandProperty Name 
        $validatesetAttribute = New-Object System.Management.Automation.validatesetAttribute($arrSet)    
        $AttributeCollection.Add($validatesetAttribute)
        $PSBoundParameters.BorderBrush = "Black"
        $RuntimeParameter = New-Object System.Management.Automation.RuntimeDefinedParameter($BorderBrush,$AttributeCollection)
        $RuntimeParameterDictionary.Add($BorderBrush,$RuntimeParameter)


        # TitleBackground
        $TitleBackground = 'TitleBackground'
        $AttributeCollection = New-Object System.Collections.ObjectModel.Collection[System.Attribute]
        $Parameterattribute = New-Object System.Management.Automation.Parameterattribute
        $Parameterattribute.Mandatory = $False
        $AttributeCollection.Add($Parameterattribute) 
        $arrSet = [System.Drawing.Brushes] | Get-Member -Static -MemberType Property | Select -ExpandProperty Name 
        $validatesetAttribute = New-Object System.Management.Automation.validatesetAttribute($arrSet)    
        $AttributeCollection.Add($validatesetAttribute)
        $PSBoundParameters.TitleBackground = "White"
        $RuntimeParameter = New-Object System.Management.Automation.RuntimeDefinedParameter($TitleBackground,$AttributeCollection)
        $RuntimeParameterDictionary.Add($TitleBackground,$RuntimeParameter)

        # ButtonTextForeground
        $ButtonTextForeground = 'ButtonTextForeground'
        $AttributeCollection = New-Object System.Collections.ObjectModel.Collection[System.Attribute]
        $Parameterattribute = New-Object System.Management.Automation.Parameterattribute
        $Parameterattribute.Mandatory = $False
        $AttributeCollection.Add($Parameterattribute) 
        $arrSet = [System.Drawing.Brushes] | Get-Member -Static -MemberType Property | Select -ExpandProperty Name 
        $validatesetAttribute = New-Object System.Management.Automation.validatesetAttribute($arrSet)    
        $AttributeCollection.Add($validatesetAttribute)
        $PSBoundParameters.ButtonTextForeground = "Black"
        $RuntimeParameter = New-Object System.Management.Automation.RuntimeDefinedParameter($ButtonTextForeground,$AttributeCollection)
        $RuntimeParameterDictionary.Add($ButtonTextForeground,$RuntimeParameter)

        # Sound
        $Sound = 'Sound'
        $AttributeCollection = New-Object System.Collections.ObjectModel.Collection[System.Attribute]
        $Parameterattribute = New-Object System.Management.Automation.Parameterattribute
        $Parameterattribute.Mandatory = $False
        #$Parameterattribute.Position = 14
        $AttributeCollection.Add($Parameterattribute) 
        $arrSet = (Get-ChildItem "$env:SystemDrive\Windows\Media" -Filter Windows* | Select -ExpandProperty Name).Replace('.wav','')
        $validatesetAttribute = New-Object System.Management.Automation.validatesetAttribute($arrSet)    
        $AttributeCollection.Add($validatesetAttribute)
        $RuntimeParameter = New-Object System.Management.Automation.RuntimeDefinedParameter($Sound,$AttributeCollection)
        $RuntimeParameterDictionary.Add($Sound,$RuntimeParameter)

        return $RuntimeParameterDictionary
    }

    Begin {
        Add-Type -AssemblyName PresentationFramework
    }
    
    Process {

# Define the XAML markup
[XML]$Xaml = @"
<Window 
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        x:Name="Window" Title="" SizetoContent="WidthAndHeight" WindowStartupLocation="CenterScreen" WindowStyle="None" ResizeMode="noresize" AllowsTransparency="True" Background="Transparent" Opacity="1">
    <Window.Resources>
        <Style targettype="{x:Type Button}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate targettype="Button">
                        <Border>
                            <Grid Background="{TemplateBinding Background}">
                                <ContentPresenter />
                            </Grid>
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Resources>
    <Border x:Name="MainBorder" Margin="10" CornerRadius="$CornerRadius" BorderThickness="$BorderThickness" BorderBrush="$($PSBoundParameters.BorderBrush)" Padding="0" >
        <Border.Effect>
            <DropShadowEffect x:Name="DSE" Color="Black" Direction="270" BlurRadius="$BlurRadius" ShadowDepth="$ShadowDepth" Opacity="0.6" />
        </Border.Effect>
        <Border.Triggers>
            <EventTrigger RoutedEvent="Window.Loaded">
                <BeginStoryboard>
                    <Storyboard>
                        <DoubleAnimation Storyboard.TargetName="DSE" Storyboard.TargetProperty="ShadowDepth" From="0" To="$ShadowDepth" Duration="0:0:1" AutoReverse="False" />
                        <DoubleAnimation Storyboard.TargetName="DSE" Storyboard.TargetProperty="BlurRadius" From="0" To="$BlurRadius" Duration="0:0:1" AutoReverse="False" />
                    </Storyboard>
                </BeginStoryboard>
            </EventTrigger>
        </Border.Triggers>
        <Grid >
            <Border Name="Mask" CornerRadius="$CornerRadius" Background="$($PSBoundParameters.ContentBackground)" />
            <Grid x:Name="Grid" Background="$($PSBoundParameters.ContentBackground)">
                <Grid.OpacityMask>
                    <VisualBrush Visual="{Binding ElementName=Mask}"/>
                </Grid.OpacityMask>
                <StackPanel Name="StackPanel" >                   
                    <TextBox Name="TitleBar" IsReadOnly="True" IsHitTestVisible="False" Text="$Title" Padding="10" FontFamily="$($PSBoundParameters.FontFamily)" FontSize="$TitleFontSize" Foreground="$($PSBoundParameters.TitleTextForeground)" FontWeight="$($PSBoundParameters.TitleFontWeight)" Background="$($PSBoundParameters.TitleBackground)" HorizontalAlignment="Stretch" VerticalAlignment="Center" Width="Auto" HorizontalContentAlignment="Center" BorderThickness="0"/>
                    <DockPanel Name="ContentHost" Margin="0,10,10"  >
                    </DockPanel>
                    <DockPanel Name="ButtonHost" LastChildFill="False" HorizontalAlignment="Center" >
                    </DockPanel>
                </StackPanel>
            </Grid>
        </Grid>
    </Border>
</Window>
"@

[XML]$ButtonXaml = @"
<Button xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="Auto" Height="30" FontFamily="Segui" FontSize="16" Background="Transparent" Foreground="White" BorderThickness="1" Margin="10" Padding="20,20,0" HorizontalAlignment="Right" Cursor="Hand"/>
"@

[XML]$Buttontextxaml = @"
<TextBlock xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" FontFamily="$($PSBoundParameters.FontFamily)" FontSize="16" Background="Transparent" Foreground="$($PSBoundParameters.ButtonTextForeground)" Padding="20,5,5" HorizontalAlignment="Center" VerticalAlignment="Center"/>
"@

[XML]$Contenttextxaml = @"
<TextBlock xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Text="$Content" Foreground="$($PSBoundParameters.ContentTextForeground)" DockPanel.Dock="Right" HorizontalAlignment="Center" VerticalAlignment="Center" FontFamily="$($PSBoundParameters.FontFamily)" FontSize="$ContentFontSize" FontWeight="$($PSBoundParameters.ContentFontWeight)" textwrapping="Wrap" Height="Auto" MaxWidth="500" MinWidth="50" Padding="10"/>
"@

    # Load the window from XAML
    $Window = [Windows.Markup.XamlReader]::Load((New-Object -TypeName System.Xml.XmlNodeReader -ArgumentList $xaml))

    # Custom function to add a button
    Function Add-Button {
        Param($Content)
        $Button = [Windows.Markup.XamlReader]::Load((New-Object -TypeName System.Xml.XmlNodeReader -ArgumentList $ButtonXaml))
        $ButtonText = [Windows.Markup.XamlReader]::Load((New-Object -TypeName System.Xml.XmlNodeReader -ArgumentList $Buttontextxaml))
        $ButtonText.Text = "$Content"
        $Button.Content = $ButtonText
        $Button.Add_MouseEnter({
            $This.Content.FontSize = "17"
        })
        $Button.Add_MouseLeave({
            $This.Content.FontSize = "16"
        })
        $Button.Add_Click({
            New-Variable -Name WPFMessageBoxOutput -Value $($This.Content.Text) -Option ReadOnly -Scope Script -Force
            $Window.Close()
        })
        $Window.FindName('ButtonHost').AddChild($Button)
    }

    # Add buttons
    If ($ButtonType -eq "OK")
    {
        Add-Button -Content "OK"
    }

    If ($ButtonType -eq "OK-Cancel")
    {
        Add-Button -Content "OK"
        Add-Button -Content "Cancel"
    }

    If ($ButtonType -eq "Abort-Retry-Ignore")
    {
        Add-Button -Content "Abort"
        Add-Button -Content "Retry"
        Add-Button -Content "Ignore"
    }

    If ($ButtonType -eq "Yes-No-Cancel")
    {
        Add-Button -Content "Yes"
        Add-Button -Content "No"
        Add-Button -Content "Cancel"
    }

    If ($ButtonType -eq "Yes-No")
    {
        Add-Button -Content "Yes"
        Add-Button -Content "No"
    }

    If ($ButtonType -eq "Retry-Cancel")
    {
        Add-Button -Content "Retry"
        Add-Button -Content "Cancel"
    }

    If ($ButtonType -eq "Cancel-TryAgain-Continue")
    {
        Add-Button -Content "Cancel"
        Add-Button -Content "TryAgain"
        Add-Button -Content "Continue"
    }

    If ($ButtonType -eq "None" -and $CustomButtons)
    {
        Foreach ($CustomButton in $CustomButtons)
        {
            Add-Button -Content "$CustomButton"
        }
    }

    # Remove the title bar if no title is provided
    If ($Title -eq "")
    {
        $TitleBar = $Window.FindName('TitleBar')
        $Window.FindName('StackPanel').Children.Remove($TitleBar)
    }

    # Add the Content
    If ($Content -is [String])
    {
        # Replace double quotes with single to avoid quote issues in strings
        If ($Content -match '"')
        {
            $Content = $Content.Replace('"',"'")
        }
        
        # Use a text Box for a string value...
        $ContentTextBox = [Windows.Markup.XamlReader]::Load((New-Object -TypeName System.Xml.XmlNodeReader -ArgumentList $Contenttextxaml))
        $Window.FindName('ContentHost').AddChild($ContentTextBox)
    }
    Else
    {
        # ...or add a WPF element as a child
        Try
        {
            $Window.FindName('ContentHost').AddChild($Content) 
        }
        Catch
        {
            $_
        }        
    }

    # Enable window to move when dragged
    $Window.FindName('Grid').Add_MouseLeftButtonDown({
        $Window.DragMove()
    })

    # Activate the window on loading
    If ($OnLoaded)
    {
        $Window.Add_Loaded({
            $This.Activate()
            Invoke-Command $OnLoaded
        })
    }
    Else
    {
        $Window.Add_Loaded({
            $This.Activate()
        })
    }
    

    # Stop the dispatcher timer if exists
    If ($OnClosed)
    {
        $Window.Add_Closed({
            If ($dispatcherTimer)
            {
                $dispatcherTimer.Stop()
            }
            Invoke-Command $OnClosed
        })
    }
    Else
    {
        $Window.Add_Closed({
            If ($dispatcherTimer)
            {
                $dispatcherTimer.Stop()
            }
        })
    }
    

    # If a window host is provided assign it as the owner
    If ($WindowHost)
    {
        $Window.Owner = $WindowHost
        $Window.WindowStartupLocation = "CenterOwner"
    }

    # If a timeout value is provided,use a dispatcher timer to close the window when timeout is reached
    If ($Timeout)
    {
        $Stopwatch = New-object System.Diagnostics.Stopwatch
        $TimerCode = {
            If ($Stopwatch.Elapsed.TotalSeconds -ge $Timeout)
            {
                $Stopwatch.Stop()
                $Window.Close()
            }
        }
        $dispatcherTimer = New-Object -TypeName System.Windows.Threading.dispatcherTimer
        $dispatcherTimer.Interval = [TimeSpan]::FromSeconds(1)
        $dispatcherTimer.Add_Tick($TimerCode)
        $Stopwatch.Start()
        $dispatcherTimer.Start()
    }

    # Play a sound
    If ($($PSBoundParameters.sound))
    {
        $SoundFile = "$env:SystemDrive\Windows\Media\$($PSBoundParameters.sound).wav"
        $Soundplayer = New-Object System.Media.soundplayer -ArgumentList $SoundFile
        $Soundplayer.Add_LoadCompleted({
            $This.Play()
            $This.dispose()
        })
        $Soundplayer.LoadAsync()
    }

    # display the window
    $null = $window.dispatcher.InvokeAsync{$window.ShowDialog()}.Wait()

    }
}

$Params = @{
    Content = "The file 'Important Document.docx' Could not be deleted."
    Title = "File Deletion Error"
    TitleBackground = "LightGray"
    TitleFontSize = 28
    TitleFontWeight = "Bold"
    TitleTextForeground = "Red"
    ContentFontSize = 18
    ContentFontWeight = "Medium"
}
 
 $Content = "ذكرت تقارير صحفية لوكالة الأنباء رويترز نقلا عن ثلاثة مسؤولين إن وزراة التجارة الأمريكية تعتزم إصدار أمر اليوم الجمعة بمنع الأشخاص داخل الولايات المتحدة من تنزيل تطبيق وي تشات WeChat وتطبيق تيك توك TikTok ابتداء من يوم الأحد المقبل 20 سبتمبر.

وأضاف المسؤولون لوكالة رويترز أن الحظر المفروض على تطبيق تيك توك قد يتم إلغاؤه من قبل الرئيس الأمريكي، دونالد ترامب قبل أن يدخل القرار حيز التنفيذ يوم الأحد المقبل. يأتي هذا في الوقت الذي تسعى فيه شركة بايت دانس ByteDance، الشركة الأم لتطبيق تيك توك، للتوصل إلى اتفاق بشأن عملياتها داخل الولايات المتحدة.

وتجدر الإشارة إلى أن هذا الحظر جاء استجابة لأوامر تنفيذية أصدرها الرئيس الأمريكي دونالد ترامب في 6 أغسطس الماضي، أعطت وزارة التجارة 45 يوما لتحديد المعاملات التي يجب حظرها من التطبيقات التي اعتبرها تشكل تهديدا للأمن القومي، وبذلك يصبح الموعد النهائي يوم الأحد المقبل.

وكان مسؤولون في وزارة التجارة الأمريكية قد صرحوا بأنهم يتخذون إجراءات غير عادية بسبب المخاطر التي تشكلها تلك التطبيقات من خلال جمع بيانات المستخدمين، بينما نفت الشركة الصينية استخدام أي من التطبيقات في عمليات التجسس.
investing
"
 
$Params = @{
    Content = $Content
    Title = "MISSION:POSSIBLE"
    TitleFontSize = 30
    TitleTextForeground = 'Red'
    TitleFontWeight = 'Bold'
    TitleBackground = 'Silver'
    FontFamily = 'Lucida Console'
    ButtonType = 'None'
    Timeout = 30
}
 
New-WPFMessageBox @Params

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)