вторник, 18 августа 2009 г.

Делаем установщик плагинов для The Elder Scrolls III в NSIS.

В своё время сильно увлекался играми в жанре RPG серии "The Elder Scrolls III", да и сейчас иногда запускаю. Для этой игры умельцами выпущена целая куча плагинов разной степени полезности и забагованности. Установка плагина заключалась в простой распаковке архива в папку "<tesdir>\Data Files", а вот с удалением были проблемы, потому что далеко не все плагины состояли из одного *.esp файла, большинство содержало в себе дополнительные ресурсы (графика, модели, звуки), которые хорошо засоряли папку с игрой.

Решил я для своих любимых плагинов сделать установщики, чтобы раскладыванием файлов по папкам занимался не я, а компьютер. Для этого я воспользовался программой NSIS и редактором HM NIS EDIT.
Я не буду расписывать подробно все шаги мастера по созданию скелета скрипта, а приведу ключевые участки кода, которые помогут найти папку с игрой и отследить зависимости.
Функция читает путь из реестра (у меня была версия игры от ) и ищет файлы дополнений.
1) Ищем папку с игрой:

Function .onInit
ReadRegStr $0 HKLM "SOFTWARE\Bethesda Softworks\Morrowind" "Installed Path"
StrCpy $INSTDIR "$0\Data Files"
IfErrors 0 +3
MessageBox MB_OK|MB_ICONEXCLAMATION "Игра Morrowind не найдена"
Abort ; causes installer to quit.
MessageBox MB_OK|MB_ICONINFORMATION "Игра Morrowind найдена по адресу: $0"
FunctionEnd
2) Тоже самое, но с проверкой наличия дополнения Tribunal:

Function .onInit
ReadRegStr $0 HKLM "SOFTWARE\Bethesda Softworks\Morrowind" "Installed Path"
StrCpy $INSTDIR "$0\Data Files"
IfErrors 0 +3
MessageBox MB_OK|MB_ICONEXCLAMATION "Игра Morrowind не найдена"
Abort ; causes installer to quit.
MessageBox MB_OK|MB_ICONINFORMATION "Игра Morrowind найдена по адресу: $0"
IfFileExists "$INSTDIR\Tribunal.esm" +3 0
MessageBox MB_OK|MB_ICONEXCLAMATION "Дополнение Tribunal не установлено"
Abort ; causes installer to quit.
FunctionEnd
3) Тоже самое, но с проверкой наличия дополнений Tribunal и Bloodmoon:

Function .onInit
ReadRegStr $0 HKLM "SOFTWARE\Bethesda Softworks\Morrowind" "Installed Path"
StrCpy $INSTDIR "$0\Data Files"
IfErrors 0 +3
MessageBox MB_OK|MB_ICONEXCLAMATION "Игра Morrowind не найдена"
Abort ; causes installer to quit.
MessageBox MB_OK|MB_ICONINFORMATION "Игра Morrowind найдена по адресу: $0"
StrCpy $INSTDIR "$0\Data Files"
IfFileExists "$INSTDIR\Tribunal.esm" +3 0
MessageBox MB_OK|MB_ICONEXCLAMATION "Дополнение Tribunal не установлено"
Abort ; causes installer to quit.
IfFileExists "$INSTDIR\Bloodmoon.esm" +3 0
MessageBox MB_OK|MB_ICONEXCLAMATION "Дополнение Bloodmoon не установлено"
Abort ; causes installer to quit.
FunctionEnd
Перед функциями распаковки файлов рекомендую добавить следующее:

BrandingText "<НАЗВАНИЕ ДОПОЛНИЯ>"
LangString MUI_TEXT_WELCOME_INFO_TEXT ${LANG_RUSSIAN} "Эта программа установит дополнение $(^NameDA) на ваш компьютер.\r\n\r\n<ОПИСАНИЕ ДОПОЛНЕНИЯ>\r\n\r\n$_CLICK"
Пример простого скрипта:

; Script generated by the HM NIS Edit Script Wizard.

; HM NIS Edit Wizard helper defines
!define PRODUCT_NAME "ВОЗВРАЩЕНИЕ КАЯ КОСАДЕСА"
!define PRODUCT_VERSION ""
!define PRODUCT_PUBLISHER "Nat"
!define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}"
!define PRODUCT_UNINST_ROOT_KEY "HKLM"

; MUI 1.67 compatible ------
!include "MUI.nsh"

; MUI Settings
!define MUI_ABORTWARNING
!define MUI_ICON "${NSISDIR}\Contrib\Graphics\Icons\modern-install.ico"
!define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\modern-uninstall.ico"

; Welcome page
!insertmacro MUI_PAGE_WELCOME
; Instfiles page
!insertmacro MUI_PAGE_INSTFILES
; Finish page
!define MUI_FINISHPAGE_SHOWREADME "$INSTDIR\ВОЗВРАЩЕНИЕ КАЯ КОСАДЕСА readme.txt"
!insertmacro MUI_PAGE_FINISH

