|
Компьютерный форум OSzone.net » Автоматическая установка Windows » Автоматическая установка приложений » .: NSIS - все вопросы :. часть 2. |
|
.: NSIS - все вопросы :. часть 2.
|
Ветеран Сообщения: 1216 |
Профиль | Отправить PM | Цитировать
Данная тема предназначена для обсуждения вопросов, связанных с инсталлятором Nullsoft Scriptable Install System, или просто NSIS. Сайт приложения. Описание: Текущая версия: NSIS 3.05 от 15 декабря 2019 года Скачать | Архив сборок версии Первая часть этой темы Скачать первую часть этой темы одним архивом ВНИМАНИЕ! прежде, чем задать вопрос, почитайте, где Вы найдете ответы на большинство вопросов: Справочник по NSIS - создан силами нашего сообщества. Руководство пользователя. Перевод – Поляков А.В, зеркало Документация Утилиты разработчика Расширение функциональности Примеры скриптов на нашем форуме Скрипт NSIS для перепаковки AIMP2+Сборки Тема для Notepad++(пример парсинга XML) Достоинства Ещё немного полезной информации: |
|
------- Отправлено: 12:02, 09-12-2012 |
Старожил Сообщения: 352
|
Профиль | Отправить PM | Цитировать Цитата MKN:
Ввод-Вывод плагина ExecDos однобайтный (в основном), поэтому нужно использовать параметр m на входе OemToChar или выходе CharToOem: Этот вариант будет работать и в Unicode и в ANSI сборках. Проверка на многострочном тексте показала, что этот способ портит символы \r, \n и, наверняка, другие спецсимволы. Более корректный универсальный ansi/unicode способ в виде макроса: !define OemToChar `!insertmacro OemToChar` !macro OemToChar STR !ifdef NSIS_UNICODE Push $0 System::Call 'kernel32::MultiByteToWideChar(i 1, i 0, m "${STR}", i -1, i 0, i 0) i.s' System::Call 'kernel32::MultiByteToWideChar(i 1, i 0, m "${STR}", i -1, t.r0, i s)' Exch $0 !else System::Call 'user32::OemToChar(m"${STR}", t.s)' !endif Pop ${STR} !macroend |
|
Последний раз редактировалось iglezz, 27-02-2023 в 14:20. Отправлено: 02:53, 27-02-2023 | #2661 |
Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети. Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля. |
Ветеран Сообщения: 2358
|
Профиль | Отправить PM | Цитировать iglezz, благодарю за разъяснение и пример.
Обнаружил интересный многофункциональный плагин - NSutils https://github.com/negrutiu/nsis-nsutils В частности интересны его StartReceivingClicks и StopReceiveClicks - функции обратного вызова NSIS для пользовательских кнопок. Помнится в ряде случаев были сложности именно с "калбаками" для собственных кнопок в разных местах окон инсталлятора... Хорошо бы на базе этого плагина(если он умеет) примеры увидеть... |
Последний раз редактировалось MKN, 27-02-2023 в 15:46. Отправлено: 15:33, 27-02-2023 | #2662 |
Старожил Сообщения: 352
|
Профиль | Отправить PM | Цитировать MKN,
Кнопки для этого плагина нужно добавлять так-же как и для плагина ButtonEvent, через редактор ресурсов. Проблем с колбеками не должно было быть и раньше - нужно всего лишь один раз понять их логику. В WinAPI вобще везде так - надо понять как это всё работает, иначе постоянно будут какие-то непонятки. Вот примерчик для кнопки с NSutils: Скрытый текст
RequestExecutionLevel user !include "LogicLib.nsh" !include "nsDialogs.nsh" Page components "" OnComponentsShow OnComponentsLeave Function .onInit FunctionEnd Section SectionEnd Var hComponentsButton Function OnComponentsShow System::Call 'user32::GetClientRect(i $HWNDPARENT,@r1)i.r2' System::Call '*$1(i,i,i.r1,i.r2)' IntOp $2 $2 - 80 System::Call 'user32::CreateWindowEx(i0,t"Button",\ t"ClickMe!",\ i${BS_PUSHBUTTON}|${WS_CHILD}|${WS_VISIBLE}|${WS_TABSTOP},\ i0,ir2,ir1,i80,\ i$HWNDPARENT,i0,ir0,i0)i.s' Pop $hComponentsButton CreateFont $0 '$(^Font)' '$(^FontSize)' SendMessage $hComponentsButton ${WM_SETFONT} $0 0 System::Call 'user32::SetWindowPos(i $hComponentsButton,i0, i0,i0,i0,i0, i3)' GetFunctionAddress $0 OnComponentsButtonClicked NSutils::StartReceivingClicks $HWNDPARENT $0 FunctionEnd Function OnComponentsButtonClicked Pop $1 Pop $2 ${If} $1 = $hComponentsButton MessageBox MB_OK "Clicked$\nHWND $1$\nID $2" ${EndIf} FunctionEnd Function OnComponentsLeave NSutils::StopReceivingClicks $HWNDPARENT FunctionEnd Кнопка создаётся в рантайме, посему криво (про это я объяснял с соседней теме по AutoIt) Лучше кнопки добавлять в редакторе ресурсов. Их можно сделать изначально невидимыми (без атрибута WS_VISIBLE) и делать видимыми (и даже перемещать/менять размер) по мере необходимости. Если хочется без проблем добавлять всякие штуки налету то придётся предварительно подправить диалоги (их порядок и свойства). |
Отправлено: 17:15, 27-02-2023 | #2663 |
Пользователь Сообщения: 93
|
Профиль | Отправить PM | Цитировать Приветствую всех.
Тут такое дело. Имеется батник, который имеет две функции: 1. Создает текстовый файл расширения .ics с добавлением в него нужных строк. 2. Если этот файл со своими строками уже имеется, то батник добавляет в готовый файл только нужные строки не трогая имеющихся и не дублирует те, которые нужно добавить, если таковы имеются Вот его код: Скрытый текст
@echo off set "File=hosts.ics" set "Folder=%windir%\system32\drivers\etc" pushd "%Folder%"||(pause &exit /B 2) set "@Add001=0.0.0.0 martau.com" set "@Add002=0.0.0.0 www.martau.com" set "@Add003=0.0.0.0 total-uninstall.com" set "@Add004=0.0.0.0 www.total-uninstall.com" set "@Add005=0.0.0.0 64.91.254.118" attrib -R -S -H "%File%" set /A NOld=1000 for /F "usebackq delims=" %%s in ("%File%") do (set /A NOld+=1 &call set "@Old%%NOld%%=%%s") for /F "usebackq tokens=1* delims==" %%i in (`2^>nul set "@Add"`) do (set /A NOld+=1 &Call set "@Old%%NOld%%=%%j") for /F "usebackq tokens=1* delims==" %%i in (`2^>nul set "@Old"`) do (set "SS=%%j" &Call set "@%%i=%%SS: =%%") >"%File%" (for /L %%i in (1001,1,%NOld%) do call :AnalizHosts %%i) attrib +R "%File%" popd exit :AnalizHosts call set "A=%%@@Old%1%%" if /I "%A%"=="" exit /B 1 if "%A:~0,1%"=="#" (call echo %%@Old%1%%&exit /B 0) (call echo %%@Old%1%%) for /F "usebackq tokens=1* delims==" %%i in (`2^>nul set "@@Old"`) do if /I "%%j"=="%A%" call set "%%i=" exit /B 0 Сделал точную работу этого батника в NSIS, работает отлично, но код какой-то громоздкой получился. Можно ли этот код каким нибудь образом упростить или усовершенствовать или он таким и должен быть? Скрытый текст
Function DelLine StrCpy $0 SkipWrite Push $0 FunctionEnd Section Var /global Text Var /global Text1 Var /global Text2 Var /global Text3 Var /global Text4 StrCpy $Text "0.0.0.0 martau.com" StrCpy $Text1 "0.0.0.0 www.martau.com" StrCpy $Text2 "0.0.0.0 total-uninstall.com" StrCpy $Text3 "0.0.0.0 www.total-uninstall.com" StrCpy $Text4 "0.0.0.0 64.91.254.118" ${If} ${FileExists} "$SYSDIR\drivers\etc\hosts.ics" SetFileAttributes "$SYSDIR\drivers\etc\hosts.ics" NORMAL ${LineSum} "$SYSDIR\drivers\etc\hosts.ics" $R0 StrCpy $R1 0 read: IntOp $R1 $R1 + 1 IntCmp $R1 $R0 0 0 end readnow: ${LineRead} "$SYSDIR\drivers\etc\hosts.ics" "$R1" $R3 ${WordFind} "$R3" "$Text" "E+1{" $R2 IfErrors read 0 ${LineFind} "$SYSDIR\drivers\etc\hosts.ics" "" "$R1" "DelLine" ${LineSum} "$SYSDIR\drivers\etc\hosts.ics" $R0 goto readnow end: ${LineSum} "$SYSDIR\drivers\etc\hosts.ics" $R0 StrCpy $R1 0 read1: IntOp $R1 $R1 + 1 IntCmp $R1 $R0 0 0 end1 readnow1: ${LineRead} "$SYSDIR\drivers\etc\hosts.ics" "$R1" $R3 ${WordFind} "$R3" "$Text1" "E+1{" $R2 IfErrors read1 0 ${LineFind} "$SYSDIR\drivers\etc\hosts.ics" "" "$R1" "DelLine" ${LineSum} "$SYSDIR\drivers\etc\hosts.ics" $R0 goto readnow1 end1: ${LineSum} "$SYSDIR\drivers\etc\hosts.ics" $R0 StrCpy $R1 0 read2: IntOp $R1 $R1 + 1 IntCmp $R1 $R0 0 0 end2 readnow2: ${LineRead} "$SYSDIR\drivers\etc\hosts.ics" "$R1" $R3 ${WordFind} "$R3" "$Text2" "E+1{" $R2 IfErrors read2 0 ${LineFind} "$SYSDIR\drivers\etc\hosts.ics" "" "$R1" "DelLine" ${LineSum} "$SYSDIR\drivers\etc\hosts.ics" $R0 goto readnow2 end2: ${LineSum} "$SYSDIR\drivers\etc\hosts.ics" $R0 StrCpy $R1 0 read3: IntOp $R1 $R1 + 1 IntCmp $R1 $R0 0 0 end3 readnow3: ${LineRead} "$SYSDIR\drivers\etc\hosts.ics" "$R1" $R3 ${WordFind} "$R3" "$Text3" "E+1{" $R2 IfErrors read3 0 ${LineFind} "$SYSDIR\drivers\etc\hosts.ics" "" "$R1" "DelLine" ${LineSum} "$SYSDIR\drivers\etc\hosts.ics" $R0 goto readnow3 end3: ${LineSum} "$SYSDIR\drivers\etc\hosts.ics" $R0 StrCpy $R1 0 read4: IntOp $R1 $R1 + 1 IntCmp $R1 $R0 0 0 end4 readnow4: ${LineRead} "$SYSDIR\drivers\etc\hosts.ics" "$R1" $R3 ${WordFind} "$R3" "$Text4" "E+1{" $R2 IfErrors read4 0 ${LineFind} "$SYSDIR\drivers\etc\hosts.ics" "" "$R1" "DelLine" ${LineSum} "$SYSDIR\drivers\etc\hosts.ics" $R0 goto readnow4 end4: ${EndIf} FileOpen $0 "$SYSDIR\drivers\etc\hosts.log" w FileWrite $0 "0.0.0.0 martau.com $\r$\n" FileWrite $0 "0.0.0.0 www.martau.com $\r$\n" FileWrite $0 "0.0.0.0 total-uninstall.com $\r$\n" FileWrite $0 "0.0.0.0 www.total-uninstall.com $\r$\n" FileWrite $0 "0.0.0.0 64.91.254.118 $\r$\n" FileClose $0 ${If} ${FileExists} "$SYSDIR\drivers\etc\hosts.ics" ${FileJoin} "$SYSDIR\drivers\etc\hosts.log" "$SYSDIR\drivers\etc\hosts.ics" "$SYSDIR\drivers\etc\hosts.ics" Delete "$SYSDIR\drivers\etc\hosts.log" ${Else} Rename "$SYSDIR\drivers\etc\hosts.log" "$SYSDIR\drivers\etc\hosts.ics" ${EndIf} SetFileAttributes "$SYSDIR\drivers\etc\hosts.ics" READONLY SectionEnd |
Отправлено: 14:43, 02-03-2023 | #2664 |
Ветеран Сообщения: 2358
|
Профиль | Отправить PM | Цитировать Цитата inco1:
|
|
Отправлено: 09:47, 04-03-2023 | #2665 |
Пользователь Сообщения: 93
|
Профиль | Отправить PM | Цитировать Цитата MKN:
|
|
Отправлено: 15:22, 04-03-2023 | #2666 |
Старожил Сообщения: 352
|
Профиль | Отправить PM | Цитировать inco1, Код нужно усовершенствовать, ибо он дико неоптимален (сам язык в основе скуден, а комплектные библиотеки (nsh) по этой части страшны). Громоздкость хорошо заметается под макросы и прячется в отдельные библиотечки.
Батник корректно работающим можно назвать только в двух случаях: 1. добавляемых строк в файле нет; 2. строки уже были добавлены в формате, жёстко заданном батником (скорее всего самим же батником ранее). В остальных случаях он будет плодить мусор в виде дублирующихся неработающих записей. Основных проблем тут две. Первая - простая техническая. Добыть данные из файла. Обработать. Запихнуть обратно. В процессе ничего не сломать. И чтобы код можно было понимать и поддерживать спустя полгода. Правильная работа начинается с правильной обработки строк, а каждая строка-запись в максимуме может содержать IP-адрес, энное количество хостов и комментарий с пробелами или табуляциями в качестве разделителей. Обычные прелести минимально структурированного простого текста. Разбор всего этого в NSIS растянется на сотни строк, это не питон какой-нибудь, где строку можно распарсить одной регуляркой. Строки могут записаны или даже так
По хорошему надо вытаскивать все данные в некую структуру (список/массив), анализировать и потом записывать обратно. И помнить про обработку ошибок - мало дать команду на запись, надо ещё убедится, что изменения реально записаны. Вторая проблема - посложнее. КАК реализовать техническую часть, чтобы всё работало, чтобы ничего не сломать пользователю, чтобы была возможность отката своих изменений. Рабочий пример с в меру гибкой обработкой hosts file есть по ссылке. То, что под капотом (hostsblock.nsh), местами корявое, местами страшное, но рабочее с большего. Со стороны основного скрипта одна команда с всего двымя параметрами - имя файла и хост. В примере присутствует !define DEBUG - это нужно только для отладки, если что-то вдруг пойдёт не так. |
Отправлено: 05:51, 05-03-2023 | #2667 |
Пользователь Сообщения: 93
|
Профиль | Отправить PM | Цитировать iglezz, это наилучшее решение, имеющееся сегодня в NSIS для HOSTS.
Проверил практически на всех системах, и с UAC и без, и с пробелами в строках и без. Работает без сучка и задоринки. Мне прекрасно подходит. Чтобы работало для моего файла "hosts.ics" я поменял в hostsblock.nsh все 54 "hosts" на "hosts.ics" и переименовал на "hostsicsblock.nsh". Результат простейшего экзешника без Errors получился таким: Скрытый текст
Unicode true SetOverwrite on RequestExecutionLevel admin !include "x64.nsh" !include "LogicLib.nsh" !include "hostsicsblock.nsh" Section Var /global hostsics StrCpy $hostsics "$SYSDIR\drivers\etc" ${IfThen} ${RunningX64} ${|} ${DisableX64FSRedirection} ${|} ${If} ${FileExists} "$hostsics\hosts.ics" SetFileAttributes "$hostsics\hosts.ics" NORMAL StrCpy $0 '$hostsics\hosts.ics' StrCpy $1 '$hostsics\1.txt' StrCpy $2 '$hostsics\2.txt' CopyFiles /SILENT $0 $1 FileOpen $3 $1 A FileSeek $3 0 END FileClose $3 CopyFiles /SILENT $1 $2 FileOpen $3 $2 A FileClose $3 ${hosts.icsfile_BlockHost} $2 'martau.com' ${hosts.icsfile_BlockHost} $2 'www.martau.com' ${hosts.icsfile_BlockHost} $2 'www.total-uninstall.com' ${hosts.icsfile_BlockHost} $2 'total-uninstall.com' ${hosts.icsfile_BlockHost} $2 '64.91.254.118' CopyFiles /SILENT $2 $0 Delete "$hostsics\1.txt" Delete "$hostsics\2.txt" ${Else} FileOpen $0 "$hostsics\hosts.ics" w FileWrite $0 "0.0.0.0 martau.com $\r$\n" FileWrite $0 "0.0.0.0 www.martau.com $\r$\n" FileWrite $0 "0.0.0.0 total-uninstall.com $\r$\n" FileWrite $0 "0.0.0.0 www.total-uninstall.com $\r$\n" FileWrite $0 "0.0.0.0 64.91.254.118 $\r$\n" FileClose $0 ${EndIf} SetFileAttributes "$hostsics\hosts.ics" READONLY SectionEnd Я так думаю, что для моей задачи с файлом "hosts.ics" код можно использовать и без вставки обработки ошибок. Огромнейшая благодарность за проделанную работу над hostsblock.nsh. |
Отправлено: 16:45, 05-03-2023 | #2668 |
Ветеран Сообщения: 2358
|
Профиль | Отправить PM | Цитировать Цитата iglezz:
Цитата iglezz:
Цитата:
|
|||
Последний раз редактировалось MKN, 05-03-2023 в 17:47. Отправлено: 17:41, 05-03-2023 | #2669 |
Старожил Сообщения: 352
|
Профиль | Отправить PM | Цитировать inco1,
1. Менять в hostsblock.nsh ничего не надо. Кроме случаев изменения функционала / правки ошибок. 2. В секции примера много лишнего. Её содержімое можно записать компактнее Скрытый текст
Section ${IfThen} ${RunningX64} ${|} ${DisableX64FSRedirection} ${|} Var /global hostsfile StrCpy $hostsfile "$SYSDIR\drivers\etc\hosts.ics" ${IfNot} ${FileExists} $hostsfile FileOpen $0 $hostsfile W FileClose $0 ${EndIf} SetFileAttributes $hostsfile NORMAL ${hostsfile_BlockHost} $hostsfile 'martau.com' ${hostsfile_BlockHost} $hostsfile 'www.martau.com' ${hostsfile_BlockHost} $hostsfile 'www.total-uninstall.com' ${hostsfile_BlockHost} $hostsfile 'total-uninstall.com' ${hostsfile_BlockHost} $hostsfile '64.91.254.118' SetFileAttributes $hostsfile READONLY SectionEnd MKN, Цитата MKN:
|
|
Последний раз редактировалось iglezz, 05-03-2023 в 17:53. Отправлено: 17:43, 05-03-2023 | #2670 |
Участник сейчас на форуме | Участник вне форума | Автор темы | Сообщение прикреплено |
| |||||
Название темы | Автор | Информация о форуме | Ответов | Последнее сообщение | |
Инфо - [ликбез] Помощь начинающим .:[все вопросы]:. часть 2 | dimadr | Наборы обновлений для Windows XP/2003/Windows 7 | 267 | 14-02-2020 08:25 | |
[архив].: NSIS - все вопросы :. | kotkovets | Автоматическая установка приложений | 3387 | 09-12-2012 11:56 | |
Инфо - [ликбез] Помощь начинающим .:[все вопросы]:. часть 1 | jameszero | Наборы обновлений для Windows XP/2003/Windows 7 | 1491 | 22-07-2011 22:42 | |
Выбор|модернизация процессора .:[все вопросы]:. Часть I | Myxa | Выбор отдельных компонентов компьютера и конфигурации в целом | 1845 | 01-01-2011 19:18 | |
Вопросы по создателю инсталляций NSIS | MaxDELETE | Программное обеспечение Windows | 14 | 04-07-2007 10:01 |
|