PDA

Показать полную графическую версию : .: NSIS - все вопросы :. часть 2.


Страниц : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 [82] 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146

Salmo
10-05-2015, 20:19
И ещё ребят кто знает как сделать цифровую подпись инсталятору на НСИС? »
Я, некоторые ЕХЕ_шники, которые не должны вызывать придирки со стороны антивирусов и которые система должна считать доверенными, подписываю с помощью программы X2Net Signcode (англ), предварительно сгенерировав сертификат в пакете Crypto4 PKI (англ). При установке программы ( это делает инсталлятор) закидываю свой сертификат в хранилище доверенных сертификатов системы и моя самоделка живет в системе, как родная, не вызывая подозрения (при условии, что это не вирус)...

Serg866
12-05-2015, 11:36
Её сначала нужно приобрести за денюжку, если не ошибаюсь, а потом уже думать над вшиванием »
да ежели оно всё само сделает как надо, я готов и купить.

Так запакуйте EXE в zip архив и распространяйте в архиве, в чем проблема? »
Ну не знаю, несолидно это как-то в зип-архив продукт пихать.

Я, некоторые ЕХЕ_шники, которые не должны вызывать придирки со стороны антивирусов и которые система должна считать доверенными, подписываю с помощью программы X2Net Signcode (англ), предварительно сгенерировав сертификат в пакете Crypto4 PKI (англ). При установке программы ( это делает инсталлятор) закидываю свой сертификат в хранилище доверенных сертификатов системы и моя самоделка живет в системе, как родная, не вызывая подозрения (при условии, что это не вирус)... »
Да мне ни к чему эти сложности. Мне всего лишь надо чтобы хром не блочил мою программу когда её качают! А блочит он только потому что файл ехешник и не имеет цифровой подписи. Антивирусы естественно ничего не блочат, потому что и вирусов нет никаких, я честный человек!

Salmo
12-05-2015, 13:44
я честный человек! » Я в этом не сомневаюсь... Тогда единственным выходом остается ZIP_архив. Помещать исполняемые файлы в архив - это распространенная практика, потому что никто не ограничивается предложением одного ЕХЕ_шника без сопроводительного файла с описанием программы и условием его инсталляции\применения. Так что "пихать" файл в архив считается хорошим тоном. Получить же платный сертификат для подписывания программы от центра сертификации непростое и дорогое удовольствие...

Dodakaedr
14-05-2015, 21:39
Подскажите, как проделать следующее: если у файла hosts стоит атрибут "только чтение", то снять его, записать некоторое значение и снова поставить атрибут "только чтение", а если атрибута нету то просто записать значение? И как удалять значение из файла hosts?

K.A.V.
14-05-2015, 23:07
если у файла hosts стоит атрибут "только чтение", то снять его, записать некоторое значение и снова поставить атрибут "только чтение", а если атрибута нету то просто записать значение? »

Function test
${GetFileAttributes} "$DESKTOP\hosts" "READONLY" $R0 ; проверяем, есть ли атрибут только чтение у файла, если после исполнения команды $R0 = 1, значит есть
StrCmp $R0 "1" 0 +2 ; если атрибут есть, то ставим файлу обычный атрибут
SetFileAttributes "$DESKTOP\hosts" "NORMAL"

FileOpen $0 "$DESKTOP\hosts" a ; открываем файл для добавления данных
FileSeek $0 0 END ; перескакиваем на последнюю строку в файле
FileWrite $0 "$\r$\n127.0.0.1 winxpregp.narod.ru" ; добавляем новую строку
FileClose $0 ; закрываем файл, завершаем с ним работу

StrCmp $R0 "1" 0 +2 ; т.к. переменная $R0 до сих пор хранит инфу о том, был ли атрибут только чтение у файла, тут же проверяем, если был - ставим обратно атрибут только чтение
SetFileAttributes "$DESKTOP\hosts" "READONLY"
FunctionEnd


