在PowerShell中检查现有文件后如何关闭表单GUI?

时间:2019-07-18 07:46:14

标签: winforms powershell

我想检查一个现有文件,如果进程仍在等待文件,它将显示一个GUI窗口。文件存在后,窗口将自动关闭。

我尝试了这段代码,即使文件已经存在,窗口也无法关闭。

检查文件:

$SN = "708TSTA"
$MAC = "2E5961370"

function Find {
    $n = 0
    while (-not (Get-ChildItem -Name "D:\SERVER\" | Where-Object {$_ -like "*$SN-$MAC*"})) {
        Start-Sleep -s 1
        D:\Auto\GUI.ps1
        $n++
        (Get-ChildItem -Name "D:\SERVER\" | Where-Object {$_ -like "*$SN-$MAC*"})
        Write-Host "Attempt no $n"
    }

    Write-Host ">>Flag found after $n attempts"
    return $true
}

if (Find) {
    Write-Host "Found"
}

GUI.ps1

Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.Application]::EnableVisualStyles()

$Form                 = New-Object System.Windows.Forms.Form
$Form.ClientSize      = '578,400'
$Form.Text            = "Form"
$Form.BackColor       = "#c1daf7"
$Form.WindowState     = 'Maximized'
$Form.FormBorderStyle = "FixedDialog"

$Label1               = New-Object System.Windows.Forms.Label
$Label1.Text          = "UNDER PROCESS"
$Label1.AutoSize      = $true
$Label1.Width         = 25
$Label1.Height        = 10
$Label1.Location      = New-Object System.Drawing.Point(600,300)
$Label1.Font          = 'Microsoft Sans Serif,30,style=Bold,Underline'
$Label1.ForeColor     = "#d0021b"

$Label2               = New-Object System.Windows.Forms.Label
$Label2.Text          = "WAITING"
$Label2.AutoSize      = $true
$Label2.Width         = 25
$Label2.Height        = 10
$Label2.Location      = New-Object System.Drawing.Point(770,500)
$Label2.Font          = 'Microsoft Sans Serif,20,style=Bold'
$Label2.ForeColor     = "#fb0505"

$Check = Get-ChildItem -Name "D:\SERVER\" | Where-Object {$_ -like "*$SN-$MAC*"}
if($Check) {
    Write-Host "File Exist"
    $Form.Close()
}

$Form.Controls.AddRange(@($Label1,$Label2))
[void]$Form.ShowDialog()

1 个答案:

答案 0 :(得分:0)

与其在GUI中执行Start-Sleep,不如使用计时器,以便表单保持响应状态。

我这样更改了GUI.ps1的代码(不是它的外观):

Param (   
    [string]$Path = '*.*',
    [string]$MaxAttempts = 5
) 

Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.Application]::EnableVisualStyles()

# set things up for the timer
$script:nAttempts = 0
$timer = New-Object System.Windows.Forms.Timer
$timer.Interval = 1000  # 1 second
$timer.Add_Tick({
    $global:Result = $null
    $script:nAttempts++
    $file = Get-Item -Path $Path
    if ($file) {
        $global:Result = [PSCustomObject]@{
            Exists   = $true
            FileName = $file.FullName
            Attempts = $script:nAttempts
        }
        $timer.Dispose()
        $Form.Close()
    }
    elseif ($script:nAttempts -ge $MaxAttempts) {
        $global:Result = [PSCustomObject]@{
            Exists   = $false
            FileName = ''
            Attempts = $script:nAttempts
        }
        $timer.Dispose()
        $Form.Close()
    }
})

$Form                 = New-Object System.Windows.Forms.Form
$Form.ClientSize      = '578,400'
$Form.Text            = "Form"
$Form.BackColor       = "#c1daf7"
$Form.WindowState     = 'Maximized'
$Form.FormBorderStyle = "FixedDialog"

$Label1               = New-Object System.Windows.Forms.Label
$Label1.Text          = "UNDER PROCESS"
$Label1.AutoSize      = $true
$Label1.Width         = 25
$Label1.Height        = 10
$Label1.Location      = New-Object System.Drawing.Point(600,300)
$Label1.Font          = 'Microsoft Sans Serif,30,style=Bold,Underline'
$Label1.ForeColor     = "#d0021b"

