1. Требуются разработчики и тестеры для проекта codebyOS. Требования для участия в проекте: Знание принципов работы ОС на базе Linux; Знание Bash; Крайне желательное знание CPP, Python, Lua; Навыки системного администрирования. Подробнее ...

    Скрыть объявление

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

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

  1. UXr

    UXr Гость

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

    Pasha Гость

    Репутация:
    0
    Для: UXr
    Мьютексы и Гугл
     
  3. UXr

    UXr Гость

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

    zubr Гость

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

    UXr Гость

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

    Pasha Гость

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

    SunSanych Well-Known Member

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

    Код:
    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 Гость

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

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

    UXr Гость

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

    zubr Гость

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

    SunSanych Well-Known Member

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

    +1
     
  12. UXr

    UXr Гость

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

    zubr Гость

    Репутация:
    0
    Вот примеры создания майлслота на прослушку (procedure TMyslotServerThread.Execute;) и записи в майлслот (procedure TMyslotClientThread.Execute;). Примеры на Delphi, но общие принципы одинаковы, суть в использовании API - функций CreateMailslot, CreateFile и WriteFile.
    Код:
    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 Гость

    Репутация:
    0
    Для: zubr
    IMHO через мьютексы будет просто короче:
    Код:
    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 Гость

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

    UXr Гость

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

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

    Pasha Гость

    Репутация:
    0
    Для: 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.996

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