Конференция "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]
    для компилятора все инклюды это непрерывная часть "основного" кода, за исключением естественно ресурсов

    з.ы. надеюсь ты догадался заменить 'Название проги' на реальное имя окна, которое в процессе работы естественно не должно меняться....
  • Dimaxx © (14.11.15 13:47) [20]
    > Мутекс - объект ядра и его область действия распространяется на сеанс или
    > на все сеансы, атом - объект user и его область действия ограничивается
    > конкректной Windowstation.
    В той статье было краткое объяснение почему, но за давностью лет я забыл конкретику, запомнилось то, что лучше атом. Да и не понадобилось мне это никогда. К тому же, емнип, используя мьютекс таким образом можно запустить только 1 копию программы вообще, независимо от кол-ва активных пользователей, а с атомом каждый пользователь сможет запустить только 1 копию программы под своей учеткой. Если пользователь один, тогда неважно что использовать, а если создастся ситуация, когда запустив копию под своей учеткой, понадобится сменить пользователя и запустить же под его учеткой ту же программу, может выйти облом. Поправьте меня, если неправ.
  • QAZ (14.11.15 20:36) [21]

    > может выйти облом. Поправьте меня, если неправ.

    ты неправ, у каждого пользователя свои изолированные мутексы будут
  • RusSun © (14.11.15 21:51) [22]
    > з.ы. надеюсь ты догадался заменить 'Название проги' на реальное
    > имя окна, которое в процессе работы естественно не должно
    > меняться....


    https://yadi.sk/d/Y--1jJzgkTV2p
    первый inc
    https://yadi.sk/d/kxnWBMG0kTUy9
    второй нет
  • QAZ (15.11.15 12:05) [23]

    > RusSun ©   (14.11.15 21:51) [22]

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

    а твой вариант, как я уже писал, при первом же открытии в моей дельфи сразу МСКой задвигается за дефин и игнорируется при компиляции как ВКЛкод

    вообще в этом плане можно было нормально переделать генератор кода МСК, в более логичный и юзабительный вид, чтоб работал код до создания всего сущего
  • RusSun © (15.11.15 15:58) [24]
    >QAZ

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

    Вообщем сделал так.
    в варианте первый inc

    1 кинул апплет на форму
    2 удалил object KOLProj: TKOLProject с формы в Design

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