Проще всего сделать sed’ом.
В том же самом файле (добавляем параметр командной строки -i
):
sed -i 's/\r$//' file.txt
В другой файл:
cat winfile.txt | sed -i 's/\r$//' >linuxfile.txt
Проще всего сделать sed’ом.
В том же самом файле (добавляем параметр командной строки -i
):
sed -i 's/\r$//' file.txt
В другой файл:
cat winfile.txt | sed -i 's/\r$//' >linuxfile.txt
Например, у нас есть софтина, которая в процессе своей установки требует перезагрузку, после чего доустанавливается. Например, софт устанавливает свой драйвер, обновление, или же регистрирует системный сервис. Как реализовать инсталлятор для такой программы?
Изначально я хотел обойтись параметрами командной строки, добавляемыми при запуске установщика, но с ними произошла жопа, поэтому будем действовать более надежными методами.
0. Проверяем наличие уникального ключа Реестра, сигнализирующего о том, что надо выполнить вторую часть установки (после перезагрузки):
DetailPrint "Read After Reboot flag..."
ReadRegStr $R0 HKCU "Software\Microsoft\Windows\CurrentVersion\"
"${APPNAME}_afterreboot"
StrCmp "$R0" "1" AfterReboot
1. Производим все действия, которые необходимо произвести до перезагрузки (устанавливаем драйвера, регистрируем DLL и т.д.)
2. Записываем в однократную автозагрузку (ключ Реестра RunOnce
) наш инсталлятор, путь к exe файлу инсталлятора, который можно взять из переменной $EXEPATH
.
Автозагрузку прописываем для текущего пользователя (пользователя, запустившего установщик), т.е. в ключ HKEY_CURRENT_USER
.
WriteRegStr HKCU
"Software\Microsoft\Windows\CurrentVersion\RunOnce"
"${APPNAME}" "$EXEPATH"
Примечание: В RunOnce
могут записаться программы, которые требуется выполнить однократно при загрузке системы. После выполнения программ, ключ RunOnce
очищается автоматически, что отличает его от ключа Run
, где данные не очищаются, и его можно использовать, как постоянную автозагрузку.
3. Устанавливаем уникальный флаг, по которому будем определять, что инсталлятор был запущен после перезагрузки, например, таким образом:
DetailPrint "Write After Reboot flag..."
WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\"
"${APPNAME}_afterreboot" "1"
4. Выдаем запрос на немедленную перезагрузку:
DetailPrint "Reboot request."
MessageBox MB_YESNO|MB_ICONINFORMATION
"Installation will be cobntinue after reboot. Press OK to reboot now." IDYES RebootID
Если пользователь ответил «Yes
«, сразу перезагружаемся:
RebootID: DetailPrint "Rebooting..." Reboot
Если нет, ждем перезагрузки вручную:
DetailPrint "Installation continue if user restart system."
Goto SecEnd
5. После перезагрузки удаляем флаг (проверив его наличие, см выше):
DetailPrint "Delete After Reboot flag..."
DeleteRegValue HKCU "Software\Microsoft\Windows\CurrentVersion\"
"${APPNAME}_afterreboot"
6. И продолжаем установку…
DetailPrint "Continue install after reboot..."
Вот серьезно, бьюсь (головой об стену) уже третий день, ну не работает функция GetOptions
, так, как заявлено в NSIS Wiki, уже и по колесам стучал, и фары протирал, в смысле просто тупо копировал код из примера в тестовый инсталлятор, и еще десяток написал, перепробовав все что можно и нельзя, ну не выходит каменный цветок, хоть тресни. Функция в любом случае выдает, либо что никаких ошибок не случилось, для следующего кода, соответственно, всегда получается found:
Section ${GetOptions} "/S /T" "/T" $R0 IfErrors 0 +2 MessageBox MB_OK "Not found" IDOK +2 MessageBox MB_OK "Found" SectionEnd
Либо, для следующего кода всегда остается значение по умолчанию, даже если в командной строке явно задано иное:
Section ${GetOptions} "/AR=N" "/AR=" $R0 DetailPrint "R0: $R0" SectionEnd
Например, выполняешь TestInstaller.exe /AR=Y
, все равно в переменной $R0
оказывается N
Такие дела.
Пришли сегодня ко мне с одной задачкой, мол есть у нас программка, которая висит в фоне и периодически выводит данные в консоль. Неудобно оператору работать, либо что-то другое делать, либо ничего не делать, лишь в консоль смотреть. Даже отдельный комп думаем программке выделить, чтоб она на нем крутилась-вертелась. И нельзя ли так сделать, чтоб программку на другом терминале запустить, чтоб можно было по Ctrl+Alt+F[номер] переключаться, и за состоянием программки смотреть?
Вот запустить нельзя, без особого бубна, а вывод переопределить, всегда пожалуйста.
Можно пользуясь стандартным перенаправлением ввода-вывода в Linux, заставить программу или скрипт отправлять сообщения на другой терминал. Пусть программка будет называться tscript
. За терминалы в Linux отвечают устройства /dev/tty*
, например, /dev/tty2
отвечает за терминал, вызываемый по Ctrl+Alt+F2.
Например, чтобы программа переопределяла вывод на /dev/tty2
, запускаем ее таким образом:
tscript >/dev/tty2
Можно отправить на другой терминал только вывод сообщений об ошибках:
tscript 2>/dev/tty2
Чтобы программа работала в фоне, а на том терминале, с которого мы ее запустили, можно было продолжить работу, добавляем после команды знак &
:
./tscript >/dev/tty2 &
Пишем тестовый скрипт, который, скажем, будет бесконечно выводить на консоль случайное шестнадцатиричное число раз в секунду:
#!/bin/bash SEC=1 echo "Test script, write to STDOUT random number after $SEC sec." while [ 1 -eq 1 ];do sleep $SEC printf 'Number: %x\n' $RANDOM done
Пишем скрипт, который будет убивать тестовый:
#!/bin/bash
echo "Kill test script..."
pkill tscript
Пишем запускающий скрипт, в котором вывод тестового скрипта переопределяется на терминал tty2
:
#!/bin/bash
TERMNO=2
echo "Send tscript output to terminal #$TERMNO"
./tscript >/dev/tty$TERMNO &
Запускаем тестовый скрипт на текущем терминале:
Выполняем запускающий скрипт:
Вывод на tty2
Исходники примера
Секции — это удобный механизм, позволяющий обеспечить пользователю выбор компонентов программы, если такие присутствуют. В каждой секции можно создавать свои ярлыки, распаковывать файлы, и производить любые другие действия, практически независимо от других секций. Естественно, значения переменных, измененные в одной секции, в других тоже будут изменены, потому что в NSIS все переменные глобальные.
Для самого простого выбора компонентов в NSIS, необходимо вставить в скрипт, перед, собственно, описанием секции, следующий код:
ComponentText "Какой-то текст"
, например:
ComponentText "Choose which features of ${APPNAMEANDVERSION} you want to install."
Естественно, ${APPNAMEANDVERSION}
должна быть заранее определена:
!define APPNAME "SectionsExample"
!define APPNAMEANDVERSION " SectionsExample 0.1"
В любом NSIS-скрипте должна быть создана хотя бы одна секция, иначе компилятор будет ругаться, и файл установщика не создаст. В самом простом случае, когда не требуется выбор компонентов, создается единственная секция без названия:
Section DetailPrint "Hello, world!" SectionEnd
Примечание: После конструкции Section
идет имя секции, заключенное в кавычки. Если кавычки пропустить, то имя секции будет некорректным, и неверно отобразится в окне выбора компонентов. Попробуйте вставить следующий код в пример, и посмотрите, как он будет работать. Ссылка на пример в конце заметки.
Section Component 4 ; Wrong section description SetOverwrite on DetailPrint "Component #4 installing..." SectionEnd
Для чего? Например, у нас есть программа, у которой, в свою очередь есть основные компоненты, например экзешник и DLL, а также дополнительные, которые можно устанавливать, а можно и не устанавливать. И если уж пользователь хочет поставить наше приложение, то он должен установить хотя бы основные компоненты.
Для того, чтобы заблокировать чекбокс, прописываем в начале секции конструкцию:
SectionIn RO
Section "Main Program and components" ; Checkbox select and disable user changes SectionIn RO SetOverwrite on DetailPrint "Main program installing..." SectionEnd
Для этого ничего делать не надо, только определить секцию с именем в кавычках и дефольными настройками. Пользователь может деактивировать checkbox (снять галочку) в окне выбора компонентов.
Section "Component #2" ; Checkbox enabled by default & user will change it state SetOverwrite on DetailPrint "Component #2 installing..." SectionEnd
Наверное, самый частый вопрос, задаваемый, что в рунете, что в Интернете вообще, по поводу NSIS. Так вот, ларчик открывается просто. Достаточно после Section
поставить специальный флаг /o
.
Пользователь также сможет активировать checkbox (галочку), если ему нужно будет установить данный компонент.
Section /o "Component #3" ; Checkbox disabled by default & user will change it state SetOverwrite on DetailPrint "Component #3 installing..." SectionEnd
Такие секции не будут отображены в окне выбора компонентов. Их названия пишутся без кавычек и без пробела, а перед названием ставится знак «-
«. Код в таких секциях будет выполнен в любом случае, независимо от желания пользователя:
Section -HiddenSection DetailPrint "This is a hidden section" DetailPrint "This code running anyway." SectionEnd
К ним, наверное, относится одна — Uninstall
, ну и еще не совсем секция, а встроенная функция, которую можно переопределить, дописав свой код, т.е. что-то типа обработчика событий в «больших» языках, например в C#
О секции Uninstall
и рассказывать особо не надо, кроме ремарки, что в секции Uninstall
«забываются» все значения глобальных переменных и значение переменной $INSTDIR
Наконец-то руки дошли прикрутить инсталлер и выложить 🙂
Программа предназначена для отображения внешнего IP-адреса компьютера, определения географической принадлежности IP-адреса, а также того, не попадает ли IP-адрес в список «запрещенных» стран.
Программа получает IP-адрес, из поставляемого с ней PHP-скрипта, размещенного на Web-сервере в Интернете, и/или (в текущей версии) с сайтов, которые информируют пользователя о его внешнем IP. В текущей версии не все такие сайты подходят (сайт не должен быть заскриптован, не требовать обязательного использования cookie и не выдавать капчу), а оригинальный скрипт PHP предоставляет некоторые дополнительные возможности.
Далее, программа получает из базы данных SxGeo сведения о геопозиции, и, если настроено и IP-адрес попал в стоп-лист стран, выводит предупреждение о попадании в данный список.
Свежую версию БД SxGeo можно бесплатно скачать с сайта разработчиков базы данных: https://sypexgeo.net/ru/download/
Программа при запуске находится в системном трее, управление производится через контекстное меню.
Изначально писалась по заказу одного активиста, у которого была проблема с периодическим отключением от VPN, в связи с чем, случайно мог «засветиться» его IP, или VPN мог переключить его на нежелательную страну.
По умолчанию программа запускается в «портативном» режиме (все данные хранятся в подкаталоге data
каталога с исполняемым файлом)
Microsoft Windows XP и выше (Vista/7/8/8.1/10), .NET Framework 2.0 и выше, 512 Мб оперативной памяти, 15 Мб на жестком диске.
В качестве контрола для ввода IP-адреса мы использовали C# IP Address Control вот этого автора:
https://www.codeproject.com/Articles/9352/A-C-IP-Address-Control
База данных SypexGeo (SxGeo):
© 2006-2018 zapimir
© 2006-2018 BINOVATOR
0.0.1 b, 19/01/2010 — Первая версия, написанная для товарища OPPosition
0.1.2 08/08/2018 — Исправлен код запросов и конфигов, многое переделано
0.2.0 01/07/2019 — Программа «отвязана» от скрипта с SxGeo на сервере, интерфейс к БД SxGeo перенесен внутрь программы, запросы к БД обрабатываются локально, добавлена поддержка других источников IP-адресов. Первая публичная версия.
Портабельная версия
Инсталлятор
Или как поместить uninstaller не в директории программы.
Конечно, возникает вопрос «зачем?». Ну, например, мы устанавливаем некое системное приложение, драйвер, или хотим что-то пропатчить. В качестве каталога по умолчанию для такого приложения может служить, например, директория $WINDIR
(обычно C:\Windows
). Если мы хотим безболезненно удалить такое приложение, то нам нужно создать анинсталлер, но, совсем не обязательно чтоб он хранился в том же каталоге, что и установленное приложение. Зачем, например, загаживать каталог C:\Windows
файлами uninstall.exe
. Да в том то все и дело, что незачем, и вот тут мы сталкиваемся с глюками анинсталлера.
В анинстайлере и инсталляторе переменная $INSTDIR
определяется по-разному. В секции установки $INSTDIR
можно задать, в т.ч. и автоматически, а в uninstaller’е она определяется, как директория, из которой запустился анинсталлер. Это довольно легко проиллюстрировать простым кодом, который на самом деле ничего не устанавливает, а просто предлагает пользователю выбрать каталог для установки, а сам выводит пути к каталогам и создает тестовый анинсталлер во временном каталоге. Анинсталлер тоже ничего не удаляет, просто выводит значения переменных, заданных в основном скрипте.
Любые пользовательские переменные при работе uninstall так же «забываются», вне зависимости от того, были ли они определены в секции, или в скрипте вообще.
Фрагмент кода из установщика:
; явно задаем директорию для установки InstallDir "$PROGRAMFILES\TestUninst" ;создаем тестовую переменную Var TESTVAR ;[..] ;выводим окно для выбора директории для установки DirText "Choose the folder in which to install ${APPNAME}." Section "Inst" ; Set Section properties SetOverwrite on StrCpy $TESTVAR "Test variable value" DetailPrint "INSTDIR (install): $INSTDIR" DetailPrint "TESTVAR (install): $TESTVAR" WriteUninstaller "$TEMP\TestUninst.exe" SectionEnd
Секция установки:
1. Заполняем $TESTVAR
2. Выходим значение $TESTVAR
3. Выводим значение $INSTDIR
4. Создаем Uninstall’ер, причем не в $INSTDIR
В секции удаления выводим значения $INSTDIR
и $TESTVAR
, анинсталлер запускаем из временного каталога.
Section Uninstall SetDetailsView show DetailPrint "INSTDIR (uninstall): $INSTDIR" DetailPrint "TESTVAR (uninstall): $TESTVAR" SectionEnd
Значение $INSTDIR
изменилось на временный каталог, а значение $TESTVAR
было потеряно. Если переместить анинсталлер в другой каталог, значение $INSTDIR
опять поменяется.
Из вышеизложенного напрашивается вывод, что значения $INSTDIR
и нужных переменных надо сохранять на этапе установки, например в Реестр или INI-файл, а на этапе удаления восстанавливать.
В следующем примере я буду сохранять нужные значения в INI-файл, который будет располагаться в директории с uninstall.exe
, а сама программа будет устанавливаться в другой каталог. Сгенерирую простой скрипт мастером скриптов и немного подправлю.
1. Меняем InstallDir
на "$TEMP\TestApp"
InstallDir "$TEMP\TestApp"
2. Заводим переменную $UNINSTDIR
Var UNINSTDIR
3. В секции установки задаем ее значение, скажем "$PROGRAMFILES\TestApp"
StrCpy $UNINSTDIR "$PROGRAMFILES\TestApp"
4. Создаем каталог $UNINSTDIR
CreateDirectory "$UNINSTDIR"
5. Меняем где надо пути в создаваемых ярлыках
CreateShortCut "$SMPROGRAMS\TestApp\Uninstall.lnk" "$UNINSTDIR\uninstall.exe"
6. …путь для записи uninstall.exe
WriteUninstaller "$UNINSTDIR\uninstall.exe"
7. …и запись в Реестре для «Программ и компонентов»
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" "UninstallString" "$UNINSTDIR\uninstall.exe"
8. После создания uninstall.exe
в каталоге $UNINSTDIR
необходимо создать INI-файл, в который сохранить пути к каталогам $UNINSTDIR
и $INSTDIR
WriteINIStr "$UNINSTDIR\dirs.ini" "dirs" "I" "$INSTDIR"
WriteINIStr "$UNINSTDIR\dirs.ini" "dirs" "U" "$UNINSTDIR"
На этом с секцией установки закончили.
В секции удаления:
1. Читаем значения из INI-файла (который для uninstall.exe
будет располагаться в каталоге из переменной $INSTDIR
) в перезаписываемые переменные $0
и $1
. Если чтение не удалось, необходимо будет обработать ошибку (см. описания функций ReadINIStr
и конструкции IfErrors
в справочнике копия).
ReadINIStr $0 "$INSTDIR\dirs.ini" "dirs" "I"
IfErrors Dupa 0
ReadINIStr $1 "$INSTDIR\dirs.ini" "dirs" "U"
IfErrors Dupa 0
2. Восстанавливаем значения $INSTDIR
и $UNINSTDIR
:
StrCpy $INSTDIR $0
StrCpy $UNINSTDIR $1
3. Удаляем uninstall.exe
, INI-файл и каталог анинсталлера:
Delete "$UNINSTDIR\uninstall.exe"
Delete "$UNINSTDIR\dirs.ini"
RMDir "$UNINSTDIR\"
4. Удаляем компоненты программы и ярлыки.
5. В конце секции заводим метку OK:
6. После удаления программы переходим в конец секции
Goto OK
7. Перед меткой OK:
заводим метку Dupa:
, куда попадем если произошла ошибка чтения INI-файла. После метки Dupa:
будет обработчик ошибки. В данном случае выводим пользователю сообщение о том, что INI-файл некорректный, и произвести автоматическое удаление программы нельзя.
Dupa: MessageBox MB_ICONSTOP|MB_OK "Error reading $INSTDIR\dirs.ini! Uninstall aborted!"
1. Исходник, иллюстрирующий баг uninstaller’а
2. Исходник примера
Не сильно хороший, но пусть будет.
Примечание: Если открываешь CHM-файл а страницы пустые, нажимаем на файле правой кнопкой мыши, заходим в свойства и разблокируем его (там кнопка будет)
Одна из частых задач при создании инсталлятора — определить версию и архитектуру ОС, например, чтобы в зависимости от этого подкладывать нужную версию экзешника, или устанавливать нужный драйвер.
Для отображения версии Windows можно воспользоваться готовым кодом из NSIS wiki. На выбор предоставлены два скрипта: только для клиентских ОС и для клиентских и серверных. Для своих целей я пользовался вторым, правда в нем есть небольшой баг — клиентская Windows XP x64 определяется как Windows Server 2003:
Создаем отдельный пустой NSIS-скрипт, копируем туда код из wiki, и сохраняем в тот же каталог, где находится основной скрипт инсталлятора под любым удобным названием, например gvv.nsi
.
В основном скрипте подключаем этот файл:
!include gvv.nsi
Далее вызываем GetWindowsVersion
, записываем результат в переменную (например, в предопределенную $R0
) и выводим результат:
${GetWindowsVersion} $R0
DetailPrint "Windows Version: $R0"
Так сказать, «точное» определение версии. Применяется, когда надо выполнить определенные действия, например, в XP и только в XP, или в семерке и только в семерке.
Для этого в комплекте есть модуль WinVer.nsh
, сначала подключим его:
!include WinVer.nsh
Далее используем if
и один из макросов IsWin?
, например IsWinXP
, IsWin7
, IsWin10
:
${If} ${IsWinXP} DetailPrint "Is Windows XP" ${EndIf}
Применяется, когда нужно выполнять код, если версия ОС выше нужной или нужная.
В WinVer.nsh
есть другой комплект макросов — AtLeastWin?
(AtLeastWin7
, AtLeastWin8
, AtLeastWin10
) которые также нужно использовать вместе с if
. Например, следующий код сработает на «семерке» и всех последующих версиях Windows. В деталях установки отобразится соответствующее сообщение:
${If} ${AtLeastWin7} DetailPrint "Is Windows 7 or higher" ${EndIf}
Для определения архитектуры ОС необходимо подключить модуль x64.nsh
(также поставляется вместе с компилятором NSIS):
!include x64.nsh
Поддерживается определение архитектуры x86 (IsNativeIA32
), PC (AMD) x64 (IsNativeAMD64
) и ARM64 (IsNativeARM64
) пример кода есть в самом файле x64.nsh
🙂 Мне ARM была не нужна, поэтому пример кода на три строки короче:
${If} ${IsNativeAMD64} DetailPrint "System Architecture: x64" ${ElseIf} ${IsNativeIA32} DetailPrint "System Architecture: x86" ${Else} DetailPrint "Unsupported CPU architecture!" ${EndIf}
1. Get Windows version
2. Stackoverflow
Может поможет и для других ноутов Acer.
Иногда надо отключить в BIOS/UEFI опцию Secure Boot, например, чтобы переустановить Windows с флешки, иначе при загрузке получим сообщение Secure Boot Fail.
Не знаю, что скурили инженеры Acer, но пункт Secure Boot в разделе Boot неактивен, и по умолчанию его значение никак не изменить. Итак, отключаем Secure Boot:
1. Заходим в BIOS/UEFI (клавиша F2 при загрузке)
2. Переходим в раздел Security
3. Задаем Supervisor Password (пароль администратора BIOS). Без разницы какой, но главное его не забыть — забудете, будете долго трахаться с перепрошивкой BIOS. Просто так сбросить его не получится! Так что задайте что-нибудь типа 111
4. На этом этапе нужные пункты уже будут открыты, но лучше зайти на последнюю вкладку, выбрать Exit & Save Changes, перезагрузиться и вновь войти в BIOS по F2
5. Потом надо будет ввести установленный пароль.
6. Пункт Secure Boot в разделе Boot стал активен, теперь можно изменить его значение на Disabled
Изучение любого языка начинается с Hello, world, вот и я не буду отступать от этой традиции. Напишем простой инсталлятор, который даже не инсталлятор, потому что ничего не устанавливает, а просто пишет сообщение пользователю.
Name "HelloWorld" OutFile "helloworld.exe" ShowInstDetails show RequestExecutionLevel User Section DetailPrint "Hello, world!" SectionEnd
Сначала пишем обязательную конструкцию Name
и придумываем имя установщика, тут, естественно, "HelloWorld"
. Имя может содержать пробелы, оно будет отображаться в заголовках окон и окнах инсталлятора, а также попадет в список программ в «Программы и компоненты», в случае реального установщика.
Далее идет обязательная конструкция OutFile
— файл установщика. Если его не прописать, то компилятор не будет знать под каким именем собрать программу установки и пошлет нас.
Следующим шагом (ShowInstDetails show
) развернем окно с логом установки, как это было описано в предыдущей копия заметке.
Теперь запрашиваем запуск из под пользователя с ограниченными правами (RequestExecutionLevel User
). Инсталляторы обычно запускаются с правами администратора, но в данном случае мы ничего не устанавливаем, и нажимать лишний раз кнопку в окошке UAC не нужно.
Далее необходимо завести хотя бы одну секцию. Если в скрипте не будет хотя бы одной секции — компилятор прервет работу. Организуем единственную секцию без названия.
Section [ТУТ БУДЕТ КОД] SectionEnd
На самом деле секции нужны для того, чтобы сделать возможным выбор компонентов устанавливаемой программы, полную или выборочную установку. Но об этом как-нибудь в другой раз.
Внутри секции пишем сообщение, выводящее заданный текст в окошко с логом (деталями установки):
DetailPrint "Hello, world!"
На самом деле выбора не так, чтобы много, но какой-никакой есть. На официальном сайте предлагают пользоваться Eclipse и плагином к нему, но у меня на Клипсу, wim и TeX стойкая аллергия еще со студенческих времен.
Есть плагин для Visual Studio, но написан он китайцами для китайцев, так что нафиг. Впрочем, может есть и нормальные плагины, но я не нашел. Сам пользуюсь пожилой средой Venis IX, там есть мастер для генерации простых установщиков, которого вполне хватает, чтоб постоянно не писать одно и то же, создавая новый инсталлятор.
Если ничего не делать, детали установки по умолчанию скрыты:
Чтобы лог установки сразу был виден пользователю, необходимо применить один из следующих методов:
1. В коде скрипта, до секций прописываем команду:
ShowInstDetails show
Окошко с логом (деталями установки) будет открыто
2. Прописать внутри секции команду:
SetDetailsView show
Это может быть полезно, например, если вы хотите, чтобы детали показывались и при удалении. В таком случае, вышеуказанная команда добавляется в начало секции, описывающей анинсталлер:
Section Uninstall SetDetailsView show [..] [..] SectionEnd
Делал, чтоб клиенту меньше ручками работать. Теперь не надо самому определять версию винды, и вытаскивать нужный devcon из архива соответственно.
Предыдущий я сделал на Inno Setup, но Inno Setup оказался той еще заразой, нихрена он версию Винды толком определить не мог, и тихой сапой подкладывал во все винды один и тот же devcon, который подходит для Windows 7 и выше. От чего у клиента с виндой XP x64 произошел адский баттхерт, так, что забрызгало пол-Петербурга, аж до моей деревни брызги долетели. Видимо, клиент меня проклял, потому что мне на ногу упал топор (слава Ктулху обухом), у меня упали форточки, точнее форточка, но стеклянная и на пол, ко мне какого-то черта приперлась лесная охрана и стала [РОСКОМНАДЗОР], и я после этого [РОСКОМНАДЗОР] в результате, теперь страдаю [МИНЗДРАВ].
Новый сделал на NSIS, но как оказалось — NSIS тоже [РОСКОМНАДЗОР], точнее, не сам NSIS, он мне как раз понравился, за исключением одного странного недокументированного глюка, о котором как-нибудь расскажу, и скрипт-язык, вполне себе такая помесь Бейсика с Башем. А вот документация, это, товарищи, лютый [РОСКОМНАДЗОР] в последней стадии.
Русский мануал к популярному инсталл-мэйкеру писали сто лет назад какие-то [ДАННЫЕ УДАЛЕНЫ] с OSZone.net, еще и назвали свое творение «справочником», хотя что-что а справочники так не делают. Просто плохо структурированные статьи, которые на [РОСКОМНАДЗОР] запихнули в chm-файл. [РОСКОМНАДЗОРКА], поучитесь у того же Исзелиона с wasm.ru, как нужно делать справочники и мануалы. На туториале Исзелиона сотня-другая студентов если не аспирантами стали, так свой зачет по ассемблеру точно получили. Аффтар еще и жалуется на форуме, типа, «ну на[РОСКОМНАДЗОР] обновлять мануал, если его никто не читает, и очевидные вопросы задает». Так [РОСКОМНАДЗОРКА], [РОСКОМНАДЗОРКА], ты так написал этот мануал, что кошка [РОСКОМНАДЗОРОМ] по клавиатуре лучше напишет. Но ладно, я много захотел, русского мануала. Да, согласен. Но теперь «поговорим о влажности в номере», точнее об оригинальной вики от разработчиков.
Оригинальная вики тоже [РОСКОМНАДЗОРНЫЙ], [РОСКОМНАДЗОР] твою мать, [РОСКОМНАДЗОР]. Причем, я вполне себе уверен, что там есть все описания функций языка NSIS, вот только отдельной категории для списка функций нет. Функции потом ищутся гуглем, который выводит на страницу-сироту с вполне нормальным описанием, но [РОСКОМНАДЗОР] знает, почему на эту страницу нельзя попасть из самой вики. В навигации [РОСКОМНАДЗОР] не валялся, в общем без стакана не разобраться. А еще пишут, что «хорошо документированный продукт». Документирован он может и хорошо, но найти в документации что-то конкретное, это как в ГОРФ пойти к чиновнику: «вы мне справку ЕПРСТ-1488 принесли, а надо было ЖПЧШЦ-666», и [РОСКОМНАДЗОР] знает где это написано.
Даже есть мысль как-нибудь выкачать эту вики себе на комп, сделать нормально, попытаться перевести и выпустить в виде справочника.
Впрочем, инсталлер сделал:
Скачать с Mega.nz
С GitHub
Исходник (файлы devcon_all.nsi и gvv.nsi)
При установке Windows 7 на компьютер с USB 3.0 можно столкнуться с ошибкой «Не найден необходимый драйвер для дисковода оптических дисков.«, на самом деле, дисковод оптических дисков тут не при чем, особенно, если установка производится с загрузочной флэшки с дистрибутивом «семерки». В Windows 7 и его установочном окружении просто нет драйверов для контроллеров USB 3.0.
Самый простой вариант, когда в BIOS/UEFI удается переключить USB-контроллер в legacy-режим. Но на многих системах это самое legacy реализовано весьма коряво. Например, live-дистрибутивы Linux могут в таком режиме видеть и контроллер, и подключенные накопители, а вот установщик Windows 7 (и сама винда) нет.
На днях попался такой ноутбук, в котором примерно так и получалось, и вот, хочу рассказать об интересном способе это побороть.
Конечно, можно поступить стандартно — создать отдельный дистрибутив для такого компьютера, внедрив нужные драйвера, или же скачать какую-нибудь «колхозную» сборку. Но есть и другой способ — воспользоваться установочным окружением от Windows 8/8.1 в котором драйвера для USB 3.0 есть.
Минус способа — в установленной Windows 7 драйвера для USB 3.0 будут отсутствовать, как, наверняка, и драйвера от сетевой карты, и возникнет проблема, как их туда затолкать.
В источнике есть способ сделать это с помощью консоли восстановления с получившейся флэшки, у меня же получилось еще проще. Кривое ноутбучное legacy поддерживалось Linux’ом с System Rescue CD, так что на этом моменте я останавливаться не буду.
1. Образ установщика Windows 7
2. Образ установщика Windows 8/8.1
3. Флэшка 🙂
1. Закатываем на флэшку дистрибутив Windows 8/8.1, например, с помощью программы Rufus, особых подробностей я рассказывать не буду, но я сначала переключил UEFI ноута в режим Legacy BIOS (хоть он работал нормально и, главное, был), снес б-гмерзкое GPT, а потом установил в Rufus «Схема раздела и тип системного интерфейса» в значение «MBR для компьютеров с BIOS или UEFI«.
2. Итак, у нас получилась флэшка с Windows 8/8.1, переходим на нее, заходим в каталог sources
и удаляем оттуда файлы install.wim
и/или install.esd
.
3. Теперь из образа Windows 7 вытаскиваем файл install.wim
(он тоже лежит в подкаталоге sources
образа). Если у вас образ AIO, т.е. «все в одном», образ, из которого можно установить сразу несколько версий Windows, например, Starter, Home и Professional, то необходимо из образа Windows 7 вытащить файлы sources/*.clg
, например, install_Windows 7 Home Basic x64.clg
, install_Windows 7 Home Premium x64.clg
и т.д. Также можно попробовать скопировать папку $OEM$
, но не везде срабатывает, т.е. иногда конкретный дистрибутив может ее проигнорировать.
4. Теперь копируем все, что вытащили из дистрибутива Windows 7 в каталог sources на флэшке.
5. ФАНФАРЫ!
Загрузчик установщика Windows современных версий сначала загружает файл boot.wim
, который представляет из себя хитрый архив (виртуальный диск, наподобие initrd
в Linux), содержащий необходимые для процесса установки драйвера, основные файлы и саму программу-установщик. Далее окружение предустановки ищет дополнительные компоненты на диске с boot.wim
, в частности install.wim
, виртуальный диск с файлами операционной системы, которая должна быть установлена. Тут мы просто оставили предустановочное окружение, подсунув ему ОС другой версии.
Мне периодически задают вопрос, а где взять тот самый Визг Свиньи, которым визжал ранее Антивирус Касперского при обнаружении зловреда?
Вот, выдрал специально для вас из какой-то старой версии (еще под Win98) KAV’а.
Насколько я понимаю, сам по себе звук некопирайтный, ибо Евгений Валентинович его сам откуда-то сгайдарил и счубайсил. Так что смело качайте, ставьте на будильник, звонок или СМС.
Когда-то давно в этом блоге упоминалось про замечательную консольную утилиту devcon
от Microsoft, это консольный аналог «Диспетчера устройств», причем бесплатный и с открытым исходным кодом.
В прошлый раз мы находили и включали/отключали конкретную сетевую карту. В этот раз будем искать все сетевые устройства, а также массово включать и отключать всю сетевую активность на локальной машине.
devcon.exe findall =net
Команда найдет и выведет на экран все сетевые устройства, включая виртуальные адаптеры, например, TUN/TAP от Openvpn или виртуальные адаптеры VMWare, а также те устройства, которые в данный момент не активны (отключены, или у них нет драйверов).
devcon.exe find =net
Выводятся только активные устройства.
Пример вывода devcon.exe findall =net
:
Отключение всей сетевой активности
devcon.exe disable =net
devcon.exe enable =net
Внимание! devcon
необходимо запускать с админскими правами!
devcon’ы входят в разные пакеты SDK, отличающиеся гигантским размером. Я тут подобрал разные версии devcon’ов для разных ОС в одном архиве, ну и плюс батники для включения/отключения сети.
Содержимое архива:
batchfiles — пакетные файлы для включения и отключения сетевой активности
с помощью devcon, а также для получения списка сетевых устройств.
x64 — devcon для Windows7-10 для 64-разрядных версий Windows.
x86 — devcon для Windows7-10 для 32-разрядных версий Windows.
XP\x64 — devcon для Windows XP 64-разрядной, работает только в WinXP x64.
XP\x86 — devcon для Windows XP 32-разрядной, работает в WinXP x32 и,
возможно, в Win Vista x32.
Скачать с Mega.nz (ZIP)
Автоматический установщик
Вот уж не думал, что данная задача будет достойна заметки, но оказалось, что нормально определить версию (а главное, удобоваримое название и архитектуру) просто так не получится.
Класс VersionDetect.cs
Весь пример целиком
Win32_OperatingSystem class
Тема на Киберфоруме
Вопрос на stackowerflow
Понадобилось тут для одного проекта получать внешний IP, да еще желательно и из нескольких источников.
Критерии были такие:
— сайт не должен быть заскриптован и засран капчей наглухо, в идеале, чтобы просто содержал страничку с внешним IP, а еще лучше, чтоб с IP, которые «протекают» через прокси, которую без бубна можно высосать хоть тем же wget’ом.
— чтоб не требовал куки и не пугался странных идентификаторов браузера (последнее, конечно, легко решается на уровне клиента, но ведь лень).
— более-менее стабильная работа
— анализ не должен требовать сложного парсинга, в идеале, IP вытаскиваются простой регуляркой.
https://api.myip.com/ — выдает IP и краткие данные в формате JSON. Бесплатный и стабильный (правда в прошлом месяце все-таки вышел из строя на два дня из-за каких-то технических проблем).
https://2ip.ru — наверное, самый известный сервис в рунете. Несмотря на требования включить javascript, информацию об IP отдает и просто так. Бесплатный, стабильный (вообще не видел, чтоб он когда-нибудь падал). IP на странице встречается несколько раз, посему, при составлении списка выкидываем одинаковые. Минус — русский сервис.
https://yandex.ru/internet/ — ВНЕЗАПНО, Яндекс. Плюсы и минусы такие же, как у предыдущего сайта.
https://hidemyna.me/ru/ip/ — Информация о IP на сайте VPN-сервиса HideMy.name. Сам сервис какой-то подозрительный, а страничка с информацией об IP вполне себе соответствует всем требованиям, правда, насчет надежности особо не тестировалась.
https://whatleaks.com/ru/ — в стабильности не уверен, в остальном, вполне соответствует.
http://whatismyip.host/my-ip-address-details — простой зарубежный сервис, отображающий IP и краткую информацию. Насчет надежности особо не тестировалось, остальное соответствует, плюс сервис не российский.
Похуже, в данном случае, значит, что требуют более продвинутого парсинга, а при простом выдирании со страницы всего, что похоже на IP, выдают паразитные данные.
https://2ip.ua/ua/ — на самом деле, я бы поставил этот сервис на второе место, после https://api.myip.com/, если бы не маленький минус — со странички выкачивается и адрес самого сервера.
http://www.findmyip.org/ — дает кучу паразитных IP
Эти хороши, только для того, чтобы посмотреть IP через браузер (и то, я бы не советовал). Реагируют различными ошибками на нестандартный идентификатор браузера, если не принимаешь куки, и/или если не грузишь с сайта какие-то картинки.
Отдельной категорией в список непопадают жадные буржуи, которые в 21 веке не могут себе позволить хостинг с безлимитным трафиком (даже я могу).
Не заморачиваться, и установить себе на хостинг скрипт, например такой, просто получающий IP из всех заголовков HTTP, такой, с геолокацией, или такой, с симпатичным оформлением.
Узнать, как сделано, можно прочитать записи по тегу ip-detect копия озаглавленные «Определение IP и местоположения посетителя сайта».
А так же ISO-образ Acronis True Image и Puppy Slacko.
Попросили превратить мою заметку про то, как можно пользоваться Acronis True Image без его акронисовского «восстановления при загрузке», превратить в интерактивный скрипт, который делает все то, что описано в заметке, но сам, задавая пользователю наводящие вопросы.
Сделал, чо. Правда, скрипт, наверняка, дичайший быдлокод, но работает без ошибок. Единственное что, предварительно надо создать основной раздел ext2/ext3 на жестком диске, и он должен идти первым. Потом установить винды, сделать линуксовый раздел активным, а потом уже запускать скрипт со всеми потрохами.
Скрипт дико большой, и отдельно его описывать мне откровенно влом, впрочем, в виде отдельных заметок, все самое основное я в этом блоге уже обсуждал.
Эмуляция восстановления при загрузке Acronis True Image с помощью syslinux/extlinux Копия
1. Создание списков (из файлов в каталоге) Копия
2. Простой интерактив в bash-скриптах (запрос Y/N и запрос строки) Копия
3. Простой интерактив в bash-скриптах (меню, списки) Копия
4. Проверка, установлен ли флаг раздела «активный» Копия
5. Определение файловой системы раздела диска в Linux Копия
6. Поиск загрузчика Windows Копия
7. Получение MBR ID и номера раздела, для передачи управления другому загрузчику Копия
8. Число или строка в переменной BASH Копия
Поскольку, наверняка набыдлокодил, то исправления и дополнения приветствуются.
Позвали тут в дружественную конторку, где после очередных обновлений перестал работать какой-то очередной русский инновационный криптопровайдер (не Крипто Про, с ним вроде такой беды не случалось). Оказалось, программулина конфликтовала с кривым активатором ODIN, да-да, винда почему-то тоже оказалась нелицензионной, несмотря на государственный статус этой самой конторки. Пришлось удалять.
А активатор кривой тому ще подсовывает в винду патченное ядро, дабы установить драйвер без цифровой подписи, нужный для эмуляции таблицы SLIC.
На рутрекере, кстати, в хорошей и обстоятельной теме про активацию семерки, предлагали просто создать BAT-файл со следующим содержимым, и запустить его с правами администратора, после чего перезагрузиться:
del "%windir%\system32\drivers\oem-drv64.sys"
del "%windir%\system32\xNtKrnl.exe"
del "%windir%\system32\xOsLoad.exe"
del "%windir%\System32\ru-RU\xOsLoad.exe.mui"
del "%windir%\System32\en-US\xOsLoad.exe.mui"
%windir%\system32\bcdedit.exe /set {current} path \Windows\system32\winload.exe
%windir%\system32\bcdedit.exe /deletevalue {current} kernel
%windir%\system32\bcdedit.exe /deletevalue {current} nointegritychecks
%windir%\system32\bcdedit.exe /deletevalue {current} custom:26000027
reg delete HKLM\SYSTEM\CurrentControlSet\services\oem-drv64 /va /f
Кому-то может и поможет, но мне не повезло, файлы активатора не удалились, reg delete не сработал, потому я просто нашел в дистрибутиве их виды «автоматический установщик» активатора, и просто провернул последовательность действий в обратном порядке.
Получился такой вот CMD-файл
В каталоге с этим батником должен быть подкаталог data, со следующим содержимым:
1. Утилита SetACL.exe, которая будет менять права доступа к ключам Реестра, и восстанавливать их после редактирования. Утилиту взял из того же дистрибутива.
2. Утилитка sleep, но это так, для красоты, моя прихоть.
3. Файлы Реестра (*.reg) для x86 и x64 ОС, в которых прописано, какие ключи удалять anti-oem-drv64.reg anti-oem-drv86.reg
Далее я сделал RAR-SFX с таким сценарием:
;Расположенный ниже комментарий содержит команды SFX-сценария
Setup=Deactivator.cmd
TempMode="Удалить активатор?","Деактиватор"
Silent=1
Overwrite=1
И поставил галочку в дополнительных параметрах SFX, на запрос административного доступа.
После перезагрузки можно удалить файлы активатора, таким вот CMD-файлом.
@ rem echo Этот файл должен быть запущен с правами администратора и после выполнения Deactivator'а
@ rem echo Чтобы окончательно удалить следы активатора нажмите любую клавишу, иначе CTRL+C!
@ rem pause
DEL "%windir%\system32\drivers\oem-drv64.sys"
DEL "%windir%\system32\xNtKrnl.exe"
DEL "%windir%\system32\xOsLoad.exe"
DEL "%windir%\System32\ru-RU\xOsLoad.exe.mui"
DEL "%windir%\System32\en-US\xOsLoad.exe.mui"
DEL "%windir%\system32\drivers\oem-drv86.sys"
@echo "Clean complete."
@pause
И SFX-сценарий к нему:
;Расположенный ниже комментарий содержит команды SFX-сценария
Setup=Cleaner.cmd
TempMode="Выполняйте только после исполнения Deactivator'а, если хотите окончательно удалить следы активации","Окончательная очистка"
Silent=1
Overwrite=1
1. Deactivator.exe
2. Cleaner.exe