0

I'm trying to make a little script with which I can alter a keyword in a file to something I have typed into a text box. I make a copy of a directory with files, and copy them with a unique directory name to a map called temp. It also starts a file. When closing the script or by pressing Cancel, the started program gets closed and the files get deleted again.

It all works okay, but whenever I close the form via the Windows task bar, and I want to start the script again, the form won't show up and the PowerShell console shows, even when minimized, completely empty, unable to edit anything. I can close it with Ctrl+C, but it stucks again when I launch the script the next time.

This is the first script I have ever made and I'm not sure how to fix the issue.

If there is a way to delete the files in that unique random directory when the process is stopped, that would be even better. For instance, if I close the file settings.txt that I opened via the script, then delete all files.

[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")  
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") 
[void] [System.Windows.Forms.Application]::EnableVisualStyles() 

# Hide PowerShell Console
Add-Type -Name Window -Namespace Console -MemberDefinition '
[DllImport("Kernel32.dll")]
public static extern IntPtr GetConsoleWindow();
[DllImport("user32.dll")]
public static extern bool ShowWindow(IntPtr hWnd, Int32 nCmdShow);
'
$consolePtr = [Console.Window]::GetConsoleWindow()
[Console.Window]::ShowWindow($consolePtr, 0)


# makes form
$form = New-Object System.Windows.Forms.Form
$form.Text = 'Data Entry Form'
$form.Size = New-Object System.Drawing.Size(200,180)
$form.StartPosition = 'CenterScreen'

$okButton = New-Object System.Windows.Forms.Button
$okButton.Location = New-Object System.Drawing.Point(10,70)
$okButton.Size = New-Object System.Drawing.Size(160,20)
$okButton.Text = 'OK'
$okButton.DialogResult = [System.Windows.Forms.DialogResult]::OK
$form.AcceptButton = $okButton
$form.Controls.Add($okButton)


$cancelButton = New-Object System.Windows.Forms.Button
$cancelButton.Location = New-Object System.Drawing.Point(10,100)
$cancelButton.Size = New-Object System.Drawing.Size(160,20)
$cancelButton.Text = 'Cancel'
$cancelButton.DialogResult = [System.Windows.Forms.DialogResult]::Cancel
$form.CancelButton = $cancelButton
$form.Controls.Add($cancelButton)

$label = New-Object System.Windows.Forms.Label
$label.Location = New-Object System.Drawing.Point(10,20)
$label.Size = New-Object System.Drawing.Size(170,20)
$label.Text = 'Please enter the Server name:'
$form.Controls.Add($label)

$textBox = New-Object System.Windows.Forms.TextBox
$textBox.Location = New-Object System.Drawing.Point(10,40)
$textBox.Size = New-Object System.Drawing.Size(160,20)
$form.Controls.Add($textBox)

$form.Topmost = $true

$form.Add_Shown({$textBox.Select()})
$result = $form.ShowDialog()

if ($result -eq [System.Windows.Forms.DialogResult]::OK)
{
    $server = $textBox.Text
    $server

    $folder = [System.IO.Path]::GetRandomFileName()

    Copy-Item -Path C:\powershell\main\  -Destination c:\powershell\temp –Recurse

    Rename-Item -Path "C:\powershell\temp\main\" -NewName $folder

    (Get-Content -Path "C:\powershell\temp\$folder\settings.txt" -raw) -replace '<SERVERNAME>',"$server" | Set-Content "C:\powershell\temp\$folder\settings.txt"

    $app = (Start-Process "C:\powershell\temp\$folder\settings.txt" -passthru).ID


$form.Size = New-Object System.Drawing.Size(250,100)
$form.StartPosition = 'CenterScreen'

$label.Location = New-Object System.Drawing.Point(10,20)
$label.Size = New-Object System.Drawing.Size(200,20)
$label.Text = "Click 'cancel' to close Server $server"


$cancelButton.Location = New-Object System.Drawing.Point(10,40)
$cancelButton.Size = New-Object System.Drawing.Size(180,20)
$cancelButton.Text = 'Cancel'


    $result = $form.ShowDialog()

    if($result -eq [System.Windows.Forms.DialogResult]::cancel)
    {
        Stop-Process $app
        Remove-Item –path "C:\powershell\temp\$folder\" –recurse
    }


}
0

1 Answer 1

1

Give the computer a restart to clean up the memory leaks then you test this code.

[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")  
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") 
[void] [System.Windows.Forms.Application]::EnableVisualStyles() 

# The reason that your form does not open sometime is caused by a memory leak.  The code below should resolve the issue.
# If you add to the GUI them add that control below. If a variable does not have a .dispose() then .NET will clean it up.
# These are Events and will fire when the window closes.
# These will fix the memory leak issue.

$Form.Add_FormClosing({  
    $form.Dispose()
    $okButton.Dispose()
    $cancelButton.Dispose()
    $label.Dispose()
    $textBox.Dispose()
})

$Form2.Add_FormClosing({  
    $form2.Dispose()
    $label2.Dispose()
    $cancelButton2.Dispose()
})

# Hide PowerShell Console
Add-Type -Name Window -Namespace Console -MemberDefinition '
[DllImport("Kernel32.dll")]
public static extern IntPtr GetConsoleWindow();
[DllImport("user32.dll")]
public static extern bool ShowWindow(IntPtr hWnd, Int32 nCmdShow);
'
$consolePtr = [Console.Window]::GetConsoleWindow()
[Console.Window]::ShowWindow($consolePtr, 0)


# makes form
$form = New-Object System.Windows.Forms.Form
$form.Text = 'Data Entry Form'
$form.Size = New-Object System.Drawing.Size(200,180)
$form.StartPosition = 'CenterScreen'

$okButton = New-Object System.Windows.Forms.Button
$okButton.Location = New-Object System.Drawing.Point(10,70)
$okButton.Size = New-Object System.Drawing.Size(160,20)
$okButton.Text = 'OK'
$okButton.DialogResult = [System.Windows.Forms.DialogResult]::OK
$form.AcceptButton = $okButton
$form.Controls.Add($okButton)


$cancelButton = New-Object System.Windows.Forms.Button
$cancelButton.Location = New-Object System.Drawing.Point(10,100)
$cancelButton.Size = New-Object System.Drawing.Size(160,20)
$cancelButton.Text = 'Cancel'
$cancelButton.DialogResult = [System.Windows.Forms.DialogResult]::Cancel
$form.CancelButton = $cancelButton
$form.Controls.Add($cancelButton)

$label = New-Object System.Windows.Forms.Label
$label.Location = New-Object System.Drawing.Point(10,20)
$label.Size = New-Object System.Drawing.Size(170,20)
$label.Text = 'Please enter the Server name:'
$form.Controls.Add($label)

$textBox = New-Object System.Windows.Forms.TextBox
$textBox.Location = New-Object System.Drawing.Point(10,40)
$textBox.Size = New-Object System.Drawing.Size(160,20)
$form.Controls.Add($textBox)

$form.Topmost = $true

# Is this line needed
#$form.Add_Shown({$textBox.Select()}) # this sometimes will not let me type in the textbox
$result = $form.ShowDialog()

if ($result -eq [System.Windows.Forms.DialogResult]::OK)
{
    $server = $textBox.Text
    $server

    $folder = [System.IO.Path]::GetRandomFileName()

    Copy-Item -Path C:\powershell\main\  -Destination c:\powershell\temp –Recurse

    Rename-Item -Path "C:\powershell\temp\main\" -NewName $folder

    (Get-Content -Path "C:\powershell\temp\$folder\settings.txt" -raw) -replace '<SERVERNAME>',"$server" | Set-Content "C:\powershell\temp\$folder\settings.txt"

    $app = (Start-Process "C:\powershell\temp\$folder\settings.txt" -passthru).ID

# This is winform.  They work on comobjects and you not reuse the variable name because it will not
# free up memory resource when the are reused.  I rename your variables to get around this issue.
$form2 = New-Object System.Windows.Forms.Form
$form2.Size = New-Object System.Drawing.Size(350,250)    
$form2.StartPosition = 'CenterScreen'


$label2 = New-Object System.Windows.Forms.Label
$label2.Location = New-Object System.Drawing.Point(10,20)
$label2.Size = New-Object System.Drawing.Size(350,20)
$label2.Text = "Click 'cancel' to close Server $server"
$form2.Controls.Add($label2)

$cancelButton2 = New-Object System.Windows.Forms.Button
$cancelButton2.Location = New-Object System.Drawing.Point(10,80)
$cancelButton2.Size = New-Object System.Drawing.Size(180,40)
$cancelButton2.Text = 'Cancel'
$form2.CancelButton = $cancelButton2
$form2.Controls.Add($cancelButton2)


    $result = $form2.ShowDialog()

    if($result -eq [System.Windows.Forms.DialogResult]::cancel)
    {
        Stop-Process $app
        Remove-Item –path "C:\powershell\temp\$folder\" –recurse
    }


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

1 Comment

a couple years to late, but this did fix my problem and i've been using it now for the past few years. thanks alot! sorry for forgetting marking this as the solution

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.