Имя пользователя:
Пароль:  
Помощь | Регистрация | Забыли пароль?  

Показать сообщение отдельно

Аватара для K.A.V.

Ленивый кусок мяса


Contributor


Сообщения: 1986
Благодарности: 723

Профиль | Сайт | Отправить PM | Цитировать


Цитата Dodakaedr:
наверное из-за переменной $R0, она берется уже с call DeleteLineFunc? Применил свою переменную, все заработало. »
Ну вот видите, достаточно всего-лишь внимательно смотреть на код и на используемые переменные. Значение переменной может быть изменено в любой части кода, что может повлиять на функционал других функций, использующих одну переменную.
Ещё советую при использовании команд внимательно читать описание к команде, некоторые команды в NSIS переназначают значения переменных своими данными, из-за чего ваш код так же может оказаться некорректным, если вы используете те же переменные, что и команда NSIS, простой пример - команда Locate для поиска файлов, её callback функция использует переменные для хранения своих данных во время процесса поиска:
Код: Выделить весь код
Function "Function"
    ; $R9    "путь\имя"
    ; $R8    "путь"
    ; $R7    "имя"
    ; $R6    "размер"  ($R6="" если директория, $R6="0" если поиск с ключем /S=)

    ; $R0-$R5  не используется функцией.
    ; ...

    Push $var    ; Если $var="StopLocate" Завершение функции
FunctionEnd
Цитата Dodakaedr:
у меня опыта с nsis ноль целых х*р десятых. Да и в программировании где-то также. »
Скрытый текст
Для изучения конкретно NSIS вам нужно только одно - желание. Я тут уже 100 раз рассказывал, как лично я познакомился с NSIS будучи ещё совсем "зелёным" (во всех смыслах), я не то чтобы даже английский язык не знал, я в то время даже не знал, что такое интернет и редактор реестра. У меня кроме дистрибутива с непонятной программой (NSIS), которая просто была на CD в куче софта, больше ничего не было, ни знаний компьютерных, ни интернета, ни уж тем более справочника на русском
Я даже сейчас не знаю ни одного языка программирования и английского языка тоже не знаю, но просто есть желание и упорство - всё получается, это я к тому, что всё зависит только от вас, к тому же, у вас есть то, чего не было лично у меня - помощь со стороны более опытных кодеров и русская справка, пусть и не с огромным количеством всяких примеров и переведённых команд - но всё же для получения базовых знаний о NSIS справочник вполне сойдёт.

Цитата Dodakaedr:
читаю я ваш справочник, если бы все понимал то и не спрашивал помощи, а так команды строковые для меня вообще темный лес »
Если после прочтения описания команды в справочнике и проведения тестов вы всё-равно не понимаете, как пользоваться командой - приходите и спрашивайте, что конкретно не понятно, в чем проблема то.
-------
Цитата Dodakaedr:
Не могу понять принцип работы строковых команд а именно как и что сравнивать надо »
Так вы логику действий у себя в голове выстроите и продумывайте команды, разберём простой пример: вам нужно удалить пустую строку
Вот дальше вам необходимо понять всю силу фразы "Читайте справочник", если вы будете знать о всех командах, которые вам доступны в NSIS - вы будете писать код в несколько раз быстрее, зная команды - у вас в голове сразу будет строится код.
Что для этого нужно? Так, ну, раз у меня простой текстовый файл, значит для начала мне нужно прочитать строку, а как я могу прочитать строку? Точно, есть же команда LineRead!
Код: Выделить весь код
${LineRead} "[Файл]" "[Номер строки]" $var
Так, ну, допустим, я прочитаю первую строку, а если моя строка записана второй, как мне сделать универсальный код, не дублируя строки? Точно, есть же математическая команда IntOp, я сделаю счетчик и он будет плюсоваться после чтения строки, если это не моя строка - будем увеличивать счетчик и идти дальше по файлу!

В голове строится код
Код: Выделить весь код
StrCpy $1 0 ; нам сначала нужно обнулить счетчик, т.к. переменная возможно уже ранее использовалась
IntOp $1 $1 + 1 ; в переменную будет помещено текущее значение переменной $1 с прибавлением на 1
${LineRead} "[Файл]" "$1" $0
Так, круто, что дальше то, я прочитал первую строку, а как понять, что она пустая то? Точно, есть же команда StrCmp!
Т.к. содержимое прочитанной строки помещается в переменную $0 (смотри описание команды LineRead), то, соответственно, нам нужно сделать условие сравнения этой переменной с пустым значением в команде StrCmp, с пустым потому, что нам нужно определить, что прочитанная строка действительно пустая, а не с данными
Код: Выделить весь код
StrCpy $1 0 ; нам сначала нужно обнулить счетчик, т.к. переменная возможно уже ранее использовалась
${LineRead} "[Файл]" "$1" $0
  StrCmp $0 "" 0 ЕСЛИ_НЕТ ; метка 0 означает, что если условие истина, т.е. значение переменной $0 - пусто, то опускаемся дальше по коду
