Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Как заставить прогу перезапустить саму себя

9.0K
29 сентября 2006 года
Yurezxxx
18 / / 21.08.2005
Нужно в проге выполнить действия требующие после себя полной переинициализации всего приложения, как бы соорудить чтото типа как в WinAmp, когда он перезапускается после установки плагинов
21K
29 сентября 2006 года
fast-wind-sharp-eye
2 / / 07.09.2006
ну создай двойника и умри
257
29 сентября 2006 года
kosfiz
1.6K / / 18.09.2005
попробовать можно еще так:
получив новые настройки сохраняешь их в файл, чтобы при старте их учесть. потом используешь батник следующего содержания:
 
Код:
start /wait taskkill.exe /F /IM program.exe
start program.exe

которы запускаешь функцией winexec('batnik.bat',0). создать батник заранее или во время выполнения твоей программы - решать тебе.
261
30 сентября 2006 года
ahilles
1.5K / / 03.11.2005
вот это заморочки

winexec(pchar(paramstr(0)),SW_SHOWNORMAL);
exitprocess(0);
257
30 сентября 2006 года
kosfiz
1.6K / / 18.09.2005
2ahilles
а как ты будешь это реализовывать, если твоя прога должна быть запущена в единственном экземпляре? вдруг не успеешь выгрузиться.
309
30 сентября 2006 года
el scorpio
1.1K / / 19.09.2006
[QUOTE=kosfiz]а как ты будешь это реализовывать, если твоя прога должна быть запущена в единственном экземпляре? вдруг не успеешь выгрузиться.[/QUOTE]
Очень просто - в Delphi есть секции initialise и finalize. Первая отвечает за действия при запуске программы, вторая - при заверщении.
Для анализа запущенности программы производится проверка некоторых системных флагов в секции инициализации: если есть флаг - значит, выход. Так вот, если в секции финализации обнулить эти флаги, а уже потом дать команду на запуск, то другая программа решит, что она единственная, даже если первая ещё не исчезла из списков процессов системы.
257
30 сентября 2006 года
kosfiz
1.6K / / 18.09.2005
2 el scorpio
т.к. ты в этом по-видимому знаток, то, пожале, объясни мне, где найти эти секции на следующем примере или как их добавить, чтобы к ним добавить нужный код:
 
Код:
program Project1;
uses
  windows;
begin
end.
309
01 октября 2006 года
el scorpio
1.1K / / 19.09.2006
Я не знаток Delphi, но по институту (а потом я перешёл на Builder :D ) помню, что в каждом pas файле можно создать четыре раздела:

 
Код:
unit Unit_name;
interface
// код
implementation
// код
initialization
// код
finalization
// код
end.


1. interface. Производится объявление типов, классов, глобальных функций и объектов. Также подключаются другие модули (uses). Объявленные элементы доступны в других модулях
2. implementation. Всё тоже самое, но ещё производится реализация функций и методов классов. Объявленные элементы не доступны в других модулях
3. initialization. Указанная последовательность команд выполняется в момент запуска программы. Обратите внимание - здесь не объявляются функции или переменные - они вызываются так, как вызывались бы внутри функции
4. finalization. Указанная последовательность команд выполняется в момент завершения программы
 
Код:
initialization // начало блока запуска
  OleCheck(CoGetMalloc(1, GlobalMalloc)); // Эта команда выполнится при запуске программы
finalization // начало блока завершения
  GlobalMalloc := nil; // эта команда выполнится при завершении программы
end. // конец модуля :D
261
01 октября 2006 года
ahilles
1.5K / / 03.11.2005
в любом случае успеешь выгрузиться
потому что если использовать ExitProcess то очень быстро вылетаешь из приложения

