Предотвращение повторного запуска программы.

Тема в разделе "Другие", создана пользователем UXr, 18 ноя 2007.

  1. UXr

    UXr Гость

    Необходим метод, позволяющий определить программе, что её копия загружена и выполняется.
    Если есть какие соображения поделитесь!
     
  2. Pasha

    Pasha Гость

    Для: UXr
    Мьютексы и Гугл
     
  3. UXr

    UXr Гость

    случай:
    программу "насильно" завершает другой процесс, будет ли уничтожен созданный мьютекс?
     
  4. zubr

    zubr Гость

    Для: UXr
    Смотри в MSDN описание функции CreateMutex.
     
  5. UXr

    UXr Гость

    случай:
    создаётся мьютекс с уникальным именем.
    GetLastError возвращает значение <> 0 (мьютекс уже имеется),
    но программа на самом деле не запущена. Как избежать такой ситуации?
     
  6. Pasha

    Pasha Гость

    Для: UXr
    Если мьютекс создается (т.е. CreateMutex вернул не NULL), то GetLastError вообще нет смысла вызывать.
     
  7. SunSanych

    SunSanych Well-Known Member

    Регистрация:
    28 июн 2006
    Сообщения:
    71
    Симпатии:
    0
    Для Windows приложения можно так:

    Код (Text):
    int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
    {
    TCHAR szClassName[] = "MyMegaProgram";

    // Преверяем, не было ли это приложение запущено ранее
    if( ::FindWindow(szClassName, NULL) )
    return FALSE;

    // Регистрируем класс окна
    wc.lpszClassName = szClassName;
    .
    .
    RegisterClassEx(&wc);
    .
    .
    // и т.д.
    }
     
  8. UXr

    UXr Гость

    пояснение:
    "Программа запущена" - это и значит что она запущена и при этом создала мьютекс.
    пояснение к случаю:
    какое-то приложение(не наша программа) уже создало мьютекс с именем, которое использует
    наша программа.

    Может необходим метод динамического формирования уникального имени на основе сис-ых параметров ОС или каких-нибудь других?
    Только какие(или какой) лучше использовать?
    Или кто предложет более простой но верный метод?
     
  9. UXr

    UXr Гость

    Для: SunSanych
    программа не имеет окон. Это будет работать?
    Но в любом случае я считаю, что для моей программы статическое задание имени (класса окна, мьютекса, что там ещё... атома(где-то встречал) не очень верный способ).
    Может у кого есть мысли о варианте наиболее действенного метода определения запущенной копии программы.
    (без ложных срабатываний)!
     
  10. zubr

    zubr Гость

    Вариант:
    Создаем майлслот (пайп, сокет) на прослушку. При получении определенного сообщения, даем определенный ответ. Прога при открытии посылает сообщение "Я открываюсь", а ей в ответ "Закройся" или ничего.
     
  11. SunSanych

    SunSanych Well-Known Member

    Регистрация:
    28 июн 2006
    Сообщения:
    71
    Симпатии:
    0
    Для: UXr
    Да, будет, лишь бы это было Windows-приложение.
    В Windows прежде чем создать любое окно, необходимо зарегистрировать для него так называемый "класс окна", для программиста это значит, что нужно заполнить поля структуры WNDCLASSEX и затем вызвать функцию RegisterClassEx(LPWNDCLASSEX wc) (или RegisterClass(LPWNDCLASS wc), как понятно из названия эта более старая).
    Причем класс окна регестрируется в системе и может использоваться любыми запущеными программами для своих целей. Удаляется при выходе из программы в которой был зарегестрирован.

    +1
     
  12. UXr

    UXr Гость

    Хотелось бы побольше про эти самые майлслот (пайп, сокет) узнать на примере в исходниках.
     
  13. zubr

    zubr Гость

    Вот примеры создания майлслота на прослушку (procedure TMyslotServerThread.Execute;) и записи в майлслот (procedure TMyslotClientThread.Execute;). Примеры на Delphi, но общие принципы одинаковы, суть в использовании API - функций CreateMailslot, CreateFile и WriteFile.
    Код (Text):
    procedure TMyslotServerThread.Execute;
    var
    mailslot, nb:cardinal;
    buf:PChar;
    s:string;
    begin
    mailslot:=CreateMailslot(PChar('\\.\Mailslot\Myslot'), 100,
    MAILSLOT_WAIT_FOREVER, nil);
    If mailslot=INVALID_HANDLE_VALUE then
    begin
    ShowMessage('Error slot');
    exit;
    end;
    buf:=StrAlloc(120);
    FillChar(buf^, 120, #0);
    While (not Terminated) do
    begin
    ReadFile(mailslot, buf^, 120, nb, nil);
    If nb<>0 then
    begin
    s:=string(buf);
    If s='close' then
    break;
    FOwner.Spisok.Add(s);
    Synchronize(ToSpisok);
    end;
    FillChar(buf^, 120, #0);
    end;
    StrDispose(buf);
    CloseHandle(mailslot);
    end;

    procedure TMyslotClientThread.Execute;
    var
    mailslot, nb:cardinal;
    buf:PChar;
    i:Integer;
    begin
    mailslot:=CreateFile(PChar(FAdress), GENERIC_WRITE, FILE_SHARE_READ, nil,
    OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
    If mailslot=INVALID_HANDLE_VALUE then
    begin
    ShowMessage('Error clientslot');
    exit;
    end;
    buf:=StrAlloc(Length(FMsg)+1);
    FillChar(buf^, Length(FMsg), #0);
    StrPCopy(buf, FMsg);
    For i:=1 to FCount do
    begin
    If Terminated then
    break;
    WriteFile(mailslot, buf^, Length(FMsg)+1, nb, nil);
    Sleep(10);
    end;
    StrDispose(buf);
    CloseHandle(mailslot);
    end;
     
  14. Pasha

    Pasha Гость

    Для: zubr
    IMHO через мьютексы будет просто короче:
    Код (Text):
    HANDLE hnd = CreateMutex(NULL, TRUE, m_pszAppName);
    if ( GetLastError() == ERROR_ALREADY_EXISTS && WAIT_ABANDONED != WaitForSingleObject(hnd, 1000))
    {
    AfxMessageBox("Application already running. ");
    return FALSE;
    }
    (с) не мое
     
  15. zubr

    zubr Гость

    Для: Pasha
    Никто не спорит. Но автора темы вариант с мьютексами не устраивает. У меня к сожалению времени нет проверить версию автора, что при убийстве приложения мьютекс остается.
     
  16. UXr

    UXr Гость

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

    Насколько я понял, прочитав MSDN, при любом способе завершения процесса, все связанные с ним дескрипторы закрываются.
    В XP мьютекс, созданный данной программой, при завершении из диспетчера уничтожался, проблем не было,
    но как это будет в 98-ой?
     
  17. Pasha

    Pasha Гость

    Для: zubr
    Мьютекс остается, и новый экземпляр приложения дожидается его с результатом WAIT_ABANDONED.
    Для: UXr
    <!--QuoteBegin-UXr+24:11:2007, 00:00 -->
    <span class="vbquote">(UXr @ 24:11:2007, 00:00 )</span><!--QuoteEBegin-->В XP мьютекс, созданный данной программой, при завершении из диспетчера уничтожался, проблем не было,
    но как это будет в 98-ой?
    [snapback]87189" rel="nofollow" target="_blank[/snapback]​
    [/quote] Точно так же. Если хочешь быть уверен в этом, найди старый MSDN, и посмотри.
     
Загрузка...
Похожие Темы - Предотвращение повторного запуска
  1. Kizarek86
    Ответов:
    17
    Просмотров:
    5.898

Поделиться этой страницей