How to call win32 CreateMutex from .Net

I've been successfully creating a .net mutex like this: SingleIns = new Mutex(true, AppName); for a while. It works in XP, Vista, but apparently not in Windows7. So I need to make an interop call to a Win32 library so other Com components can identify the mutex. I found the following code, but the Win32Calls. is not found... is there an assembly or reference I need? Thanks in advance,

Found code from: http://www.pinvoke.net/default.aspx/kernel32/CreateMutex.html

using System.Runtime.InteropServices;

    [DllImport("kernel32.dll")]
    public static extern IntPtr CreateMutex(IntPtr lpMutexAttributes, bool bInitialOwner, string lpName);


       // create IntPtrs for use with CreateMutex()
        IntPtr    ipMutexAttr = new IntPtr( 0 );
        IntPtr    ipHMutex = new IntPtr( 0 );

        try
        {
            // Create the mutex and verify its status BEFORE construction
            // of the main form.

            ipHMutex = Win32Calls.CreateMutex( ipMutexAttr,
                true, "CompanyName_AppName_MUTEX" );

            if (ipHMutex != (IntPtr)0)
            {
                // check GetLastError value (MUST use this call. See MSDN)

                int iGLE = Marshal.GetLastWin32Error();

                // if we get the ERROR_ALREADY_EXISTS value, there is
                // already another instance of this application running.

                if (iGLE == Win32Calls.ERROR_ALREADY_EXISTS)
                    // So, don't allow this instance to run.
                    return;
            }
            else    
            {    // CreateMutex() failed.
                // once the app is up and running, I log the failure from
                // within the frmMain constructor.
                bool m_bMutexFailed = true;
            }

            // construct the main form object and
            //form = new frmMain();

            // run the app.
            //Application.Run( form );

        }
        catch( Exception oEx )
        {
            //...handle it...
        }
        finally
        {
            // release the mutex
            if (ipHMutex != (IntPtr)0)
                Win32Calls.ReleaseMutex( ipHMutex );

            // cleanup the main form object instance.
            if (form != null) {
                form.Dispose();
            }
        }
    }

It doesn't work is because you CreateMutex declaration is not in the Win32Calls namespace. Your next problem is that it still won't work because you forgot to set the SetLastError property in the [DllImport] attribute. Required to make Marshal.GetLastWin32Error() return the error.

Rewinding a bit, using the Mutex class in Win7 should work without a problem. The only failure mode I can think of is not prefixing the mutex name with "Global\" so the mutex is visible in all sessions. That's a bit remote.

More to the point, you are trying to do something that is already very well supported in the .NET framework. Project + Add Reference, select Microsoft.VisualBasic. Make your Program.cs code look like this:

using System;
using System.Windows.Forms;
using Microsoft.VisualBasic.ApplicationServices;

namespace WindowsFormsApplication1 {
  class Program : WindowsFormsApplicationBase {
    [STAThread]
    static void Main(string[] args) {
      var prog = new Program();
      prog.EnableVisualStyles = true;
      prog.IsSingleInstance = true;
      prog.MainForm = new Form1();
      prog.Run(args);
    }
  }
}

Bonus goodies with this approach is that it automatically sets the focus to the running instance of your program when the user starts it again. And you can override the OnStartupNextInstance method to know what command line arguments were used and respond accordingly.

So I need to make an interop call to a Win32 library so other Com components can identify the mutex. I found the following code, but the Win32Calls. is not  In case it might help you, the .NET Framework already provides a wrapper of the Win32 mutex object. See System.Threading.Mutex. All of the major functionality is there, including the ability to use prefixes like "Global\".

In case it might help you, the .NET Framework already provides a wrapper of the Win32 mutex object. See System.Threading.Mutex. All of the major functionality is there, including the ability to use prefixes like "Global\".

So I need to make an interop call to a Win32 library so other Com components can identify the mutex. I found the following code, but the Win32Calls. is not  However, to release its ownership, the thread must call ReleaseMutex once for each time that the mutex satisfied a wait. Two or more processes can call CreateMutex to create the same named mutex. The first process actually creates the mutex, and subsequent processes with sufficient access rights simply open a handle to the existing mutex.

Should be as simple as:

private static System.Threading.Mutex _mutex = null;

const string guid = "{...GUID...}";
bool createdNew;

_mutex = new Mutex(true, guid, out createdNew);

if (!createdNew) {
    // it is in use already
}

system wide mutex creation - ownership: https://stackoverflow.com/a/3111740/1644202

You can use a mutex object to protect a shared resource from simultaneous the __try block includes a call to the TerminateThread function). Here, the FlipInt32 method takes the address of an Int32 value, accesses the data, negates it, and assigns the negated value to the original variable. In the following code, the caller's variable x would have its value changed from 10 to -10 by the FlipInt32 method: Int32 x = 10; FlipInt32 (ref x);

I've been successfully creating a .net mutex like this: SingleIns = new Mutex(true, AppName); for a while. It works in XP, Vista, but apparently not in Windows7. The following example uses the CreateMutex function to create a mutex object and the CreateThread function to create worker threads. When a thread of this process writes to the database, it first requests ownership of the mutex using the WaitForSingleObject function.

The CreateMutex API. using nsWin32Calls; // encapsulates Win32 calls namespace dsh Net and a Windows service running under different ids. I put this  A mutex can be in one of two states: signaled or nonsignaled. A mutex is in the signaled state when no thread owns the mutex. Threads take ownership of mutexes via the OpenMutex() or CreateMutex() functions. Ownership of a mutex is released by a call to the ReleaseMutex() function, which only has one parameter, the handle to the mutex to be released.

NET framework class Mutex is actually a wrapper class for the same Win32 You should note that Mutex is created with the call of the Win32 CreateMuteX call​. How to import methods from a non-managed Win32 API call using Platform Invocation Services (PInvoke). PInvoke allows managed code to call unmanaged methods that are implemented in a DLL. There are two ways that your C# code can directly call unmanaged code (code which .Net cannot see or have access to), a direct call to a function exported from a DLL or through a call to an interface method on a COM object.

Comments
  • Hmm. I just removed the Win32Calls portion of Win32Calls.CreateMutex and called CreateMutex direct... seems like it might work
  • Are you on a 64-bit version of Windows 7? A .NET Mutex should basically work the same in Windows 7 as in previous versions.
  • This is a better reference... msdn.microsoft.com/en-us/library/…
  • Yes it is a 64-bit Win7 machine...
  • Does the .NET mutex work as expected if you set your platform target to 'x86'? What you are seeing could also be a 32/64-bit interop issue (just an idea since you mentioned COM).
  • The problem is the .Net Mutex that works for XP and Vista, is not being detected by an unmanaged program (c++) for Windows 7. On Windows 7, GetLastError() always returns ERROR_SUCCESS whether the mutex exists or not. So, I am attempting to change the way I call the mutex to accomodate the native c++ code. NOTE: the .net mutex to .net works fine on Windows 7. The .Net mutex to interop c++ mutex is what is failing... could be on the c++ side.
  • I think the problem is not that the mutex not being created in a globally recognized way in Windows 7 since a service is creating it. I've appended "Global\" to the mutex name since some posts indicated that worked for them. However, that doesn't work for me either. (The mutex created by the service doesn't show up in the ProcessExplorer find handle, but I know it's there because if I run the same program, the mutex wanrns its already created.) Microsoft, what's going on with services and mutextes?
  • In my tests, it seems to be a user space thing.