1. Pascal / Говнокод #15886

    +96

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    Var
    h : THandle;
    
    procedure TMain.FormCreate(Sender: TObject);
    
    begin
    begin
    h := CreateMutex(nil, True, PChar(ExtractFileName(Application.ExeName)));
    if WaitForSingleObject(h, 0)<>0 then
    begin
    ShowMessage(‘Программа уже запущена!’);
    Application.Terminate;
    CloseHandle(h);
    end;
    end;

    http://moron.1side.ru/programmirovanie/delphi/zapret-povtornogo-zapuska-programmy.php

    Запостил: brutushafens, 02 Мая 2014

    Комментарии (17) RSS

    • Всяко лучше чем GlobalFindAtom
      Ответить
      • "Программа project1.exe уже запущена!"

        А в остальном (если дать мутексу более уникальное имя) - вроде как нормальный способ. Ну разве что WaitForSingleObject можно убрать, т.к. у CreateMutex был какой-то способ выяснить, запилил ли он новый мутех или вернул существующий.

        P.S. Ну и вместо выхода с сообщением, если есть возможность, лучше найти окно от той самой уже запущенной программы и кинуть ему какую-нибудь команду - например чтобы показалось или просто всплыло наверх...
        Ответить
    • А не проще список процессов получить и себя там поискать?
      Ответить
      • Нет. Вот это уж точно будет говном...
        Ответить
      • cleaned
        Ответить
      • Если переименовать файл, имя процесса будет другим, и работать не будет.
        Ответить
        • Кстати, если назвать программу svchost.exe, lsass.exe и как-то там еще, то диспетчер задач не захочет ее убивать. Т.к. проверяет как раз по имени.
          Ответить
          • cleaned
            Ответить
            • Вот поэтому я и писал выше, что надо не ExtractFileName(Application.ExeName), а что-нибудь мало-мальски уникальное, например в жабьем стиле с доменом/автором/прогой "ru.govnokod.Stertor.SuperMinusator2 ", uuid какой-нибудь ("edcfb5a3-3b1e-4add-8ebd-1a60b332266b") или что-то еще, что точно не встретится в других прогах.
              Ответить
    • procedure TfmMain.FormCreate(Sender: TObject);
      var Wnd: hWnd;
      buff: array[0.. 127] of Char;
      begin
      //Получили указатель на первое окно
      Wnd:=GetWindow(fmMain.Handle, gw_HWndFirst);
      // Поиск
      while Wnd<>0 do begin
      // Это окно предыдущей копии ?
      if (Wnd<>Application.Handle) and (GetWindow(Wnd, gw_Owner)=0) then begin
      GetWindowText(Wnd, buff, SizeOf(buff));
      if StrPas(buff)=Application.Title then begin
      SendMessage(Wnd, WM_SHOWWINDOW, 0, 0);
      SetWindowPos(Wnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE);
      Windows.ExitProcess(0);
      SetWindowPos(Wnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE);
      Application.Terminate;
      Exit;
      end;
      end;
      Wnd:=GetWindow(Wnd, gw_hWndNext);
      end;
      end;
      Ответить
    • в FormCreate??? не понял
      Ответить

    Добавить комментарий