Mutex открыт в приложении Delphi, проверен в консольном приложении C#

Я запускаю приложение Delphi и создаю для него мьютекс:

var
  AMutex: THandle;

function OpenMutex(const AMutexName: String): Boolean;
begin

  { Assume the Windows Mutext is already open }
  Result := False;

  { Is the Mutex already open? }
  if AMutex <> 0 then
    exit;

  { Try to create Windows Mutex }
  if CreateProgramMutex( AMutexName , AMutex) then
    Result := True
  else
    AMutex := 0;
end;

 function CreateProgramMutex( AMutexName: string; var AMutex: THandle ): boolean;
begin
    { Assume the new program mutex was created successfully. }
    Result := true;

    { Attempt to create a new mutex. }
    AMutex := CreateMutex(nil, False, PChar(AMutexName));

    { If we at least got a handle to the mutex... }
    if (AMutex <> 0) then
    begin

      if GetLastError = ERROR_ALREADY_EXISTS then begin
        { Close the handle, since it already exists. }
        CloseHandle(AMutex);

        { Set the return to show that it was already running. }
        Result := false;
      end;
    end else
      Result := false;
end;

И я пытаюсь из C#(как новичок) выяснить, запущено ли уже мое приложение в консольном приложении:

using System;
using System.Threading;

namespace ConsoleApplication1
{
    class OneAtATimePlease
    {
        private static Mutex _mutex;

        private static bool IsSingleInstance()
        {
            _mutex = new Mutex(false, "my mutex name");

            // keep the mutex reference alive until the normal 
            //termination of the program
            GC.KeepAlive(_mutex);

            try
            {
                return _mutex.WaitOne(0, false);
            }
            catch (AbandonedMutexException)
            {
                // if one thread acquires a Mutex object 
                //that another thread has abandoned 
                //by exiting without releasing it

                _mutex.ReleaseMutex();
                return _mutex.WaitOne(0, false);
            }
        }
        static void Main()
        {
            if (!IsSingleInstance())
                Console.WriteLine("already running");
            Console.ReadLine();

        }
    }
}

Даже приложение Delphi работает, IsSingleInstance возвращает true. Проверка мьютекса в консольном приложении Delphi с использованием того же кода Delphi работает. Я уверен, что это что-то очевидное, но я не мог понять, что я делаю неправильно.

PS: все делается в рамках одной пользовательской сессии Windows

2 ответа

Решение

Вы говорите, что ваша цель - проверить, запущено ли стороннее приложение (используя именованный мьютекс). Ну, для такого случая вы не должны пытаться создать объект мьютекса с заданным именем в вашем приложении, а только пытаться открыть его. Причина проста: если это стороннее приложение использует такой мьютекс, чтобы проверить, работает ли оно само по себе, вы фактически украли бы этот мьютекс для своего приложения, а этот чужой никогда не запустился бы.

Для вашей цели используйте функцию класса TryOpenExisting. Например:

using System;
using System.Threading;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            Mutex mutex;

            if (Mutex.TryOpenExisting("My unique mutex name", out mutex)) {
                try {
                    // with the used TryOpenExisting overload you can work with
                    // the mutex object here; you can wait for it or release
                    Console.WriteLine("Application is running!");
                }
                finally {
                    mutex.Close();
                }
            }
            else {
                Console.WriteLine("Application is NOT running!");
            }
            Console.ReadLine();
        }
    }
}

Я думаю, вам нужно проверить, существует ли мьютекс или нет.

Mutex appMutex = new Mutex(true, "MyMutex", out exclusive);
if (!exclusive)
{
  //Instance already existed
}
Другие вопросы по тегам