.....
ну даже если не успеешь выгрузиться и ну что дальше?.....
309
01 октября 2006 года
el scorpio
1.1K / / 19.09.2006
[QUOTE=Ahilles]в любом случае успеешь выгрузиться
потому что если использовать ExitProcess то очень быстро вылетаешь из приложения
.....
ну даже если не успеешь выгрузиться и ну что дальше?.....[/QUOTE]
Проблема в том, что "быстро вылетать" из приложения может быть вредно для самого приложения :( - ситуации бывают разные. Да и быстродействие у компьютеров может различаться.
Кроме того, если рассуждать "ну даже если не успеешь" и заниматься гаданием подобным на кофейной гуще, то лучше вообще отказаться от возможности автоматического перезапуска.

Лучше сделать так, как я предлагал, в отдельном либо главном модуле
 
Код:
initialization[INDENT]if (Test_Running) then // Проверка возможности запуска программы
     Set_Running (true); // Установка флага запущенности программы
else begin
// Программа уже запущена - отменить повторный запуск программы
end;[/INDENT]finalization[INDENT]Set_Running (false); //Снятие флага запущенности программы
if (Need_Restarting) then // Проверка требования перезапуска
Restart_Program; //Перезапуск программы
[/INDENT]end.

Функции Test_Running, Set_Running и Restart_Program напишите сами. По крайней мере, алгоритмы для проверки запущенности программы приведены во многих книгах по программированию.
257
01 октября 2006 года
kosfiz
1.6K / / 18.09.2005
мне кажется то, что предлагает el scorpio (или то, что я предложил) может понадобиться, если прога ищет себя по окнам или в процессах, а если проверять запущенность с помощью мьютексов, то в случае необходимости вызвать ReleaseMutex(потом то, что писал ahilles) и вновь запущенная прога работающую не обнаружит.
309
02 октября 2006 года
el scorpio
1.1K / / 19.09.2006
kosfiz
Кстати, я тоже в расчёте на мьютексы и им подобное код писал. Только конкретную реализацию не расписывал
257
02 октября 2006 года
kosfiz
1.6K / / 18.09.2005
el scorpio
мьютексы, на мой взгляд, лучший способ для определения того, запущена прога или нет.
261
02 октября 2006 года
ahilles
1.5K / / 03.11.2005
я вам ещё раз повторяю приведённый код winexec/exitprocess в 99,99% случаев сработает
просто сами подумайте что быстрее уничтожение процесса + выгрузка его из памяти намного быстрее чем создание процесса + загрузка его в память + всякие инициилизации

-----------------------------------------
ЛОМАТЬ - НЕ СТРОИТЬ!!!!
-----------------------------------------
309
03 октября 2006 года
el scorpio
1.1K / / 19.09.2006
[QUOTE=ahilles]winexec/exitprocess в 99,99% случаев сработает
просто сами подумайте что быстрее уничтожение процесса + выгрузка его из памяти намного быстрее чем создание процесса + загрузка его в память + всякие инициилизации
[/QUOTE]
Не факт, не факт :)
Статистика - вещь хорошая, но по закону подлости, ваша программа как раз и будет периодически попадать в оставшиеся 0.01% :D
Мой же способ сработает на все сто :cool:
261
03 октября 2006 года
ahilles
1.5K / / 03.11.2005
это тоже правильно
я как раз делал такую прогу и никгода не задумывался об 0.01%
309
05 октября 2006 года
el scorpio
1.1K / / 19.09.2006
[QUOTE=ahilles]это тоже правильно
я как раз делал такую прогу и никгода не задумывался об 0.01%[/QUOTE]
Зря, зря...
"Авоська" - парень добрый - или выручит, или выучит :D
Если неприятность может случится - она случается :D

Подобные закономерности, регулярно подтверждаемые практикой, любой специалист со стажем может цитировать десятками.
339
05 октября 2006 года
verybadbug
619 / / 12.09.2005
хмм... а если между закрытием проги и запуском её необходимо, например, файл проги обновить.....
257
05 октября 2006 года
kosfiz
1.6K / / 18.09.2005
verybadbug
имеешь ввиду сам экзе файл обновить... тогда, наверное, по принципу прог, которые могут удалять сами себя, т.е. размещаешь в памяти, обновляешь файл, а потом перезапуск, вроде так, хотя может и ошибаюсь.
309
05 октября 2006 года
el scorpio
1.1K / / 19.09.2006
Тогда ручками :). Или через вызов .bat файла.
Забить цикл копирования обновлённой версии в исходный файл. Условие выхода из цикла - безошибочный процесс копирования, или же - пока время создания файла не станет равным времени обновлённого.
А дальше - опять запуск программы.
339
06 октября 2006 года
verybadbug
619 / / 12.09.2005
а с bat'ником такое проканает?
 
