![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Ограничение числа экземпляров
TStas © (2006-03-20 14:51:00)Читал сегодня статью с форума на эту тему, много это обсуждалось. ОДно мне непонятно: чем вариант с инишкой плох. СПециально только что провери - все отлично работает.
Вот файл проекта:
program Project1;
uses
Forms,
Unit1 in 'Unit1.pas', {Form1}
IniFiles, SysUtils;
{$R *.res}
var
ini: TINiFile;
b: Boolean;
begin
ini:=TINiFile.Create(ExtractFilePath(Application.ExeName)+'Run.ini');
B:=Ini.ReadBool('Runned', 'Already', false);
Ini.WriteBool('Runned', 'Already', true);
if b then
begin
Ini.Free;
Halt;
end;
Ini.Free;
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
end. //В нем -то и чииается инишка
А вот файл формы, в нем инишка ставится на место
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs;
type
TForm1 = class(TForm)
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
uses IniFiles;
{$R *.dfm}
procedure TForm1.FormDestroy(Sender: TObject);
var
ini: TIniFile;
begin
ini:=TINiFile.Create(ExtractFilePath(Application.ExeName)+'Run.ini');
Ini.WriteBool('Runned', 'Already', false);
Ini.Free;
end;
end.
ВСе работает. МОжет, в каких-то сложных случаях что-то не так?
Piter (2006-03-21 20:27:00) [81]Leonid Troyanovsky © (21.03.06 19:49) [14]
FindWindow же всегда даст верный результат, например, 0
означает, что окно не нашлось
я понимаю. Ладно, сейчас сформулирую.
Различие в том, что в случае с формой у тебя элементарно нету функции, которая может проверить наличие окна и создать новое.
Отсюда всегда возможны коллизии (хоть и не особо вероятны).
То есть, например ты вызываешь FindForm... ничего. После чего ты создаешь свое окно, но в этом промежутке времени может сработать и другой процесс, провести проверку и создать свое окно - в результате две копии запущенного приложения.
Повторная проверка? Отлично, но может случится ситуация, что каждая из копий создала окно и проводит повторную проверку... Обнаруживает уже запущенную копию и... ? Оба приложения закрываются, в результате ни одного запущенного процесса :)))
Конечно, чем больше таких повторных проверок и т.д. - тем шансы ошибки все больше стремятся к нулю.
В случае же мьютекста ты одной коммандой и проверяешь наличие мьютекса такого, и тут же его создаешь! Причем, Windows гарантирует, что ошибки не будет. Что если создать в разных процессах мьютексы с одним имененм - один из процессов СТО ПРОЦЕНТОВ получит ERROR_ALREADY_EXISTS.
Комбинация же FindForm, CreateForm такого не гарантирует нифига.
Sergey Masloff (2006-03-21 19:57:00) [82]Ihor Osov'yak © (20.03.06 23:57) [4]
> Вообще-то может ткое понятие как задание существовало и в NT4 - не уверен, а документацию сейчас смотреть влом.
Нет не существовало
Leonid Troyanovsky (2006-03-21 19:49:00) [83]
> Piter © (21.03.06 19:27) [13]
> В общем, к чему спор, FindWindow может дать неверный результат,
> это факт.
> А вот мьютекс нет...
А почему, собс-но, " А вот мьютекс".
Он чего, разве не именованный объект? :)
FindWindow же всегда даст верный результат, например, 0
означает, что окно не нашлось (To get extended error information, call
GetLastError).
"Повторить все" это значит, что после некоторой паузы,
процесс повторяют сначала, т.е., если угодно, с мьютекса.
Если же хочется большей определенности можно взять memory
mapped file и писать туда что-то полезное для идентификации
первой копии.
--
Regards, LVT.
Piter (2006-03-21 19:27:00) [84]Leonid Troyanovsky © (21.03.06 8:40) [10]
Остается одна тонкость - объект существует, а окна еще нет.
Тогда, можно повторить все после небольшой паузы
а вот эта пауза может быть значительна.
В общем, к чему спор, FindWindow может дать неверный результат, это факт.
А вот мьютекс нет...
Гаврила © (21.03.06 10:21) [11]
Аналогично может случиться, что процесс запущен, но до создания семафора дело еще не дошло. Или до создания файла в памяти.
Тут разница то где?
а ты подумай, в чем разница :)
TStas (2006-03-21 10:52:00) [85]>ANB А за что? Ну нечаянно дважды щелкнул по значку и что хорошего? Два экземплята и будет.
У меня была собственная идея: сделать чобы программа создавала что-то ненужное, у этого ненежного будет handle Его не задушишь, не убъешь, при выключении света тоже исчезнет. Вот его-то и проверять. Только я очень плохо понимаю, как винды работают.
Гаврила (2006-03-21 10:21:00) [86]
> а вот здесь нет. Процесс может быть уже запущен, но
>до функции
> > создания окна дело не дошло, на этом этапе
>FindWindow ничего
> > не найдет и запустится второй процесс.
Аналогично может случиться, что процесс запущен, но до создания семафора дело еще не дошло. Или до создания файла в памяти.
Тут разница то где?
Leonid Troyanovsky (2006-03-21 08:40:00) [87]
> Piter © (21.03.06 01:53) [6]
> а вот здесь нет. Процесс может быть уже запущен, но до функции
> создания окна дело не дошло, на этом этапе FindWindow ничего
> не найдет и запустится второй процесс.
Именованный объект создают до инициализации приложения,
а закрывают - после его Run (или не закрывают).
Ищут же окно при GetLastError = ERROR_ALREADY_EXISTS.
Остается одна тонкость - объект существует, а окна еще нет.
Тогда, можно повторить все после небольшой паузы.
--
Regards, LVT.
ANB (2006-03-21 04:06:00) [88]
> А вот с этого места, пожалуйста подробнее. Что "убрали"
> и по какой причине? :-)
Да взяли наши программисты и присобачили ограничение, которое не позволяет запускать более одного экземпляра приложения на компе (если точнее, то их даже установить несколько проблематично было). А для тестирования их надо штук 15 запускать. Исправили, когда клиенту понадобилось запускать 2 копии.
Германн (2006-03-21 02:35:00) [89]
> Джо © (21.03.06 02:11) [7]
>
> > [5] ANB © (21.03.06 01:44)
> > ЗЫ. Нашим программистам за такие шутки мы уже все руки
> поотрывали.
> > Ограничение убрали.
>
> И как же они без рук теперь пишут? 8()
Наверно, они уже не пишут! :) Или пишут, но не программы, а "исковые заявки". :-)
> ANB © (21.03.06 01:44) [5]
>
> Ограничение убрали.
А вот с этого места, пожалуйста подробнее. Что "убрали" и по какой причине? :-)
Джо (2006-03-21 02:11:00) [90]> [5] ANB © (21.03.06 01:44)
> ЗЫ. Нашим программистам за такие шутки мы уже все руки поотрывали.
> Ограничение убрали.
И как же они без рук теперь пишут? 8()
Piter (2006-03-21 01:53:00) [91]ANB © (21.03.06 1:44) [5]
просто тупой FindWindow
а вот здесь нет. Процесс может быть уже запущен, но до функции создания окна дело не дошло, на этом этапе FindWindow ничего не найдет и запустится второй процесс.
Не такая уж и невероятная ситуация, например, на долго инициализирующихся приложениях, при тормозящем компьютере...
Я самолично открывал два окна одного Dial-up соединения :)
ANB (2006-03-21 01:44:00) [92]Семафоры, мьютексы, файлы, отображаемые в память, просто тупой FindWindow - способов куча.
ЗЫ. Нашим программистам за такие шутки мы уже все руки поотрывали. Ограничение убрали.
Ihor Osov'yak (2006-03-20 23:57:00) [93]> написано, что много путей и все с недостатками.
статьи не читал, искать влом..
но навскидку на ум экспромтом приходит как минимум два варианта решения
1. использование именнованых семафоров, при запуске - попытка овладеть.. Игра на том, что можно указать при создании семафора количество максимально допустимых "овладений"... Подводных камней не вижу, так как при нештатном завершении процесса система все же счетчик семафора уменшит на единицу.
2. Если система Win2K и више - процессы объеденить в задание, для задания назначить квоту на количество процессов. Вообще-то может ткое понятие как задание существовало и в NT4 - не уверен, а документацию сейчас смотреть влом.
TStas (2006-03-20 15:07:00) [94]>Плохиш Вот и ответ про сложный случай. Спасибо. Просто в статье прямого ответа тоже нет, написано, что много путей и все с недостатками.
Плохиш (2006-03-20 15:05:00) [95]
> МОжет, в каких-то сложных случаях что-то не так?
Программа зависла и её убили через диспетчер задач, свет выключили...
Кашперук Иван (2006-03-20 15:00:00) [96]ну а вдруг вашу ini - шку кто-то решит удалить, другой процесс, или вы сами ненароком.
И файл лишний на винте