Модераторы: Snowy, bartram, MetalFan, bems, Poseidon, Riply

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как недопустить запуск второй копии программы, Нашел решение, чем оно плохое? 
V
    Опции темы
instumental
Дата 8.1.2006, 18:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 4
Регистрация: 11.12.2005

Репутация: нет
Всего: нет



Искал как это сделать и находил всегда длиннющие решения, в которых не мог разобраться и которые еще к тому же и не работали почему-то. Сегодня сделал так:

это код dpr.

Код

program Project1;

uses
  Forms, Windows,
  Unit1 in 'Unit1.pas' {AppId0071},

var
  PrevAppCopy: HWND;
{$R *.res}

begin
  PrevAppCopy := FindWindow('TAppId0071', nil);
  if PrevAppCopy <> 0 then
  begin
  SetForegroundWindow(PrevAppCopy);
  Application.Terminate;
  Exit;
  end;
  Application.Initialize;
  Application.Title := 'Project1';
  Application.CreateForm(TAppId0071, AppId0071);
  Application.Run;
end.


AppId0071 - это имя главной формы,
TAppId071 - это имя класса. Работает так: ищем окно с именем класса как у нашей проги и если находим то показываем его и делам Terminate текущей копии. Код этот работает, глюков не нашел. Надо только чтобы имя класса было уникальным и не совпало с каким-нибудь другим приложением.

Вопрос у меня такой. Есть ли здесь какое-нибудь слабое место. Почему всегда предлагают какие-то длинные решения этой задачи, может я что-то не то сделал.
PM MAIL   Вверх
z-END
Дата 8.1.2006, 18:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прафесар™
****


Профиль
Группа: Комодератор
Сообщений: 3014
Регистрация: 13.3.2003
Где: Венья, Пиетари

Репутация: 1
Всего: 102



instumental ну как минимум:
1. может у другого приложения совпасть имя формы=)
2. возможно твое приложение в рантайме создает форму и в момент проверки оно небыло создано


--------------------
Каждый чилавек пасвоему праф...а памоему НЕТ! 

PM WWW ICQ   Вверх
Poseidon
Дата 8.1.2006, 19:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Delphi developer
****


Профиль
Группа: Комодератор
Сообщений: 5273
Регистрация: 4.2.2005
Где: Гомель, Беларусь

Репутация: 10
Всего: 133



Цитата(instumental @ 8.1.2006, 17:16 Найти цитируемый пост)

Искал как это сделать и находил всегда длиннющие решения, в которых не мог разобраться и которые еще к тому же и не работали почему-то.

Плохо искал smile http://forum.vingrad.ru/index.php?showtopic=56734


--------------------
Если хочешь, что бы что-то работало - используй написанное, 
если хочешь что-то понять - пиши сам...
PM MAIL ICQ   Вверх
instumental
Дата 8.1.2006, 22:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 4
Регистрация: 11.12.2005

Репутация: нет
Всего: нет



Цитата(z-END @ 8.1.2006, 18:26 Найти цитируемый пост)

instumental ну как минимум:
1. может у другого приложения совпасть имя формы=)
2. возможно твое приложение в рантайме создает форму и в момент проверки оно небыло создано

1. Конечно может совпасть. Но вероятность этого очень мала. Надо назвать позаковыристее и все.
Неприятность я заметил одну. Делфи создает форму с тем же именем. Поэтому при работающей делфи прога не запускается и считает что она уже работает, т.к. находит форму созданную delphi.
2. Не совсем понял. Ищем же главную форму приложения.

Цитата(Poseidon @ 8.1.2006, 19:07 Найти цитируемый пост)

Цитата(instumental @ 8.1.2006, 17:16 )

Искал как это сделать и находил всегда длиннющие решения, в которых не мог разобраться и которые еще к тому же и не работали почему-то.


Плохо искал  http://forum.vingrad.ru/index.php?showtopic=56734


Спасибо за ссылку. Я вообще-то не здесь искал (не на этом форуме). Находил такое что мамадарагая. Уже отчаился найти.
PM MAIL   Вверх
ivan219
Дата 8.1.2006, 23:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1121
Регистрация: 19.11.2005
Где: Планета земля

