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

Winforms 如何在检查PowerShell中的现有文件后关闭表单GUI?,winforms,powershell,Winforms,Powershell,我想检查一个现有文件,如果进程仍在等待该文件,它将显示一个GUI窗口。文件存在后,窗口将自动关闭 我试过这个代码,窗口无法关闭,甚至文件已经存在 正在检查文件: $SN=“708TSTA” $MAC=“2E5961370” 函数查找{ $n=0 while(-not(获取ChildItem-Name“D:\SERVER\”| Where对象{$|-like“*$SN-$MAC*”})){ 开始睡眠-s1 D:\Auto\GUI.ps1 $n++ (获取ChildItem-名称“D:\SERVER

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

我试过这个代码,窗口无法关闭,甚至文件已经存在

正在检查文件:

$SN=“708TSTA”
$MAC=“2E5961370”
函数查找{
$n=0
while(-not(获取ChildItem-Name“D:\SERVER\”| Where对象{$|-like“*$SN-$MAC*”})){
开始睡眠-s1
D:\Auto\GUI.ps1
$n++
(获取ChildItem-名称“D:\SERVER\”|其中对象{$\类似于“*$SN-$MAC*”})
写入主机“尝试号$n”
}
写入主机“>>在$n次尝试后找到标志”
返回$true
}
如果(查找){
写入主机“找到”
}
GUI.ps1

添加类型-AssemblyName System.Windows.Forms
[System.Windows.Forms.Application]::EnableVisualStyles()
$Form=新对象System.Windows.Forms.Form
$Form.ClientSize='578400'
$Form.Text=“Form”
$Form.BackColor=“#c1daf7”
$Form.WindowState='Maximized'
$Form.FormBorderStyle=“FixedDialog”
$Label1=新对象System.Windows.Forms.Label
$Label1.Text=“正在处理中”
$Label1.AutoSize=$true
$Label1.Width=25
$Label1.Height=10
$Label1.Location=新对象系统.绘图.点(600300)
$Label1.Font='Microsoft无衬线,30,样式=粗体,下划线'
$Label1.ForeColor=“#d0021b”
$Label2=新对象System.Windows.Forms.Label
$Label2.Text=“等待”
$Label2.AutoSize=$true
$Label2.Width=25
$Label2.Height=10
$Label2.Location=新对象系统.绘图.点(770500)
$Label2.Font='Microsoft无衬线,20,style=Bold'
$Label2.ForeColor=“#fb0505”
$Check=Get ChildItem-Name“D:\SERVER\”| Where对象{$\类似“*$SN-$MAC*”}
如果($支票){
写入主机“文件存在”
$Form.Close()
}
$Form.Controls.AddRange(@($Label1,$Label2))
[void]$Form.ShowDialog()

与其在GUI中执行
启动睡眠
,不如使用计时器,使窗体保持响应

我更改了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"
}

希望这有帮助

谢谢你@Theo。但这并不是我所期望的。因为当现有文件为true时,关闭表单窗口的触发器依赖于其他脚本,而不是使用how-MaxAttempts@Job我已经用控制表单显示和关闭的新代码更新了我的答案,所有这些都来自主脚本。嗨@Theo,我用你的建议更新了我的问题。你能帮我看看吗?我真的需要你的帮助。谢谢。