Показать полную графическую версию : [архив].: NSIS - все вопросы :.
Painkiller
31-07-2011, 18:55
апи не надо не любить, а пользоваться, эти функции объявлены в "заголовках" дельфи..
в батниках я не спец, но обязательно нужно опредилить путь к makensis и полный путь к скрипту
${NSISDIR}\makensis.exe "путь к скрипту"
Вам пример привести на делфи или на nsis посредством апи? »
Приведите , посмотрим
kotkovets
31-07-2011, 19:25
Пример на делфи
function Exec(RunApp : string; cmdline : string) : bool;
var
si : TStartupInfo;
pi : TProcessInformation;
begin
try
ZeroMemory(@si,SizeOf(si));
si.cb := SizeOf(si);
si.dwFlags := STARTF_USESHOWWINDOW;
si.wShowWindow := SW_SHOW; // SW_HIDE - скрытый запуск
Result := CreateProcess(PChar(RunApp),PChar(' ' + cmdline),nil, nil,False,0,nil,nil,si,pi);
WaitForSingleObject(pi.hProcess, INFINITE); // ожидаем завершения процесса
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
except
Result := false;
end;
end;
//запуск функции
// Exec('путь к makensis', 'путь к скрипту');
Пример на апи, запуск консоли, в скрытом режиме и ожидание завершения. Если все хорошо в $0 возвращается 0
!include "MUI2.nsh"
!include "Util.nsh"
OutFile "Tes_Run_MAKE.exe"
ShowInstDetails show
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_LANGUAGE "Russian"
!define INFINITE -1
!define DETACHED_PROCESS 0x00000008
!define ExecWait "!insertmacro ExecWaitCall"
!macro ExecWaitCall CmdLine ExitCode
Push `${CmdLine}`
${CallArtificialFunction} _CallExecWait
Pop ${ExitCode}
!macroend
!macro _CallExecWait
System::Store S
Push error
System::Alloc 72
Pop $2
System::Call "*$2(i72)"
System::Call "*(i,i,i,i)i.r3"
Exch
System::Call "kernel32::CreateProcess(i0, ts, i0, i0, i0, i${DETACHED_PROCESS}, i0, i0, ir2, ir3)i.r4"
${Unless} $4 = 0
Pop $6
System::Call "*$3(i.r4)"
System::Call "kernel32::WaitForSingleObject(ir4, i${INFINITE})"
System::Call "kernel32::GetExitCodeProcess(ir4, *i.s)"
System::Call "kernel32::CloseHandle(ir4)"
${EndUnless}
System::Free $2
System::Free $3
System::Store L
!macroend
Section ""
${ExecWait} '"${NSISDIR}\makensis.exe" "D:\designer\Debug.nsi"' $0
DetailPrint "ExitCode: $0"
SectionEnd
Если через диспетчер завершть makensis - код возврата 1
Painkiller
31-07-2011, 19:44
kotkovets, в том то и дело что путь к makensis', 'путь к скрипту не работает. И я использую функцию
function SwitchToProg(const Path: string): Boolean;
var
SI: TStartupInfo;
PI: TProcessInformation;
ExitCode: Cardinal;
begin
FillChar(SI, SizeOf(SI), 0);
SI.cb := SizeOf(SI);
Result := CreateProcess(nil, PChar(Path), nil, nil, False, 0, nil, nil,
SI, PI);
if Result then
begin
while GetExitCodeProcess(PI.hProcess, ExitCode) and
(ExitCode = STILL_ACTIVE) do
; // ждем завершения, пустой цикл
Form1.StatusBar1.SimpleText:=' Копиляция выполнена!';
Form2.show;
end;
end;
Мне нужно как-то запустить makensis ? Получается запустить только через батник. А ту функцию что вы мне написали я знаю. Ещё куча других подобных примеров есть . Мне лишь нужно знать как запустить makensis ?
kotkovets
31-07-2011, 19:55
А на фига здесь цикл? WaitForSingleObject - и все!
Мне нужно как-то запустить makensis »
Так укажите полный путь к makensis! если вы правильно указали путь, но не указали командную строку или неправильно - makensis сразу завершается, с кодом возврата 1 . Пропишите полный путь к исполнителю и скрипту... или где то еще у вас косяк, проверьте у себя скрипт который я показал в качестве примера - уверяю вас все отработает как нужно.
или вы просто не вылазите из цикла... :)
Painkiller
31-07-2011, 19:59
Ваш пример не работает. Где тут ошибка? :
function Exec(RunApp : string; cmdline : string) : bool;
var
si : TStartupInfo;
pi : TProcessInformation;
begin
try
ZeroMemory(@si,SizeOf(si));
si.cb := SizeOf(si);
si.dwFlags := STARTF_USESHOWWINDOW;
si.wShowWindow := SW_SHOW; // SW_HIDE - ñêðûòûé çàïóñê
Result := CreateProcess(PChar(RunApp),PChar(' ' + cmdline),nil, nil,False,0,nil,nil,si,pi);
WaitForSingleObject(pi.hProcess, INFINITE); // îæèäàåì çàâåðøåíèÿ ïðîöåññà
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
except
Result := false;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
Exec('C:\Program Files\NSIS\makensis.exe','C:\myscript.nsi');
end;
end.
Пример на nsis работает =)
kotkovets
31-07-2011, 20:03
Вы наверно в юникоде работаете... :) это для анси..
Painkiller
31-07-2011, 20:18
Вы наверно в юникоде работаете... это для анси.. »
Значит нужно перекодировать в анси
Krinkels
31-07-2011, 20:23
Могу привести еще один пример, функция для запуска exe с параметром и ожидание его завершения.
function ExecAndWait(const FileName, Params: string; WindowState: Word): Longword;
var { by Pat Ritchey }
StartupInfo: TStartupInfo;
ProcessInfo: TProcessInformation;
CmdLine: string;
begin
CmdLine := '"' + FileName + '"' + Params;
FillChar(StartupInfo, SizeOf(StartupInfo), #0);
StartupInfo.cb := SizeOf(StartupInfo);
StartupInfo.dwFlags := STARTF_USESHOWWINDOW;
StartupInfo.wShowWindow := WindowState;
if not CreateProcess(nil,
PChar(CmdLine), // pointer to command line string
nil, // pointer to process security attributes
nil, // pointer to thread security attributes
False, // handle inheritance flag
CREATE_NEW_CONSOLE or // creation flags
NORMAL_PRIORITY_CLASS,
nil, //pointer to new environment block
nil, // pointer to current directory name {PChar(ExtractFilePath(FileName)),}
StartupInfo, // pointer to STARTUPINFO
ProcessInfo) // pointer to PROCESS_INF
then Result := WAIT_FAILED
else
begin
while WaitForSingleObject(ProcessInfo.hProcess, 0) = WAIT_TIMEOUT do
begin
Application.ProcessMessages;
Sleep(50);
end;
WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
GetExitCodeProcess(ProcessInfo.hProcess, Result);
CloseHandle(ProcessInfo.hProcess);
CloseHandle(ProcessInfo.hThread);
end;
end;
//Пример использования
procedure TForm1.Button1Click(Sender: TObject);
begin
ExecAndWait( 'C:\Program Files\NSIS\makensis.exe', 'C:\myscript.nsi', SW_HIDE );
end;
Painkiller
31-07-2011, 20:25
Могу привести еще один пример, функция для запуска exe с параметром и ожидание его завершения.
« скрыть »
Эту функцию я тоже знаю и тоже использую иногда . И с ней не пашит. Дело тут не в функциях .
уже мозг кипит, не знаю, может вы чем сможете помочь.
нужно сделать кастомную страницу лицензии.
так исторически сложилось, что делается все на ини файлах.
сделал поле
[Field 1]
Type=Bitmap
Text=C:\WINDOWS\TEMP\captura.bmp
Left=0
Right=290
Top=20
Bottom=43
[Field 2]
Type=Text
State=
Left=4
Right=288
Top=44
Bottom=94
Flags=MULTILINE|VSCROLL|NOTABSTOP
но как в него запихнуть текст лицензии?
пробовал читать текст из файла построчно в переменную, а затем вставить его
!insertmacro INSTALLOPTIONS_WRITE "pantallatoolbar" "Field 1" "Text" "$TEMP\captura.bmp"
!insertmacro INSTALLOPTIONS_WRITE "pantallatoolbar" "Field 2" "State" "$text_license"
но тут наткнулся на ограничение NSIS "default, variables are limited to 1024 characters. "
нашел плагин " CustomLicense" пробовал на его основе запихнуть текст в свое окно, тоже не вышло...
как можно какой нибудь текст неизвестной за ранее длины из файла запихнуть в требуемое поле?
kotkovets
01-08-2011, 13:40
yyv, парсить текст построчно и отказаться от стандартных страничек,нарисовать текстовое поле - но мелькание строк невозможно избавиться.
Если текст юникодный, то размер уменьшается в 2 раза, из-за того, что в юникоде один символ занимает 2 байта.
Использовать расширенную версию NSIS, где размер хранения значения увеличен до 8192 байта (т.е тект максимум должен быть 8кБ, в юникоде 4кБ).
Large strings (http://nsis.sourceforge.net/Special_Builds) - распаковываем архив и заменяем из архива все файлы.
все таки решил проблему с помощью CustomLicense plug-in
может кому еще нужно будет
работает примерно так
!insertmacro MUI_INSTALLOPTIONS_INITDIALOG "ReadmePage.ini"
Pop $MUI_HWND
GetDlgItem $0 $MUI_HWND 1201
CustomLicense::LoadFile "$PLUGINSDIR\readme.txt" "$0"
!insertmacro MUI_INSTALLOPTIONS_SHOW
если не хочется использовать плагин то можно так
вместо
CustomLicense::LoadFile "$PLUGINSDIR\readme.txt" "$0"
ClearErrors
FileOpen $0 $PLUGINSDIR\${LICENSEPAGE} r
IfErrors exit
System::Call 'kernel32::GetFileSize(i r0, i 0) i .r1'
IntOp $1 $1 + 1 ; for terminating zero
System::Alloc $1
Pop $2
System::Call 'kernel32::ReadFile(i r0, i r2, i r1, *i .r3, i 0)'
FileClose $0
Pop $MUI_HWND
GetDlgItem $0 $MUI_HWND 1201
SendMessage $0 ${EM_SETLIMITTEXT} $1 0
SendMessage $0 ${WM_SETTEXT} 0 $2
System::Free $2
exit:
в итоге у меня получилось закинуть текст из нужного мне файла в кастомное окно.
kotkovets
01-08-2011, 14:59
yyv,
Вы проверочку на размер сделаете, а то если текст будет превышать размер хранения переменной - с треском грохнется NSIS. Вы же помещаете текст целиком в переменную... в $1 - размер в байтах...
FileOpen $0 text.txt r
IfErrors Exit
System::Call 'kernel32::GetFileSize(ir0, i0) i .r1'
IntOp $1 $1 + 1 ; for terminating zero
IntCmp $1 ${NSIS_MAX_STRLEN} 0 0 Exit
System::Alloc $1
Pop $2
System::Call 'kernel32::ReadFile(ir0, ir2, ir1, *i.r3, i0)'
FileClose $0
System::Call "*$2(&t$3.r4)" ;из указателя на буфер - вытаскиваем текст
MessageBox MB_ICONINFORMATION|MB_OK "$4" IDOK ;в $4 - содержимое всего файла
System::Free $2
Exit:
Вы проверочку на размер сделаете, а то если текст будет превышать размер хранения переменной - с треском грохнется NSIS. Вы же помещаете текст целиком в переменную... в $1 - размер в байтах. »
размер хранения переменной это вы имеете ввиду это:
"default, variables are limited to 1024 characters. "?
текстовый файл размером 7,1 Кб. проходит без всяких проблем.
на нсис форуме в ветке самого плагина автор аписал
" Max file size 305 666 bytes (298KB)"
а этот код я так понял выполняет практически тоже самое что и плагин.
Вообщем надо будет попробовать разные размеры по подставлять, посмотерть что будет.
kotkovets
01-08-2011, 17:04
размер хранения переменной это вы имеете ввиду это:
"default, variables are limited to 1024 characters. "?
текстовый файл размером 7,1 Кб. проходит без всяких проблем »
Это я к тому, если файл будет превышать размер 8192 байта - с треском NSIS свалится, для стандарттного NSIS 1024 байта - кто нибудь скопирует код и будет такие же вопросы задавать.
kernel32::ReadFile старая апишка, позволяет только читать файлы в кодировке ANSI, для юникода, т.е любого файла, есть ReadFileEx (http://msdn.microsoft.com/en-us/library/aa365468(v=vs.85).aspx) , но синтаксис написания этой функции несколько иной.
qwestins
08-08-2011, 14:25
Народ, подскажите. Есть прога TightVNC Viewer, которая включает в себя Сервер и Вьювер, а так же установку пароля. Нужно создать энсис файл, в котором будет производится автоматический выбор Сервера, Вьювер лучше даже вырезать и автоматически задаваться пароль.
kotkovets
08-08-2011, 15:17
Народ, подскажите »
Это называется - народ сделайте за меня...
Вы бы сами начали то, что то делать для начала...
Мужики привет, я буду запускать интсталяционный пакет, вопрос в следующем, NSIS передает прогресс установки программы которая запустилла инстлаятор ?? как можно отследить прогресс установки ?? Через внешнее приложение или еще как нибудь ????
kotkovets
10-08-2011, 09:14
как можно отследить прогресс установки ?? »
можно, в скрипте после каждого файла или после каждой команды помещать значение в процентах установки и вывести в окно деталей значение установки, только придется рассчитывать вручную - сколько прибавлять процентов установки в переменную, либо взять хэндл прогресса, посылать после каждой команды соотвтствующее сообщение PBM_GETPOS получение позиции прогресса и PBM_GetRange (информация о текущих верхних и нижних пределах данного контрола) значение записывать в определенную переменную.
Name "PROGRESSBAR Example"
OutFile "Example.exe"
ShowInstDetails show
Var PROGBAR
Var GETRANGE
Var HWND
CompletedText "Установка на 100% выполнена!"
Function ProgressBar
FindWindow $HWND "#32770" "" $HWNDPARENT
GetDlgItem $HWND $HWND 1004
SendMessage $HWND 0x0407 0 0 $GETRANGE
SendMessage $HWND 0x0408 0 0 $PROGBAR
IntOp $PROGBAR $PROGBAR * 100
IntOp $PROGBAR $PROGBAR / $GETRANGE
SetDetailsPrint textonly
DetailPrint "Установка $PROGBAR%"
SetDetailsPrint both
FunctionEnd
Section
Call ProgressBar
Sleep 300
Call ProgressBar
Sleep 300
Call ProgressBar
Sleep 300
Call ProgressBar
Sleep 300
Call ProgressBar
Sleep 300
Call ProgressBar
Sleep 300
Call ProgressBar
Sleep 300
Call ProgressBar
Sleep 300
Call ProgressBar
Sleep 300
Call ProgressBar
SectionEnd
В переменной $PROGBAR - "заполненность" в процентах прогресс бара
kotkovets,
Мне надо что чужая прога отлавливала прогресс установки!! Внешняя!!!
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.
Available in ZeroNet 1osznRoVratMCN3bFoFpR2pSV5c9z6sTC