Репутация: нет
Всего: 12



А вот мой вареант оцените.


Код

unit Unit1;
.
.
uses.........., Unit2......;
.
.
var  A: Boolean;
  Form1: TForm1;
.
.
procedure TForm1.N7Click(Sender: TObject);
begin
  if A=false then
  begin
  Application.CreateForm(TForm2, Form2);
  Form2.Show;
  Form2.FreeOnRelease;
  A:=true;
  end
  else
  begin
  Exit;
  end;
end;



Код

unit Unit2;
.
.
implementation

uses Unit1;

{$R *.dfm}
.
.
procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
A:=false;
end;
end.


PM MAIL ICQ   Вверх
Delphins
Дата 8.1.2006, 23:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 93
Регистрация: 10.8.2005
Где: Россия, Краснодар

Репутация: нет
Всего: нет



Пеерменная A не распространяется на всю систему. В другой программе её не будет видно.
Самый лучший способ это послать WM сообщения всем окнам и если прийдет ответ то завершить себя. Иначе работать дальше.

PM MAIL ICQ Skype MSN   Вверх
Albinos_x
Дата 8.1.2006, 23:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Evil Skynet
****


Профиль
Группа: Комодератор
Сообщений: 3288
Регистрация: 28.5.2004
Где: X-6120400 Y-1 4624650

Репутация: 3
Всего: 108



Delphins
это он наверно проверку на форму2 делал...


--------------------
"Кто владеет информацией, тот владеет миром"    
Уинстон Черчилль
PM MAIL ICQ   Вверх
ivan219
Дата 8.1.2006, 23:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1121
Регистрация: 19.11.2005
Где: Планета земля

Репутация: нет
Всего: 12



Этот код для отдельно взятого окна.

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

А поповоду "послать WM сообщения всем окнам" можеш поподробнее раскозать ато и вправду лучше будет.
PM MAIL ICQ   Вверх
Akina
Дата 9.1.2006, 00:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: нет
Всего: 454



Создай мьютекс с явно уникальным именем. Если вернется ошибка already_exist - это дубликат. В отличие от атома и семафора он гарантированно умрет в момент выгрузки приложения.

Способ с сообщением вообще не универсален - приложение может быть настолько занято собой, что прозевает мессагу.


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
Albinos_x
Дата 9.1.2006, 00:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Evil Skynet
****


Профиль
Группа: Комодератор
Сообщений: 3288
Регистрация: 28.5.2004
Где: X-6120400 Y-1 4624650

Репутация: 3
Всего: 108



Цитата(ivan219 @ 8.1.2006, 23:55 Найти цитируемый пост)

Этот код для отдельно взятого окна.

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

проще:
Код
...
procedure TForm1.N7Click(Sender: TObject);    
begin
if Form2<>nil then
   begin
   MessageDlg('Форма уже существует',mtWarning,[mbOk],0);
   end
   else
   begin
   Application.CreateForm(TForm2, Form2);    
   Form2.Show;
   Form2.Update;
   end;
end;
...
procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);    
begin    
Form2.Free;    
end;


Это сообщение отредактировал(а) Albinos_x - 9.1.2006, 00:33


--------------------
"Кто владеет информацией, тот владеет миром"    
Уинстон Черчилль
PM MAIL ICQ   Вверх
ivan219
Дата 9.1.2006, 03:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1121
Регистрация: 19.11.2005
Где: Планета земля

Репутация: нет
Всего: 12



Да немного проще но после закрытия её незльзя болше открыть а сообшение осталось.

Вот ещё вареант.

Первая форма

Код

...
procedure TForm1.N7Click(Sender: TObject);
begin
if not Assigned(Form2) then
 begin
 Form2 := TForm2.Create(Application);
 Form2.Show;
 end
 else
 begin
 MessageDlg('Форма уже существует',mtWarning,[mbOk],0);
 end;
end;
...



Вторая форма

Код

