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.