; Uninstaller pages
!insertmacro MUI_UNPAGE_INSTFILES

; Language files
!insertmacro MUI_LANGUAGE "Russian"

; MUI end ------

Name "${PRODUCT_NAME} ${PRODUCT_VERSION}"
OutFile "Caius_Return.exe"
InstallDir "$PROGRAMFILES\ВОЗВРАЩЕНИЕ КАЯ КОСАДЕСА"
ShowInstDetails show
ShowUnInstDetails show
BrandingText "ВОЗВРАЩЕНИЕ КАЯ КОСАДЕСА"
LangString MUI_TEXT_WELCOME_INFO_TEXT ${LANG_RUSSIAN} "Эта программа установит дополнение $(^NameDA) на ваш компьютер.\r\n\r\nПлагин возвращает Главного шпиона Империи в Морровинд. Однако, чтобы Кай вернулся нужно выполнить ряд квестов. В завершении игрока ждут подарки от Косадеса.\r\n\r\n$_CLICK"

Function .onInit
ReadRegStr $0 HKLM "SOFTWARE\Bethesda Softworks\Morrowind" "Installed Path"
StrCpy $INSTDIR "$0\Data Files"
IfErrors 0 +3
MessageBox MB_OK|MB_ICONEXCLAMATION "Игра Morrowind не найдена"
Abort ; causes installer to quit.
MessageBox MB_OK|MB_ICONINFORMATION "Игра Morrowind найдена по адресу: $0"
FunctionEnd

Section "MainSection" SEC01
SetOutPath "$INSTDIR\Icons\gld"
SetOverwrite try
File "Icons\gld\g_statue_icon.dds"
SetOutPath "$INSTDIR\Meshes\big"
File "Meshes\big\in_fresco_tamriel_01.nif"
SetOutPath "$INSTDIR\Meshes\gld"
File "Meshes\gld\golden saint.nif"
SetOutPath "$INSTDIR"
File "nat.esp"
File '/oname=ВОЗВРАЩЕНИЕ КАЯ КОСАДЕСА readme.txt' readme.txt
CreateDirectory "$SMPROGRAMS\Morrowind"
CreateShortCut "$SMPROGRAMS\Morrowind\ВОЗВРАЩЕНИЕ КАЯ КОСАДЕСА readme.lnk" "$INSTDIR\ВОЗВРАЩЕНИЕ КАЯ КОСАДЕСА readme.txt"
SetOutPath "$INSTDIR\Textures"
File "Textures\tx_big_tamriel_map.dds"
Setautoclose true
SectionEnd

Section -AdditionalIcons
SetOutPath $INSTDIR
CreateShortCut "$SMPROGRAMS\Morrowind\Удалить ВОЗВРАЩЕНИЕ КАЯ КОСАДЕСА.lnk" "$INSTDIR\uninstCaius_Return.exe"
SectionEnd

Section -Post
WriteUninstaller "$INSTDIR\uninstCaius_Return.exe"
WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayName" "$(^Name)"
WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "UninstallString" "$INSTDIR\uninstCaius_Return.exe"
WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayVersion" "${PRODUCT_VERSION}"
WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "Publisher" "${PRODUCT_PUBLISHER}"
SectionEnd


Function un.onUninstSuccess
HideWindow
MessageBox MB_ICONINFORMATION|MB_OK "Удаление дополнения $(^Name) было успешно завершено."
FunctionEnd

Function un.onInit
MessageBox MB_ICONQUESTION|MB_YESNO|MB_DEFBUTTON2 "Вы уверены в том, что желаете удалить $(^Name) и все компоненты программы?" IDYES +2
Abort
FunctionEnd

Section Uninstall
Delete "$INSTDIR\uninstCaius_Return.exe"
Delete "$INSTDIR\Textures\tx_big_tamriel_map.dds"
Delete "$INSTDIR\ВОЗВРАЩЕНИЕ КАЯ КОСАДЕСА readme.txt"
Delete "$INSTDIR\nat.esp"
Delete "$INSTDIR\Meshes\gld\golden saint.nif"
Delete "$INSTDIR\Meshes\big\in_fresco_tamriel_01.nif"
Delete "$INSTDIR\Icons\gld\g_statue_icon.dds"

Delete "$SMPROGRAMS\Morrowind\Удалить ВОЗВРАЩЕНИЕ КАЯ КОСАДЕСА.lnk"
Delete "$SMPROGRAMS\Morrowind\ВОЗВРАЩЕНИЕ КАЯ КОСАДЕСА readme.lnk"

RMDir "$SMPROGRAMS\Morrowind"
RMDir "$INSTDIR\Textures"
RMDir "$INSTDIR\Meshes\gld"
RMDir "$INSTDIR\Meshes\big"
RMDir "$INSTDIR\Icons\gld"
RMDir "$INSTDIR"

DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}"
SetAutoClose true
SectionEnd