Показать полную графическую версию : .: NSIS - все вопросы :. часть 2.
И ещё ребят кто знает как сделать цифровую подпись инсталятору на НСИС? »
Я, некоторые ЕХЕ_шники, которые не должны вызывать придирки со стороны антивирусов и которые система должна считать доверенными, подписываю с помощью программы X2Net Signcode (англ), предварительно сгенерировав сертификат в пакете Crypto4 PKI (англ). При установке программы ( это делает инсталлятор) закидываю свой сертификат в хранилище доверенных сертификатов системы и моя самоделка живет в системе, как родная, не вызывая подозрения (при условии, что это не вирус)...
Её сначала нужно приобрести за денюжку, если не ошибаюсь, а потом уже думать над вшиванием »
да ежели оно всё само сделает как надо, я готов и купить.
Так запакуйте EXE в zip архив и распространяйте в архиве, в чем проблема? »
Ну не знаю, несолидно это как-то в зип-архив продукт пихать.
Я, некоторые ЕХЕ_шники, которые не должны вызывать придирки со стороны антивирусов и которые система должна считать доверенными, подписываю с помощью программы X2Net Signcode (англ), предварительно сгенерировав сертификат в пакете Crypto4 PKI (англ). При установке программы ( это делает инсталлятор) закидываю свой сертификат в хранилище доверенных сертификатов системы и моя самоделка живет в системе, как родная, не вызывая подозрения (при условии, что это не вирус)... »
Да мне ни к чему эти сложности. Мне всего лишь надо чтобы хром не блочил мою программу когда её качают! А блочит он только потому что файл ехешник и не имеет цифровой подписи. Антивирусы естественно ничего не блочат, потому что и вирусов нет никаких, я честный человек!
я честный человек! » Я в этом не сомневаюсь... Тогда единственным выходом остается ZIP_архив. Помещать исполняемые файлы в архив - это распространенная практика, потому что никто не ограничивается предложением одного ЕХЕ_шника без сопроводительного файла с описанием программы и условием его инсталляции\применения. Так что "пихать" файл в архив считается хорошим тоном. Получить же платный сертификат для подписывания программы от центра сертификации непростое и дорогое удовольствие...
Dodakaedr
14-05-2015, 21:39
Подскажите, как проделать следующее: если у файла hosts стоит атрибут "только чтение", то снять его, записать некоторое значение и снова поставить атрибут "только чтение", а если атрибута нету то просто записать значение? И как удалять значение из файла hosts?
если у файла 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., Огромное спасибо! Добавить несколько строк я смог, но удалить их не получается, подкиньте пожалуйста примерчик.
но удалить их не получается, подкиньте пожалуйста примерчик. »
эм, какой ещё пример? В моём посте 2 примера, 1ый - добавление данных, 2ой - удаление строки по фразе в ней
Может, у вас монитор запачкался и вы не увидели второй код на пол поста в сообщении...
Dodakaedr
15-05-2015, 22:12
2ой - удаление строки »
А я спрашивал про несколько строк.Может, у вас монитор запачкался и вы не увидели второй код на пол поста в сообщении... »
.....
А я спрашивал про несколько строк. »
Вам вызвать 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:
как я уже и раньше говорил - примерчик. »
Я вам его предоставил, но вопрос тут в том, что вы не можете им воспользоваться по одной простой причине - вы не знаете базовой информации о 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), моя любимая фраза для новичков, которую я не люблю повторять
И как удалять значение из файла 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 пустых строк. Как сделать чтобы не оставалась пустая строка?
Почему не ставится обратно атрибут? »
Давайте порассуждаем на эту тему, как вы думаете, почему атрибут не ставится? Ведь в изначальном варианте он был рабочим, так? Посмотрите на ваш код внимательней и попробуйте сами ответить на свой вопрос
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 »
главное чтобы у вас терпения хватило:)
наверное из-за переменной $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) пользователя?
Кстати, есть более простой способ определения админских прав, всего одна строчка кода :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
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.
Available in ZeroNet 1osznRoVratMCN3bFoFpR2pSV5c9z6sTC