'Using Windows Forms in powershell class

I'm trying to make my current Powershell code a little cleaner by using classes. I'm trying to make a Window class using Windows.Forms but I seem to be having trouble with it. This is what I currently have so far:

Window.psm1

using assembly System.Windows.Forms;

class Window {
    [System.Windows.Forms.Form]$Form;

    Window() {
        $this.Form = New-Object System.Windows.Forms.Form;
    }

    [void]BuildWindow() {
        $this.Form.ClientSize                            = New-Object System.Drawing.Point(600, 400)
        $this.Form.Text                                  = "Orion"
        $this.Form.TopMost                               = $false
        $this.Form.FormBorderStyle                       = "Fixed3D"
        $this.Form.MaximizeBox                           = $false
    }

    [void]ShowWindow() {
        $this.Form.ShowDialog();
    }
}

I'm then instantiating it in my start.ps1:

using module ".\Window.psm1";

$WindowObject = New-Object Window;

$WindowObject.BuildWindow();
$WindowObject.ShowWindow();

However, I'm getting the following error:

At C:\Orion\scripts\Window.psm1:4 char:6
+     [System.Windows.Forms.Form]$Form;
+      ~~~~~~~~~~~~~~~~~~~~~~~~~
Unable to find type [System.Windows.Forms.Form].
    + CategoryInfo          : InvalidOperation: (C:\Orion\scripts\Window.psm1:String) [], ParentContainsErrorRecordExc
   eption
    + FullyQualifiedErrorId : TypeNotFound

I'm new to Powershell scripting and classes especially, so I'm not sure what is going wrong here.



Solution 1:[1]

To clarify, your code as-is, works perfectly fine in a newer version of PowerShell (tested on the latest, 7.2.3). The issue is exclusively on Windows PowerShell, and to be honest, it's hard to explain why the error occurs however I can provide you what worked for me on that version.

using assembly System.Windows.Forms

class Window {
    [System.Windows.Forms.Form] $Form = [System.Windows.Forms.Form]::new()

    Window() { } # Removing the instantiation of the form from the ctor

    [void] BuildWindow() {
        $this.Form.ClientSize      = [System.Drawing.Point]::new(600, 400)
        $this.Form.Text            = "Orion"
        $this.Form.TopMost         = $false
        $this.Form.FormBorderStyle = "Fixed3D"
        $this.Form.MaximizeBox     = $false
    }

    [void] ShowWindow() {
        $this.Form.ShowDialog();
    }
}

On a personal note, I don't think having classes is a good idea when working with Windows Forms, it will make your code harder to read and by the looks of it, each form control will have their own hard-coded values which will be very hard to maintain and very hard to debug.

# would make more sense:
$form = [System.Windows.Forms.Form]@{
    ClientSize      = [System.Drawing.Point]::new(600, 400)
    Text            = "Orion"
    TopMost         = $false
    FormBorderStyle = "Fixed3D"
    MaximizeBox     = $false
}
$form.ShowDialog()

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1