gurus, need your assistance, i'm stumped!
INTRO
I have a line of components, that are developed in C# .NET 4.0, comprising a big product.
The list includes Windows services, IIS web-applications, stand-alone executables, WPF executables launched via ClickOnce..
All components are distributed via MSI deployment packages and installed by a special (explicitly made for this purpose) stand-alone AppSuite
executable, also written in C#. At appropriate moment it launches msiexec.exe
, passing path to the .msi
package and all other necessary arguments (e.g. flags suppressing default MSI UI dialogs, enabling verbose logging, etc.).
Once the files are put in place by MSI (and some other things, e.g. IIS tasks, are done), it calls a CustomAction from the component's main assembly, which launches a configuration dialog where fine-tuning of the install happens (e.g. setting DB connection strings, specifying IP addresses and ports, and so on).
Here's how this process looks regularly:
To make things simpler (since a lot of configurational settings are same from one to the next) most components use the same dlgConfig
from a shared class library assembly. It provides methods for adjustment: hiding or showing certain controls, which are not used by all components. These methods are called by a CustomAction during its initialization prior to showing the dialog.
There are a few components which have explicitly different configurational settings, so they provide their own dlgConfig
s, which are subclassed from the shared one and initialized appropriately.
ISSUE
On occasion we notice a very weird look-n-feel behavior of dlgConfig
on Windows 10: it shows up chopped off at the bottom, hiding the [OK
] and [Cancel
] buttons (and possibly some other controls). Buttons are present and accessible by [Tab]-sequence or [Enter]-key, but not in view:
Once i got to see the entire install sequence i noticed that this only happens in the shared dialog! All the subclassed ones show up in proper height. To confirm i added a new "transparent" (i.e. not providing any new functionality) subclassed dialog to a component originally using the shared one; run the install and .. yes it showed up with the buttons. Huh???
Upon closer examination i noticed that in all configuration dialogs (shared or subclassed) text fields have diminished heights. That results in visible difference in height when there's a "look-up" button right next to the textbox.
I made a test WinForms executable that would simply launch the shared dlgConfig
and compared it to the one from the installation. Yet one more mystery is here. Every component has a DB connection, therefore to modify conn-string i made a single dlgSqlConn
, which is located in the same shared assembly where the root dlgConfig
is. And that dialog opens with all its fields and buttons in full view no matter what component is being installed!! Its appearance (fonts and control heights) is also affected in similar fashion, but at least there's no chopping off:
Very long time ago i set my personal preference in font selection for UI design to Tahoma
. I even enforce that selection in code in every form/dialog's constructor:
this.Font= new System.Drawing.Font( Utils.scFntTahoma, 8.25F );
Looking at printscreens i cannot say "oh that is not Tahoma!", but a slight difference in font sizes is fairly visible (offensive versions being just a tad bigger)..
Which goes against logic, 'cause the offensive textboxes have smaller height! Huh???
Dialogs are using AutoScaleMode
set to Font (it is default, and it is reasonable).
I tried all other choices. Dpi
was the worst: it shrinked the dialog with all controls proportionally, but had no impact on its height still being chopped off. Inherit
and None
have no effect.
I added the following 2 lines from usual WinForms initialization to the start of CustomAction installer class, but it also had no effect:
Application.EnableVisualStyles( );
Application.SetCompatibleTextRenderingDefault( false );
Further, when we set display scale to 150%, AppSuite
shows its UI with slightly fuzzy font (expected). Whereas these configuration dialogs look very sharp at that point. After resetting display scale to 100% we see AppSuite
sharp, but dlgConfig
s are now fuzzy.
Another related issue: for one component a label that in designer takes almost entire width of the dialog (with 8px margins) showed up stretched horizontally hiding a lot of content:
This led me to think about user context under which different processes run:
AppSuite
is launched by the current Windows user.- It starts initial
msiexec.exe
with command-line arguments - under current user. msiexec.exe
communicates withWindows Installer
service, running under LocalSystem,- Which launches 2 more instances of
msiexec.exe
, one under current user, another under LocalSystem. - That last one (running as %machine%\SYSTEM) is calling the CustomAction in the deployment assembly and eventually opening the dialog.
And one more finding: MessageBoxes produced from processes, running under current user (Test) and %machine%\SYSTEM (installed component) show distinctly different - one is fuzzy, other is not:
Well, my code has absolutely no control over MessageBox's font!!
So, it boils down to: somehow font selection for a new window is depending on user account which the process is run under (even when font is explicitly specified and exists)! Why? How?
Why does that affect only vertical dimension - all controls [except 1 label.. ??] retain their widths?
Can i fix it? If yes - how do i fix it?
I don't believe that behavior has anything to do with C# code (dialogs work and look perfectly on most machines, including many Win-10s, and there are only few flukes)
We could live with textbox heights being squished and fonts being slightly off, but chopping off the height of the dialog .. only when it is a shared one?? WFT's going on?!?!