Why is my form fuzzy?

So you downloaded PowerShell Studio and designed the latest and greatest PowerShell application. Much blood, sweat, and coffee went into endless hours of pushing controls pixel by pixel, sizing things correctly, testing and debugging. And finally, you are ready! Ready to show off to your peers what you have created. Then you upload or email your exported script to your friends and colleagues.

(drum roll)

And they send you messages like this: “Dude, Windows 95 called, and it wants its app back.”, ”Why is it so small?”, “Can you make it not fuzzy?”.

Now you are obviously a little distraught and surprised. So you go and check if you missed something. Let’s say this is your design:

Design

I know, I know, yours is much prettier, more complex, and does a lot of things. But that is not important at the moment.

You run this in PowerShell Studio, and it looks just like you wanted:

Run SPS

Obviously, “they” must be doing something wrong, so you fire off an email asking for screenshots.

Your colleague Bert ran your exported script in the PowerShell console (Windows PowerShell or PowerShell 7, it makes no difference). This is what he sends:

Fuzzy console

It truly is fuzzy. Hmm, puzzling.

Your friend Ernie sends you this, using the PowerShell ISE:

image

Oh dear, that is even worse. Shrunken down to an unreadable size, controls cut off. What is going on!?

Now you go and package your script into an executable file using PowerShell Studio, and lo and behold, now it looks great everywhere!

But why is that?

Packaged exe

The answer is in the application manifest. By default, when you package a script, a manifest is added to the executable file. (See more here: Script Packaging Step-by-Step: Output Settings)

If you want to see the manifests embedded in executable files (yours or others), please feel free to download our handy-dandy Manifest Viewer.

If you open the packaged executable with the Manifest Viewer, you see the embedded manifest. The “secret” here is the <dpiaware>true</dpiaware> part highlighted as shown in the screenshot below:

image

If you package the same code with the “No manifest” option and compare it side-by-side to the one with a manifest, it becomes very clear that this is a vital part of any Windows Forms application.

Manifest compare

If you searched the internet for ways to make this work better without a manifest, you might have stumbled across code like this:

#Enable DPI awareness
$code = @"
[System.Runtime.InteropServices.DllImport("user32.dll")]
public static extern bool SetProcessDPIAware();
"@
$Win32Helpers = Add-Type -MemberDefinition $code -Name "Win32Helpers" -PassThru
$null = $Win32Helpers::SetProcessDPIAware()

Unfortunately, it does not quite do the same thing.

DPI aware at runtime

You may recognize the result as being the same as when you run the exported script in the ISE. More than likely, the ISE is running code very similar to this. If you look at the manifest of the PowerShell_ISE.exe, you will notice that it is missing a DpiAware tag.

The difference between a manifest and the code mentioned above is, more or less, one of timing. An application’s manifest is read when the executable image is loaded—before any code is executed. This initializes things differently and earlier.

Unfortunately, at this time, we have no remedy to fix exported scripts in the ISE or the console. Therefore, we recommend that you package your application as an executable file to get reproducible results.

Feedback

If you have any comment or suggestions, please feel free to use the comments below or post in our support forums.