Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WinForms] Related Forms closing #13150

Closed
NVoronchev opened this issue Feb 22, 2019 · 0 comments · Fixed by xamarin/xamarin-android#3105

Comments

@NVoronchev
Copy link
Contributor

@NVoronchev NVoronchev commented Feb 22, 2019

Assume one click a button on a Form ButtonedForm in the following program:

using System;
using System.Drawing;
using System.Windows.Forms;

namespace forms_closing_issue
{
    public partial class ButtonedForm : Form
    {
        private Button button = new Button();
        private Label label = new Label();
        
        public OnClosedForm onClosedForm;

        public ButtonedForm()
        {
            this.Controls.Add(button);
            this.Controls.Add(label);
            
            button.Click += click_Button;
            
            this.Text = "ButtonedForm";
            button.Text = "Click to Close";
        }

        protected void click_Button(object sender, EventArgs e)
        {
            // this.Controls.Remove(button); // !!!
            onClosedForm.Close();
        }
    }
    
    public partial class OnClosedForm : Form
    {
        public ButtonedForm buttonedForm;

        public OnClosedForm()
        {
            this.Text = "OnClosedForm";
        }

        protected override void OnClosed(EventArgs e)
        {
            base.OnClosed(e);
            buttonedForm.Close();
        }
    }
    
    public partial class MainForm : Form
    {
        public MainForm()
        {
            var onClosedForm = new OnClosedForm();
            var buttonedForm = new ButtonedForm();
            
            onClosedForm.buttonedForm = buttonedForm;
            buttonedForm.onClosedForm = onClosedForm;

            onClosedForm.Show();
            buttonedForm.Show();
            
            this.Text = "MainForm";
        }
    }
    
    static class Program
    {
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new MainForm());
        }
    }
}

Let's consider two cases:

  1. The line this.Controls.Remove(button); // !!! is commented ...
  2. ... and the line is uncommented.

The line is commented

The Button is always present on the Form ButtonedForm. Click on this button leads to the following exception:

System.ArgumentException: Cannot activate invisible or disabled control.
  at System.Windows.Forms.ContainerControl.set_ActiveControl (System.Windows.Forms.Control value) [0x00221] in /home/voron/src/mono/mcs/class/System.Windows.Forms/System.Windows.Forms/ContainerControl.cs:210 
  at System.Windows.Forms.Control.Select (System.Windows.Forms.Control control) [0x00018] in /home/voron/src/mono/mcs/class/System.Windows.Forms/System.Windows.Forms/Control.cs:1314 
  at System.Windows.Forms.Form.SelectActiveControl () [0x00079] in /home/voron/src/mono/mcs/class/System.Windows.Forms/System.Windows.Forms/Form.cs:238 
  at (wrapper remoting-invoke-with-check) System.Windows.Forms.Form.SelectActiveControl()
  at System.Windows.Forms.Form.WmClose (System.Windows.Forms.Message& m) [0x00115] in /home/voron/src/mono/mcs/class/System.Windows.Forms/System.Windows.Forms/Form.cs:2597 
  at System.Windows.Forms.Form.WndProc (System.Windows.Forms.Message& m) [0x000de] in /home/voron/src/mono/mcs/class/System.Windows.Forms/System.Windows.Forms/Form.cs:2425 
  at System.Windows.Forms.Control+ControlWindowTarget.OnMessage (System.Windows.Forms.Message& m) [0x00000] in /home/voron/src/mono/mcs/class/System.Windows.Forms/System.Windows.Forms/Control.cs:228 
  at System.Windows.Forms.Control+ControlNativeWindow.WndProc (System.Windows.Forms.Message& m) [0x00000] in /home/voron/src/mono/mcs/class/System.Windows.Forms/System.Windows.Forms/Control.cs:209 
  at System.Windows.Forms.NativeWindow.WndProc (System.IntPtr hWnd, System.Windows.Forms.Msg msg, System.IntPtr wParam, System.IntPtr lParam) [0x00085] in /home/voron/src/mono/mcs/class/System.Windows.Forms/System.Windows.Forms/NativeWindow.cs:240 

The origin of it is clear: System.Windows.Forms.Form.SelectActiveControl () tries to select the button on the already closed Form ButtonedForm. This is so, because disposed ButtonedForm stores the button in the filed active_control.

The line is ucommented

In this case forms hang. The Form ButtonedForm is closed and disposed, but the child_controls filed stores a link to the Label label. Note, that the label.Parent is already null. This condition turns the while loop in the System.Windows.Forms.Control.SelectNextControl() to be infinite. The unselectable label is the only child of Form, but the Parent link is broken. Therefore SelectNextControl() cann't move higher in the controls hierarchy and select a someone.

marek-safar added a commit that referenced this issue Mar 21, 2019
akoeplinger added a commit that referenced this issue May 12, 2019
Fixes #13150

Backport of #13151
grendello added a commit to grendello/xamarin-android that referenced this issue May 22, 2019
Add build-time support for *Windows* [mono archives][0].

Context: [xamarin-android/d16-2-with-mono-2018-10-via-6e8a50ea][1]
Context: mono/mono#14307
Context: mono/mono#14333

Fixes: mono/mono#13150
Fixes: mono/mono#14223
Fixes: mono/mono#14247
Fixes: mono/mono#14290

The [Xamarin.Android Designer][2] is an interesting beast: it runs a
Xamarin.Android-like Java stack on desktop macOS and Windows.  A Java
process is created, and that Java process loads:

  * *Desktop* Mono via `libmonosgen-2.0.dylib` (macOS)` or
    `libmonosgen-2.0.dll` (Windows).`
  * The Xamarin.Android runtime via `libmono-android.debug.dylib`
    (macOS) or `libmono-android.debug.dll` (Windows)
  * Other Java code (to render items to the screen)
  * `Mono.Android.dll` and other user assemblies (to render items to
    the screen).