И как удалять значение из файла hosts? »
Вы не представляете, сколько уже раз здесь задавались вопросы по поводу работы с обычными текстовыми файлами...
Но такого кода ещё не было, свежачок :)
Function test2
${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" "winxpregp.narod.ru" "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

ps
в начале кода пропишите
!include "FileFunc.nsh"
!include "TextFunc.nsh"
!include "WordFunc.nsh"

pindows_xp
15-05-2015, 08:02
привет форучани нужна ваша помош хочу вот такой файлик зделат на свой сайт файл сам ехе формате когда кликаеш на файл она распакует файлы в програм файл и на рабочий стол кидает ярлык это сылка на сайт прошу помоч как можна зделат для себя вот сылка на ехе файл https://yadi.sk/d/vcmRINowgcSeH :sorry:

Dodakaedr
15-05-2015, 20:18
K.A.V., Огромное спасибо! Добавить несколько строк я смог, но удалить их не получается, подкиньте пожалуйста примерчик.

K.A.V.
15-05-2015, 22:09
но удалить их не получается, подкиньте пожалуйста примерчик. »
эм, какой ещё пример? В моём посте 2 примера, 1ый - добавление данных, 2ой - удаление строки по фразе в ней
Может, у вас монитор запачкался и вы не увидели второй код на пол поста в сообщении...

Dodakaedr
15-05-2015, 22:12
2ой - удаление строки »
А я спрашивал про несколько строк.Может, у вас монитор запачкался и вы не увидели второй код на пол поста в сообщении... »
.....

K.A.V.
15-05-2015, 22:58
А я спрашивал про несколько строк. »
Вам вызвать 2 раза функцию с разным текстом искомой строки религия не позволяет? Не понимаю, чего вы от меня ещё хотите :o

Dodakaedr
15-05-2015, 23:14
Вам вызвать 2 раза функцию с разным текстом искомой строки религия не позволяет? »
позволяет конечно, пробовал, но не получается.Не понимаю, чего вы от меня ещё хотите »
как я уже и раньше говорил - примерчик.
Собрал такое, но не работает
${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:

K.A.V.
16-05-2015, 00:19
как я уже и раньше говорил - примерчик. »
Я вам его предоставил, но вопрос тут в том, что вы не можете им воспользоваться по одной простой причине - вы не знаете базовой информации о NSIS и как вообще пишутся скрипты, поэтому рекомендую начать штудировать наш справочник, особенно страничку о переменных, которая бы помогла решить вашу проблему с моим примером.

Собрал такое, но не работает »
:lamer: А с чего бы "такому" работать?

${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 (http://forum.oszone.net/thread-168287.html), моя любимая фраза для новичков, которую я не люблю повторять

MKN
16-05-2015, 10:01
И как удалять значение из файла hosts? »
Первым делом надо получить права на работу с реальным файлом hosts ( $SYSDIR\drivers\etc\hosts )
Без этого, как правило, манипуляции с файлом будут не возможны... (т.к. либо файл "занят" системой , а ещё хуже, когда файл hosts под контролем какого нибудь "защитника" или антивируса, что встречается всё чаще и чаще... )

Dodakaedr
16-05-2015, 16:06
Первым делом надо получить права на работу с реальным файлом hosts »
И как это сделать?

Dodakaedr
16-05-2015, 20:11
Решил в одну функцию запихнуть удаление строк в файле 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 пустых строк. Как сделать чтобы не оставалась пустая строка?

K.A.V.
16-05-2015, 21:03
Почему не ставится обратно атрибут? »
Давайте порассуждаем на эту тему, как вы думаете, почему атрибут не ставится? Ведь в изначальном варианте он был рабочим, так? Посмотрите на ваш код внимательней и попробуйте сами ответить на свой вопрос

StrCmp $R0 "1" 0 +2 ;если здесь поставить +1 то атрибут ставится постоянно не зависимо от результата проверки »
Повторю в последний раз, читайте Справочник по NSIS (http://forum.oszone.net/thread-168287.html), ленивых и не желающих вникать в NSIS "кодеров" не переношу


блин, вот скажите мне, для кого писался справочник?
Я создавал его в надежде на то, что им будут пользоваться менее опытные кодеры, которым я смогу передать полученные знания и хотел, чтобы другие люди чему-то научились из этого справочника, но почему-то всё же находятся такие личности, которые хотят "всё и сразу и без чтения инфы" - ребят, в этой теме так не бывает, хотите, чтобы вам помогали решить вашу проблему - будьте добры, прочитайте справочник (да хотя бы самый минимум, те команды, которые используете - пишите правильно, а не наугад подставляйте параметры)
Ключевое слово - помогаем, а не делаем всё за вас
такое ощущение складывается, как-будто мне это нужно и я сижу уговариваю человека "ну прочитай, пожалуйста" :glare:


И еще вопрос: при удалении строк в конце файла постоянно остается пустая строка и получается что после 10 запусков в итоге имеем 10 пустых строк. Как сделать чтобы не оставалась пустая строка? »
Вопрос или задание для нас?
Давайте вы:
1. Воспользуетесь поиском по этой и предыдущей теме NSIS по ключевым словам LineFind, LineRead
2. Прочитаете в справке описание команд LineRead, StrCmp
3. Попробуете совместить команды LineRead, StrCmp с моим кодом удаления строки, в котором каждая строка с комментарием
4. Покажите, что у вас получилось

Давайте запустим здесь для всех ленивых новичков режим "Обучение", будем только указывать на ошибки, давать рекомендации и не будем давать готовых кодов?
Посмотрим, через какое время им всё же придётся обратиться к справочнику :)
Мне кажется, этот способ будет очень эффективный, не хотите изучать NSIS - либо мы заставим, либо вы забьёте на NSIS

Dodakaedr
16-05-2015, 23:13
как вы думаете, почему атрибут не ставится? »
наверное из-за переменной $R0, она берется уже с call DeleteLineFunc? Применил свою переменную, все заработало.блин, вот скажите мне, для кого писался справочник? »
для реальных новичков! а не для менее опытные кодеры »
у меня опыта с nsis ноль целых х*р десятых. Да и в программировании где-то также.будьте добры, прочитайте справочник (да хотя бы самый минимум, те команды, которые используете - пишите правильно, а не наугад подставляйте параметры) »
читаю я ваш справочник, если бы все понимал то и не спрашивал помощи, а так команды строковые для меня вообще темный лес. По поводу "наугад" это вы подумали про переход +1 в комментарии в строке 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
который похож с моей проблемой, но совместить с вашим кодом не могу.
Мне кажется, этот способ будет очень эффективный, не хотите изучать NSIS - либо мы заставим, либо вы забьёте на NSIS »
главное чтобы у вас терпения хватило:)

K.A.V.
17-05-2015, 02:09
наверное из-за переменной $R0, она берется уже с call DeleteLineFunc? Применил свою переменную, все заработало. »
Ну вот видите, достаточно всего-лишь внимательно смотреть на код и на используемые переменные. Значение переменной может быть изменено в любой части кода, что может повлиять на функционал других функций, использующих одну переменную.
Ещё советую при использовании команд внимательно читать описание к команде, некоторые команды в NSIS переназначают значения переменных своими данными, из-за чего ваш код так же может оказаться некорректным, если вы используете те же переменные, что и команда NSIS, простой пример - команда Locate для поиска файлов, её callback функция использует переменные для хранения своих данных во время процесса поиска:

Function "Function"
; $R9 "путь\имя"
; $R8 "путь"
; $R7 "имя"
; $R6 "размер" ($R6="" если директория, $R6="0" если поиск с ключем /S=)

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

Push $var ; Если $var="StopLocate" Завершение функции
FunctionEnd

у меня опыта с nsis ноль целых х*р десятых. Да и в программировании где-то также. »
Для изучения конкретно NSIS вам нужно только одно - желание. Я тут уже 100 раз рассказывал, как лично я познакомился с NSIS будучи ещё совсем "зелёным" (во всех смыслах), я не то чтобы даже английский язык не знал, я в то время даже не знал, что такое интернет и редактор реестра. У меня кроме дистрибутива с непонятной программой (NSIS), которая просто была на CD в куче софта, больше ничего не было, ни знаний компьютерных, ни интернета, ни уж тем более справочника на русском
Я даже сейчас не знаю ни одного языка программирования и английского языка тоже не знаю, но просто есть желание и упорство - всё получается, это я к тому, что всё зависит только от вас, к тому же, у вас есть то, чего не было лично у меня - помощь со стороны более опытных кодеров и русская справка, пусть и не с огромным количеством всяких примеров и переведённых команд - но всё же для получения базовых знаний о NSIS справочник вполне сойдёт.

читаю я ваш справочник, если бы все понимал то и не спрашивал помощи, а так команды строковые для меня вообще темный лес »
Если после прочтения описания команды в справочнике и проведения тестов вы всё-равно не понимаете, как пользоваться командой - приходите и спрашивайте, что конкретно не понятно, в чем проблема то.
-------
Не могу понять принцип работы строковых команд а именно как и что сравнивать надо »
Так вы логику действий у себя в голове выстроите и продумывайте команды, разберём простой пример: вам нужно удалить пустую строку
Вот дальше вам необходимо понять всю силу фразы "Читайте справочник", если вы будете знать о всех командах, которые вам доступны в 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 и немного времени, чтобы продумать логику действий в коде.

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

Limonica
25-05-2015, 00:31
Определение у пользователя прав администратора :

OutFile "Admin_privileges.exe"
Section
System::Call "kernel32::GetModuleHandle(t 'shell32.dll') i .s"
System::Call "kernel32::GetProcAddress(i s, i 680) i .r0"
System::Call "::$0() i .r0"
IntCmp $0 1 +3
MessageBox MB_OK "Требуются права администратора для запуска этой установки"
Abort
SectionEnd »

MKN можешь доработать способ чтобы определял какими привилегиями обладает аккаунт (как UserInfo) пользователя?

K.A.V.
25-05-2015, 07:57
Кстати, есть более простой способ определения админских прав, всего одна строчка кода :tongue:

System::Call setupapi::IsUserAdmin()i.r0
StrCmp $0 "1" 0 +2
MessageBox MB_OK|MB_ICONINFORMATION "Есть права администратора"
StrCmp $0 "0" 0 +2
MessageBox MB_OK|MB_ICONINFORMATION "Нет прав администратора"




© OSzone.net 2001-2012