...
procedure TForm2.FormDestroy(Sender: TObject);
begin
Form2 := nil;
end;

procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action := CaFree;
end;
...


Это сообщение отредактировал(а) ivan219 - 9.1.2006, 03:16
PM MAIL ICQ   Вверх
Poseidon
Дата 9.1.2006, 03:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Delphi developer
****


Профиль
Группа: Комодератор
Сообщений: 5273
Регистрация: 4.2.2005
Где: Гомель, Беларусь

Репутация: 10
Всего: 133



Я что-то не пойму, нужно запретить запуск прогаммы или формы? Если формы, то зачем такие извращения, если по Show и ShowModal больше одной копии формы и так не откроется?


--------------------
Если хочешь, что бы что-то работало - используй написанное, 
если хочешь что-то понять - пиши сам...
PM MAIL ICQ   Вверх
Guedda
Дата 9.1.2006, 10:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Подрывник
****


Профиль
Группа: Завсегдатай
Сообщений: 3137
Регистрация: 27.12.2005
Где: Ростов-на-Дону

Репутация: 3
Всего: 78



А что, так нельзя?:
Код

program ANV;

uses
  Forms,
  Windows,
  Dialogs,
  Main in 'Main.pas' {MainForm};

const 
  MEM_F_S = 1024;
  MEM_F_N = 'BU'; //Здесь любое имя можешь написать.

var
  MemHnd : HWND;

{$R *.res}

begin
  MemHnd := CreateFileMapping(HWND($FFFFFFFF), nil, PAGE_READWRITE, 0, MEM_FILE_S, MEM_FILE_N);
  if GetLastError <> ERROR_ALREADY_EXISTS then begin
    Application.Initialize;
    Application.Title := 'Thenoid';
    Application.CreateForm(TMainForm, MainForm);
    Application.Run;
  end else MessageDlg('Приложение уже в рантайме!!!', mtError, [mbOk], 0);
  CloseHandle(MemHnd);
end.



--------------------
Ll 2
PM MAIL WWW ICQ Skype GTalk   Вверх
Delphins
Дата 9.1.2006, 22:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 93
Регистрация: 10.8.2005
Где: Россия, Краснодар

Репутация: нет
Всего: нет



Если для формы то нафига столько кода? smile
Она не откроется вторая. Конечно если вы её не создаёте в RunTime.

Самый просто способ это сообщения WM.

Как для программы так и для отдельных форм.

Код

const
  wm_mymsg = WM_USER+66;
//---------
procedure WM_MYAPPEXIST( {Че тут не помню... :(( wmparam1 и wmparam2 чтоли.} ); message wm_mymsg;


а потом процдуру обрабатывать. Сообщение обработается всегда. Кроме случаев когда оно зависло.
Сообщения ставятся в очеред на обработку.
Отсылааются они вроде как через SendMessage.
Неогу сказать точно потому, что Delphi перестал запускаться.
PM MAIL ICQ Skype MSN   Вверх
Romero
Дата 8.3.2006, 16:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 129
Регистрация: 17.6.2005

Репутация: 1
Всего: 1



Я в одной из своих прог использовал следующий механизм:
При запуске программа пишет куда-либо (в файл или реестр) свой PID. Перед записью из того же места считывается PID предыдущей копии программы и выполняется TerminateProcess.
2 нюанса:
- мне нужно было именно перезапускать прогу (убивать старую версию) в случае повторного запуска;
- есть небольшой шанс, что убьешь левый процесс (в случае, если предыдущая версия проги завершилась и был запущен процесс с тем же PID).
PM   Вверх
Страницы: (3) Все [1] 2 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: WinAPI и системное программирование"
Snowybartram
MetalFanbems
PoseidonRrader
Riply

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Delphi обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи
  • 99% ответов по WinAPI можно найти в MSDN Library, оставшиеся 1% здесь

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, bartram, MetalFan, bems, Poseidon, Rrader, Riply.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: WinAPI и системное программирование | Следующая тема »


 




[ Время генерации скрипта: 0.1144 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.