$Label2               = New-Object System.Windows.Forms.Label
$Label2.Text          = "WAITING"
$Label2.AutoSize      = $true
$Label2.Width         = 25
$Label2.Height        = 10
$Label2.Location      = New-Object System.Drawing.Point(770,500)
$Label2.Font          = 'Microsoft Sans Serif,20,style=Bold'
$Label2.ForeColor     = "#fb0505"

$Form.Controls.AddRange(@($Label1,$Label2))

# start the timer as soon as the dialog is visible
$Form.Add_Shown({ $timer.Start() })

[void]$Form.ShowDialog()

# clean up when done
$Form.Dispose()

要从其他脚本中调用它,请使用:

$SN  = "708TSTA"
$MAC = "2E5961370"

function Test-FileExists {
    $file = Get-Item -Path "D:\*$SN-$MAC*"
    if ($file) {
        $global:Result = [PSCustomObject]@{
            Exists   = $true
            FileName = $file.FullName
            Attempts = 1
        }
    }
    else {
        & "D:\GUI.ps1" -Path "D:\*$SN-$MAC*" -MaxAttempts 3
    }
}

# call the function that can call the GUI.ps1 script
Test-FileExists

# check the Global result object
if ($global:Result.Exists) {
    Write-Host "File '$($global:Result.FileName)' Exists. Found after $($global:Result.Attempts) attempts." -ForegroundColor Green
}
else {
    Write-Host "File not found after $($global:Result.Attempts) attempts." -ForegroundColor Red
}

更新

根据您的评论,我了解调用脚本应显示该表单(该表单只显示屏幕上的内容),并负责在找到文件后将其关闭。

下面的代码应通过将$ Form定义为全局变量并使用表单的.Show()方法而不是ShowDialog()来完成您所要求的操作:

GUI.ps1

Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.Application]::EnableVisualStyles()

$global:Form                 = New-Object System.Windows.Forms.Form
$global:Form.ClientSize      = '578,400'
$global:Form.Text            = "Form"
$global:Form.BackColor       = "#c1daf7"
$global:Form.WindowState     = 'Maximized'
$global:Form.FormBorderStyle = "FixedDialog"
$global:Form.ControlBox      = $false  # hide sizing and close buttons
$global:Form.TopMost         = $true

$Label1               = New-Object System.Windows.Forms.Label
$Label1.Text          = "UNDER PROCESS"
$Label1.AutoSize      = $true
$Label1.Width         = 25
$Label1.Height        = 10
$Label1.Location      = New-Object System.Drawing.Point(600,300)
$Label1.Font          = 'Microsoft Sans Serif,30,style=Bold,Underline'
$Label1.ForeColor     = "#d0021b"

$Label2               = New-Object System.Windows.Forms.Label
$Label2.Text          = "WAITING"
$Label2.AutoSize      = $true
$Label2.Width         = 25
$Label2.Height        = 10
$Label2.Location      = New-Object System.Drawing.Point(770,500)
$Label2.Font          = 'Microsoft Sans Serif,20,style=Bold'
$Label2.ForeColor     = "#fb0505"

$global:Form.Controls.AddRange(@($Label1,$Label2))

# don't use ShowDialog() here because it will block the calling script
$global:Form.Show()

呼叫脚本

function Test-FileExists {
    [CmdletBinding()]
    param (
        [parameter(Mandatory = $true, ValueFromPipeline = $true, Position = 0)]
        [string]$Path,
        [string]$Pattern = '*.*'
    )
    $nAttempts = 1
    $file = Get-ChildItem -Path $Path -Filter $Pattern -File | Select-Object -First 1
    if (!$file) {
        # show the GUI
        & "D:\GUI.ps1"

        do {
            Start-Sleep -Seconds 1
            $nAttempts++
            Write-Verbose "Attempt No. $nAttempts"
            $file = Get-ChildItem -Path $Path -Filter $Pattern -File | Select-Object -First 1
        } until ($file)
        # clean up the form
        $global:Form.Dispose()
        $global:Form = $null
    }

    Write-Verbose "File '$($file.FullName)' Exists. Found after $nAttempts attempt(s)."
    return $true
}


$SN  = "708TSTA"
$MAC = "2E5961370"

# call the function that can call the GUI.ps1 script
if (Test-FileExists -Path 'D:\SERVER\SHARE' -Pattern "*$SN-$MAC*" -Verbose) {
    Write-Host "Found"
}

希望有帮助