Playing with Appbars via https://www.codeproject.com/Articles/6741/AppBar-using-C and https://github.com/tip2tail/t2tWinFormAppBarLib , I noticed that .NET 6 applications do not exit properly:
- The code reaches the bottom of
Program.Main(i.e.,Application.Run(new Form1());completes), but the application remains running. - If I call
Environment.Exit(0);at the bottom ofProgram.Main, that call hangs. - If the form has no child controls after its constructor runs, the issue does not happen.
- The issue does not happen in .Net Framework 4.8, but does in .NET 6 (as well as in .NET 7)
- Adding
Process.GetCurrentProcess().Kill();to the bottom ofProgram.Main"fixes" the problem. - Commenting out
Controls.Add(q)"fixes" the problem.
Below is sample application. Note that this is an intentionally simplified, self-contained reproduction. For example, it doesn't bother to position the window against the dock nor does it handle AppBar messaging. I was also able to reproduce the problem by directly using both of the libraries mentioned above, but felt that a self-contained example would be easier to follow.
Warning: If you run this code, close the window so that SHAppBarMessage((UInt32)AppBarMessages.Remove, ref msgData); has a chance to run. Otherwise, you'll likely lose a chunk of screen real estate until you reboot.
public partial class Form1 : Form
{
[DllImport("shell32.dll")]
public static extern UInt32 SHAppBarMessage(UInt32 dwMessage, ref APPBARDATA pData);
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public Int32 left;
public Int32 top;
public Int32 right;
public Int32 bottom;
}
[StructLayout(LayoutKind.Sequential)]
public struct APPBARDATA
{
public UInt32 cbSize;
public IntPtr hWnd;
public UInt32 uCallbackMessage;
public UInt32 uEdge;
public RECT rc;
public Int32 lParam;
}
public enum AppBarMessages
{
New = 0x00,
Remove = 0x01,
QueryPos = 0x02,
SetPos = 0x03,
GetState = 0x04,
GetTaskBarPos = 0x05,
Activate = 0x06,
GetAutoHideBar = 0x07,
SetAutoHideBar = 0x08,
WindowPosChanged = 0x09,
SetState = 0x0a
}
Control q;
public Form1()
{
InitializeComponent();
APPBARDATA msgData = new APPBARDATA();
msgData.cbSize = (UInt32)Marshal.SizeOf(msgData);
msgData.hWnd = Handle;
msgData.uCallbackMessage = 0x410; //0x400 WM_User
SHAppBarMessage((UInt32)AppBarMessages.New, ref msgData);
msgData = new APPBARDATA();
msgData.cbSize = (UInt32)Marshal.SizeOf(msgData);
msgData.hWnd = Handle;
msgData.uEdge = (UInt32)1; //ABE_Top
msgData.rc = new RECT()
{
left = 0,
right = SystemInformation.PrimaryMonitorSize.Width,
bottom = 50,
top = 0
};
SHAppBarMessage((UInt32)AppBarMessages.SetPos, ref msgData);
q = new Button();
Controls.Add(q);
}
protected override void OnClosing(CancelEventArgs e)
{
APPBARDATA msgData = new APPBARDATA();
msgData.cbSize = (UInt32)Marshal.SizeOf(msgData);
msgData.hWnd = Handle;
SHAppBarMessage((UInt32)AppBarMessages.Remove, ref msgData);
base.OnClosing(e);
}
protected override void OnClosed(EventArgs e)
{
base.OnClosed(e);
}
}