Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

повторный запуск [D7, WinXP]


Страницы:   1 2

urri ©   (2005-05-20 20:51:00) 

Здравствуйте! Помогите пожалуйста с проблемой... "Как в исключить повторный запуск приложения" Заранее благодарен!


alpet   (2005-05-23 13:57:00) [1]

С окнами лучше не связываться при решении этой задачи. Когда запускаются два экземпляра, с очень малой задержкой, может получится так что до выполнения проверки ни один из них не успеет создать окно (форму), и в итоге оба процесса эту проверку пройдут. Так-что события рулят...


begin...end   (2005-05-22 21:21:00) [2]

> GuAV ©   (22.05.05 20:48) [19]

Твоя правда. Приношу извинения и прошу всех не обращать внимания на пост [18].


GuAV   (2005-05-22 20:48:00) [3]


> Пусть CreateMutex <> 0, тогда ошибки нет и
> GetLastError проверять незачем.

Нет. CreateMutex + F1


begin...end   (2005-05-22 18:23:00) [4]

> Eraser ©   (22.05.05 18:01) [16]

> А что если оптимизатор посчитает нужным сначала
> проверить 2 условие?

"Эт вряд ли" (c)

По крайней мере, при отключённой Complete Boolean Eval поведение компилятора документировано -- вычисление выражение будет идти слева направо: Short-circuit evaluation means strict left-to-rightevaluation that stops as soon as the result of the entire expression is determined.

Но здесь дело в другом. Непонятно, зачем в коде [10] второе условие. Пусть CreateMutex <> 0, тогда ошибки нет и GetLastError проверять незачем. Пусть, наоборот, CreateMutex = 0, тогда, независимо от значения GetLastError, всё выражение будет истинным, и GetLastError проверять опять незачем.

Я бы сделал так:

if (CreateMutex(...) = 0) and(GetLastError = ERROR_ALREADY_EXISTS) then
 // выход


или так:

if CreateMutex(...) = 0 then
 if GetLastError = ERROR_ALREADY_EXISTS then
   // выход


Первый вариант подойдёт только для {$B-}, второй -- как для {$B-}, так и для {$B+}.


Eraser   (2005-05-22 18:02:00) [5]

ATarget ©   (21.05.05 17:13) [8]

У этого способа помимо кучи других недостатков, есть такой "Очень интересный заголовок моей главной формы" должен быть ОЧЕНЬ интересным )


Eraser   (2005-05-22 18:01:00) [6]

GrayFace ©   (21.05.05 17:46) [10]

if (CreateMutex(nil, True, 'MySuperProject!!!!!!!!!!!')=0) or (GetLastError = ERROR_ALREADY_EXISTS) then halt;


А что если оптимизатор посчитает нужным сначала проверить 2 условие?
имхо на "всякий_пожарный" лучше вариант [4], тем более что кода там ровно столько же, если убрать MessageBox.


ATarget   (2005-05-22 01:23:00) [7]

А вот код для поиска ID процесса тупо по полному имени ехе-шника:
uses
 Tlhelp32, Windows, SysUtils;

function findTask(ExeFileName: string): cardinal;
var
 ContinueLoop: BOOL;
 FSnapshotHandle: THandle;
 FProcessEntry32: TProcessEntry32;
begin
 result := 0;

 FSnapshotHandle := CreateToolhelp32Snapshot
 (TH32CS_SNAPPROCESS, 0);
 FProcessEntry32.dwSize := Sizeof(FProcessEntry32);
 ContinueLoop := Process32First(FSnapshotHandle,
 FProcessEntry32);

 while integer(ContinueLoop) <> 0 do
 begin
   if ((UpperCase(FProcessEntry32.szExeFile) =
   UpperCase(ExeFileName)) then
     Result := FProcessEntry32.th32ProcessID;
   ContinueLoop := Process32Next(FSnapshotHandle, FProcessEntry32);
 end;
 CloseHandle(FSnapshotHandle);
end;


Вызывать так :
*.dpr

program prject1;
...
begin
if findtask(application.exename) <> 0 then halt;
application.initialization;
...
end.
----------

Ну что утешил ? :)


