Monday, May 5, 2014

invoke or begininvoke cannot be called on a control until the window handle has been created c# splash screen issue using Microsoft.VisualBasic.dll

One app has this issue when first started

Searched around and found Microsoft rejected to fix this issue:

https://connect.microsoft.com/VisualStudio/feedback/details/769497/hidesplashscreen-causing-invalidoperationexception

One guy posted his work around:

Posted by Tony Tullemans on 1/15/2014 at 2:20 PM
I have had this InvalidOperationException problem for many years in a very large app that I have written but it does not occur very often - probably 1 out of every 300 launches. As ugly as it might appear, this is what I have done to overcome it and it seems to be working. Add this method to your main form.

Protected Overrides Sub OnLoad(ByVal e As System.EventArgs)
    Try
     MyBase.OnLoad(e)
    Catch ex As Exception
     If ex.StackTrace.Contains("HideSplashScreen") Then
        ' Just continue on as the HideSplashScreen call is made after the Form.Load() event is completed - i.e. just ignore it.
     Else
        ' Report the error however you would like.
     End If
    End Try
End Sub

The detail below:
You add reference Microsoft.Visualbasic.dll  to the app, so you can use splash screen

The sequence is before the main form load, the splash screen loads, then mainform loads, but splash during closing caused error. below is a log of sequence of events:

2014-05-07 11:22:29:925 - XYZ.OnCreateSplashScreen ~~~ Entering ~~~
2014-05-07 11:22:30:895 - XYZ.OnCreateSplashScreen ~~~ Exiting ~~~
2014-05-07 11:22:31:037 - XYZ.OnCreateMainForm ~~~ Entering ~~~
2014-05-07 11:22:38:369 - MyMainform..ctor ~~~ Exiting ~~~
2014-05-07 11:22:38:370 - XYZ.OnCreateMainForm ~~~ Exiting ~~~
2014-05-07 11:22:38:386 - MyMainform.OnLoad ~~~ Entering ~~~
2014-05-07 11:22:38:387 - MyMainform.MyMainform_Load ~~~ Entering ~~~
2014-05-07 11:22:38:417 - MyMainform.MyMainform_Activated ~~~ Entering ~~~
2014-05-07 11:22:38:418 - MyMainform.MyMainform_Activated ~~~ Exiting ~~~
2014-05-07 11:22:38:418 - MyMainform.MyMainform_Load ~~~ Exiting ~~~
2014-05-07 11:22:38:670 - OnLoad - this is a hide splash screen error
2014-05-07 11:22:39:041 - MyMainform.OnLoad ~~~ Exiting ~~~


Progam.cs
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Diagnostics;

namespace XYZ
{
    /// <summary>
    /// The Main entry point into the XYZ application
    /// </summary>
    static class Program
    {
        [DllImport("User32.dll", EntryPoint = "ShowWindowAsync")]
        private static extern int ShowWindowAsync(IntPtr hWnd, int swCommand);

        private const int SW_SHOWNORMAL = 1;
        private const int SW_SHOWMINIMIZED = 2;
        private const int SW_RESTORE = 9;

        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main(string[] args)
        {
            try
            {
                Process[] RunningProcesses = Process.GetProcessesByName("XYZ");

                if (RunningProcesses.Length > 1)
                {
                    MessageBox.Show("An instance of this application is already open.", "XYZ", MessageBoxButtons.OK);
                    ShowWindowAsync(RunningProcesses[0].MainWindowHandle, SW_SHOWMINIMIZED);
                    ShowWindowAsync(RunningProcesses[0].MainWindowHandle, SW_RESTORE);
                    Application.Exit();
                }
                else
                {
                    Application.EnableVisualStyles();
                    Application.SetCompatibleTextRenderingDefault(false);
                    new XYZ().Run(args); //this is run class to create splash screen and main form
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Error happenend on main " + ex.Message);
                
            }

       
        }
    }
}

XYZ.cs
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.VisualBasic.ApplicationServices;
using Wendys.Shared.BreakfastIndicator;
using Wendys.Shared;
using System.Windows.Forms;
using System.Reflection;

namespace XYZ
{
    /// <summary>
    /// The Main MIS class that handles UI event synchronization.
    /// </summary>
    public class XYZ : WindowsFormsApplicationBase
    {

        public xyz()
        {
        }

        #region Protected Methods
        /// <summary>
        /// Displays the Splash Screen
        /// </summary>
        protected override void OnCreateSplashScreen()
        {
            this.SplashScreen = new FrmSplash();
        }

        /// <summary>
        /// Initializes and calls the main form.
        /// </summary>
        protected override void OnCreateMainForm()
        {
            try
            {
                this.MainForm = new Yourmainform();
            }
            catch (Exception ex)
            {
                if (m_Log != null)
                {
                    m_Log.LogException("OnCreateMainForm", ex);
                }

                MessageBox.Show(String.Format("Error: {0}, please contact the Help Desk", ex.Message), "xxx", MessageBoxButtons.OK);
            }
          }
        #endregion
        }
    }


using System;
using System.Collections.Generic;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Reflection;
using System.Text;
using System.Windows.Forms;
using Wendys.Shared;
using Wendys.Shared.BreakfastIndicator;
using Wendys.Backoffice.StoreHours;

namespace XYZ
{
    public partial class MyMainForm : Form
    {

        protected override void OnLoad(System.EventArgs e)
        {
            string sMeth = MethodBase.GetCurrentMethod().Name;

            try
            {
                 base.OnLoad(e);
            }
            catch (Exception ex)
            {
                if (ex.StackTrace.Contains("HideSplashScreen"))
                {
                    // Just continue on as the HideSplashScreen call is made after the Form.Load() event is completed - i.e. just ignore it.
                    Log("OnLoad - this is a hide splash screen error")  //this log is my log routine
                }
                else
                {
                    // Report the error however you would like.

                }
            }
            finally
            {
                m_Log.ExitWithClassName(m_sClassName, sMeth);
            }
        }
   

        public MyMainForm() //Constructors
        {
            try
            {
            
            }
            catch (Exception ex)
            {
            }
            finally
            {
            }
        }

        private void MyMainForm_Load(object sender, EventArgs e)
        {
                 this.Activate(); 
        }
        
        private void MyMainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
        }
        #endregion

        private void MyMainForm_Shown(object sender, EventArgs e)
        {
        }

        private void MyMainForm_Activated(object sender, EventArgs e)
        {
         
        }
     }
}

No comments:

Post a Comment