From b2f7a685892d61c923d65ac7eef83606e710077b Mon Sep 17 00:00:00 2001 From: Ochenstarik Date: Thu, 24 Sep 2026 16:37:48 +0700 Subject: [PATCH] feat(installer): update release build script and NSIS installer with Windows Service and driver detection --- installer/KronaStaffTerminal.nsi | 103 ++++++++++++++++++++++++----- scripts/build-terminal-release.ps1 | 18 +++++ 2 files changed, 105 insertions(+), 16 deletions(-) diff --git a/installer/KronaStaffTerminal.nsi b/installer/KronaStaffTerminal.nsi index bf6fe11..7ffa56e 100644 --- a/installer/KronaStaffTerminal.nsi +++ b/installer/KronaStaffTerminal.nsi @@ -2,6 +2,7 @@ Unicode True SetCompressor /SOLID lzma !include "MUI2.nsh" +!include "x64.nsh" !ifndef APP_VERSION !define APP_VERSION "0.2.5" @@ -18,14 +19,16 @@ SetCompressor /SOLID lzma !define APP_NAME "Krona Staff Terminal" !define APP_EXE "KronaStaffTerminal.exe" +!define SERVICE_EXE "KronaStaffService.exe" +!define SERVICE_NAME "KronaStaffService" !define APP_REGISTRY_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\KronaStaffTerminal" !define DRIVER_URL "https://www.zkteco.com/en/Biometrics_Module_SDK/ZKFinger-SDK-for-Windows" Name "${APP_NAME}" OutFile "${OUTPUT_DIR}\KronaStaffTerminal-Setup-${APP_VERSION}.exe" -InstallDir "$LOCALAPPDATA\Programs\Krona Staff Terminal" -InstallDirRegKey HKCU "${APP_REGISTRY_KEY}" "InstallLocation" -RequestExecutionLevel user +InstallDir "$PROGRAMFILES64\Krona Staff Terminal" +InstallDirRegKey HKLM "${APP_REGISTRY_KEY}" "InstallLocation" +RequestExecutionLevel admin Icon "${PROJECT_ROOT}\apps\KronaStaffTerminal\Assets\AppIcon.ico" BrandingText "Krona" ShowInstDetails show @@ -58,33 +61,88 @@ VIAddVersionKey /LANG=1049 "ProductVersion" "${APP_VERSION}" !insertmacro MUI_LANGUAGE "Russian" +Function .onInit + ${If} ${RunningX64} + SetRegView 64 + ${Else} + MessageBox MB_ICONSTOP "Для работы программы требуется 64-разрядная версия Windows." + Abort + ${EndIf} +FunctionEnd + +Function un.onInit + ${If} ${RunningX64} + SetRegView 64 + ${EndIf} +FunctionEnd + Section "Krona Staff Terminal" SecMain SectionIn RO - SetShellVarContext current + SetShellVarContext all + + DetailPrint "Остановка службы ${SERVICE_NAME} (если запущена)..." + ExecWait 'sc.exe stop ${SERVICE_NAME}' + Sleep 500 + SetOutPath "$INSTDIR" SetOverwrite try File /r "${PUBLISH_DIR}\*" + DetailPrint "Настройка службы ${SERVICE_NAME}..." + ExecWait 'sc.exe create ${SERVICE_NAME} binPath= "\"$INSTDIR\${SERVICE_EXE}\"" start= auto DisplayName= "Krona Staff Service"' + ExecWait 'sc.exe config ${SERVICE_NAME} binPath= "\"$INSTDIR\${SERVICE_EXE}\"" start= auto' + ExecWait 'sc.exe description ${SERVICE_NAME} "Служба фоновой синхронизации Krona Staff Terminal"' + DetailPrint "Запуск службы ${SERVICE_NAME}..." + ExecWait 'sc.exe start ${SERVICE_NAME}' + WriteUninstaller "$INSTDIR\Uninstall.exe" CreateDirectory "$SMPROGRAMS\Krona" CreateShortcut "$SMPROGRAMS\Krona\Krona Staff Terminal.lnk" "$INSTDIR\${APP_EXE}" "" "$INSTDIR\${APP_EXE}" 0 - WriteRegStr HKCU "${APP_REGISTRY_KEY}" "DisplayName" "${APP_NAME}" - WriteRegStr HKCU "${APP_REGISTRY_KEY}" "DisplayVersion" "${APP_VERSION}" - WriteRegStr HKCU "${APP_REGISTRY_KEY}" "Publisher" "Krona" - WriteRegStr HKCU "${APP_REGISTRY_KEY}" "InstallLocation" "$INSTDIR" - WriteRegStr HKCU "${APP_REGISTRY_KEY}" "DisplayIcon" "$INSTDIR\${APP_EXE}" - WriteRegStr HKCU "${APP_REGISTRY_KEY}" "UninstallString" "$\"$INSTDIR\Uninstall.exe$\"" - WriteRegDWORD HKCU "${APP_REGISTRY_KEY}" "NoModify" 1 - WriteRegDWORD HKCU "${APP_REGISTRY_KEY}" "NoRepair" 1 + WriteRegStr HKLM "${APP_REGISTRY_KEY}" "DisplayName" "${APP_NAME}" + WriteRegStr HKLM "${APP_REGISTRY_KEY}" "DisplayVersion" "${APP_VERSION}" + WriteRegStr HKLM "${APP_REGISTRY_KEY}" "Publisher" "Krona" + WriteRegStr HKLM "${APP_REGISTRY_KEY}" "InstallLocation" "$INSTDIR" + WriteRegStr HKLM "${APP_REGISTRY_KEY}" "DisplayIcon" "$INSTDIR\${APP_EXE}" + WriteRegStr HKLM "${APP_REGISTRY_KEY}" "UninstallString" "$\"$INSTDIR\Uninstall.exe$\"" + WriteRegDWORD HKLM "${APP_REGISTRY_KEY}" "NoModify" 1 + WriteRegDWORD HKLM "${APP_REGISTRY_KEY}" "NoRepair" 1 + + # Create install log + FileOpen $9 "$INSTDIR\install.log" w + FileWrite $9 "Krona Staff Terminal v${APP_VERSION} installed successfully at: $INSTDIR$\r$\n" + FileClose $9 + + # Driver detection check + IfFileExists "$SYSDIR\drivers\slk20r.sys" driver_present 0 + IfFileExists "$SYSDIR\drivers\zkfp.sys" driver_present 0 + IfFileExists "$SYSDIR\drivers\zkfpos.sys" driver_present 0 + IfFileExists "$SYSDIR\drivers\ZKUSB.sys" driver_present 0 + ReadRegStr $1 HKLM "SYSTEM\CurrentControlSet\Services\slk20r" "ImagePath" + StrCmp $1 "" 0 driver_present + ReadRegStr $1 HKLM "SYSTEM\CurrentControlSet\Services\zkfp" "ImagePath" + StrCmp $1 "" 0 driver_present + ReadRegStr $1 HKLM "SYSTEM\CurrentControlSet\Services\ZKUSB" "ImagePath" + StrCmp $1 "" 0 driver_present + + DetailPrint "Драйвер сканера ZKTeco SLK20R не обнаружен." + IfSilent driver_done + MessageBox MB_YESNO|MB_ICONINFORMATION "Драйвер биометрического сканера ZKTeco SLK20R не обнаружен в системе.$\r$\n$\r$\nДля работы со сканером отпечатков пальцев требуется официальный драйвер ZKTeco.$\r$\n$\r$\nОткрыть страницу загрузки официального драйвера сейчас?" IDNO driver_done + ExecShell "open" "${DRIVER_URL}" + Goto driver_done + +driver_present: + DetailPrint "Драйвер биометрического сканера обнаружен." + +driver_done: SectionEnd Section "Значок на рабочем столе" SecDesktop - SetShellVarContext current + SetShellVarContext all CreateShortcut "$DESKTOP\Krona Staff Terminal.lnk" "$INSTDIR\${APP_EXE}" "" "$INSTDIR\${APP_EXE}" 0 SectionEnd -LangString DESC_SecMain ${LANG_RUSSIAN} "Основная программа учёта прихода и ухода." +LangString DESC_SecMain ${LANG_RUSSIAN} "Основная программа учёта прихода и ухода со службой синхронизации." LangString DESC_SecDesktop ${LANG_RUSSIAN} "Создать значок программы на рабочем столе." !insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN !insertmacro MUI_DESCRIPTION_TEXT ${SecMain} $(DESC_SecMain) @@ -92,10 +150,23 @@ LangString DESC_SecDesktop ${LANG_RUSSIAN} "Создать значок прог !insertmacro MUI_FUNCTION_DESCRIPTION_END Section "Uninstall" - SetShellVarContext current + SetShellVarContext all + + DetailPrint "Остановка службы ${SERVICE_NAME}..." + ExecWait 'sc.exe stop ${SERVICE_NAME}' + Sleep 1000 + DetailPrint "Удаление службы ${SERVICE_NAME}..." + ExecWait 'sc.exe delete ${SERVICE_NAME}' + + IfSilent keep_data + MessageBox MB_YESNO|MB_ICONQUESTION "Сохранить локальную базу данных и журнал терминала (%ProgramData%\Krona\StaffTerminal)?$\r$\n$\r$\nНажмите 'Да', чтобы сохранить данные для будущей установки.$\r$\nНажмите 'Нет', чтобы полностью удалить данные с устройства." IDYES keep_data + RMDir /r "$APPDATA\Krona\StaffTerminal" + RMDir "$APPDATA\Krona" +keep_data: + Delete "$DESKTOP\Krona Staff Terminal.lnk" Delete "$SMPROGRAMS\Krona\Krona Staff Terminal.lnk" RMDir "$SMPROGRAMS\Krona" - DeleteRegKey HKCU "${APP_REGISTRY_KEY}" + DeleteRegKey HKLM "${APP_REGISTRY_KEY}" RMDir /r "$INSTDIR" SectionEnd diff --git a/scripts/build-terminal-release.ps1 b/scripts/build-terminal-release.ps1 index febf40f..033af42 100644 --- a/scripts/build-terminal-release.ps1 +++ b/scripts/build-terminal-release.ps1 @@ -30,6 +30,8 @@ if (Test-Path -LiteralPath $stagingRoot) { New-Item -ItemType Directory -Path $publishDirectory -Force | Out-Null New-Item -ItemType Directory -Path $outputDirectory -Force | Out-Null +$serviceProjectPath = Join-Path $repositoryRoot 'apps\KronaStaffService\KronaStaffService.csproj' + $publishArguments = @( 'publish', $projectPath, @@ -46,6 +48,22 @@ if ($LASTEXITCODE -ne 0) { throw "Terminal publish failed." } +$servicePublishArguments = @( + 'publish', + $serviceProjectPath, + '-c', 'Release', + '-r', 'win-x64', + '--self-contained', 'true', + '-p:Platform=x64', + "-p:Version=$Version", + "-p:BaseOutputPath=$(Join-Path $stagingRoot 'bin-service')\", + '-o', $publishDirectory +) +& dotnet @servicePublishArguments +if ($LASTEXITCODE -ne 0) { + throw "Service publish failed." +} + $nsisCandidates = @( (Join-Path ${env:ProgramFiles(x86)} 'NSIS\makensis.exe'), (Join-Path $env:ProgramFiles 'NSIS\makensis.exe'),