0

I want to check an existing file, if the process still waiting for the file, it will display a GUI window. After the file is exist, the window will close automatically.

I tried this code, the window can not close, even the file already exist.

Checking the file:

$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 Answer 1

1

Instead of doing Start-Sleep inside the GUI, it is better to use a timer so the form stays responsive.

I changed the code of the GUI.ps1 (not the way it looks) like this:

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()

And to call it from your other script, use:

$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
}

Update

As per your comments, I understand that the calling script should show the form (which does nothing more that show on screen) AND is responsible for closing it after the file has been found.

The code below should do what you ask by defining the $Form as a global variable and by using the .Show() method of the form instead of 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()

the calling script

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"
}

Hope that helps

Sign up to request clarification or add additional context in comments.

3 Comments

Thank you @Theo. But It does not what I expect. Because the trigger to close the form window depend on the other script when the existing file is true, not using how -MaxAttempts
@Job I have updated my answer with new code that controls the showing AND closing of the form, all from the main script.
Hi @Theo, I updated my question with your advice here. stackoverflow.com/q/57487559/11099245 Could you please help me to take a look about it and really need your help. Thanks a lot.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.