Being "interesting" means it introduces all kinds of "fun":
`libmono-android.debug.dll` needs to be built *for Windows* (which is
why there's `#if WINDOWS` within `src/monodroid`),
`libmonosgen-2.0.dll` needs to be built for Windows (not a huge
issue), and -- "equally" important but *more* important regarding the
next few paragraphs! -- `mscorlib.dll` needs to target Windows.

`mscorlib.dll` is where things get annoying.  Once Upon A Time™,
Mono's `mscorlib.dll` was platform agnostic: build it for one
platform, it would run everywhere, as it would internally perform
runtime OS-checks to behave appropriately on Unix/Windows/etc.

That hasn't been true for awhile, but the Xamarin.Android build and
install environment still assumes it to be true.  Consequently, a
"Unix" `mscorlib.dll` is used by the Designer on Windows.  This
[*apparently* (?)][3] hasn't blown up catastrophically before, but
with the mono/2019-02 migration (b8c30f9) we have now entered
"catastrophic" territory: [Designer integration tests on Windows][4]
may fail because `System.Native` cannot be found:

	System.TypeInitializationException: The type initializer for 'System.Console' threw an exception. ---> System.DllNotFoundException: System.Native

The fix?  We need a *Windows*-targeting build of `mscorlib.dll` and
other BCL assemblies, in this case one that *doesn't* use the
`System.Native` native library in P/Invokes.

Enter the [Multi-platform monodroid BCL builds mono epic][5]: instead
of mono building and providing a *single* "mono archive" which
contains files for *every* supported architecture (macOS, Windows,
Android), mono will instead provide [*multiple* mono archives][6],
each supporting a particular subset.  For example, the
[archives for mono/2019-02@0bd00ec][7] include:

  * `android-release-Windows-0bd00ec58809f2a6ec5feff587b1117255b080fd.zip`:
    `monodroid`-profile BCL assemblies built to run on Windows.

  * `android-release-Darwin-0bd00ec58809f2a6ec5feff587b1117255b080fd.zip`:
    `monodroid`-profile BCl assemblies built to run on macOS, *and*
    `libmonosgen-2.0.dylib` for macOS, *and* `libmonosgen-2.0.dll`
    for Win32 & Win64, *and*...everything else (for now).

Thus, the fix for Designer-on-Windows: Download *all* required mono
archives (both Darwin & Windows for now) -- not just the Darwin
archive -- and extract those archives where the xamarin-android build
requires them to be.

Host-specific BCL files are placed into the
`$(MonoAndroidBinDirectory)\bcl`, e.g. the macOS-targeting
`mscorlib.dll` will be installed into:

	…/lib/xamarin.android/xbuild/Xamarin/Android/Darwin/bcl/mscorlib.dll

While Windows (currently) omits the OS name, and will install into:

	…/Xamarin/Android/bcl/mscorlib.dll

TODO:

  * Many of the host-specific BCL assemblies are "identical enough"
    to the Android-targeting BCL assemblies, e.g. the only difference
    between `System.Net.dll` for Windows & Android is the MVID GUID.
    We could be smarter about which files we redistribute, which
    would shrink the installation size.

  * Stop special-casing Windows within `$(MonoAndroidBinDirectory)`.
    Windows-specific files such as `cross-arm.exe` should be
    installed into `…/Xamarin/Android/Windows/cross-arm.exe`, and
    use `…/Xamarin/Android/Windows/bcl/mscorlib.dll` for the
    Windows-targeting monodroid-profile `mscorlib.dll`.

[0]: https://github.com/xamarin/xamarin-android/projects/10
[1]: xamarin@1f003cc
[2]: https://docs.microsoft.com/en-us/xamarin/android/user-interface/android-designer/
[3]: https://developercommunity.visualstudio.com/content/problem/440975/xamarin-xaml-designer-still-fails.html
[4]: https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=2634805
[5]: mono/mono#14333
[6]: https://jenkins.mono-project.com/view/All/job/archive-mono/
[7]: https://jenkins.mono-project.com/view/All/job/archive-mono/job/2019-02/232/Azure/
jonpryor added a commit to xamarin/xamarin-android that referenced this issue May 22, 2019
Add build-time support for *Windows* [mono archives][0].

Context: [xamarin-android/d16-2-with-mono-2018-10-via-6e8a50ea][1]
Context: mono/mono#14307
Context: mono/mono#14333

Fixes: mono/mono#13150
Fixes: mono/mono#14223
Fixes: mono/mono#14247
Fixes: mono/mono#14290

The [Xamarin.Android Designer][2] is an interesting beast: it runs a
Xamarin.Android-like Java stack on desktop macOS and Windows.  A Java
process is created, and that Java process loads:

  * *Desktop* Mono via `libmonosgen-2.0.dylib` (macOS)` or
    `libmonosgen-2.0.dll` (Windows).`
  * The Xamarin.Android runtime via `libmono-android.debug.dylib`
    (macOS) or `libmono-android.debug.dll` (Windows)
  * Other Java code (to render items to the screen)
  * `Mono.Android.dll` and other user assemblies (to render items to
    the screen).

Being "interesting" means it introduces all kinds of "fun":
`libmono-android.debug.dll` needs to be built *for Windows* (which is
why there's `#if WINDOWS` within `src/monodroid`),
`libmonosgen-2.0.dll` needs to be built for Windows (not a huge
issue), and -- "equally" important but *more* important regarding the
next few paragraphs! -- `mscorlib.dll` needs to target Windows.

`mscorlib.dll` is where things get annoying.  Once Upon A Time™,
Mono's `mscorlib.dll` was platform agnostic: build it for one
platform, it would run everywhere, as it would internally perform
runtime OS-checks to behave appropriately on Unix/Windows/etc.

That hasn't been true for awhile, but the Xamarin.Android build and
install environment still assumes it to be true.  Consequently, a
"Unix" `mscorlib.dll` is used by the Designer on Windows.  This
[*apparently* (?)][3] hasn't blown up catastrophically before, but
with the mono/2019-02 migration (b8c30f9) we have now entered
"catastrophic" territory: [Designer integration tests on Windows][4]
may fail because `System.Native` cannot be found:

	System.TypeInitializationException: The type initializer for 'System.Console' threw an exception. ---> System.DllNotFoundException: System.Native

The fix?  We need a *Windows*-targeting build of `mscorlib.dll` and
other BCL assemblies, in this case one that *doesn't* use the
`System.Native` native library in P/Invokes.

Enter the [Multi-platform monodroid BCL builds mono epic][5]: instead
of mono building and providing a *single* "mono archive" which
contains files for *every* supported architecture (macOS, Windows,
Android), mono will instead provide [*multiple* mono archives][6],
each supporting a particular subset.  For example, the
[archives for mono/2019-02@0bd00ec][7] include:

  * `android-release-Windows-0bd00ec58809f2a6ec5feff587b1117255b080fd.zip`:
    `monodroid`-profile BCL assemblies built to run on Windows.

  * `android-release-Darwin-0bd00ec58809f2a6ec5feff587b1117255b080fd.zip`:
    `monodroid`-profile BCl assemblies built to run on macOS, *and*
    `libmonosgen-2.0.dylib` for macOS, *and* `libmonosgen-2.0.dll`
    for Win32 & Win64, *and*...everything else (for now).

Thus, the fix for Designer-on-Windows: Download *all* required mono
archives (both Darwin & Windows for now) -- not just the Darwin
archive -- and extract those archives where the xamarin-android build
requires them to be.

Host-specific BCL files are placed into the
`$(MonoAndroidBinDirectory)\bcl`, e.g. the macOS-targeting
`mscorlib.dll` will be installed into:

	…/lib/xamarin.android/xbuild/Xamarin/Android/Darwin/bcl/mscorlib.dll

While Windows (currently) omits the OS name, and will install into:

	…/Xamarin/Android/bcl/mscorlib.dll

TODO:

  * Many of the host-specific BCL assemblies are "identical enough"
    to the Android-targeting BCL assemblies, e.g. the only difference
    between `System.Net.dll` for Windows & Android is the MVID GUID.
    We could be smarter about which files we redistribute, which
    would shrink the installation size.

  * Stop special-casing Windows within `$(MonoAndroidBinDirectory)`.
    Windows-specific files such as `cross-arm.exe` should be
    installed into `…/Xamarin/Android/Windows/cross-arm.exe`, and
    use `…/Xamarin/Android/Windows/bcl/mscorlib.dll` for the
    Windows-targeting monodroid-profile `mscorlib.dll`.

[0]: https://github.com/xamarin/xamarin-android/projects/10
[1]: 1f003cc
[2]: https://docs.microsoft.com/en-us/xamarin/android/user-interface/android-designer/
[3]: https://developercommunity.visualstudio.com/content/problem/440975/xamarin-xaml-designer-still-fails.html
[4]: https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=2634805
[5]: mono/mono#14333
[6]: https://jenkins.mono-project.com/view/All/job/archive-mono/
[7]: https://jenkins.mono-project.com/view/All/job/archive-mono/job/2019-02/232/Azure/
jonpryor added a commit to xamarin/xamarin-android that referenced this issue May 22, 2019
Add build-time support for *Windows* [mono archives][0].

Context: [xamarin-android/d16-2-with-mono-2018-10-via-6e8a50ea][1]
Context: mono/mono#14307
Context: mono/mono#14333

Fixes: mono/mono#13150
Fixes: mono/mono#14223
Fixes: mono/mono#14247
Fixes: mono/mono#14290

The [Xamarin.Android Designer][2] is an interesting beast: it runs a
Xamarin.Android-like Java stack on desktop macOS and Windows.  A Java
process is created, and that Java process loads:

  * *Desktop* Mono via `libmonosgen-2.0.dylib` (macOS)` or
    `libmonosgen-2.0.dll` (Windows).`
  * The Xamarin.Android runtime via `libmono-android.debug.dylib`
    (macOS) or `libmono-android.debug.dll` (Windows)
  * Other Java code (to render items to the screen)
  * `Mono.Android.dll` and other user assemblies (to render items to
    the screen).

Being "interesting" means it introduces all kinds of "fun":
`libmono-android.debug.dll` needs to be built *for Windows* (which is
why there's `#if WINDOWS` within `src/monodroid`),
`libmonosgen-2.0.dll` needs to be built for Windows (not a huge
issue), and -- "equally" important but *more* important regarding the
next few paragraphs! -- `mscorlib.dll` needs to target Windows.

`mscorlib.dll` is where things get annoying.  Once Upon A Time™,
Mono's `mscorlib.dll` was platform agnostic: build it for one
platform, it would run everywhere, as it would internally perform
runtime OS-checks to behave appropriately on Unix/Windows/etc.

That hasn't been true for awhile, but the Xamarin.Android build and
install environment still assumes it to be true.  Consequently, a
"Unix" `mscorlib.dll` is used by the Designer on Windows.  This
[*apparently* (?)][3] hasn't blown up catastrophically before, but
with the mono/2019-02 migration (b8c30f9) we have now entered
"catastrophic" territory: [Designer integration tests on Windows][4]
may fail because `System.Native` cannot be found:

	System.TypeInitializationException: The type initializer for 'System.Console' threw an exception. ---> System.DllNotFoundException: System.Native

The fix?  We need a *Windows*-targeting build of `mscorlib.dll` and
other BCL assemblies, in this case one that *doesn't* use the
`System.Native` native library in P/Invokes.

Enter the [Multi-platform monodroid BCL builds mono epic][5]: instead
of mono building and providing a *single* "mono archive" which
contains files for *every* supported architecture (macOS, Windows,
Android), mono will instead provide [*multiple* mono archives][6],
each supporting a particular subset.  For example, the
[archives for mono/2019-02@0bd00ec][7] include:

  * `android-release-Windows-0bd00ec58809f2a6ec5feff587b1117255b080fd.zip`:
    `monodroid`-profile BCL assemblies built to run on Windows.

  * `android-release-Darwin-0bd00ec58809f2a6ec5feff587b1117255b080fd.zip`:
    `monodroid`-profile BCl assemblies built to run on macOS, *and*
    `libmonosgen-2.0.dylib` for macOS, *and* `libmonosgen-2.0.dll`
    for Win32 & Win64, *and*...everything else (for now).

Thus, the fix for Designer-on-Windows: Download *all* required mono
archives (both Darwin & Windows for now) -- not just the Darwin
archive -- and extract those archives where the xamarin-android build
requires them to be.

Host-specific BCL files are placed into the
`$(MonoAndroidBinDirectory)\bcl`, e.g. the macOS-targeting
`mscorlib.dll` will be installed into:

	…/lib/xamarin.android/xbuild/Xamarin/Android/Darwin/bcl/mscorlib.dll

While Windows (currently) omits the OS name, and will install into:

	…/Xamarin/Android/bcl/mscorlib.dll

TODO:

  * Many of the host-specific BCL assemblies are "identical enough"
    to the Android-targeting BCL assemblies, e.g. the only difference
    between `System.Net.dll` for Windows & Android is the MVID GUID.
    We could be smarter about which files we redistribute, which
    would shrink the installation size.

  * Stop special-casing Windows within `$(MonoAndroidBinDirectory)`.
    Windows-specific files such as `cross-arm.exe` should be
    installed into `…/Xamarin/Android/Windows/cross-arm.exe`, and
    use `…/Xamarin/Android/Windows/bcl/mscorlib.dll` for the
    Windows-targeting monodroid-profile `mscorlib.dll`.

[0]: https://github.com/xamarin/xamarin-android/projects/10
[1]: 1f003cc
[2]: https://docs.microsoft.com/en-us/xamarin/android/user-interface/android-designer/
[3]: https://developercommunity.visualstudio.com/content/problem/440975/xamarin-xaml-designer-still-fails.html
[4]: https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=2634805
[5]: mono/mono#14333
[6]: https://jenkins.mono-project.com/view/All/job/archive-mono/
[7]: https://jenkins.mono-project.com/view/All/job/archive-mono/job/2019-02/232/Azure/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants
You can’t perform that action at this time.