【问题标题】:Unable to execute powershell GUI using wpf无法使用 wpf 执行 powershell GUI
【发布时间】:2019-10-29 00:24:29
【问题描述】:

我正在尝试为我们在工作中必须完成的一些日常任务构建一个 GUI(一个简单的单击按钮)。我从 GUI 中内置的磁盘空间检查 .ps1 脚本开始,如下所示

Add-Type -AssemblyName PresentationFramework

[xml]$XAMLWindow = '
<Window 
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        Title="Windows Management Tool" Height="450" Width="600" Background="Gray">
    <Grid>

        <Button Name="DiskSpace" Content="Check Available Disk Space" HorizontalAlignment="Left" Height="43" Margin="56,194,0,0" VerticalAlignment="Top" Width="181"/>


           </Grid>
</Window>

'

$Reader=(New-Object System.Xml.XmlNodeReader $XAMLWindow)
$Window=[Windows.Markup.XamlReader]::Load( $Reader )


$DiskSpace = $Window.FindName('DiskSpace')



$DiskSpace.Add_Click({
.\checkDiskSpaceOnMulti.ps1
})


$Window.ShowDialog() | Out-Null

下面是我嵌入到 GUI 中的 checkDiskSpaceOnMulti.ps1 的代码

$file = get-Content C:\list.txt  

foreach ( $args in $file) { 
get-WmiObject win32_logicaldisk -ComputerName $args -Filter "Drivetype=3"  |  
ft SystemName,DeviceID,VolumeName,@{Label="Total SIze";Expression={$_.Size / 1gb -as [int] }},@{Label="Free Size";Expression={$_.freespace / 1gb -as [int] }} -autosize 
} 

当我单击 GUI 上的按钮时,出现以下错误。从 powershell ISE 使用时,checkDiskSpaceOnMulti.ps1 可以根据我的需要完美运行。问题仅在与 GUI 脚本一起使用时出现。

.\checkDiskSpaceOnMulti.ps1 : The term '.\checkDiskSpaceOnMulti.ps1' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try 
again.
At H:\Powershell\Powershell\Windows_Utility_Tool.ps1:54 char:1
+ .\checkDiskSpaceOnMulti.ps1
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (.\checkDiskSpaceOnMulti.ps1:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

还给我推荐一个PoSh GUI开发工具的好工具。

【问题讨论】:

  • 那不是winforms,那是wpf
  • 不要使用$args作为变量名,因为它是PowerShell中的automatic variable
  • 强烈建议不要在 PowerShell 中构建 UI。仅仅因为你可以做某事并不意味着你应该
  • 它不完全是图形化 PoSh。我只是想通过单击从 GUI 窗口获取 .ps1 可执行文件。
  • 我们还没有收到您的来信。我的回答解决了您的问题吗?如果是这样,请点击左侧的✓ 考虑accepting。这将帮助其他有类似问题的人更轻松地找到它。

标签: wpf powershell user-interface


【解决方案1】:

也许您最好在窗口中使用等宽字体的多行文本框来显示结果。另外,由于要运行的代码非常小,我会将它放在一个函数中并在单击按钮时运行它:

Add-Type -AssemblyName PresentationFramework

[xml]$XAMLWindow = @'
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        Title="Windows Management Tool" Height="450" Width="600" Background="Gray">

    <Grid Margin="0,10,0,0">

        <TextBox Name="ResultBox" Height="300" Width="500" TextWrapping="Wrap" 
                 AcceptsReturn="True" VerticalScrollBarVisibility="Auto" FontFamily="Consolas"
                 VerticalAlignment="Top" Margin="0,20,0,0"/>

        <Button Name="DiskSpace" Content="Check Available Disk Space" HorizontalAlignment="Left" 
                Height="43" Margin="40,330,0,0" VerticalAlignment="Top" Width="181"/>

    </Grid>
</Window>
'@

$Reader = New-Object System.Xml.XmlNodeReader $XAMLWindow
$Window = [Windows.Markup.XamlReader]::Load($Reader)

function checkDiskSpaceOnMulti {
    $textBox = $Window.FindName("ResultBox")
    $textBox.Clear()

    # read the file as string array and skip empty lines
    # UPDATE: force the result of Get-Content to be an array if only one computer is listed
    $file = @(Get-Content 'C:\list.txt') | Where-Object { $_ -match '\S' }

    # fill the textbox with the results
    $textBox.Text = foreach ($computer in $file) {
        # add a test to see if the computer can be reached
        if (Test-Connection -ComputerName $computer -Count 1 -Quiet) {
            Get-WmiObject -Class Win32_LogicalDisk -ComputerName $computer -Filter "Drivetype=3" |
            Format-Table SystemName, DeviceID, VolumeName,
                         @{Label="Total Size";Expression={$_.Size / 1gb -as [int] }},
                         @{Label="Free Size" ;Expression={$_.Freespace / 1gb -as [int] }} -AutoSize | Out-String
        }
        else {
            "WARNING: Computer '$computer' is off-line or does not exist.`r`n"
        }
    }
}

$DiskSpace = $Window.FindName("DiskSpace")
$DiskSpace.Add_Click({ checkDiskSpaceOnMulti })

$Window.ShowDialog() | Out-Null

上面会产生一个像这样的窗口:

希望有帮助

【讨论】:

  • 嘿,谢谢你非常详细的解释。我是 PoSh 的新手,您显示代码的方式对我来说很容易理解。但是,结果是从 Test-Connection 而不是磁盘空间返回 True,我也没有看到第 33 行有任何错误。我错过了什么? ``` 警告:计算机“真”已脱机或不存在。 ```
  • @JayaSankarYakkala 我已经编辑了读取文本文件的行并将空行或仅空白行删除到$file = (Get-Content 'C:\list.txt') | Where-Object { $_ -match '\S' }。前一个(较短的)版本适用于我的 PowerShell 版本 5.1,但也许你有不同的版本?
  • 我也有 5.x。
  • @JsJ 在这种情况下,C:\list.txt 中除了计算机名称列表之外还有什么,每个计算机名称都在单独的行上?它可能包含True这个词吗?
  • 计算机名是 D-V0-12,没有空格。如果有多个计算机名称,我将它们放在单独的行中。
猜你喜欢
  • 2018-09-27
  • 2018-10-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-16
  • 2019-01-17
相关资源
最近更新 更多