当前位置:网站首页 > 更多 > 玩电脑 > 正文

[玩转系统] PowerShell 输入工具

作者:精品下载站 日期:2024-12-14 07:52:19 浏览:14 分类:玩电脑

PowerShell 输入工具


在 PowerShell 中,从用户获取交互式输入的主要方法是使用 Read-Host cmdlet。它没有任何问题,但有时如果您在 PowerShell ISE 或 VS Code 等图形工具中使用它,您可能没有意识到系统会提示您。或者,您可能正在构建某种其他类型的基于 PowerShell 的工具,您需要除基于控制台的提示之外的其他功能。我想先了解一下我将添加到 PSScriptTools 模块中的函数,该函数使用 WPF 创建图形输入框。

过去,您可能编写过 PowerShell 代码来生成 VBScript 样式的输入框。我知道我有几个版本。当我写它们时,它们工作得很好。它们仍然“工作”,但今天使用非常高分辨率的显示器,我目前运行的是 4K 显示器,任何使用 Windows 窗体的东西都不能很好地扩展。另一方面,WPF 被设计为自动缩放和调整。它并不关心我运行的是 4K 屏幕。

我编写的函数名为 Invoke-InputBox,其工作原理与 Read-Host 相同。您可以指定提示,输入一些内容,然后命令将其写回管道。尽管这是一个表单,您也可以指定一个标题。这是带有默认值的表单。

$p = Invoke-InputBox

[玩转系统] PowerShell 输入工具

按“确定”会将文本框中的值写入管道并将其分配给 $p。我还添加了一个参数,以便您可以输入安全字符串。

$s = Invoke-InputBox -Title "New Password" -Prompt "Enter a new password" -AsSecureString

[玩转系统] PowerShell 输入工具

我“快速而肮脏”地使用堆栈面板创建了一个简单的 WPF 表单。没有凌乱的 xaml。我认为代码非常简单。我将在这里分享当前版本,但希望它最终出现在 PSScriptTools 模块中。

Function Invoke-InputBox {

    [cmdletbinding(DefaultParameterSetName="plain")]
    [OutputType([system.string],ParameterSetName='plain')]
    [OutputType([system.security.securestring],ParameterSetName='secure')]

    Param(
        [Parameter(ParameterSetName="secure")]
        [Parameter(HelpMessage = "Enter the title for the input box. No more than 25 characters.",
        ParameterSetName="plain")]        

        [ValidateNotNullorEmpty()]
        [ValidateScript({$_.length -le 25})]
        [string]$Title = "User Input",

        [Parameter(ParameterSetName="secure")]        
        [Parameter(HelpMessage = "Enter a prompt. No more than 50 characters.",ParameterSetName="plain")]
        [ValidateNotNullorEmpty()]
        [ValidateScript({$_.length -le 50})]
        [string]$Prompt = "Please enter a value:",
        
        [Parameter(HelpMessage = "Use to mask the entry and return a secure string.",
        ParameterSetName="secure")]
        [switch]$AsSecureString
    )

    if ($PSEdition -eq 'Core') {
        Write-Warning "Sorry. This command will not run on PowerShell Core."
        #bail out
        Return
    }

    Add-Type -AssemblyName PresentationFramework
    Add-Type -assemblyName PresentationCore
    Add-Type -assemblyName WindowsBase

    #remove the variable because it might get cached in the ISE or VS Code
    Remove-Variable -Name myInput -Scope script -ErrorAction SilentlyContinue

    $form = New-Object System.Windows.Window
    $stack = New-object System.Windows.Controls.StackPanel

    #define what it looks like
    $form.Title = $title
    $form.Height = 150
    $form.Width = 350

    $label = New-Object System.Windows.Controls.Label
    $label.Content = "    $Prompt"
    $label.HorizontalAlignment = "left"
    $stack.AddChild($label)

    if ($AsSecureString) {
        $inputbox = New-Object System.Windows.Controls.PasswordBox
    }
    else {
        $inputbox = New-Object System.Windows.Controls.TextBox
    }

    $inputbox.Width = 300
    $inputbox.HorizontalAlignment = "center"

    $stack.AddChild($inputbox)

    $space = new-object System.Windows.Controls.Label
    $space.Height = 10
    $stack.AddChild($space)

    $btn = New-Object System.Windows.Controls.Button
    $btn.Content = "_OK"

    $btn.Width = 65
    $btn.HorizontalAlignment = "center"
    $btn.VerticalAlignment = "bottom"

    #add an event handler
    $btn.Add_click( {
            if ($AsSecureString) {
                $script:myInput = $inputbox.SecurePassword
            }
            else {
                $script:myInput = $inputbox.text
            }
            $form.Close()
        })

    $stack.AddChild($btn)
    $space2 = new-object System.Windows.Controls.Label
    $space2.Height = 10
    $stack.AddChild($space2)

    $btn2 = New-Object System.Windows.Controls.Button
    $btn2.Content = "_Cancel"

    $btn2.Width = 65
    $btn2.HorizontalAlignment = "center"
    $btn2.VerticalAlignment = "bottom"

    #add an event handler
    $btn2.Add_click( {
            $form.Close()
        })

    $stack.AddChild($btn2)

    #add the stack to the form
    $form.AddChild($stack)

    #show the form
    $inputbox.Focus() | Out-Null
    $form.WindowStartupLocation = [System.Windows.WindowStartupLocation]::CenterScreen

    $form.ShowDialog() | out-null

    #write the result from the input box back to the pipeline
    $script:myInput

}

由于该函数使用 WPF,因此它无法在 PowerShell Core 中运行。同时,我希望你们中的一些人尝试一下并让我知道您的想法。

您需要 登录账户 后才能发表评论

取消回复欢迎 发表评论:

关灯