Конференция "KOL" » Предотвращение запуска второй копии программы [Delphi, Windows]
 
  • Md3r © (01.06.15 08:53) [0]
    Как правильно на KOL сделать предотвращение запуска второй копии программы.
    Вроде написано, то для этого нужно поместить какие-то команды в файл "<название проекта>_1.inc".
    Но как правильно завершить работу программы из файла "<название проекта>_1.inc"???
  • QAZ (01.06.15 15:14) [1]
    в файле <название проекта>_1.inc пишешь
    if <это единственный экземпляр> then begin

    в файле <название проекта>_4.inc пишешь
    end;

    как будешь определять единственность зависит от твоей фантазии
  • RusSun © (01.06.15 19:07) [2]

    var  Wnd: HWnd;
    ...
    Wnd := FindWindow('obj_Form', 'Название проги');
     if Wnd <> 0 then begin
       if IsIconic(Wnd) then SendMessage(Wnd, WM_SYSCOMMAND, SC_RESTORE, 0);
       SetForegroundWindow(Wnd);
       Exit;
     end;


    Как вариант.
  • RusSun © (29.10.15 19:14) [3]
    Посмотрел ещё раз этот вопрос.
    В чистом KOL будет работать:
    > RusSun ©   (01.06.15 19:07) [2]

    но в мск я его немного переделал,
    иначе не работает.)
    в событии procedure TForm1.KOLFormFormCreate(Sender: PObj);

    CreateMutex(Nil, True, 'Kol');
    If GetLastError <> 0 Then
                           Begin
    if IsIconic(Wnd) then SendMessage(Wnd, WM_SYSCOMMAND, SC_RESTORE, 0);
    SetForegroundWindow(Wnd);
    Halt;
                           End;



    Правда возник вопрос: Мутекс потом нужно освобождать?
  • Dimaxx © (31.10.15 00:10) [4]
    Читал, что лучше использовать Atom, а не Mutex. Атомы создаются во время работы винды и исчезают после перезагрузки, нигде не сохраняясь. Можно при закрытии приложения удалить руками.
  • QAZ (01.11.15 15:42) [5]

    > в событии procedure TForm1.KOLFormFormCreate(Sender: PObj);

    фигня метод, считай запускается прога создаются все элементы интерфейса и прочий мусор, а ты только надумал проверять уникальность...

    > Атомы создаются во время работы винды и исчезают после перезагрузки,
    >  нигде не сохраняясь

    прикольно, а где же сохраняются мутексы?
  • RusSun © (01.11.15 19:30) [6]
    Мне нужно было чтобы не запускалось ничего сверх 1 копии.

    С удовольствием посмотрю на Ваш метод. С уважением RusSun.
  • Игорь Шевченко © (02.11.15 10:33) [7]

    > Читал, что лучше использовать Atom, а не Mutex. Атомы создаются
    > во время работы винды и исчезают после перезагрузки, нигде
    > не сохраняясь


    Надо понимать, мутексы живут и при неработающей системе :)

    Мутекс - объект ядра и его область действия распространяется на сеанс или на все сеансы, атом - объект user и его область действия ограничивается конкректной Windowstation.
  • QAZ (02.11.15 10:33) [8]
    так мой метод описан в [1], странно что Вы не заметили :)
  • RusSun © (03.11.15 20:20) [9]
    Хорошо. В Вашем методе как Вы определяете <это единственный экземпляр>?
    :)
  • QAZ (04.11.15 14:00) [10]
    o'kay
    достаточно такого

    в файле проекта пишем все нужные переменные
    Var MemHnd : HWND;

    в файле <название проекта>_1.inc
    MemHnd := CreateMutex(NIL, FALSE, 'Название мутекса в идеале гуид');
    if GetLastError<>ERROR_ALREADY_EXISTS then  begin


    в файле <название проекта>_4.inc
    CloseHandle(MemHnd);
    end else begin
    //здесь все что касается того, что это не первый экземпляр
    end;


    в итоге стартует только апплет, если он используется вообще
  • QAZ (04.11.15 14:02) [11]
    пардон, не стартует, а только создается\уничтожается
  • RusSun © (04.11.15 15:52) [12]
    Спасибо)
  • RusSun © (05.11.15 17:37) [13]
    if GetLastError<>ERROR_ALREADY_EXISTS then  begin


    ругается на > ERROR_ALREADY_EXISTS не видит откуда "взято" модуль windows чего не хватает?
  • QAZ (06.11.15 17:53) [14]

    > модуль windows

    да естественно, в файле проекта добавь
  • RusSun © (12.11.15 19:19) [15]
    Спасибо за справку, Игорю Шевченко по данной тематике.

    Резюме
    { KOL MCK } // Do not remove this line!
    {$DEFINE KOL_MCK}

    program Pipet;

    uses
    KOL,Windows,Messages,
     Mainunit in 'Mainunit.pas' {Form1};
    var MemHnd: HWnd;
    {$R *.res}
    //{$R Pipet.res}
    {$R WinXP.res}

      begin // PROGRAM START HERE -- Please do not remove this comment

    {$IF Defined(KOL_MCK)} {$I Pipet_0.inc} {$ELSE}
     Application.Initialize;
     Application.CreateForm(TForm1, Form1);
     Application.Run;

    {$IFEND}
       end;
    end.

    { Pipet_1.inc
     This file is for you. Place here any code to run it
     just following Applet creation (if it present) but
     before creating other forms. E.g., You can place here
     <IF> statement, which prevents running of application
     in some cases. TIP: always use Applet for such checks
     and make it invisible until final decision if to run
     application or not. }


     MemHnd := CreateMutex(NIL, FALSE, 'KtqcfybLbkz');
    if GetLastError<> ERROR_ALREADY_EXISTS  then  begin   //  183

    { Pipet_4.inc
     This file is for you. Place here any code to be inserted
     after Run call, if necessary. }


     CloseHandle(MemHnd);
    //здесь все что касается того, что это не первый экземпляр
    if IsIconic(MemHnd) then SendMessage(MemHnd, WM_SYSCOMMAND, SC_RESTORE, 0);
    SetForegroundWindow(MemHnd);//MsgOk('Программа уже выполняется!');
    Exit;                  


    и
    { KOL MCK } // Do not remove this line!
    {$DEFINE KOL_MCK}

    program Pipet;

    uses
     KOL,Windows, Messages,
     Mainunit in 'Mainunit.pas' {Form1};

    {$R *.res}
    //{$R Pipet.res}
    {$R WinXP.res}

    var Wnd: HWnd;

    procedure CloseHandle_Wnd_AfterAll(Sender: PObj);
    begin
    if Wnd<>0 then CloseHandle(Wnd)
    end;

    begin // PROGRAM START HERE -- Please do not remove this comment

    Wnd := FindWindow('obj_Form', 'Название проги');

    if Wnd <> 0 then begin
      if IsIconic(Wnd) then SendMessage(Wnd, WM_SYSCOMMAND, SC_RESTORE, 0);
      SetForegroundWindow(Wnd);
      exit
                     end;

    {$IF Defined(KOL_MCK)} {$I Pipet_0.inc}

    Applet := NewApplet('');
    Applet.OnDestroy:=TonEvent(MakeMethod(nil,@CloseHandle_Wnd_AfterAll));

    {$ELSE}
     Application.Initialize;
     Application.CreateForm(TForm1, Form1);
     Application.Run;

    {$IFEND}
    end.


    Всё же есть отличие. Когда мы запускаем 2ую и последующие разы
    в одном случае фокус не возвращается к первому "экземпляру программы".
    Всем спасибо)
  • QAZ (13.11.15 15:28) [16]

    > Всё же есть отличие. Когда мы запускаем 2ую и последующие
    > разыв одном случае фокус не возвращается к первому "экземпляру
    > программы".

    так ты мой вариант скопипастил и понял неправильно :)

    а твой код записаный в самом проекте после begin // PROGRAM START HERE -- Please do not remove this comment будет автоматом задвигаться в дефины при каждом изменении форм
  • QAZ (13.11.15 15:41) [17]
    исправил непроверяя, надеюсь в этот раз справишься :)))
    { Pipet_4.inc
     This file is for you. Place here any code to be inserted
     after Run call, if necessary. }


    CloseHandle(MemHnd);
    end else begin
    //здесь все что касается того, что это не первый экземпляр
    Wnd := FindWindow('obj_Form', 'Название проги');
    if Wnd <> 0 then begin
    if IsIconic(Wnd) then SendMessage(Wnd, WM_SYSCOMMAND,SC_RESTORE, 0);
    SetForegroundWindow(Wnd);
    end;

    end;

  • RusSun © (13.11.15 20:12) [18]
    QAZ попробовал;)
    Но как мне кажется дело немного не этом.
    ИМХО: это связанно с тем как компилятор собирает эти части в воедино.
    Если куски разбиты _1.inc и _4.inc, то разделены и снова соединены.
    В файле проекта код цельный (нет дробности) в одном "теле" и работают как
    целое.
    Вопрос закрыт. Всем спасибо))
  • QAZ (14.11.15 12:38) [19]
    для компилятора все инклюды это непрерывная часть "основного" кода, за исключением естественно ресурсов

    з.ы. надеюсь ты догадался заменить 'Название проги' на реальное имя окна, которое в процессе работы естественно не должно меняться....
 
Конференция "KOL" » Предотвращение запуска второй копии программы [Delphi, Windows]
Есть новые Нет новых   [134427   +34][b:0][p:0.002]