так, а что мне делать дальше то? Если строка пустая, то...она мне не нужна, значит прописываю команду удаления ниже по коду, а как? Точно, мне же K.A.V. пример кидал с комментарием на каждой строке!
Код: Выделить весь код
 ${LineFind} "$DESKTOP\hosts" "" "$R1" "DeleteLineCallback" ; удалем строку, в которой найдена фраза, передавая номер удаляемой строки
так, в комменте сказано, что в команду нужно передавать номер строки, а у меня он где?! Точняк, это же счетчик в переменной $1, значит меняю переменную из примера на свою
Код: Выделить весь код
StrCpy $1 0
IntOp $1 $1 + 1
${LineRead} "[Файл]" "$1" $0
  StrCmp $0 "" 0 ЕСЛИ_НЕТ
  ${LineFind} "$DESKTOP\hosts" "" "$1" "DeleteLineCallback"
так, что дальше то делать после удаления строки? а, ну, нам нужно прочитать следующую строку, т.е. нам нужно как-то вернуться на начало код...хм, о, есть же команда goto, её нужно поместить так, чтобы после удаления строки наш счетчик увеличился
Код: Выделить весь код
StrCpy $1 0
NextLineRead:
IntOp $1 $1 + 1
${LineRead} "[Файл]" "$1" $0
  StrCmp $0 "" 0 ЕСЛИ_НЕТ
  ${LineFind} "$DESKTOP\hosts" "" "$1" "DeleteLineCallback"
  goto NextLineRead
Вроде что-то получается, так, K.A.V. же вроде говорил, что при удалении строки - другие строки смещаются, значит если у меня будет 2 пустые строки подряд, то я сначала удалю первую, у меня увеличится счетчик и я пропущу вторую строку, которая сместилась выше относительно других строк...как же быть, о, значит после удаления строки нам нужно прочитать эту строку ещё раз! Давай добавим меточку и изменим условие после удаления строки
Так, стоп, а как же условие того, что наша строка не пустая, что делать то...а, ну всё правильно, нам нужно перейти к следующей строке, значит в условие 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
Тааак, теперь я знаю количество строк в файле! Теперь нужно вставить условие после счетчика и сравнивать, достигнута ли последняя строка, но подожди, комадна StrCmp же не подойдёт, потому что если я увеличу счетчик и сразу же сравню это значение с общим количеством строк - я могу не прочитать последнюю строку, значит нужна другая команда...точно, IntCmp!
Я укажу так, что если текущий счетчик строки больше общего количества строк, то закончим обработку, а если меньше либо равно - то продолжу чтение
Код: Выделить весь код
${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:
Так, ну, вроде бы всё...а нет, K.A.V. же ещё делал замечание по поводу того, что если мы удаляем строку - то общее количество строк становится меньше, и чтобы не делать лишних попыток чтения после удаления нескольких строк, нам нужно после каждой команды удаления строки заново получать общее количество строк в файле, продублирую команду
Код: Выделить весь код
${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:
Кстати, при использовании LineRead в переменной будет значение с символом перехода на новую строку, поэтому команда сравнения может не сработать, для удаления символа перехода на новую строку мы используем команду ${TrimNewLines} после чтения строки
Вроде бы всё, осталось добавить callback функцию DeleteLineCallback для удаления строки
Код: Выделить весь код
Function DeleteLineCallback
	StrCpy $0 SkipWrite
	Push $0
FunctionEnd
Круто, работает! Вроде и ничего сложного, если знаешь, какие команды есть в NSIS...

На самом деле, если посмотреть на этот код - здесь реально ничего мегакрутого нет - обычный код с использованием стандартных команд, вся фишка в том, что я знаю много команд в NSIS и знаю, что конкретно могу получить от той или иной команды. На основе этих знаний у меня код в голове строится автоматически, остаётся только его напечатать и проверить работоспособность
В примере этого сообщения я вам продемонстрировал, как на самом деле всё просто, достаточно всего-лишь знания команд NSIS и немного времени, чтобы продумать логику действий в коде.

Цитата Dodakaedr:
главное чтобы у вас терпения хватило »
Главное, чтобы вы реально прочитали справочник перед написанием постов в этой теме, в этой теме было пару человек, сообщения которых я просто игнорировал, зная ответы, по причине того, что им лень было открыть справочник и прочитать инфу, когда их об этом просили неоднократно, им нужны были только готовые примеры.

-------
[Справочник по командам Windows] -- [Справочник по NSIS] -- [SFX Creator - для создания SFX архивов]


Последний раз редактировалось K.A.V., 17-05-2015 в 02:20.

Это сообщение посчитали полезным следующие участники:

Отправлено: 02:09, 17-05-2015 | #1638