1

can some one take a look to my C# source that has a crash issue? The program is supposed to omit unwanted double clicks the mouse sometimes sends and it works but after a while using the program it crashes.

The line that crashes:

Application.Run(new TheContext());

This is the error code:

An unhandled exception of type 'System.NullReferenceException' occurred in Gma.System.MouseKeyHook.dll

I'm using Visual studio community 2017

Source:

program.cs: https://pastebin.com/AX9VRi00

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;

namespace MouseFixer
{
    static class Program
    {

        static Mutex pmu;

        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {

            // Console.WriteLine("Hello");

            try
            {
                Mutex.OpenExisting("MouseFixer");

                MessageBox.Show("MouseFixer is already running", "", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                return;
            }
            catch
            {
                pmu = new Mutex(true, "MouseFixer");
            }

            Application.Run(new TheContext());

        }


    }
}

thecontext.cs: https://pastebin.com/G1cNzj4d

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

using Gma.System.MouseKeyHook;

using System.Diagnostics;


namespace MouseFixer
{
    public class TheContext : ApplicationContext
    {

        // https://stackoverflow.com/questions/30061813/intercept-mouse-click

        StringBuilder logText;

        long lastClickTime;
        long lastMouseUp;
        bool ignoreClick = false;

        void writeLog(string msg)
        {
            logText.Append(msg + Environment.NewLine);
            File.AppendAllText("log.txt", logText.ToString());
            logText.Clear();
        }

        bool errorShown = false;
        void errorMsg(string str)
        {
            if(!errorShown)
            MessageBox.Show(str);

            errorShown = true;
        }

        long getTime()
        {
           return DateTimeOffset.Now.ToUnixTimeMilliseconds();
        }

        public TheContext()
        {

            Application.ApplicationExit += new EventHandler(this.OnExit);

            logText = new StringBuilder();

            lastClickTime = getTime();
            lastMouseUp = getTime();

            Hook.GlobalEvents().MouseDownExt += async (sender, e) =>
            {
                if (e.Button == MouseButtons.Left)
                {
                    //  e.Handled = true;

                    //  writeLog("Handling click DOWN! " + e.Delta);

                    long lmu = (getTime() - lastMouseUp);

                    if (lmu < 10)
                    {
                        Debug.WriteLine("Too fast click - ignoring " + (getTime() - lastMouseUp) + Environment.NewLine);
                        e.Handled = true;
                        ignoreClick = true;
                    }

                    long lct = getTime() - lastClickTime;

                    lastClickTime = getTime();

                    Debug.WriteLine("MouseDOWN " + lct + " ( " + lmu + " ) " + Environment.NewLine);
                }
            };

            Hook.GlobalEvents().MouseUpExt += async (sender, e) =>
            {
                if (e.Button == MouseButtons.Left)
                {
                    if (!ignoreClick)
                    {

                        //  e.Handled = true;

                        //    writeLog("Handling click UP! " + e.Delta);

                        long lct = getTime() - lastClickTime;

                        lastClickTime = getTime();

                        Debug.WriteLine("MouseUP " + lct + Environment.NewLine);

                        lastMouseUp = getTime();


                    }
                    else
                    {
                        Debug.WriteLine("Ignoring click " + Environment.NewLine);

                        e.Handled = true;
                        ignoreClick = false;
                    }
                }
            };


                }

        private void OnExit(object sender, EventArgs e)
        {
          //  File.AppendAllText("log.txt", logText.ToString());
        }


    }

}
Coder547
  • 119
  • 9
  • It is regrettable that this library makes it so easy to get this wrong. Using Hook.GlobalEvents() is where the problem started, your program has no live reference to the class object that implements the hook. Next garbage collection destroys it and now you'll get an AccessViolationException when the OS makes the callback. The CLR turns it into NRE. Note the usage of m_GlobalHook in the author's [sample code](https://github.com/gmamaladze/globalmousekeyhook), that's the important reference that the GC needs to see. Don't hesitate to make it *static*. – Hans Passant Mar 17 '19 at 11:28

0 Answers0