|
Компьютерный форум 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 |
Ветеран Сообщения: 860
|
Профиль | Отправить PM | Цитировать Цитата K.A.V.:
Цитата K.A.V.:
Собрал такое, но не работает ${LineSum} "$DESKTOP\hosts" $R0 ; в переменную $R0 заносим количество строк в файле StrCpy $R1 0 ; обновляем счетчик, в этой переменной будет хранится порядковый номер строки, которая читается в данный момент readnext: IntOp $R1 $R1 + 1 ; увеличиваем счетчик и читаем следующую строку IntCmp $R1 $R0 0 0 end ; если текущее значение читаемой строки больше, чем общее количество строк в файле - завершаем обработку и прыгаем на метку end readlinenow: ; сюда будем прыгать после удаления строки, необходимо после удаления строки ещё раз прочитать эту же строку, т.к. данные в файле будут "сдвинуты" после удаления строки ${LineRead} "$DESKTOP\hosts" "$R1" $R3 ; читаем содержимое строки ${LineRead} "$DESKTOP\hosts" "$R4" $R5 ; читаем содержимое строки ${WordFind} "$R3" "127.0.0.1 winxpregp.narod.ru" "E+1{" $R2 ; ищем фразу в строке ${WordFind} "$R5" "127.0.0.1 winxp.narod.ru" "E+1{" $R6 ; ищем фразу в строке IfErrors readnext 0 ; если фраза не найдена - прыгаем на метку readnext и читаем следующую строку, если фраза найдена - спускаемся дальше по коду ${LineFind} "$DESKTOP\hosts" "" "$R1" "DeleteLineCallback" ; удалем строку, в которой найдена фраза, передавая номер удаляемой строки ${LineFind} "$DESKTOP\hosts" "" "$R4" "DeleteLineCallback" ; удалем строку, в которой найдена фраза, передавая номер удаляемой строки ${LineSum} "$DESKTOP\hosts" $R0 ; после попытки удаления строки желательно обновить данные о количестве строк в файле, если удалений строк с фразой будет много - будут лишние команды чтения строк goto readlinenow ; после удаления строки нужно прочитать эту строку ещё раз, т.к. данные в файле сразу же сдвигаются, прыгаем на метку readlinenow end: |
||
------- Отправлено: 23:14, 15-05-2015 | #1631 |
Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети. Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля. |
Ленивый кусок мяса Сообщения: 1986
|
Профиль | Сайт | Отправить PM | Цитировать Цитата Dodakaedr:
Цитата Dodakaedr:
${LineSum} "$DESKTOP\hosts" $R0 ; в переменную $R0 заносим количество строк в файле StrCpy $R1 0 ; обновляем счетчик, в этой переменной будет хранится порядковый номер строки, которая читается в данный момент readnext: IntOp $R1 $R1 + 1 ; увеличиваем счетчик и читаем следующую строку IntCmp $R1 $R0 0 0 end ; если текущее значение читаемой строки больше, чем общее количество строк в файле - завершаем обработку и прыгаем на метку end readlinenow: ; сюда будем прыгать после удаления строки, необходимо после удаления строки ещё раз прочитать эту же строку, т.к. данные в файле будут "сдвинуты" после удаления строки ${LineRead} "$DESKTOP\hosts" "$R1" $R3 ; читаем содержимое строки ${LineRead} "$DESKTOP\hosts" "$R4" $R5 ; читаем содержимое строки ${WordFind} "$R3" "127.0.0.1 winxpregp.narod.ru" "E+1{" $R2 ; ищем фразу в строке ${WordFind} "$R5" "127.0.0.1 winxp.narod.ru" "E+1{" $R6 ; ищем фразу в строке IfErrors readnext 0 ; если фраза не найдена - прыгаем на метку readnext и читаем следующую строку, если фраза найдена - спускаемся дальше по коду ${LineFind} "$DESKTOP\hosts" "" "$R1" "DeleteLineCallback" ; удалем строку, в которой найдена фраза, передавая номер удаляемой строки ${LineFind} "$DESKTOP\hosts" "" "$R4" "DeleteLineCallback" ; удалем строку, в которой найдена фраза, передавая номер удаляемой строки ${LineSum} "$DESKTOP\hosts" $R0 ; после попытки удаления строки желательно обновить данные о количестве строк в файле, если удалений строк с фразой будет много - будут лишние команды чтения строк goto readlinenow ; после удаления строки нужно прочитать эту строку ещё раз, т.к. данные в файле сразу же сдвигаются, прыгаем на метку readlinenow Ошибка чтения строки, почему? Потому что вы передаёте ранее не задействованную переменную $R4 с пустым значением, соответственно, никакая строка прочитана не будет Вторая выделенная строка. Т.к. выше была ошибка чтения строки, то и поиск фразы будет неудачным Третья выделенная строка. Т.к. было выше 2 ошибки, никакая строка удалена не будет Вы просто наугад подставили переменные и думали, что код магическим образом заработает? Если бы вы прочли наш справочник, то смогли бы создать 1 глобальную переменную, в которую бы помещали фразу для поиска и вызывали бы мою написанную функцию сколько угодно раз. Скрытый текст
Function test Var /global MyText StrCpy $MyText "winxpregp.narod.ru" call DeleteLineFunc StrCpy $MyText "microsoft.com" call DeleteLineFunc StrCpy $MyText "oszone.net" call DeleteLineFunc FunctionEnd Function DeleteLineFunc ${LineSum} "$DESKTOP\hosts" $R0 ; в переменную $R0 заносим количество строк в файле StrCpy $R1 0 ; обновляем счетчик, в этой переменной будет хранится порядковый номер строки, которая читается в данный момент readnext: IntOp $R1 $R1 + 1 ; увеличиваем счетчик и читаем следующую строку IntCmp $R1 $R0 0 0 end ; если текущее значение читаемой строки больше, чем общее количество строк в файле - завершаем обработку и прыгаем на метку end readlinenow: ; сюда будем прыгать после удаления строки, необходимо после удаления строки ещё раз прочитать эту же строку, т.к. данные в файле будут "сдвинуты" после удаления строки ${LineRead} "$DESKTOP\hosts" "$R1" $R3 ; читаем содержимое строки ${WordFind} "$R3" "$MyText" "E+1{" $R2 ; ищем фразу в строке IfErrors readnext 0 ; если фраза не найдена - прыгаем на метку readnext и читаем следующую строку, если фраза найдена - спускаемся дальше по коду ${LineFind} "$DESKTOP\hosts" "" "$R1" "DeleteLineCallback" ; удалем строку, в которой найдена фраза, передавая номер удаляемой строки ${LineSum} "$DESKTOP\hosts" $R0 ; после попытки удаления строки желательно обновить данные о количестве строк в файле, если удалений строк с фразой будет много - будут лишние команды чтения строк goto readlinenow ; после удаления строки нужно прочитать эту строку ещё раз, т.к. данные в файле сразу же сдвигаются, прыгаем на метку readlinenow end: FunctionEnd Function DeleteLineCallback StrCpy $0 SkipWrite Push $0 FunctionEnd Читайте Справочник по NSIS, моя любимая фраза для новичков, которую я не люблю повторять |
||
------- Отправлено: 00:19, 16-05-2015 | #1632 |
Ветеран Сообщения: 2358
|
Профиль | Отправить PM | Цитировать Цитата Dodakaedr:
Без этого, как правило, манипуляции с файлом будут не возможны... (т.к. либо файл "занят" системой , а ещё хуже, когда файл hosts под контролем какого нибудь "защитника" или антивируса, что встречается всё чаще и чаще... ) |
|
Отправлено: 10:01, 16-05-2015 | #1633 |
Ветеран Сообщения: 860
|
Профиль | Отправить PM | Цитировать Цитата MKN:
|
|
------- Отправлено: 16:06, 16-05-2015 | #1634 |
Ветеран Сообщения: 860
|
Профиль | Отправить PM | Цитировать Решил в одну функцию запихнуть удаление строк в файле hosts с проверкой атрибута для удобства, при выходе из исталлятора атрибут снимается, но не ставится обратно после удаления строк. Вызываю вот такую функцию
function delete ${GetFileAttributes} "$DESKTOP\hosts" "READONLY" $R0 StrCmp $R0 "1" 0 +2 SetFileAttributes "$DESKTOP\hosts" "NORMAL" StrCpy $MyText "127.0.0.1 support.soft.com" call DeleteLineFunc StrCpy $MyText "127.0.0.1 soft.com" call DeleteLineFunc StrCmp $R0 "1" 0 +2 ;если здесь поставить +1 то атрибут ставится постоянно не зависимо от результата проверки SetFileAttributes "$DESKTOP\hosts" "READONLY" functionend И еще вопрос: при удалении строк в конце файла постоянно остается пустая строка и получается что после 10 запусков в итоге имеем 10 пустых строк. Как сделать чтобы не оставалась пустая строка? |
------- Последний раз редактировалось Dodakaedr, 16-05-2015 в 20:21. Отправлено: 20:11, 16-05-2015 | #1635 |
Ленивый кусок мяса Сообщения: 1986
|
Профиль | Сайт | Отправить PM | Цитировать Цитата Dodakaedr:
Цитата Dodakaedr:
крик души
блин, вот скажите мне, для кого писался справочник? Я создавал его в надежде на то, что им будут пользоваться менее опытные кодеры, которым я смогу передать полученные знания и хотел, чтобы другие люди чему-то научились из этого справочника, но почему-то всё же находятся такие личности, которые хотят "всё и сразу и без чтения инфы" - ребят, в этой теме так не бывает, хотите, чтобы вам помогали решить вашу проблему - будьте добры, прочитайте справочник (да хотя бы самый минимум, те команды, которые используете - пишите правильно, а не наугад подставляйте параметры) Ключевое слово - помогаем, а не делаем всё за вас такое ощущение складывается, как-будто мне это нужно и я сижу уговариваю человека "ну прочитай, пожалуйста" Цитата Dodakaedr:
Давайте вы: 1. Воспользуетесь поиском по этой и предыдущей теме NSIS по ключевым словам LineFind, LineRead 2. Прочитаете в справке описание команд LineRead, StrCmp 3. Попробуете совместить команды LineRead, StrCmp с моим кодом удаления строки, в котором каждая строка с комментарием 4. Покажите, что у вас получилось Давайте запустим здесь для всех ленивых новичков режим "Обучение", будем только указывать на ошибки, давать рекомендации и не будем давать готовых кодов? Посмотрим, через какое время им всё же придётся обратиться к справочнику Мне кажется, этот способ будет очень эффективный, не хотите изучать NSIS - либо мы заставим, либо вы забьёте на NSIS |
|||
------- Отправлено: 21:03, 16-05-2015 | #1636 |
Ветеран Сообщения: 860
|
Профиль | Отправить PM | Цитировать Цитата K.A.V.:
Цитата K.A.V.:
Цитата K.A.V.:
Цитата K.A.V.:
StrCmp $R0 "1" 0 +2 ;если здесь поставить +1 то атрибут ставится постоянно не зависимо от результата проверки Скрытый текст
Function ReplaceLinesInFile ${LineSum} "$_FindInFile" $_LineNumbers ; Подсчитываем количество строк strcpy $_CurLineNumber 0 startLineRead: intop $_CurLineNumber $_CurLineNumber + 1 IntCmp $_CurLineNumber $_LineNumbers 0 0 endFunc ; Если номер текущей строки больше количества строк в файле - поиск завершен ${LineRead} "$_FindInFile" "$_CurLineNumber" $_CurLine ; Читаем строку по номеру текущей строки ${WordFind} '$_CurLine' "$_LineReplace" "E+1{" $R0 ; Ищем в строке нужный текст StrCmp $R0 "1" startLineRead 0 ; Если в строке присутствует искомый текст, выполняем код ниже ${LineFind} "$_FindInFile" "" "" "Insert_Line" ; Вызываем функцию Insert_Line, которая произведёт замену goto startLineRead endFunc: ; FunctionEnd Function Insert_Line StrCmp $R8 "$_CurLineNumber" 0 push ${StrRep} $_CurLine "$_CurLine" "$_LineReplace" "$_LineToInsert" FileWrite $R4 "$_CurLine" StrCpy $0 SkipWrite push: Push $0 FunctionEnd Цитата K.A.V.:
|
|||||
------- Отправлено: 23:13, 16-05-2015 | #1637 |
Ленивый кусок мяса Сообщения: 1986
|
Профиль | Сайт | Отправить PM | Цитировать Цитата Dodakaedr:
Ещё советую при использовании команд внимательно читать описание к команде, некоторые команды в NSIS переназначают значения переменных своими данными, из-за чего ваш код так же может оказаться некорректным, если вы используете те же переменные, что и команда NSIS, простой пример - команда Locate для поиска файлов, её callback функция использует переменные для хранения своих данных во время процесса поиска: Function "Function" ; $R9 "путь\имя" ; $R8 "путь" ; $R7 "имя" ; $R6 "размер" ($R6="" если директория, $R6="0" если поиск с ключем /S=) ; $R0-$R5 не используется функцией. ; ... Push $var ; Если $var="StopLocate" Завершение функции FunctionEnd Цитата Dodakaedr:
Скрытый текст
Для изучения конкретно NSIS вам нужно только одно - желание. Я тут уже 100 раз рассказывал, как лично я познакомился с NSIS будучи ещё совсем "зелёным" (во всех смыслах), я не то чтобы даже английский язык не знал, я в то время даже не знал, что такое интернет и редактор реестра. У меня кроме дистрибутива с непонятной программой (NSIS), которая просто была на CD в куче софта, больше ничего не было, ни знаний компьютерных, ни интернета, ни уж тем более справочника на русском
Я даже сейчас не знаю ни одного языка программирования и английского языка тоже не знаю, но просто есть желание и упорство - всё получается, это я к тому, что всё зависит только от вас, к тому же, у вас есть то, чего не было лично у меня - помощь со стороны более опытных кодеров и русская справка, пусть и не с огромным количеством всяких примеров и переведённых команд - но всё же для получения базовых знаний о NSIS справочник вполне сойдёт. Цитата Dodakaedr:
------- Цитата Dodakaedr:
Вот дальше вам необходимо понять всю силу фразы "Читайте справочник", если вы будете знать о всех командах, которые вам доступны в NSIS - вы будете писать код в несколько раз быстрее, зная команды - у вас в голове сразу будет строится код. Что для этого нужно? Так, ну, раз у меня простой текстовый файл, значит для начала мне нужно прочитать строку, а как я могу прочитать строку? Точно, есть же команда LineRead! Так, ну, допустим, я прочитаю первую строку, а если моя строка записана второй, как мне сделать универсальный код, не дублируя строки? Точно, есть же математическая команда IntOp, я сделаю счетчик и он будет плюсоваться после чтения строки, если это не моя строка - будем увеличивать счетчик и идти дальше по файлу! В голове строится код StrCpy $1 0 ; нам сначала нужно обнулить счетчик, т.к. переменная возможно уже ранее использовалась IntOp $1 $1 + 1 ; в переменную будет помещено текущее значение переменной $1 с прибавлением на 1 ${LineRead} "[Файл]" "$1" $0 Т.к. содержимое прочитанной строки помещается в переменную $0 (смотри описание команды LineRead), то, соответственно, нам нужно сделать условие сравнения этой переменной с пустым значением в команде StrCmp, с пустым потому, что нам нужно определить, что прочитанная строка действительно пустая, а не с данными StrCpy $1 0 ; нам сначала нужно обнулить счетчик, т.к. переменная возможно уже ранее использовалась ${LineRead} "[Файл]" "$1" $0 StrCmp $0 "" 0 ЕСЛИ_НЕТ ; метка 0 означает, что если условие истина, т.е. значение переменной $0 - пусто, то опускаемся дальше по коду ${LineFind} "$DESKTOP\hosts" "" "$R1" "DeleteLineCallback" ; удалем строку, в которой найдена фраза, передавая номер удаляемой строки StrCpy $1 0 IntOp $1 $1 + 1 ${LineRead} "[Файл]" "$1" $0 StrCmp $0 "" 0 ЕСЛИ_НЕТ ${LineFind} "$DESKTOP\hosts" "" "$1" "DeleteLineCallback" StrCpy $1 0 NextLineRead: IntOp $1 $1 + 1 ${LineRead} "[Файл]" "$1" $0 StrCmp $0 "" 0 ЕСЛИ_НЕТ ${LineFind} "$DESKTOP\hosts" "" "$1" "DeleteLineCallback" goto NextLineRead Так, стоп, а как же условие того, что наша строка не пустая, что делать то...а, ну всё правильно, нам нужно перейти к следующей строке, значит в условие StrCmp делаем ссылку на метку NextLineRead StrCpy $1 0 NextLineRead: IntOp $1 $1 + 1 NowRead: ${LineRead} "[Файл]" "$1" $0 StrCmp $0 "" 0 NextLineRead ${LineFind} "$DESKTOP\hosts" "" "$1" "DeleteLineCallback" goto NowRead Точно, есть же команда LineSum, которая подсчитывает общее количество строк в файле! Давай-ка её в начало пропишем и назначим переменную для хранения $R0. ${LineSum} "[Файл]" $R0 StrCpy $1 0 NextLineRead: IntOp $1 $1 + 1 NowRead: ${LineRead} "[Файл]" "$1" $0 StrCmp $0 "" 0 NextLineRead ${LineFind} "$DESKTOP\hosts" "" "$1" "DeleteLineCallback" goto NowRead Я укажу так, что если текущий счетчик строки больше общего количества строк, то закончим обработку, а если меньше либо равно - то продолжу чтение ${LineSum} "[Файл]" $R0 StrCpy $1 0 NextLineRead: IntOp $1 $1 + 1 IntCmp $1 $R0 0 0 end NowRead: ${LineRead} "[Файл]" "$1" $0 StrCmp $0 "" 0 NextLineRead ${LineFind} "$DESKTOP\hosts" "" "$1" "DeleteLineCallback" goto NowRead end: ${LineSum} "[Файл]" $R0 StrCpy $1 0 NextLineRead: IntOp $1 $1 + 1 IntCmp $1 $R0 0 0 end NowRead: ${LineRead} "[Файл]" "$1" $0 ${TrimNewLines} '$0' $0 StrCmp $0 "" 0 NextLineRead ${LineFind} "$DESKTOP\hosts" "" "$1" "DeleteLineCallback" ${LineSum} "[Файл]" $R0 goto NowRead end: Вроде бы всё, осталось добавить callback функцию DeleteLineCallback для удаления строки Круто, работает! Вроде и ничего сложного, если знаешь, какие команды есть в NSIS... На самом деле, если посмотреть на этот код - здесь реально ничего мегакрутого нет - обычный код с использованием стандартных команд, вся фишка в том, что я знаю много команд в NSIS и знаю, что конкретно могу получить от той или иной команды. На основе этих знаний у меня код в голове строится автоматически, остаётся только его напечатать и проверить работоспособность В примере этого сообщения я вам продемонстрировал, как на самом деле всё просто, достаточно всего-лишь знания команд NSIS и немного времени, чтобы продумать логику действий в коде. Цитата Dodakaedr:
|
|||||
------- Последний раз редактировалось K.A.V., 17-05-2015 в 02:20. Отправлено: 02:09, 17-05-2015 | #1638 |
Старожил Сообщения: 152
|
Профиль | Отправить PM | Цитировать Цитата MKN:
|
||
Отправлено: 00:31, 25-05-2015 | #1639 |
Ленивый кусок мяса Сообщения: 1986
|
Профиль | Сайт | Отправить PM | Цитировать |
------- Отправлено: 07:57, 25-05-2015 | #1640 |
Участник сейчас на форуме | Участник вне форума | Автор темы | Сообщение прикреплено |
| |||||
Название темы | Автор | Информация о форуме | Ответов | Последнее сообщение | |
Инфо - [ликбез] Помощь начинающим .:[все вопросы]:. часть 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 |
|