0

Despite the Add-Type cmdlet, the PowerShell session does not recognize these types '[System.Windows.Forms.DialogResult]::OK' and '[System.Windows.Forms.DialogResult]::Cancel' inside a class. Do you understand why?

It works very well with a simple function like here in the creation of a simple inputBox https://learn.microsoft.com/en-us/powershell/scripting/samples/creating-a-custom-input-box?view=powershell-7.2 but in the form of a class I encounter this problem of assembly

Can you help me understand why assembly is not done ?

The problem is solved when I do the assembly in console instead of inside the file. Is it possible to run the program while keeping the Add-Type commands at the top of my main.ps1 file?

PS C:\> Add-Type -AssemblyName System.Windows.Forms
PS C:\> Add-Type -AssemblyName System.Drawing
PS C:\> .\main.ps1
    Add-Type -AssemblyName System.Windows.Forms
    Add-Type -AssemblyName System.Drawing
    Add-Type -AssemblyName PresentationFramework
    
    class Menu {
        [Object]$Form
        [Object]$Res
    
        Menu([String]$title,[Int]$lo,[Int]$la) {
            try {
                $this.Form = New-Object System.Windows.Forms.Form
                $this.Form.Text = $title
                $this.Form.Size = New-Object System.Drawing.Size($lo,$la)
                $this.Form.StartPosition = 'CenterScreen'
                $this.Form.Topmost = $true
            }
            catch {
                Throw "Error constructing new Menu"
            }
        }
    
        # Valeurs possibles d'enum : None;OK;Cancel;Abort;Retry;Ignore;Yes;No
        [Void]Ok_btn([int]$X,[int]$Y,[int]$lo,[int]$la) {
            $btn = New-Object System.Windows.Forms.Button
            $btn.Location = New-Object System.Drawing.Point($X,$Y)
            $btn.Size = New-Object System.Drawing.Size($lo,$la)
            $btn.Text = 'Ok'
            $btn.DialogResult = [System.Windows.Forms.DialogResult]::OK
            $this.Form.AcceptButton = $btn
            $this.Form.Controls.Add($btn)
        }
    
        [Void]Cancel_btn([int]$X,[int]$Y,[int]$lo,[int]$la) {
            $btn = New-Object System.Windows.Forms.Button
            $btn.Location = New-Object System.Drawing.Point($X,$Y)
            $btn.Size = New-Object System.Drawing.Size($lo,$la)
            $btn.Text = 'Cancel'
            $btn.DialogResult = [System.Windows.Forms.DialogResult]::Cancel
            $this.Form.CancelButton = $btn
            $this.Form.Controls.Add($btn)
        }

# ....
    }
> .\main.ps1
Au caractère C:\...\main.ps1:31 : 30
+         $btn.DialogResult = [System.Windows.Forms.DialogResult]::OK
+                              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Type [System.Windows.Forms.DialogResult] introuvable.
Au caractère C:\...\main.ps1:41 : 30
+ ...        $btn.DialogResult = [System.Windows.Forms.DialogResult]::Cance ...       
+                                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Type [System.Windows.Forms.DialogResult] introuvable.
    + CategoryInfo          : ParserError: (:) [], ParseException
    + FullyQualifiedErrorId : TypeNotFound
Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Samuel
  • 1
  • 1
  • 2
    PowerShell parses and emits type definitions (eg. `class C { ... }`) _before_ it executes the rest of the script, so `Add-Type` hasn't been executed by the time `[DialogResult]` is attempted resolved, hence the failure. You need to ensure the required assembly has already been loaded by the time you import/source the file that contains the type definition (as you've already found) – Mathias R. Jessen Sep 13 '22 at 14:43

0 Answers0