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

iglezz
27-02-2023, 02:53
почему не сработал OemToChar ? »
У плагина System параметр t означает ANSI (однобайтную) кодировку в ANSI-сборке и юникод в юникод-сборке.
Ввод-Вывод плагина ExecDos однобайтный (в основном), поэтому нужно использовать параметр m на входе OemToChar или выходе CharToOem:
System::Call 'user32::OemToChar(mr0, t.r0)'
Этот вариант будет работать и в 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
Пример использования: SetOutPath "$DOCUMENTS"
nsExec::ExecToStack `"$SYSDIR\cmd.exe" /c "" dir /b `
Pop $0
Pop $0
StrCpy $0 $0 -2
${OemToChar} $0
MessageBox MB_OK "$0"

MKN
27-02-2023, 15:33
iglezz, благодарю за разъяснение и пример.

Обнаружил интересный многофункциональный плагин - NSutils
https://github.com/negrutiu/nsis-nsutils

В частности интересны его StartReceivingClicks и StopReceiveClicks - функции обратного вызова NSIS для пользовательских кнопок. Помнится в ряде случаев были сложности именно с "калбаками" для собственных кнопок в разных местах окон инсталлятора...
Хорошо бы на базе этого плагина(если он умеет) примеры увидеть...

iglezz
27-02-2023, 17:15
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 (http://forum.oszone.net/post-3003837-2.html))
Лучше кнопки добавлять в редакторе ресурсов. Их можно сделать изначально невидимыми (без атрибута WS_VISIBLE) и делать видимыми (и даже перемещать/менять размер) по мере необходимости.
Если хочется без проблем добавлять всякие штуки налету то придётся предварительно подправить диалоги (их порядок и свойства).

inco1
02-03-2023, 14:43
Приветствую всех.
Тут такое дело. Имеется батник, который имеет две функции:
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

MKN
04-03-2023, 09:47
упростить или усовершенствовать »
Поместить работу с строками и пр. - в цикл.

inco1
04-03-2023, 15:22
Поместить работу с строками и пр. - в цикл. »
Можно пример этого цикла?

iglezz
05-03-2023, 05:51
inco1, Код нужно усовершенствовать, ибо он дико неоптимален (сам язык в основе скуден, а комплектные библиотеки (nsh) по этой части страшны). Громоздкость хорошо заметается под макросы и прячется в отдельные библиотечки.

Батник корректно работающим можно назвать только в двух случаях:
1. добавляемых строк в файле нет;
2. строки уже были добавлены в формате, жёстко заданном батником (скорее всего самим же батником ранее).

В остальных случаях он будет плодить мусор в виде дублирующихся неработающих записей.

Основных проблем тут две.

Первая - простая техническая.
Добыть данные из файла. Обработать. Запихнуть обратно. В процессе ничего не сломать.
И чтобы код можно было понимать и поддерживать спустя полгода.

Правильная работа начинается с правильной обработки строк, а каждая строка-запись в максимуме может содержать IP-адрес, энное количество хостов и комментарий с пробелами или табуляциями в качестве разделителей. Обычные прелести минимально структурированного простого текста. Разбор всего этого в NSIS растянется на сотни строк, это не питон какой-нибудь, где строку можно распарсить одной регуляркой.
Строки могут записаны 0.0.0.0 martau.com #site1
0.0.0.0 www.martau.com #site2
0.0.0.0 total-uninstall.com 0.0.0.0 martau.com www.martau.com total-uninstall.com 0.0.0.0 martau.com www.martau.com www.total-uninstall.com # block total-uninstall.com

По хорошему надо вытаскивать все данные в некую структуру (список/массив), анализировать и потом записывать обратно.
И помнить про обработку ошибок - мало дать команду на запись, надо ещё убедится, что изменения реально записаны.

Вторая проблема - посложнее.
КАК реализовать техническую часть, чтобы всё работало, чтобы ничего не сломать пользователю, чтобы была возможность отката своих изменений.

Рабочий пример с в меру гибкой обработкой hosts file есть по ссылке (https://gist.github.com/iglezz/ba6442c57b48aab0d818411e8485a9ba). То, что под капотом (hostsblock.nsh), местами корявое, местами страшное, но рабочее с большего. Со стороны основного скрипта одна команда с всего двымя параметрами - имя файла и хост.
В примере присутствует !define DEBUG - это нужно только для отладки, если что-то вдруг пойдёт не так.

inco1
05-03-2023, 16:45
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.

MKN
05-03-2023, 17:41
Рабочий пример »
Вот это помогли товарищу уменьшить код... :lol: Но всё равно здорово. Спасибо.
местами корявое, местами страшное »
Вот и я сваял нечто, но рабочее и наглядное в понимании... В хосте есть смысл искать всего два слова в строке, т.к. в одну строку редко пишут...
outfile host-test.exe
;unicode true

!include "LogicLib.nsh"
!include "TextFunc.nsh"
!include "WordFunc.nsh"
!include "StrFunc.nsh"

Var Str
Var Word_a1
Var Word_a2
Var Word_a3
Var Word_a4
Var Word_a5
Var Word_b2
Var Word_c2
Var Word_d2
Var Word_e2
Var Word_f2

!define a "0.0.0.0"
!define b2 "martau.com"
!define c2 "www.martau.com"
!define d2 "total-uninstall.com"
!define e2 "www.total-uninstall.com"
!define f2 "64.91.254.118"

Section
FileOpen $R4 "$EXEDIR\hosts.ics" r
FileOpen $R5 "$EXEDIR\hosts2.ics" w
IfErrors done
ClearErrors
${LineSum} "$EXEDIR\hosts.ics" $8
StrCpy $3 0
${Do}
IntOp $3 $3 + 1
${LineRead} "$EXEDIR\hosts.ics" "$3" $Str

${If} $3 = 1
${WordReplace} '$Str' "${a}" "${a}" "E+" $Word_a1 ; outvarerror =1 ,если слово для замены не найдено
${WordReplace} '$Str' "${b2}" "${b2}" "E+" $Word_b2
${ElseIf} $3 = 2
${WordReplace} '$Str' "${a}" "${a}" "E+" $Word_a2
${WordReplace} '$Str' "${c2}" "${c2}" "E+" $Word_c2
${ElseIf} $3 = 3
${WordReplace} '$Str' "${a}" "${a}" "E+" $Word_a3
${WordReplace} '$Str' "${d2}" "${d2}" "E+" $Word_d2
${ElseIf} $3 = 4
${WordReplace} '$Str' "${a}" "${a}" "E+" $Word_a4
${WordReplace} '$Str' "${e2}" "${e2}" "E+" $Word_e2
${ElseIf} $3 = 5
${WordReplace} '$Str' "${a}" "${a}" "E+" $Word_a5
${WordReplace} '$Str' "${f2}" "${f2}" "E+" $Word_f2
${EndIf}

${If} $5 = 1
Goto next1
${ElseIf} $5 = 2
Goto next2
${ElseIf} $5 = 3
Goto next3
${ElseIf} $5 = 4
Goto next4
${ElseIf} $5 = 5
Goto next5
${EndIf}

${If} $Word_a1 = 1
${OrIf} $Word_b2 = 1
FileWrite $R5 "${a} ${b2}$\r$\n"
StrCpy $5 1
${EndIf}
next1:
${If} $Word_a2 = 1
${OrIf} $Word_c2 = 1
FileWrite $R5 "${a} ${c2}$\r$\n"
StrCpy $5 2
${EndIf}
next2:
${If} $Word_a3 = 1
${OrIf} $Word_d2 = 1
FileWrite $R5 "${a} ${d2}$\r$\n"
StrCpy $5 3
${EndIf}
next3:
${If} $Word_a4 = 1
${OrIf} $Word_e2 = 1
FileWrite $R5 "${a} ${e2}$\r$\n"
StrCpy $5 4
${EndIf}
next4:
${If} $Word_a5 = 1
${OrIf} $Word_f2 = 1
FileWrite $R5 "${a} ${f2}$\r$\n"
StrCpy $5 5
${EndIf}
next5:
${If} $3 > $8
${ExitDo}
${EndIf}
${Loop}
done:
FileClose $R4
FileClose $R5
SectionEnd

Замена части однотипных действий макросами уменьшит код на треть... Пути хоста ессно выбраны для наглядности примера. Окончательные и очевидные действия в код не включены.

iglezz
05-03-2023, 17:43
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
05-03-2023, 17:57
вся сложность загоняется под коврик »
Это я понимаю. И это не только в программировании... И это наверное не есть хорошо... Хотя потребителю пофиг...

inco1
05-03-2023, 18:37
iglezz,
Менять в hostsblock.nsh ничего не надо.
Я сразу даже не понял, что это для любых расширений и полез изменять.
Даже адреса с 127.0.0.1 не пропускаются, а бекапятся и записываются как 0.0.0.0
Отступы и пробелы так же четко отрабатываются и не дублируются.
Дааа..., код в несколько строчек для качественной правки HOSTS это нечто.
Теперь понятно, сколько вложено труда в hostsblock.nsh.

MKN, Так же огромная благодарность за отклик и проделанную работу. Но работа iglezz - шедевр.

iglezz
05-03-2023, 18:59
MKN, inco1,
В качестве замечания, на будущее и для лучшего понимания.

${LineRead} В подобных циклах - штука дико неэффективная. Алгоритм маляра Шлемиеля, как шутят.
Для N-ой по номеру строки будет сделана куча работы - FileOpen, N FileRead'ов, FileClose, счётчики и проверки

Простейший цикл последовательного чтения файла: FileOpen $handle $filename R
${Do}
FileRead $handle $fileread
${IfThen} ${Errors} ${|} ${ExitDo} ${|}

DetailPrint '[$fileread]'
${Loop}
FileClose $handle

inco1
06-03-2023, 01:59
iglezz,
Проверил множество раз. Ваш предложенный компактный вариант не работает, если файла hosts.ics не существует. Точнее сказать работает, но добавляет только четыре строки без первой.
Если же файл hosts.ics уже существует, то работает правильно. как и задумано. Проверял самым простым экзешником:

Unicode true
SetOverwrite on
RequestExecutionLevel admin

!include "x64.nsh"
!include "LogicLib.nsh"
!include "hostsblock.nsh"

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
Тот, что я предложил с лишними записями работает как надо, и когда файл hosts.ics отсутствует и когда он уже есть:

Unicode true
SetOverwrite on
RequestExecutionLevel admin

!include "x64.nsh"
!include "LogicLib.nsh"
!include "hostsblock.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
${hostsfile_BlockHost} $2 'martau.com'
${hostsfile_BlockHost} $2 'www.martau.com'
${hostsfile_BlockHost} $2 'www.total-uninstall.com'
${hostsfile_BlockHost} $2 'total-uninstall.com'
${hostsfile_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", так и без него такой вариант:

Unicode true
SetOverwrite on
RequestExecutionLevel admin
!include "x64.nsh"
!include "LogicLib.nsh"
!include "hostsblock.nsh"
Section
Var /global hostsfile
StrCpy $hostsfile "$SYSDIR\drivers\etc\hosts.ics"
${IfThen} ${RunningX64} ${|} ${DisableX64FSRedirection} ${|}
${If} ${FileExists} "$hostsfile"
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'
${Else}
FileOpen $0 "$hostsfile" 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 "$hostsfile" READONLY
SectionEnd

iglezz
06-03-2023, 22:28
inco1, Файл исправлен по старой ссылке.
Косяков там на самом деле там было больше..

inco1
07-03-2023, 12:28
iglezz, Огромнейшая благодарность.
Теперь код, практически в семь строчек работает четко,красиво и правильно, и лучше, чем код в семьдесят строк из "справки", которую всем в свое время навязывал K.A.V. Ему было пытались объяснить, что его код с hosts не корректно работает, но в ответ было, типа "сам дурак, учи справку".

MKN
19-03-2023, 11:57
Задача: нужна кастомная страница, на которой, к примеру, вверху страницы помещаются несколько кликабельных либо кнопок, либо текст-заголовков, не суть.
При клике на кнопке-заголовке - раскрывается соответствующий список с чекбоксами.
При клике на другой кнопке-заголовке - предыдущий список закрывается, а новый открывается.
Ессно запоминается состояние чекбоксов, иходя из которого применяются действия...

Список с чекбоксами позволяет сделать плагин ListView. Но возможно ли сделать несколько раскрывающихся списков на кастомной странице ?

И ещё, можно ли, имея статичную часть окна на странице с кликабельными заголовками, раскрывать списки с чекбоксами в виде других вновь созданных собственных окон с разными элементами в них ? (Совершенно не ясно, как в NSIS можно на одной странице переключать разные окна, при этом сохраняя статично-видимую часть окна откуда осуществляется переключение...)

iglezz
19-03-2023, 18:56
Задача: нужна кастомная страница, на которой, к примеру, вверху страницы помещаются несколько кликабельных либо кнопок, либо ...»

В простейшем случае по событию от кнопки или другого контрола показываются нужные вещи и прячутся ненужные. Фактически это имитация (с кучей ручной работы) отсутствующего в nsDialogs Tab Control.
А дальше зависит от потребностей и фантазии..
RequestExecutionLevel user
!include "LogicLib.nsh"
!include "nsDialogs.nsh"

Page custom NSD

Section
SectionEnd

Var Dialog
Var hButtonOpt1
Var hButtonOpt11
Var hButtonOpt12
Var hButtonOpt13
Var hButtonOpt2
Var hButtonOpt21
Var hButtonOpt22
Var hButtonOpt3
Var hButtonOpt31
Var hButtonOpt32

Function NSD
nsDialogs::Create 1018
Pop $Dialog


${NSD_CreateFirstRadioButton} 0u 0u 30% 16u "Options 1"
Pop $hButtonOpt1
${NSD_OnClick} $hButtonOpt1 SwitchOptions

${NSD_CreateAdditionalRadioButton} 33% 0u 30% 16u "Options 2"
Pop $hButtonOpt2
${NSD_OnClick} $hButtonOpt2 SwitchOptions

${NSD_CreateAdditionalRadioButton} 66% 0u 30% 16u "Options 3"
Pop $hButtonOpt3
${NSD_OnClick} $hButtonOpt3 SwitchOptions


${NSD_CreateCheckBox} 10u 30u 80u 20u "111"
Pop $hButtonOpt11
${NSD_AddStyle} $hButtonOpt11 ${WS_GROUP}
${NSD_CreateCheckBox} 10u 50u 80u 20u "222"
Pop $hButtonOpt12
${NSD_CreateCheckBox} 10u 70u -20u 20u "333"
Pop $hButtonOpt13

${NSD_CreateCheckBox} 10u 30u -20u 20u "2x111"
Pop $hButtonOpt21
${NSD_CreateCheckBox} 10u 50u -20u 20u "2x222"
Pop $hButtonOpt22

${NSD_CreateCheckBox} 10u 30u -20u 20u "3x111"
Pop $hButtonOpt31
${NSD_CreateCheckBox} 10u 50u -20u 20u "3x222"
Pop $hButtonOpt32

SendMessage $hButtonOpt1 ${BM_CLICK} 0 0

nsDialogs::Show
FunctionEnd


Function SwitchOptions
Pop $0

${Select} $0
${Case} $hButtonOpt1
StrCpy $1 ${SW_SHOW}
StrCpy $2 ${SW_HIDE}
StrCpy $3 ${SW_HIDE}
${Case} $hButtonOpt2
StrCpy $1 ${SW_HIDE}
StrCpy $2 ${SW_SHOW}
StrCpy $3 ${SW_HIDE}
${Case} $hButtonOpt3
StrCpy $1 ${SW_HIDE}
StrCpy $2 ${SW_HIDE}
StrCpy $3 ${SW_SHOW}
${EndSelect}

ShowWindow $hButtonOpt11 $1
ShowWindow $hButtonOpt12 $1
ShowWindow $hButtonOpt13 $1

ShowWindow $hButtonOpt21 $2
ShowWindow $hButtonOpt22 $2

ShowWindow $hButtonOpt31 $3
ShowWindow $hButtonOpt32 $3
FunctionEnd

MKN
19-03-2023, 19:12
iglezz,
Такой способ понятен, но списки хотелось бы выпадающие, а не пропадающие...
Если всё же использовать несколько ListView размером во всю страницу, их получится переключать(скрывать) без проблем ? Они ведь будут друг на друге... И запомниться ли состояние выбранных элементов в LV при переключении ?

iglezz
19-03-2023, 19:23
MKN, А тут всё равно какой контент будет. Хоть Listview, хоть RichText, хоть видео...
На состояние контролов это не повлияет- они просто прячутся/показываются.




© OSzone.net 2001-2012