Powershell-based GUI behaves differently when run from PS command prompt and PS ISE

Evgeny Lotosh 156 Reputation points
2021-12-23T10:52:46.827+00:00

I've written a GUI in Powershell. It's just a bunch of text fields and buttons that call REST APIs on a remote server. When I run it from Powershell ISE editor, everything is working as expected. However, if I run it from a usual PS command line OR from ISE when the script is not opened in the editor, it works completely different. Visual element styles are Win95-like, setting text field content doesn't always work, popup message boxes don't appear ("not found" messages) and so on.

The form is creating by adding the Winforms assembly (Add-Type -assembly System.Windows.Forms) and then calling constructors for each visual element (like $MainForm = New-Object System.Windows.Forms.Form).

What could be the reason for such differences?

Powershell 5.1 on Windows 10. X64 all versions.

Windows Server PowerShell
Windows Server PowerShell
Windows Server: A family of Microsoft server operating systems that support enterprise-level management, data storage, applications, and communications.PowerShell: A family of Microsoft task automation and configuration management frameworks consisting of a command-line shell and associated scripting language.
5,432 questions
{count} votes

Accepted answer
  1. MotoX80 32,526 Reputation points
    2021-12-27T19:44:36.497+00:00

    There is a System.Windows.Messagebox...

    https://learn.microsoft.com/en-us/dotnet/api/system.windows.messagebox?view=windowsdesktop-6.0

    And a System.Windows.Forms.Messagebox...

    https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.messagebox?view=windowsdesktop-6.0

    It would appear that ISE loads the first assembly, I would guess for it's own user interface. If your script loads the System.Windows.Forms assembly, then use the Forms.Messagebox.

    Add-Type -assembly System.Windows.Forms  
    [System.Windows.Forms.MessageBox]::Show("Can't resolve $($Name) into FQDN. Check spelling", "Failure", "OK", "Error")  
    

    I see what you mean about the different variable data. ISE is being deprecated, so I tried VSCode too. It acts like ISE. I guess it's something to do with running in a debugger.

    @Rich Matheisen any ideas on this? What did I miss?

    Function DoSomething() {  
        "Doing something."  
        "DS - I see your name is {0}" -f  $UserCredentials.UserName  
        $global:UserCredentials = Get-Credential -Message "Enter login and password for globalcredentials."  
        "DS - Your global name is {0}" -f  $Global:UserCredentials.UserName  
        "DS - I see your name is {0}" -f  $UserCredentials.UserName  
    }  
    $UserCredentials = Get-Credential -Message "Enter login and password for script level credentials."  
    "Your name is {0}" -f  $UserCredentials.UserName  
    DoSomething  
    

    160761-capture.jpg


3 additional answers

Sort by: Most helpful
  1. AnthonyGuyon 1 Reputation point
    2021-12-23T15:53:18.777+00:00

    I have written a few GUI's in PowerShell using both forms and xaml and did not observe the behaviour you describe. I always write in the ISE and run in the console. The console does have vagaries since the ISE has a dedicated separate UI thread to handle your GUI elements - whereas the console is truly single threaded..

    I think as MotoX80 says we need a code sample to understand how and when your elements are being constructed or skipped as the case may be.

    0 comments No comments

  2. Limitless Technology 39,466 Reputation points
    2021-12-24T19:45:49.523+00:00

    Hello @Evgeny Lotosh

    There are many differences between ISE and Powershell session: https://devblogs.microsoft.com/powershell/differences-between-the-ise-and-powershell-console/

    Ideally, you could share some snippets form your code in order for the community to help with it.

    Hope this helps with your query,

    -------
    --If the reply is helpful, please Upvote and Accept as answer--

    0 comments No comments

  3. Evgeny Lotosh 156 Reputation points
    2021-12-27T11:05:05.093+00:00

    The script has about 1000 lines of code, so it's somewhat difficult to place it all here. However, there is a couple of typical examples. The assembly is loaded by the script with command

    Add-Type -assembly System.Windows.Forms

    1) Dialog box calls work in ISE but fail in the command line:

    [void] [System.Windows.MessageBox]::Show("Can't resolve $($Name) into FQDN. Check spelling", "Failure", "OK", "Error")
    

    Error message: "Unable to find type [System.Windows.MessageBox]".

    2) Addressing global variables in a method works differently. The below code is called from a function, UserCredentials variable is defined on the script level.

        $global:UserCredentials = Get-Credential -Message "Enter login and password"
        $UserNameTextbox.Text = $UserCredentials.UserName
    

    This code works as expected in ISE. However, in the command line, the text in the text field is not set (the second line of code) unless the variable is addressed as $global:UserCredentials.UserName. It was a mistake in the code (of course, the global variable should be addressed with "global") but it worked in ISE nonetheless. Why the difference?

    0 comments No comments