Показать полную графическую версию : [архив] Скрипты Inno Setup. Помощь и советы [часть 2]
Здравствуйте.
Прикрепил к сообщению скрипт, который позволяет запускать другие программы с ожиданием их завершения и при этом инсталлятор остаётся "живым", т.е. отвечает на действия пользователя.
Пример использования, подробно описан в скрипте.
R.i.m.s.k.y.
21-01-2010, 09:35
Еще косметический вопрос: как увеличить окошко выбора компонентов и само белое поле с компонентами? А то одна строчка не влезает и из-за нее приходится вниз проматывать. »
WizardForm.ComponentsList.Width:= ScaleX(550);
WizardForm.TypesCombo.Width:= ScaleX(550); »
Спасибо!
А если надо кардинально увеличить окно? Ведь элементы поупираются в кнопки, линии и пр, как все перенести/раздвинуть?
Качнул Inno Setup Form Designer - а там с кодировкой что-то
Добрый день, такой вопрос! хочу сделать что-бы здесь писало не 38мб, а 38мб + строка NeedSize := 15350;
то есть я хочу что-бы это:
http://s52.radikal.ru/i137/1001/f9/c147934ab5b3.jpg (http://www.radikal.ru)
складывалось с этим:
http://i079.radikal.ru/1001/fa/91d96a7ec693.jpg (http://www.radikal.ru)
и в итоге тут: http://i079.radikal.ru/1001/fa/91d96a7ec693.jpg (http://www.radikal.ru) получалась сумма 1 и 2 скриншота!
А если надо кардинально увеличить окно? Ведь элементы поупираются в кнопки, линии и пр, как все перенести/раздвинуть? »
Используйте расширенную версию от ResTools. Там есть WizardForm Designer.
Прикрепил к сообщению скрипт, который позволяет запускать другие программы с ожиданием их завершения и при этом инсталлятор остаётся "живым", т.е. отвечает на действия пользователя.
Пример использования, подробно описан в скрипте. »
не очень понятно где это можно применить на практике, если только рассматривать этот вопрос как чисто академический
если вызвать ExecAndWait, то вызвавшая процедура/функция не завершится пока не завершится запущенное приложение.
а если после этого должны выполнится еще какие-то действия?
сдается мне, что _ProcIsRunning вообще не в кассу, постоянно шмонать список процессов далеко не лучшее решение. вообще для этих целей существует WaitForSingleObject
данные о запущенных процессах я бы заносил в массив
по уму процедуру ожидания надо делать в отдельном потоке. в инно с этим проблемы, поэтому я бы запустил таймер (не очень хорошо, но на безрыбье ...), а в нем прошелся бы циклом по массиву
if WaitForSingleObject(PI.hProcess,200)<>WAIT_TIMEOUT then begin
_CloseHandle(PI.hProcess);
_CloseHandle(PI.hThread);
ну и удаляем элемент массива, чтобы не отсвечивал
end;
и была бы отдельная процедура прибития процессов при выходе из инсталла: прибили таймер и опять же пробежались по массиву и всем процессам TerminateProcess. это можно сделать в том же OnCloseQuery
тогда и _Application_ProcessMessages не нужен
ну как-то так
ЗЫ в цикле от "if _QUIT then Break; " не будет толку. если процесс первый в списке, то ты из цикла "while _ProcIsRunning(ProcessName, ProcessID) do;" не выйдешь. в этом же случае не сработает _Application_ProcessMessages
Всем доброго времени суток!
Есть вопрос один. У меня в инсталере есть окно, на котором 3 чекбокса, как сделать что бы первый из них стал главным, т.е. если он убирается второй и третий чекбокс становятся некликабельными или же вариант когда все кликабельные, но как только выбрать 2 или 3 чекбокс, первый ставиться автоматически (это вариант используется в [Components]).
Прикрепил пример того что хочется сделать у себя. На скрине видно, что на 2 и 3 чекбоксе галочки стоят, но была убрана первая, которая отменяет установку не только себя, но 2 и 3 чекбокса.
Заранее благодарен за любую помощь!
Cranz86
а если сделать первый(главный) с неубераемой галочкой? а 2 и 3 выбрать как угодно???
если пойдет то просто поставь там флаг Flags: fixed
вот тебе пример как выглядит: http://i079.radikal.ru/1001/fa/91d96a7ec693.jpg (http://www.radikal.ru)
на обведенное красным, внимание не обращай)))
R.i.m.s.k.y.
21-01-2010, 16:20
В шапке темы есть коллекция скриптов, в нем файлик SelComp-EnableGroup.iss, думаю он поможет.
вот тебе пример как выглядит: »
Нет, это совсем другое. Я там мини-скрин прикрепил...Check.jpg »
R.i.m.s.k.y.
21-01-2010, 16:27
Я вообще скачал себе эту коллекцию, chm-файл "Сборник вопросов" и сначала ищу там. Поверьте - там ответы на половину вопросов.
R.i.m.s.k.y. - я то там просмотрел и эту исску видел, но это не то или не пойму как её привинтить к моему окну. Эти чекбоскы в окне компонентов пишутся. А у меня все чеки в коде пишуться...
var
*****
GreathCheck : TCheckBox;
SearchCheck : TCheckBox;
HomeCheck : TCheckBox;
******
R.i.m.s.k.y.
21-01-2010, 17:21
Cranz86
тогда да, файлик не в тему, как чекбоксы в коде делать я не знаю и уже вряд ли помогу.
не очень понятно где это можно применить на практике, если только рассматривать этот вопрос как чисто академический »
При запуске распаковки архивов.
если вызвать ExecAndWait, то вызвавшая процедура/функция не завершится пока не завершится запущенное приложение.
а если после этого должны выполнится еще какие-то действия? »
Совершенно верно.
Видимо вы слабо знакомы с Inno Setup. Попробуйте запустить любую программу через Exec или ShellExec с параметром ожидания ewWaitUntilTerminated или запустить через [Run] и вы не сможите передвинуть окно инсталлятора.
сдается мне, что _ProcIsRunning вообще не в кассу, постоянно шмонать список процессов далеко не лучшее решение. »
:) Понятно, вы знакомы с программированием...
Самый простой вариант, это открыть файл через OpenProcess, если Handle > 0, то процесс работает...
Ну вообще-то, вы наверно заметили, что я сначала сверяю ID процесса, а затем его имя, т.е. чтоб определить, что это именно тот файл.
Не знаю, знаете вы или нет, но ID процесса в системе не уникален. После завершения этого процесса, его ID освобождается и при запуске другого процесса ему может быть присвоен системой точно такой же ID.
Так что проверка просто по ID, я счёл не совсем правильным и точным.
Ну а более простой способ узнать имя процесса через его ID, мне к сожалению не известен. Если вам известен более простой способ, то поделитесь, так сказать для само развития.
вообще для этих целей существует WaitForSingleObject »
Не согласен, инсталлятор, так же будет мёртвым, т.е. переместить вы его не сможете.
данные о запущенных процессах я бы заносил в массив »
и что дальше? Процесс закрылся, а с таким же ID, работает уже другой...
по уму процедуру ожидания надо делать в отдельном потоке. в инно с этим проблемы, поэтому я бы запустил таймер (не очень хорошо, но на безрыбье ...), »
Совершенно с вами согласен, но стандартный Inno не поддерживает, не только многопоточность, он также не знает, что такое таймер (этот недостаток исправлен в версии от Restools). Если конечно не использовать дополнительных библиотек, а именно эту цель я и приследывал при написании данного скрипта, чтоб можно было использовать его без ничего.
и была бы отдельная процедура прибития процессов при выходе из инсталла: прибили таймер и опять же пробежались по массиву и всем процессам TerminateProcess »
и прибили другой процесс...
тогда и _Application_ProcessMessages не нужен »
да, если была бы возможность всё делать в отдельном потоке.
в цикле от "if _QUIT then Break; " не будет толку. если процесс первый в списке, то ты из цикла "while _ProcIsRunning(ProcessName, ProcessID) do;" не выйдешь. в этом же случае не сработает _Application_ProcessMessages »
Здесь я с вами полностью согласен, недоглядел...
Inno Setup Compiler (http://restools.hanzify.org/inno/InnoCompiler100121_English(7zip).zip) 5.3.7 build 100121 (English) by Restools (http://restools.hanzify.org/)
Цитата South:
не очень понятно где это можно применить на практике, если только рассматривать этот вопрос как чисто академический »
При запуске распаковки архивов.
да вроде библиотек уже куча есть, хотя в данном случае не важно
Цитата South:
если вызвать ExecAndWait, то вызвавшая процедура/функция не завершится пока не завершится запущенное приложение.
а если после этого должны выполнится еще какие-то действия? »
Совершенно верно.
Видимо вы слабо знакомы с Inno Setup. Попробуйте запустить любую программу через Exec или ShellExec с параметром ожидания ewWaitUntilTerminated или запустить через [Run] и вы не сможите передвинуть окно инсталлятора. про это я в курсе. кстати, если не лень, можете глянуть в исходники инно и посмотреть каким образом используется ewWaitUntilTerminated.
Цитата South:
сдается мне, что _ProcIsRunning вообще не в кассу, постоянно шмонать список процессов далеко не лучшее решение. »
Понятно, вы знакомы с программированием... с программированием немного знаком
Самый простой вариант, это открыть файл через OpenProcess, если Handle > 0, то процесс работает...
может и простой, но работает дольше чем WaitForMultipleObjects,WaitForSingleObjects
Ну вообще-то, вы наверно заметили, что я сначала сверяю ID процесса, а затем его имя, т.е. чтоб определить, что это именно тот файл.
Не знаю, знаете вы или нет, но ID процесса в системе не уникален. После завершения этого процесса, его ID освобождается и при запуске другого процесса ему может быть присвоен системой точно такой же ID.
Так что проверка просто по ID, я счёл не совсем правильным и точным.
Ну а более простой способ узнать имя процесса через его ID, мне к сожалению не известен. Если вам известен более простой способ, то поделитесь, так сказать для само развития. чтобы более наглядно было
TProcessInformation = record
hProcess: THandle;
hThread: THandle;
dwProcessId: DWORD;
dwThreadId: DWORD;
end;
начнем с того, что я не предлагал использовать dwProcessId. я предложил использовать hProcess, который не будет освобожден, пока не вызван CloseHandle
Цитата South:
вообще для этих целей существует WaitForSingleObject »
Не согласен, инсталлятор, так же будет мёртвым, т.е. переместить вы его не сможете. в общем случае да, будет мертвым, а если его использовать как я предложил, то должен ожить
Цитата South:
данные о запущенных процессах я бы заносил в массив »
и что дальше? Процесс закрылся, а с таким же ID, работает уже другой... читаем выше, id не при чем
Цитата South:
по уму процедуру ожидания надо делать в отдельном потоке. в инно с этим проблемы, поэтому я бы запустил таймер (не очень хорошо, но на безрыбье ...), »
Совершенно с вами согласен, но стандартный Inno не поддерживает, не только многопоточность, он также не знает, что такое таймер (этот недостаток исправлен в версии от Restools). Если конечно не использовать дополнительных библиотек, а именно эту цель я и приследывал при написании данного скрипта, чтоб можно было использовать его без ничего. да, пока не нажата кнопка 'install', приложение является однопоточным, только вот распаковку он может делать в несколько потоков. если по теме, то да, создавать потоки без привлечения самописных длл не получится. а про таймер, ваша религия позволила вам использовать системные библиотеки, так почему же не использовать SetTimer и KillTimer :shocked:
Цитата South:
и была бы отдельная процедура прибития процессов при выходе из инсталла: прибили таймер и опять же пробежались по массиву и всем процессам TerminateProcess »
и прибили другой процесс...
Цитата South:
тогда и _Application_ProcessMessages не нужен »
да, если была бы возможность всё делать в отдельном потоке. » не прибил бы, это все непонятки с PID'ом
может и простой, но работает дольше чем WaitForMultipleObjects,WaitForSingleObjects »
здесь ничего возразить не могу, просто не знаю, кто быстрее.
я предложил использовать hProcess, который не будет освобожден, пока не вызван CloseHandle »
Согласен, но сразу забыл сказать, что PI.hProcess, не знаю почему, но именно в Inno показывает не верное значение, может где-то, что я не так сделал…
Это можно увидеть, если добавить сообщение в функцию _StartProc, пример:
ProcessName:= ExtractFileName(Filename);
ProcessId:= PI.dwProcessId;
MsgBox('Запущена программа: ' + ProcessName + #13#10 +
'PI.hProcess: ' + IntToStr(PI.hProcess) + #13#10 +
'_OpenProcess: ' + IntToStr(_OpenProcess(PROCESS_ALL_ACCESS, False, ProcessId)),
mbInformation, MB_OK);
_CloseHandle(PI.hProcess);
_CloseHandle(PI.hThread);
в общем случае да, будет мертвым, а если его использовать как я предложил, то должен ожить »
теоретически да, но я не пробовал, врать не буду.
а про таймер, ваша религия позволила вам использовать системные библиотеки, так почему же не использовать SetTimer и KillTimer »
Причём тут религия? Попробуйте, в стандартной версии SetTimer и у вас вылетит ошибка. Цель написания скрипта была, чтоб с ним можно было работать в разных версиях Inno и не тащить с собой в инсталляторе дополнительные библиотеки.
А так понятно, можно было написать отдельную dll'ку и всего это скрипта не надо, но этих dll'ок и так уже куча...
P.S.
const
PROCESS_ALL_ACCESS = $000F0000 or $00100000 or $FFF;
Цитата South:
я предложил использовать hProcess, который не будет освобожден, пока не вызван CloseHandle »
Согласен, но сразу забыл сказать, что PI.hProcess, не знаю почему, но именно в Inno показывает не верное значение, может где-то, что я не так сделал…
Это можно увидеть, если добавить сообщение в функцию _StartProc, пример:
Код:
ProcessName:= ExtractFileName(Filename);
ProcessId:= PI.dwProcessId;
MsgBox('Запущена программа: ' + ProcessName + #13#10 +
'PI.hProcess: ' + IntToStr(PI.hProcess) + #13#10 +
'_OpenProcess: ' + IntToStr(_OpenProcess(PROCESS_ALL_ACCESS, False, ProcessId)),
mbInformation, MB_OK);
_CloseHandle(PI.hProcess);
_CloseHandle(PI.hThread);
у меня в инно с PI.hProcess проблем не было
по поводу приведенного куска
hProcess:THandle, THandle=Longword
Longint -2147483648..2147483647 signed 32-bit
Longword 0..4294967295 unsigned 32-bit
в инно - function IntToStr(i: Longint): String;
выводы по поводу IntToStr(PI.hProcess) должны быть очевидны
Цитата South:
в общем случае да, будет мертвым, а если его использовать как я предложил, то должен ожить »
теоретически да, но я не пробовал, врать не буду. я вообще-то тоже не пробовал и полной уверенности, что это сработает нет, надо пробовать
Цитата South:
а про таймер, ваша религия позволила вам использовать системные библиотеки, так почему же не использовать SetTimer и KillTimer »
Причём тут религия? Попробуйте, в стандартной версии SetTimer и у вас вылетит ошибка. Цель написания скрипта была, чтоб с ним можно было работать в разных версиях Inno и не тащить с собой в инсталляторе дополнительные библиотеки.
А так понятно, можно было написать отдельную dll'ку и всего это скрипта не надо, но этих dll'ок и так уже куча... я в своих скриптах никогда не использовал версии от ResTools (если это имелось ввиду), только только стандартный инно, даже препроцессор никогда не использовал. и SetTimer у меня всегда работал. только вот ему нужна innocallback.dll, тут я не подумал, каюсь
ЗЫ все-таки для данной задачи в такой постановке достаточно WaitForSingleObjects. если интересно можно посмотреть на руборде в шапке скрипт ExecAppAndMoveWindow.iss. давненько делал, тоже была задача без привлечения внешних длл запустить приложение и переместить его окно и тоже для распаковки внешних архивов :). там и hProcess, и WaitForSingleObjects используется, а общий подход примерно такой же :)
ЗЗЫ тут глянул, в TStartupInfo 3 поля являются указателями, ты же их обзываешь Longint'ом, который может принимать отрицательные значения, при этом не инициализируешь все поля, хотя это нужно делать.
попробуй эти три поля объявить как Longword, обнули все поля которые не заполняешь конкретными значениями (обычно вызывают FillChar(TStartupInfo , SizeOf(TStartupInfo ), 0)). после этого вызывай CreateProcess, тогда возможно Longword нормально приведется к Pointer и в ответ нормально заполнится TProcessInformation
выводы по поводу IntToStr(PI.hProcess) должны быть очевидны »
Согласен.
скрипт ExecAppAndMoveWindow.iss. давненько делал »
Нашёл у себя на диске этот скрипт, интересно и если вы говорите, что его писали давно...
Приятно познакомиться с экспертом... :)
Эх, давненько я не просматривал архив со скриптами, не пришлось бы над многим ломать голову.
Кстати запускается там файл у вас через ShellExec, а не через CreateProcess и я попробовал такой вариант:
while WaitForSingleObject(PI.hProcess, 50) = WAIT_TIMEOUT do
_Application_ProcessMessages;
Действительно работает ;) Спасибо.
скрипт ExecAppAndMoveWindow.iss. давненько делал »
Нашёл у себя на диске этот скрипт, интересно и если вы говорите, что его писали давно...
Приятно познакомиться с экспертом... взаимно, хотя я себя экспертом не считаю
Эх, давненько я не просматривал архив со скриптами, не пришлось бы над многим ломать голову.
Кстати запускается там файл у вас через ShellExec, а не через CreateProcess и я попробовал такой вариант:
Код:
while WaitForSingleObject(PI.hProcess, 50) = WAIT_TIMEOUT do
_Application_ProcessMessages;
Действительно работает Спасибо. »
я тоже нашел у себя этот скрипт, теперь сижу и думаю: почему я тогда не использовал CreateProcess, а стал городить огород с поиском хэндла и идентификатора процесса :o
вот так вот, из 2 скриптов можно уже собрать что-то человеческое
PS а вот тут (http://forum.ru-board.com/topic.cgi?forum=5&topic=27438&start=2000#7) я выкладывал этот скрипт. правда поиск местонахождения скрипта так и не прояснил не использование CreateProcess :( видимо я тогда изрядно ступил
теперь сижу и думаю: почему я тогда не использовал CreateProcess, а стал городить огород с поиском хэндла »
У меня тоже не с первого раза вышло. Сначала искал и загонял в массив, как вы и предлагали, только я туда заносил ещё и дочерние процессы запущенной программы, чтоб потом всех их за одно, если чего... :)
Потом смотрю, чего-то много строк в скрипте получается... решил лишнее не делать, а в итоге оказывается можно ещё проще где-то ещё на 50-70 строк :)
вот так вот, из 2 скриптов можно уже собрать что-то человеческое »
:) согласен
PS а вот тут я выкладывал этот скрипт. правда поиск местонахождения скрипта так и не прояснил »
Хм, я тогда бы и не разобрался... это только сейчас начинаю немного понимать чего куда...
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.
Available in ZeroNet 1osznRoVratMCN3bFoFpR2pSV5c9z6sTC