ATarget   (2005-05-22 01:11:00) [8]


> Кстати, а если у меня много оконное приложение, то что мне
> делать, как мне искать не окно, а проект с таким же именем?


ПО ПЕРВОЙ СОЗДАВАЕМОЙ ФОРМЕ она находится даже если в коде встретится form.hide;


Kerk   (2005-05-21 20:35:00) [9]

petya-kurochkin ©   (21.05.05 18:21) [11]

см [10]


Floppy   (2005-05-21 20:33:00) [10]

В dpr после
Application.Initialize;
добавить
if FirstHinstanceRunning(0) then Exit;


petya-kurochkin   (2005-05-21 18:21:00) [11]

Кстати, а если у меня много оконное приложение, то что мне делать, как мне искать не окно, а проект с таким же именем?


GrayFace   (2005-05-21 17:46:00) [12]

ATarget ©   (21.05.05 17:13) [8]
А что здесь сложного:
if (CreateMutex(nil, True, 'MySuperProject!!!!!!!!!!!')=0) or (GetLastError = ERROR_ALREADY_EXISTS) then halt;


ATarget   (2005-05-21 17:16:00) [13]

Да и ещё в Uses надо дописать Windows


ATarget   (2005-05-21 17:13:00) [14]

А я так делаю:

program Project1;

uses
 Forms,windows,
 Unit1 in 'Unit1.pas' {Form1};

{$R *.res}

begin
 if findwindow(nil,'Очень интересный заголовок моей главной формы') <> 0 then halt;
 Application.Initialize;
 Application.CreateForm(TForm1, Form1);
 Application.Run;
end.


При компиляции по F9 программа закроется так как в конструкторе уже есть окно с таким заголовком, но если прэкт закрыт всё рулит. Скажете: "неудобно" - отвечу "зато просто" да и строки эти я добавляю когда всё работает и писать ничего уже не надо.


Marser   (2005-05-21 12:48:00) [15]


> urri ©   (21.05.05 12:42) [6]

Uses Windows, Messages


urri   (2005-05-21 12:42:00) [16]

Выдаёт следующую ошибку:
[Error] Project1.dpr(13): Undeclared identifier: 'CreateMutex'
[Error] Project1.dpr(14): Undeclared identifier: 'ERROR_ALREADY_EXISTS'
[Error] Project1.dpr(16): Undeclared identifier: 'MessageBox'
[Error] Project1.dpr(16): Undeclared identifier: 'MB_ICONERROR'


urri   (2005-05-21 12:42:00) [17]

Выдаёт следующую ошибку:
[Error] Project1.dpr(13): Undeclared identifier: 'CreateMutex'
[Error] Project1.dpr(14): Undeclared identifier: 'ERROR_ALREADY_EXISTS'
[Error] Project1.dpr(16): Undeclared identifier: 'MessageBox'
[Error] Project1.dpr(16): Undeclared identifier: 'MB_ICONERROR'


Eraser   (2005-05-20 21:17:00) [18]

urri ©   (20.05.05 21:10) [3]

В .dpr файле впиши перед Application.Initialize;

   CreateMutex(nil, True, 'MySuperProject!!!!!!!!!!!');
   if GetLastError = ERROR_ALREADY_EXISTS then
   begin
     MessageBox(0, PChar('Already EXISTS!'), 'My super proga!!!', MB_ICONERROR);
     Halt;
   end;


urri   (2005-05-20 21:10:00) [19]

как проверить при запуске, не была ли запущена уже наша программа (и, если это так, то завершить работу её копии)? :)


begin...end   (2005-05-20 21:02:00) [20]

Исключить повторный запуск только средствами Delphi вряд ли возможно.
А вот проверить при запуске, не была ли запущена уже Ваша программа (и, если это так, то завершить работу её копии), можно.
Как -- сказали в [1]. Примеры есть в Сети.


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо