System Details Output
### VSCode extensions:
[email protected]
[email protected]
[email protected]
[email protected]
### PSES version: 1.13.3.0
### PowerShell version:
Name Value
---- -----
PSVersion 7.0.0
PSEdition Core
GitCommitId 7.0.0
OS Microsoft Windows 10.0.18362
Platform Win32NT
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0鈥
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0
When trying to use Windows Forms in a Powershell script I get errors that I don't get when running the same script/lines in Powershell ISE
Running this:
# Init PowerShell Gui
Add-Type -AssemblyName System.Windows.Forms
# Create a new form
$LocalForm = New-Object system.Windows.Forms.Form
# Define the size, title and background color
$LocalForm.ClientSize = '500,300'
$LocalForm.text = "LazyAdmin - PowerShell GUI Example"
$LocalForm.BackColor = "#ffffff"
# Display the form
[void]$LocalForm.ShowDialog()
Should run smoothly without any errors.
However, I get the following errors:
SetValueInvocationException:
Line |
8 | $LocalForm.ClientSize = '500,300'
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| Exception setting "ClientSize": "Cannot convert the "500,300" value of type "System.String" to type "System.Drawing.Size"."
SetValueInvocationException:
Line |
10 | $LocalForm.BackColor = "#ffffff"
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| Exception setting "BackColor": "Cannot convert the "#ffffff" value of type "System.String" to type "System.Drawing.Color"."
I get it to work with the following changes :
$LocalForm.ClientSize = New-Object System.Drawing.Size(500,300)
$LocalForm.text = "Azure VM Decommission"
$LocalForm.BackColor = [System.Drawing.Color]::White
Notice that if I tried to use:
$LocalForm.BackColor = New-Object System.Drawing.Color("White")
I would get:
A constructor was not found. Cannot find an appropriate constructor for type System.Drawing.Color.
So I had to use
$LocalForm.BackColor = [System.Drawing.Color]::White
/cc @TylerLeonhardt Have you any thoughts about the issue?
@DanteNahuel do you get the same result running your code in a PowerShell 7 console outside of VS Code?
@TylerLeonhardt
Indeed, same errors.
This seems to be a type system thing; PowerShell isn't automatically processing the type lookup to coerce the constructor arguments to constructor calls.
In the case of System.Drawing.Size there is a constructor, so I wonder if this occurs because it's a struct.
In the case of System.Drawing.Color, there's no constructor but there is a ColorConverter.
@SteveL-MSFT and @daxian-dbw and possibly @vexx32 might know if changes have been made for coercions relating to this.
Sorry, It is known issue in .Net Core 3.1 and we get the fix with .Net Core 5.0 only. See #10869
I wonder if it's related to the TypeConverter changes that we ran into before with some of the System.Drawing.Point casts from string?
@vexx32 In the repo is a link to .Net Core 3 code where we can see full list affected Type converters.
@iSazonov so there's no fix currently?
Or do we fix it by installing .net core 5.0 in the running system?
I'm sorry if this is a silly question, I'm very new to Dev
edit: I stand corrected. There's no current Net Core 5.0 available
So I assume there's no fix for this if I'm running PS 7?
@DanteNahuel While I am working on fix .Net Core team fixed this for 5.0 and I stopped my work.
Yes, we get 5.0 release in October.
I still have no understanding how we could move PS 7.1 to .Net 5.0 since it is not LTS. So MSFT team should make a conclusion about #10869 /cc @SteveL-MSFT
@iSazonov so even if .Net Core 5.0 releases in October, PS 7.1 has yet to use it?
So this could be a long lasting bug?
That's bad...Not having an easy, linear way of using WinForms in new scripts is bad enough, but not having backwards compatibility for this functionality is huge.
PS 7.1 has yet to use it
PS 7.1 will use it, but PS 7 set to the LTS channel won't get that update
@rjmholt so the only workaround is the way I did it?
New-Object System.Drawing.Font("Microsoft Sans Serif",13)
and
?
not having backwards compatibility for this functionality is huge.
Unfortunately type-level APIs like this are out of our control; we rely on .NET's implementation completely.
It may turn out that this is something we can fix in PowerShell, but there are some things that are changed at the fundamental .NET layer.
so the only workaround is the way I did it?
If you're targeting 5.1 I'd recommend:
[System.Drawing.Font]::new("Microsoft Sans Serif", 13)
But the New-Object syntax is compatible with PowerShell 3 and up (compared to 5 and up), so it depends on the versions you're targeting.
Converting scripts to that syntax will work will all PowerShells.
Is there another kind of workaround you're looking for?
@rjmholt No, no, I understand this is completely dependant on .Net's implementation since it's an API call. But it still a big deal.
That workaround works, but the main problem is that the code is inconsistant which makes it a lot harder to read.