0

From a console app which has no window (ProcessWindowStyle.Hidden) I need to start and display a Form (yes - I know this is bad design which should be avoided).

My first intent was the following code:

var thread = new Thread(() =>
                            {
                                Application.EnableVisualStyles();
                                Application.SetCompatibleTextRenderingDefault(false);
                                Application.Run(new MyCustomMessageBoxForm());
                            });
thread.SetApartmentState(ApartmentState.STA);
thread.IsBackground = false;
thread.Start();
thread.Join();

This does not work: The form will be created, but is hidden. You manually need to set Visible to true to make it work as expected (see answer of Show Form from hidden console application).

var thread = new Thread(() =>
                            {
                                Application.EnableVisualStyles();
                                Application.SetCompatibleTextRenderingDefault(false);
                                Application.Run(new MyCustomMessageBoxForm { Visible = true }); //Note the change
                            });
thread.SetApartmentState(ApartmentState.STA);
thread.IsBackground = false;
thread.Start();
thread.Join();

Neither the answer nor I have an explanation why you have to set the visibility explicitly – in a 'normal' console app (with a visible console window) this is not required.

Anyways, what puzzles me more is that after calling MessageBox.Show this explicit set is no longer required to make it work - even more, it doesn’t matter where in the application MessageBox.Show is called (whether it's the same thread or not), so both samples below work as expected:

MessageBox.Show("test"); // Note: called on other thread
var thread = new Thread(() =>
                            {
                                Application.EnableVisualStyles();
                                Application.SetCompatibleTextRenderingDefault(false);
                                Application.Run(new MyCustomMessageBoxForm()); //Works
                            });
thread.SetApartmentState(ApartmentState.STA);
thread.IsBackground = false;
thread.Start();
thread.Join();

and

var thread = new Thread(() =>
                            {
                                MessageBox.Show("test"); //Note: called on same thread
                                Application.EnableVisualStyles();
                                Application.SetCompatibleTextRenderingDefault(false);
                                Application.Run(new MyCustomMessageBoxForm()); //Works
                            });
thread.SetApartmentState(ApartmentState.STA);
thread.IsBackground = false;
thread.Start();
thread.Join();

So my question is: Why does this happen - what (cross thread!) side effects does calling MessageBox.Show involve?

Note: I used .NET Framework, the behaviour might be different for .NET Core or .NET 5.

BudBrot
  • 1,341
  • 2
  • 24
  • 44
  • 2
    Something something MessageBox.Show() being evil and starting its own message pump and probably more, just wait for Hans Passant. – CodeCaster Dec 23 '20 at 11:09
  • "From a console app which has no window (ProcessWindowStyle.Hidden) I need to start and display a Form (yes - I know this is bad design which should be avoided)." So you don't really need a Console app? Use a standard WinFoms app, but pass your own [ApplicationContext](https://docs.microsoft.com/en-us/dotnet/api/system.windows.forms.applicationcontext?view=net-5.0) to `Application.Run()`. This way you get an app that doesn't show an interface unless you want it to, and it won't end unless you explicitly kill it from code. [Example here](https://stackoverflow.com/a/32909558/2330053). – Idle_Mind Dec 23 '20 at 14:54
  • Read the notes here: [Can I keep worker and GUI separate without cross thread exceptions?](https://stackoverflow.com/a/61386769/7444103) (Console app with *interactive* Forms) – Jimi Dec 23 '20 at 19:51
  • Also, [here](https://referencesource.microsoft.com/#System.Windows.Forms/winforms/Managed/System/WinForms/Form.cs,2632) and the code [here](https://referencesource.microsoft.com/#System.Windows.Forms/winforms/Managed/System/WinForms/Form.cs,6071) and [here](https://referencesource.microsoft.com/#System.Windows.Forms/winforms/Managed/System/WinForms/Form.cs,6132) – Jimi Dec 23 '20 at 20:03

0 Answers0