В некоторых случаях, например, при установке драйверов, необходимых для работы вашей программы, или при внесении серьезных изменений в систему, хотелось бы задействовать механизм создания точек восстановления, чтобы в случае непредвиденной ситуации, пользователь мог бы безболезненно откатить все назад.
Как, например, поступает Driver Pack Solutions перед установкой драйверов.
Для создания точек восстановления в NSIS применяется плагин SysRestore, который можно скачать с официальной NSIS wiki (копия).
Установка тривиальна — надо распаковать архив в каталог NSIS, например в "C:\Program Files (x86)\NSIS\"
После подключения плагина становятся доступны 4 функции:
SysRestore::StartInstallPoint "<название>"
— функция создает точку восстановления с типом «Установка», применяется для создания точки восстановления при установке программы.
SysRestore::StartUninstallPoint "<название>"
— функция создает точку восстановления с типом «Удаление», применяется для создания точки восстановления при удалении программы.
В стек эти функции (как и другие функции данного модуля) помещают код возврата, который можно извлечь из стека командой
Pop <переменная>
И далее проанализировать:
0
— Функция завершена успешно, точка восстановления создана.
1
— Уже запущено создание точки восстановления, предыдущую точку восстановления надо закрыть или отменить (см. ниже).
10
— Windows запущена в «Безопасном режиме»
13
— The sequence number is invalid (сам автор плагина не знает, что это за ошибка).
80
— Ошибка с таким кодом встречается в Windows ME.
112
— Восстановление системы находится в режиме ожидания, поскольку закончилось место на жестком диске под точки восстановления.
1058
— Восстановление системы отключено.
1359
— Внутренняя ошибка при создании точки восстановления.
1460
— Время ожидания вызова истекло из-за ожидания мьютекса для установки точек восстановления (вот это уже я не знаю, что такое).
Впрочем, про коды ошибок, автор пишет следующее:
Я не знаю, являются ли эти коды актуальными кодами ошибок, я просто проанализировал соответствующие include-файлы в SDK. Я тестировал код 1058 — восстановление системы отключено, и провел тест в безопасном режиме — код ошибки 10, я предполагаю, что эти коды верны.
Так что возможно ограничиться анализом кодов 0 (ОК), 1 (см. ниже), 10 (безопасный режим) и 1058 (восстановление системы отключено). Если функция выдаст что-то кроме этих четырех понятных кодов, остальное можно (в первом приближении) отправить в великий класс Неизвестная Ошибка (Unknown Error). Хотя, если вы знаете больше, чем автор плагина, а тем более, чем я — добро пожаловать в комментарии.
Кроме вышеперечисленных инициализирующих функций, существует «закрывающая» и «отменяющая» функции. «Закрывающая»:
SysRestore::FinishRestorePoint
Ее необходимо вызывать, после того, как все изменения в системе произведены, чтобы закрыть точку восстановления, и чтобы система получила нужные данные о том, что было изменено в системных/программных файлах и Реестре. Попытка создать новую точку восстановления без закрытия предыдущей, в одном и том же инсталляторе, приводит к тому что функции StartInstallPoint/StartUninstallPoint
выдадут ошибку 1
.
Как я понимаю, система все равно закроет restore point после завершения работы установщика, но лучше эту функцию использовать.
«Отменяющая» функция, это:
SysRestore::RemoveRestorePoint
Она позволяет удалить незакрытую точку восстановления из системы. Может понадобиться в случае, если пользователь отменил установку в процессе, и установщик откатил процесс установки.
Коды возврата последних двух функций:
0
— OK
2 — Не произведен запуск точки восстановления (т.е. предварительно не вызваны функции StartInstallPoint
или StartUninstallPoint
)
В первой секции… Вообще, для этого можно создать скрытую секцию, чтоб сначала создать restore point, а потом с ней работать далее, но пример простой, так что в первой секции, до начала изменений, создаем точку восстановления
Section "Create Restore Point Example" ;Настраиваем секцию ;Создаем точку восстановления DetailPrint "Create restore point..." SysRestore::StartRestorePoint "Test Restore Point" Pop $0 ;достаем из стека код восстановления в переменную $0 ${If} $0 = 0 ;анализируем его DetailPrint "OK" ${ElseIf} $0 = 1 DetailPrint "Start point already set (start function only)." ${ElseIf} $0 = 10 DetailPrint "The system is running in safe mode. " ${ElseIf} $0 = 13 DetailPrint "The sequence number is invalid." ${ElseIf} $0 = 80 DetailPrint "Windows Me code." ${ElseIf} $0 = 112 DetailPrint "System Restore is in standby mode because disk space is low." ${ElseIf} $0 = 1058 DetailPrint "System Restore is disabled." ${ElseIf} $0 = 1359 DetailPrint "An internal error with system restore occurred." ${ElseIf} $0 = 1460 DetailPrint "The call timed out due to a wait on a mutex for setting restore points." ${Else} DetailPrint "Unknow error." ${EndIf} ;производим установку программы, копируем файлы, пишем в Реестр ;... SectionEnd ;в завершающей секции Section -FinishSection ;... ; Генерируем uninstaller, пишем соотв. ключи в Реестр ;... ;Закрываем точку восстановления SysRestore::FinishRestorePoint DetailPrint "Finish restore point..." ${If} $0 = 0 DetailPrint "OK" ${ElseIf} $0 = 2 DetailPrint "No Start point set (finish function only)." ${Else} DetailPrint "Unknow error." ${EndIf} SectionEnd
Тестовый установщик создает точку восстановления, далее устанавливает во временный каталог системы программу, которая при запуске показывает приветственное окно и завершает работу, прописывает ее в автозагрузку Реестра, и генерирует uninstaller во временном каталоге.
Код на GitHub
Скомпилированный инсталлятор