Windows powershell GUI 方法

|
Document-edit Created with Sketch.
|

PowerShell GUI脚本开发

在公司电脑没有管理员权限、没有互联网连接的情况下,使用PowerShell内置的.NET框架创建图形用户界面(GUI)应用程序。主要利用以下两种技术:

  • Windows Forms (WinForms)(新手推荐)
  • Windows Presentation Foundation (WPF)

实战示例:文件搜索工具

完整代码:

Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing

# 创建主窗体
$form = New-Object System.Windows.Forms.Form
$form.Text = "File Search Tool"
$form.Size = New-Object System.Drawing.Size(600, 500)
$form.StartPosition = "CenterScreen"
$form.MinimizeBox = $false
$form.MaximizeBox = $false
$form.FormBorderStyle = 'Fixed3D'

# 创建目录选择标签
$labelDirectory = New-Object System.Windows.Forms.Label
$labelDirectory.Location = New-Object System.Drawing.Point(10, 15)
$labelDirectory.Size = New-Object System.Drawing.Size(150, 20)
$labelDirectory.Text = "Select Directory:"
$form.Controls.Add($labelDirectory)

# 创建目录显示文本框
$textBoxDirectory = New-Object System.Windows.Forms.TextBox
$textBoxDirectory.Location = New-Object System.Drawing.Point(110, 20)
$textBoxDirectory.Size = New-Object System.Drawing.Size(350, 20)
$textBoxDirectory.ReadOnly = $true
$form.Controls.Add($textBoxDirectory)

# 创建浏览按钮
$buttonBrowse = New-Object System.Windows.Forms.Button
$buttonBrowse.Location = New-Object System.Drawing.Point(470, 18)
$buttonBrowse.Size = New-Object System.Drawing.Size(75, 23)
$buttonBrowse.Text = "Browse..."
$form.Controls.Add($buttonBrowse)

# 创建文件名标签
$labelFileName = New-Object System.Windows.Forms.Label
$labelFileName.Location = New-Object System.Drawing.Point(10, 60)
$labelFileName.Size = New-Object System.Drawing.Size(150, 20)
$labelFileName.Text = "File Name:"
$form.Controls.Add($labelFileName)

# 创建文件名输入框
$textBoxFileName = New-Object System.Windows.Forms.TextBox
$textBoxFileName.Location = New-Object System.Drawing.Point(110, 60)
$textBoxFileName.Size = New-Object System.Drawing.Size(350, 20)
$textBoxFileName.Text = "*.*"
$form.Controls.Add($textBoxFileName)

# 创建搜索按钮
$buttonSearch = New-Object System.Windows.Forms.Button
$buttonSearch.Location = New-Object System.Drawing.Point(470, 58)
$buttonSearch.Size = New-Object System.Drawing.Size(75, 23)
$buttonSearch.Text = "Search"
$form.Controls.Add($buttonSearch)

# 创建结果列表框
$listBoxResults = New-Object System.Windows.Forms.ListBox
$listBoxResults.Location = New-Object System.Drawing.Point(10, 100)
$listBoxResults.Size = New-Object System.Drawing.Size(560, 300)
$listBoxResults.Anchor = 'Top, Bottom, Left, Right'
$listBoxResults.Font = New-Object System.Drawing.Font("Consolas", 9)
$form.Controls.Add($listBoxResults)

# 创建状态标签
$labelStatus = New-Object System.Windows.Forms.Label
$labelStatus.Location = New-Object System.Drawing.Point(10, 420)
$labelStatus.Size = New-Object System.Drawing.Size(560, 20)
$labelStatus.Text = "Ready. Please select a directory and enter a file name."
$labelStatus.TextAlign = 'MiddleLeft'
$form.Controls.Add($labelStatus)

# 创建打开位置按钮
$buttonOpenLocation = New-Object System.Windows.Forms.Button
$buttonOpenLocation.Location = New-Object System.Drawing.Point(10, 450)
$buttonOpenLocation.Size = New-Object System.Drawing.Size(150, 23)
$buttonOpenLocation.Text = "Open File Location"
$buttonOpenLocation.Enabled = $false
$form.Controls.Add($buttonOpenLocation)

# 创建退出按钮
$buttonExit = New-Object System.Windows.Forms.Button
$buttonExit.Location = New-Object System.Drawing.Point(470, 450)
$buttonExit.Size = New-Object System.Drawing.Size(75, 23)
$buttonExit.Text = "Exit"
$form.Controls.Add($buttonExit)

# 创建一个全局列表来存储文件对象
$global:fileList = New-Object System.Collections.ArrayList

# 浏览按钮点击事件
$buttonBrowse.Add_Click({
    $folderBrowser = New-Object System.Windows.Forms.FolderBrowserDialog
    $folderBrowser.Description = "Please select a directory to search"
    $folderBrowser.RootFolder = 'MyComputer'

    if ($folderBrowser.ShowDialog() -eq 'OK') {
        $textBoxDirectory.Text = $folderBrowser.SelectedPath
    }
    $folderBrowser.Dispose()
})

# 搜索按钮点击事件
$buttonSearch.Add_Click({
    $searchDir = $textBoxDirectory.Text
    $searchPattern = $textBoxFileName.Text

    if ([string]::IsNullOrEmpty($searchDir)) {
        [System.Windows.Forms.MessageBox]::Show("Please select a directory first!", "Warning", "OK", "Warning")
        return
    }

    if (-not (Test-Path -Path $searchDir)) {
        [System.Windows.Forms.MessageBox]::Show("The selected directory does not exist!", "Error", "OK", "Error")
        return
    }

    $labelStatus.Text = "Searching... Please wait."
    $listBoxResults.Items.Clear()
    $buttonOpenLocation.Enabled = $false
    $global:fileList.Clear()

    try {
        $files = Get-ChildItem -Path $searchDir -Filter $searchPattern -File -Recurse -ErrorAction SilentlyContinue
        foreach ($file in $files) {
            $displayString = "{0:yyyy-MM-dd HH:mm} | {1,10:N0} KB | {2}" -f $file.LastWriteTime, ($file.Length / 1KB), $file.Name
            $listBoxResults.Items.Add($displayString)
            # 将文件对象添加到全局列表,与列表框中的索引对应
            $global:fileList.Add($file) | Out-Null
        }
        $labelStatus.Text = "Search completed. Found $($files.Count) files."
    } catch {
        $labelStatus.Text = "Error during search: $($_.Exception.Message)"
    }
})

# 列表框选择变化事件
$listBoxResults.Add_SelectedIndexChanged({
    $buttonOpenLocation.Enabled = ($listBoxResults.SelectedIndex -ne -1)
})

# 打开位置按钮点击事件
$buttonOpenLocation.Add_Click({
    if ($listBoxResults.SelectedIndex -ne -1) {
        $selectedFile = $global:fileList[$listBoxResults.SelectedIndex]
        Start-Process "explorer.exe" -ArgumentList ("/select, `"{0}`"" -f $selectedFile.FullName)
    }
})

# 退出按钮点击事件
$buttonExit.Add_Click({
    $form.Close()
})

# 启动窗体
[void]$form.ShowDialog()

运行后可以看到: alt text 这便是以上代码实现的情况,后续将会深入研究Windows.form的使用方法,为工作创建实用的脚本。

附录

Windows PowerShell实战指南(第3版)

参考文章