Как позвонить в win32 CreateMutex из .Net - PullRequest
0 голосов
/ 15 декабря 2009

Я успешно создаю мьютекс .net, например так: SingleIns = новый Mutex (true, AppName); какое-то время. Он работает в XP, Vista, но, видимо, не в Windows7. Поэтому мне нужно сделать вызов взаимодействия с библиотекой Win32, чтобы другие компоненты Com могли идентифицировать мьютекс. Я нашел следующий код, но Win32Calls. не найден ... мне нужна сборка или ссылка? Заранее спасибо,

Найден код от: http://www.pinvoke.net/default.aspx/kernel32/CreateMutex.html

с использованием 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();
            }
        }
    }

Ответы [ 3 ]

2 голосов
/ 15 декабря 2009

Это не работает, потому что ваше объявление CreateMutex не находится в пространстве имен Win32Calls. Ваша следующая проблема заключается в том, что он все равно не будет работать, потому что вы забыли установить свойство SetLastError в атрибуте [DllImport]. Требуется, чтобы Marshal.GetLastWin32Error () возвращал ошибку.

Немного перемотав, использование класса Mutex в Win7 должно работать без проблем. Единственный способ сбоя, о котором я могу подумать, - это не добавлять префикс имени мьютекса к «Global \», чтобы мьютекс был виден во всех сеансах. Это немного отдаленно.

Более того, вы пытаетесь сделать что-то, что уже очень хорошо поддерживается в .NET Framework. Проект + Добавить ссылку, выберите Microsoft.VisualBasic. Сделайте так, чтобы ваш код Program.cs выглядел так:

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);
    }
  }
}

Преимуществом этого подхода является то, что он автоматически устанавливает фокус на работающий экземпляр вашей программы, когда пользователь запускает его снова. И вы можете переопределить метод OnStartupNextInstance, чтобы узнать, какие аргументы командной строки были использованы, и ответить соответствующим образом.

1 голос
/ 15 декабря 2009

В случае, если это может вам помочь, .NET Framework уже предоставляет оболочку объекта мьютекса Win32. См. System.Threading.Mutex . Есть все основные функции, в том числе возможность использовать префиксы, такие как «Global \».

0 голосов
/ 21 октября 2018

Должно быть так же просто, как:

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
}

создание мьютекса во всей системе - владелец: https://stackoverflow.com/a/3111740/1644202

...