Код:
start /wait taskkill.exe /F /IM program.exe
copy newprog.exe program.exe
start program.exe
309
06 октября 2006 года
el scorpio
1.1K / / 19.09.2006
taskkill - незнаю...
А если программа требует "правильного" закрытия. Например, при работе с одной БД через BDE, при прерывании работы программы, база данных продолжала считаться "открытой" - соответственно, ексклюзивный доступ к ней получался невозможным :(
Или же при завершении нужно сохранить данные в файл.
339
06 октября 2006 года
verybadbug
619 / / 12.09.2005
Цитата:
Например, при работе с одной БД через BDE...



блин... вот тока не надо в крайности... моя прога не на столько тупая, чтобы перед вызовом этого BAT оставить открытую БД, несохраненные данные, невысвобожденную память и всё в таком духе....

257
06 октября 2006 года
kosfiz
1.6K / / 18.09.2005
verybadbug
всмысле обновить прогу:1) подправить пару байт; 2) полностью заменить экзе. если пункт 1, то смотри мой первый ответ на твой вопрос, если 2, то что это за необходимость полностью файл менять?
309
06 октября 2006 года
el scorpio
1.1K / / 19.09.2006
[QUOTE=verybadbug]блин... вот тока не надо в крайности... моя прога не на столько тупая, чтобы перед вызовом этого BAT оставить открытую БД, несохраненные данные, невысвобожденную память и всё в таком духе....[/QUOTE]
Рад за вас. Но вот только даже самая "умная" прога всё равно использует объекты ОС и файлы, которые остаются открыты во время работы - а тут ей, ни с того, ни с сего - taskkill :(.

P.S.
А причём в батнике "start /wait"? Что это означает - я знаю; просто не могу понять - зачем?
257
06 октября 2006 года
kosfiz
1.6K / / 18.09.2005
[QUOTE=el scorpio]Рад за вас. Но вот только даже самая "умная" прога всё равно использует объекты ОС и файлы, которые остаются открыты во время работы - а тут ей, ни с того, ни с сего - taskkill :(.
[/QUOTE]
так он же перед вызовом все, что можно закроет, а то что останется вряд ли к какой-то большой ошибке приведет - ось должна сама справиться. можно подумать, что никто зависшую прогу с помощью диспетчера задач не закрывал ни разу.
[QUOTE=el scorpio]
А причём в батнике "start /wait"? Что это означает - я знаю; просто не могу понять - зачем?[/QUOTE]
очевидно, чтобы в памяти не висели две копии проги - и в этом я с verybadbug'ом согласен - потому что две копии проги в памяти - это неправильно.
309
07 октября 2006 года
el scorpio
1.1K / / 19.09.2006
[QUOTE=kosfiz]так он же перед вызовом все, что можно закроет, а то что останется вряд ли к какой-то большой ошибке приведет - ось должна сама справиться. можно подумать, что никто зависшую прогу с помощью диспетчера задач не закрывал ни разу.
[/QUOTE]
Закрывали - только порой он закрыть файлы - закроет, а вот сохранить изменения в этих файлах не сможет :(. Так что лучше завершать программу правильно.
Если использовать taskkill с ключём /f (форсированное закрытие), то "хвосты" останутся. Если же использовать без этого ключа, то программа может не закрыться, а просто вывести сообщение типа "Вы уверены?" или "Сохранить изменения?" - соответственно, выполнение её не прервётся.

Цитата:

очевидно, чтобы в памяти не висели две копии проги - и в этом я с verybadbug'ом согласен - потому что две копии проги в памяти - это неправильно.


Дело в том, что "start /wait" в батниках используется для ожидания завершения оконных приложений. Консольные же (к числу коих относится и

339
07 октября 2006 года
verybadbug
619 / / 12.09.2005
Цитата:

...что это за необходимость полностью файл менять...


обновление программных модулей например....

хорошо... у меня тут ещё одна идея возникла... а что если использовать след порядок действий?
прога
1. прога создаёт батник
2. прога запускает его
3. прога закрывается
батник
1. копирование пока возникает ошибка
2. запуск проги

309
07 октября 2006 года
el scorpio
1.1K / / 19.09.2006
verybag
Протестую - это плагиат :)
Подобную идею я предложил на последнем посте страницы 2 этой темы.
339
09 октября 2006 года
verybadbug
619 / / 12.09.2005
Цитата:
Протестую...


хмм... действительно... а ты пробовал так делать?

309
09 октября 2006 года
el scorpio
1.1K / / 19.09.2006
Command.com (cmd) имеет достаточно команд, чтобы это реализовать в файле .bat
Надо только вспомнить, как же правильно использовать переменную ERRORLEVEL...
339
09 октября 2006 года
verybadbug
619 / / 12.09.2005
сделал.... работает как часики...

1.bat
 
Код:
:CopyLoop
copy 1.exe 2.exe
if ERRORLEVEL 1 goto CopyLoop
start 2.exe


где-то в проге...
 
Код:
ShellExecute(Handle,
    'open',
    PChar(ExtractFilePath(Application.ExeName) + '1.bat'),
    nil,
    PChar(ExtractFilePath(Application.ExeName)),
    SW_SHOWMINIMIZED);
  Close;
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог