diff --git a/.gitignore b/.gitignore index 26c12cc6920bd1b55a7ef5279614b97c206ceed0..903a02a8c9f314e50f8d6a5d769b83c3c7a3ab58 100755 --- a/.gitignore +++ b/.gitignore @@ -50,7 +50,7 @@ indra/newview/dbghelp.dll indra/newview/filters.xml indra/newview/fmod.dll indra/newview/fmod.log -indra/newview/installers/windows/* +indra/newview/installers/windows/*.ico indra/newview/mozilla-theme indra/newview/mozilla-universal-darwin.tgz indra/newview/pilot.txt diff --git a/indra/cmake/BuildPackagesInfo.cmake b/indra/cmake/BuildPackagesInfo.cmake index bc48fe5328b0f305703df3c8a3f77a3e292e54c4..348432c55d9934aadcc52a1f2488a8df1dd9d23e 100644 --- a/indra/cmake/BuildPackagesInfo.cmake +++ b/indra/cmake/BuildPackagesInfo.cmake @@ -17,5 +17,5 @@ add_custom_command(OUTPUT packages-info.txt COMMAND ${Python3_EXECUTABLE} ${CMAKE_SOURCE_DIR}/cmake/run_build_test.py -DAUTOBUILD_ADDRSIZE=${ADDRESS_SIZE} -DAUTOBUILD=${AUTOBUILD_EXECUTABLE} ${Python3_EXECUTABLE} - ${CMAKE_SOURCE_DIR}/../scripts/packages-formatter.py "${VIEWER_CHANNEL}" "${VIEWER_SHORT_VERSION}" "${LIBS_PREBUILT_DIR}" > packages-info.txt + ${CMAKE_SOURCE_DIR}/../scripts/packages-formatter.py "${VIEWER_CHANNEL}" "${VIEWER_SHORT_VERSION}.${VIEWER_VERSION_REVISION}" "${LIBS_PREBUILT_DIR}" > packages-info.txt ) diff --git a/indra/cmake/BuildVersion.cmake b/indra/cmake/BuildVersion.cmake index 3f883e054031e6432aeffd206ae9b97e9bb0d208..a41718a3b8b5f983afa4b2e34637ea552431ea5c 100644 --- a/indra/cmake/BuildVersion.cmake +++ b/indra/cmake/BuildVersion.cmake @@ -54,20 +54,21 @@ if(NOT DEFINED VIEWER_SHORT_VERSION) # will be true in indra/, false in indra/ne set(VIEWER_VERSION_BASE_FILE "${CMAKE_SOURCE_DIR}/newview/VIEWER_VERSION.txt") if(EXISTS ${VIEWER_VERSION_BASE_FILE}) - file(STRINGS ${VIEWER_VERSION_BASE_FILE} VIEWER_FILE_VERSION REGEX "^[0-9]+\\.[0-9]+") - string(REGEX REPLACE "^([0-9]+)\\.[0-9]+" "\\1" VIEWER_VERSION_MAJOR ${VIEWER_FILE_VERSION}) - string(REGEX REPLACE "^[0-9]+\\.([0-9]+)" "\\1" VIEWER_VERSION_MINOR ${VIEWER_FILE_VERSION}) + file(STRINGS ${VIEWER_VERSION_BASE_FILE} VIEWER_SHORT_VERSION REGEX "^[0-9]+\\.[0-9]+\\.[0-9]+") + string(REGEX REPLACE "^([0-9]+)\\.[0-9]+\\.[0-9]+" "\\1" VIEWER_VERSION_MAJOR ${VIEWER_SHORT_VERSION}) + string(REGEX REPLACE "^[0-9]+\\.([0-9]+)\\.[0-9]+" "\\1" VIEWER_VERSION_MINOR ${VIEWER_SHORT_VERSION}) + string(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.([0-9]+)" "\\1" VIEWER_VERSION_PATCH ${VIEWER_SHORT_VERSION}) if(REVISION_FROM_VCS) find_package(Git) endif() if((NOT REVISION_FROM_VCS) AND DEFINED ENV{CI_PIPELINE_ID}) - set(VIEWER_VERSION_PATCH $ENV{CI_PIPELINE_ID}) - message(STATUS "Revision (from environment): ${VIEWER_VERSION_PATCH}") + set(VIEWER_VERSION_REVISION $ENV{CI_PIPELINE_ID}) + message(STATUS "Revision (from environment): ${VIEWER_VERSION_REVISION}") elseif((NOT REVISION_FROM_VCS) AND DEFINED ENV{AUTOBUILD_BUILD_ID}) - set(VIEWER_VERSION_PATCH $ENV{AUTOBUILD_BUILD_ID}) - message(STATUS "Revision (from autobuild environment): ${VIEWER_VERSION_PATCH}") + set(VIEWER_VERSION_REVISION $ENV{AUTOBUILD_BUILD_ID}) + message(STATUS "Revision (from autobuild environment): ${VIEWER_VERSION_REVISION}") elseif(Git_FOUND) execute_process( COMMAND ${GIT_EXECUTABLE} rev-list HEAD --count @@ -76,26 +77,24 @@ if(NOT DEFINED VIEWER_SHORT_VERSION) # will be true in indra/, false in indra/ne OUTPUT_STRIP_TRAILING_WHITESPACE) if(GIT_REV_LIST_COUNT) - set(VIEWER_VERSION_PATCH ${GIT_REV_LIST_COUNT}) + set(VIEWER_VERSION_REVISION ${GIT_REV_LIST_COUNT}) else(GIT_REV_LIST_COUNT) - set(VIEWER_VERSION_PATCH 0) + set(VIEWER_VERSION_REVISION 0) endif(GIT_REV_LIST_COUNT) else() - set(VIEWER_VERSION_PATCH 0) + set(VIEWER_VERSION_REVISION 0) endif() - message(STATUS "Building '${VIEWER_CHANNEL}' Version ${VIEWER_SHORT_VERSION}") - - if("${VIEWER_VERSION_PATCH}" STREQUAL "") - message(STATUS "Ultimate fallback, revision was blank or not set: will use 0") - set(VIEWER_VERSION_PATCH 0) - endif("${VIEWER_VERSION_PATCH}" STREQUAL "") - - set(VIEWER_SHORT_VERSION "${VIEWER_VERSION_MAJOR}.${VIEWER_VERSION_MINOR}.${VIEWER_VERSION_PATCH}") + message(STATUS "Building '${VIEWER_CHANNEL}' Version ${VIEWER_SHORT_VERSION}.${VIEWER_VERSION_REVISION}") else(EXISTS ${VIEWER_VERSION_BASE_FILE}) message(SEND_ERROR "Cannot get viewer version from '${VIEWER_VERSION_BASE_FILE}'") endif(EXISTS ${VIEWER_VERSION_BASE_FILE}) - set(VIEWER_VERSION_AND_CHANNEL "${VIEWER_CHANNEL} ${VIEWER_SHORT_VERSION}") + if("${VIEWER_VERSION_REVISION}" STREQUAL "") + message(STATUS "Ultimate fallback, revision was blank or not set: will use 0") + set(VIEWER_VERSION_REVISION 0) + endif("${VIEWER_VERSION_REVISION}" STREQUAL "") + + set(VIEWER_VERSION_AND_CHANNEL "${VIEWER_CHANNEL} ${VIEWER_SHORT_VERSION}.${VIEWER_VERSION_REVISION}") endif(NOT DEFINED VIEWER_SHORT_VERSION) if (NOT DEFINED VIEWER_COMMIT_LONG_SHA) @@ -153,6 +152,7 @@ target_compile_definitions( ll::versioninfo INTERFACE LL_VIEWER_VERSION_MAJOR=${VIEWER_VERSION_MAJOR} LL_VIEWER_VERSION_MINOR=${VIEWER_VERSION_MINOR} LL_VIEWER_VERSION_PATCH=${VIEWER_VERSION_PATCH} + LL_VIEWER_VERSION_BUILD=${VIEWER_VERSION_REVISION} LL_VIEWER_COMMIT_SHA="${VIEWER_COMMIT_LONG_SHA}" LL_VIEWER_COMMIT_SHORT_SHA="${VIEWER_COMMIT_SHORT_SHA}" ) \ No newline at end of file diff --git a/indra/llfilesystem/lldir_win32.cpp b/indra/llfilesystem/lldir_win32.cpp index 7fa594f9163174b15be5a2d482ff1734ba59d496..afd95b1afa94da904d3cc0c4bdebe661688e461f 100644 --- a/indra/llfilesystem/lldir_win32.cpp +++ b/indra/llfilesystem/lldir_win32.cpp @@ -381,7 +381,7 @@ bool LLDir_Win32::fileExists(const std::string& filename) const /*virtual*/ std::string LLDir_Win32::getLLPluginLauncher() { - return gDirUtilp->getLLPluginDir() + gDirUtilp->getDirDelimiter() + + return gDirUtilp->getExecutableDir() + gDirUtilp->getDirDelimiter() + "SLPlugin.exe"; } diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 061470316c9b19f0c2f0b30e69b09ddfce8a6e94..92f667cb7814029cc03c049df87f48ecb8c24145 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -52,9 +52,6 @@ include(LLPrimitive) # Viewer Branding Assets use_prebuilt_binary(branding) -if (WINDOWS) - use_prebuilt_binary(squirrel) -endif() if( LLPHYSICSEXTENSIONS_SRC_DIR ) if (NOT HAVOK_TPV) @@ -1531,12 +1528,12 @@ source_group("CMake Rules" FILES ViewerInstall.cmake) #build_data.json creation moved to viewer_manifest.py MAINT-6413 # the viewer_version.txt file created here is for passing to viewer_manifest and autobuild file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt" - "${VIEWER_SHORT_VERSION}\n") + "${VIEWER_SHORT_VERSION}.${VIEWER_VERSION_REVISION}\n") -if (WINDOWS) - LIST(APPEND viewer_SOURCE_FILES alsquirrelupdater.cpp) - LIST(APPEND viewer_HEADER_FILES alsquirrelupdater.h) -endif (WINDOWS) +# if (WINDOWS) +# LIST(APPEND viewer_SOURCE_FILES alsquirrelupdater.cpp) +# LIST(APPEND viewer_HEADER_FILES alsquirrelupdater.h) +# endif (WINDOWS) if (DARWIN) LIST(APPEND viewer_SOURCE_FILES llappviewermacosx.cpp) @@ -1638,8 +1635,8 @@ if (WINDOWS) ) execute_process( COMMAND ${CMAKE_COMMAND} -E copy_if_different - "${LIBS_PREBUILT_DIR}/branding/installer/splash/${ICON_PATH}/install_splash.gif" - "${CMAKE_CURRENT_SOURCE_DIR}/installers/windows/install_splash.gif" + "${LIBS_PREBUILT_DIR}/branding/installer/icons/uninstall_icon.ico" + "${CMAKE_CURRENT_SOURCE_DIR}/installers/windows/uninstall_icon.ico" ) # Add resource files to the project. @@ -1706,10 +1703,6 @@ if (WINDOWS) ${CMAKE_CURRENT_BINARY_DIR}/viewerRes.rc ) - configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/viewer.nuspec - ${CMAKE_CURRENT_BINARY_DIR}/viewer.nuspec - ) - list(APPEND viewer_RESOURCE_FILES windows.manifest ${CMAKE_CURRENT_BINARY_DIR}/viewerRes.rc @@ -1760,7 +1753,6 @@ set_source_files_properties(${viewer_SHADER_FILES} PROPERTIES HEADER_FILE_ONLY TRUE) list(APPEND viewer_SOURCE_FILES ${viewer_SHADER_FILES}) - set(viewer_APPSETTINGS_FILES app_settings/anim.ini app_settings/cmd_line.xml @@ -1883,8 +1875,6 @@ if (WINDOWS) LINK_FLAGS_RELEASE "/OPT:REF /LARGEADDRESSAWARE" ) - set_target_properties(${VIEWER_BINARY_NAME} PROPERTIES OUTPUT_NAME "${WIN_BINARY_NAME}") - if(NOT LL_GENERATOR_IS_MULTI_CONFIG) set_target_properties(${VIEWER_BINARY_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/$<IF:$<BOOL:${LL_GENERATOR_IS_MULTI_CONFIG}>,$<CONFIG>,>") @@ -2017,12 +2007,6 @@ if (WINDOWS) ${CMAKE_CURRENT_SOURCE_DIR}/event_host_manifest.py ) - if (ENABLE_DELTA_GEN) - set(DELTA_GEN_SETTING "--gendelta=ON") - else () - set(DELTA_GEN_SETTING "") - endif () - add_custom_command( OUTPUT ${CMAKE_CFG_INTDIR}/touched.bat COMMAND ${Python3_EXECUTABLE} @@ -2044,7 +2028,6 @@ if (WINDOWS) --touch=${CMAKE_CURRENT_BINARY_DIR}/$<IF:$<BOOL:${LL_GENERATOR_IS_MULTI_CONFIG}>,$<CONFIG>,>/touched.bat --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt --updateurl=${VIEWER_UPDATE_SERVICE} - ${DELTA_GEN_SETTING} DEPENDS ${VIEWER_BINARY_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py @@ -2151,7 +2134,7 @@ set(ARTWORK_DIR ${CMAKE_CURRENT_SOURCE_DIR} CACHE PATH "Path to artwork files.") if (LINUX) - set(product Alchemy-${ARCH}-${VIEWER_SHORT_VERSION}) + set(product Alchemy-${ARCH}-${VIEWER_SHORT_VERSION}.${VIEWER_VERSION_REVISION}) # These are the generated targets that are copied to package/ set(COPY_INPUT_DEPENDENCIES @@ -2232,10 +2215,10 @@ if (DARWIN) set(MACOSX_BUNDLE_INFO_STRING "${VIEWER_CHANNEL}") set(MACOSX_BUNDLE_ICON_FILE "alchemy.icns") set(MACOSX_BUNDLE_GUI_IDENTIFIER "org.alchemyviewer.viewer") - set(MACOSX_BUNDLE_LONG_VERSION_STRING "${VIEWER_CHANNEL} ${VIEWER_SHORT_VERSION}") + set(MACOSX_BUNDLE_LONG_VERSION_STRING "${VIEWER_CHANNEL} ${VIEWER_SHORT_VERSION}.${VIEWER_VERSION_REVISION}") set(MACOSX_BUNDLE_BUNDLE_NAME "Alchemy") - set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${VIEWER_SHORT_VERSION}") - set(MACOSX_BUNDLE_BUNDLE_VERSION "${VIEWER_SHORT_VERSION}") + set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${VIEWER_SHORT_VERSION}.${VIEWER_VERSION_REVISION}") + set(MACOSX_BUNDLE_BUNDLE_VERSION "${VIEWER_SHORT_VERSION}${VIEWER_VERSION_REVISION}") set(MACOSX_BUNDLE_COPYRIGHT "Copyright (C) 2013-2023 Alchemy Development Group") set(MACOSX_BUNDLE_NSMAIN_NIB_FILE "Alchemy.nib") set(MACOSX_BUNDLE_NSPRINCIPAL_CLASS "LLApplication") @@ -2384,7 +2367,7 @@ if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND VIE "-C" "${PARENT_DIRECTORY_CYGWIN}" "alchemy-bin.pdb" - DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${WIN_BINARY_NAME}.pdb" + DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/alchemy-bin.pdb" COMMENT "Packing viewer PDB into ${VIEWER_SYMBOL_FILE_CYGWIN}" ) add_custom_target(generate_symbols DEPENDS "${VIEWER_SYMBOL_FILE}" ${VIEWER_BINARY_NAME}) diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt index 4fedf1d20e15761409d6e4e3bf99c0beb499fdfe..66ce77b7ead5c03f8d614495285190635c0889d9 100644 --- a/indra/newview/VIEWER_VERSION.txt +++ b/indra/newview/VIEWER_VERSION.txt @@ -1 +1 @@ -7.0 +7.0.0 diff --git a/indra/newview/app_settings/cmd_line.xml b/indra/newview/app_settings/cmd_line.xml index 0866b667228dc46ed04fb2991c570ddb9b830232..bcbb6a2b171f2977f1fb2a4c5f237d683d6cc30c 100644 --- a/indra/newview/app_settings/cmd_line.xml +++ b/indra/newview/app_settings/cmd_line.xml @@ -421,40 +421,5 @@ <key>map-to</key> <string>CmdLineSkipUpdater</string> </map> - <key>squirrel-install</key> - <map> - <key>count</key> - <integer>1</integer> - <key>map-to</key> - <string>CmdLineSquirrelInstall</string> - </map> - <key>squirrel-firstrun</key> - <map> - <key>count</key> - <integer>0</integer> - <key>map-to</key> - <string>CmdLineSquirrelFirstRun</string> - </map> - <key>squirrel-updated</key> - <map> - <key>count</key> - <integer>1</integer> - <key>map-to</key> - <string>CmdLineSquirrelUpdated</string> - </map> - <key>squirrel-obsolete</key> - <map> - <key>count</key> - <integer>1</integer> - <key>map-to</key> - <string>CmdLineSquirrelObsolete</string> - </map> - <key>squirrel-uninstall</key> - <map> - <key>count</key> - <integer>1</integer> - <key>map-to</key> - <string>CmdLineSquirrelUninstall</string> - </map> </map> </llsd> diff --git a/indra/newview/app_settings/settings_alchemy.xml b/indra/newview/app_settings/settings_alchemy.xml index 844862144de9e625f8e8d3b10666da6ffd4e851c..1949442391a9bfc35cd7e5e5f7afa9958dc45443 100644 --- a/indra/newview/app_settings/settings_alchemy.xml +++ b/indra/newview/app_settings/settings_alchemy.xml @@ -827,28 +827,6 @@ <key>Value</key> <integer>1</integer> </map> - <key>AlchemyUpdatePreference</key> - <map> - <key>Comment</key> - <string>Default behavior of updater 0(Download and install), 1(download and prompt for install), 2(Prompt for download and install)</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>0</integer> - </map> - <key>AlchemyUpdateCheckInterval</key> - <map> - <key>Comment</key> - <string>How frequently to check for updates in seconds.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>F32</string> - <key>Value</key> - <real>14400.0</real> - </map> <key>ChatAlerts</key> <map> <key>Comment</key> @@ -871,61 +849,6 @@ <key>Value</key> <boolean>0</boolean> </map> - <key>CmdLineSquirrelInstall</key> - <map> - <key>Comment</key> - <string>Command line flag for initial install from squirrel with version as arguement</string> - <key>Persist</key> - <integer>0</integer> - <key>Type</key> - <string>String</string> - <key>Value</key> - <string /> - </map> - <key>CmdLineSquirrelFirstRun</key> - <map> - <key>Comment</key> - <string>Command line flag for initial application run from squirrel</string> - <key>Persist</key> - <integer>0</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>0</integer> - </map> - <key>CmdLineSquirrelUpdated</key> - <map> - <key>Comment</key> - <string>Command line flag for update from squirrel with version as arguement</string> - <key>Persist</key> - <integer>0</integer> - <key>Type</key> - <string>String</string> - <key>Value</key> - <string /> - </map> - <key>CmdLineSquirrelObsolete</key> - <map> - <key>Comment</key> - <string>Command line flag for obsolete version from squirrel with version as arguement</string> - <key>Persist</key> - <integer>0</integer> - <key>Type</key> - <string>String</string> - <key>Value</key> - <string /> - </map> - <key>CmdLineSquirrelUninstall</key> - <map> - <key>Comment</key> - <string>Command line flag for uninstall from squirrel with version as arguement</string> - <key>Persist</key> - <integer>0</integer> - <key>Type</key> - <string>String</string> - <key>Value</key> - <string /> - </map> <key>DoubleClickAttachmentAdd</key> <map> <key>Comment</key> diff --git a/indra/newview/installers/windows/FILES_ARE_UNICODE_UTF-16LE.txt b/indra/newview/installers/windows/FILES_ARE_UNICODE_UTF-16LE.txt new file mode 100644 index 0000000000000000000000000000000000000000..30f9349111d117a99d4af183bfb11607286239b0 --- /dev/null +++ b/indra/newview/installers/windows/FILES_ARE_UNICODE_UTF-16LE.txt @@ -0,0 +1,6 @@ +The language files in this directory are Unicode (Little-Endian) format, also known as UTF-16 LE. + +This is the format required for NSIS Unicode. See http://www.scratchpaper.com/ for details. + +James Cook +September 2008 diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi new file mode 100644 index 0000000000000000000000000000000000000000..c782c901c37d4fb4b38fc7470f06a3467295694e --- /dev/null +++ b/indra/newview/installers/windows/installer_template.nsi @@ -0,0 +1,868 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Second Life setup.nsi +;; Copyright 2004-2015, Linden Research, Inc. +;; +;; This library is free software; you can redistribute it and/or +;; modify it under the terms of the GNU Lesser General Public +;; License as published by the Free Software Foundation; +;; version 2.1 of the License only. +;; +;; This library is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; Lesser General Public License for more details. +;; +;; You should have received a copy of the GNU Lesser General Public +;; License along with this library; if not, write to the Free Software +;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +;; +;; Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +;; +;; NSIS 3 or higher required for Unicode support +;; +;; Author: James Cook, TankMaster Finesmith, Don Kjer, Callum Prentice +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Compiler flags +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +Unicode true +SetOverwrite on # Overwrite files +SetCompress auto # Compress if saves space +SetCompressor /solid lzma # Compress whole installer as one block +SetDatablockOptimize off # Only saves us 0.1%, not worth it +XPStyle on # Add an XP manifest to the installer +RequestExecutionLevel admin # For when we write to Program Files + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Project flags +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +# This placeholder is replaced by viewer_manifest.py +%%VERSION%% + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; - language files - one for each language (or flavor thereof) +;; (these files are in the same place as the nsi template but the python script generates a new nsi file in the +;; application directory so we have to add a path to these include files) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Ansariel notes: "Under certain circumstances the installer will fall back +;; to the first defined (aka default) language version. So you want to include +;; en-us as first language file." +!include "%%SOURCE%%\installers\windows\lang_en-us.nsi" + +# Danish and Polish no longer supported by the viewer itself +##!include "%%SOURCE%%\installers\windows\lang_da.nsi" +!include "%%SOURCE%%\installers\windows\lang_de.nsi" +!include "%%SOURCE%%\installers\windows\lang_es.nsi" +!include "%%SOURCE%%\installers\windows\lang_fr.nsi" +!include "%%SOURCE%%\installers\windows\lang_ja.nsi" +!include "%%SOURCE%%\installers\windows\lang_it.nsi" +##!include "%%SOURCE%%\installers\windows\lang_pl.nsi" +!include "%%SOURCE%%\installers\windows\lang_pt-br.nsi" +!include "%%SOURCE%%\installers\windows\lang_ru.nsi" +!include "%%SOURCE%%\installers\windows\lang_tr.nsi" +!include "%%SOURCE%%\installers\windows\lang_zh.nsi" + +# *TODO: Move these into the language files themselves +##LangString LanguageCode ${LANG_DANISH} "da" +LangString LanguageCode ${LANG_GERMAN} "de" +LangString LanguageCode ${LANG_ENGLISH} "en" +LangString LanguageCode ${LANG_SPANISH} "es" +LangString LanguageCode ${LANG_FRENCH} "fr" +LangString LanguageCode ${LANG_JAPANESE} "ja" +LangString LanguageCode ${LANG_ITALIAN} "it" +##LangString LanguageCode ${LANG_POLISH} "pl" +LangString LanguageCode ${LANG_PORTUGUESEBR} "pt" +LangString LanguageCode ${LANG_RUSSIAN} "ru" +LangString LanguageCode ${LANG_TURKISH} "tr" +LangString LanguageCode ${LANG_TRADCHINESE} "zh" + +# This placeholder is replaced by viewer_manifest.py +%%INST_VARS%% + +Name ${INSTNAME} + +SubCaption 0 $(LicenseSubTitleSetup) # Override "license agreement" text + +!define MUI_ICON "%%SOURCE%%\installers\windows\install_icon.ico" +!define MUI_UNICON "%%SOURCE%%\installers\windows\uninstall_icon.ico" + +BrandingText " " # Bottom of window text +Icon "${MUI_ICON}" +UninstallIcon "${MUI_UNICON}" +WindowIcon on # Show our icon in left corner +BGGradient off # No big background window +CRCCheck on # Make sure CRC is OK +InstProgressFlags smooth colored # New colored smooth look +SetOverwrite on # Overwrite files by default +AutoCloseWindow true # After all files install, close window + +# Registry key paths, ours and Microsoft's +!define LINDEN_KEY "SOFTWARE\Alchemy Development Group" +!define INSTNAME_KEY "${LINDEN_KEY}\${INSTNAME}" +!define MSCURRVER_KEY "SOFTWARE\Microsoft\Windows\CurrentVersion" +!define MSNTCURRVER_KEY "SOFTWARE\Microsoft\Windows NT\CurrentVersion" +!define MSUNINSTALL_KEY "${MSCURRVER_KEY}\Uninstall\${INSTNAME}" + +# from http://nsis.sourceforge.net/Docs/MultiUser/Readme.html +### Highest level permitted for user: Admin for Admin, Standard for Standard +##!define MULTIUSER_EXECUTIONLEVEL Highest +!define MULTIUSER_EXECUTIONLEVEL Admin +!define MULTIUSER_MUI +### Look for /AllUsers or /CurrentUser switches +##!define MULTIUSER_INSTALLMODE_COMMANDLINE +# appended to $PROGRAMFILES, as affected by MULTIUSER_USE_PROGRAMFILES64 +!define MULTIUSER_INSTALLMODE_INSTDIR "${INSTNAME}" +# expands to !define MULTIUSER_USE_PROGRAMFILES64 or nothing +%%PROGRAMFILES%% +# should make MultiUser.nsh initialization read existing INSTDIR from registry +## SL-10506: don't +##!define MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_KEY "${INSTNAME_KEY}" +##!define MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_VALUENAME "" +# Don't set MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_KEY and +# MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_VALUENAME to cause the installer to +# write $MultiUser.InstallMode to the registry, because when the user installs +# multiple viewers with the same channel (same ${INSTNAME}, hence same +# ${INSTNAME_KEY}), the registry entry is overwritten. Instead we'll write a +# little file into the install directory -- see .onInstSuccess and un.onInit. +!include MultiUser.nsh +!include MUI2.nsh +!define MUI_BGCOLOR FFFFFF +!insertmacro MUI_FUNCTION_GUIINIT + +UninstallText $(UninstallTextMsg) +DirText $(DirectoryChooseTitle) $(DirectoryChooseSetup) +##!insertmacro MULTIUSER_PAGE_INSTALLMODE +!define MUI_PAGE_CUSTOMFUNCTION_PRE dirPre +!insertmacro MUI_PAGE_DIRECTORY +!insertmacro MUI_PAGE_INSTFILES + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Variables +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +Var INSTNAME +Var INSTEXE +Var VIEWER_EXE +Var INSTSHORTCUT +Var COMMANDLINE # Command line passed to this installer, set in .onInit +Var SHORTCUT_LANG_PARAM # "--set InstallLanguage de", Passes language to viewer +Var SKIP_DIALOGS # Set from command line in .onInit. autoinstall GUI and the defaults. +Var SKIP_AUTORUN # Skip automatic launch of the viewer after install + +# Function definitions should go before file includes, because calls to +# DLLs like LangDLL trigger an implicit file include, so if that call is at +# the end of this script NSIS has to decompress the whole installer before +# it can call the DLL function. JC + +!include "FileFunc.nsh" # For GetParameters, GetOptions +!insertmacro GetParameters +!insertmacro GetOptions +!include WinVer.nsh # For OS and SP detection +!include 'LogicLib.nsh' # for value comparison +!include "x64.nsh" # for 64bit detection + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Pre-directory page callback +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +Function dirPre + StrCmp $SKIP_DIALOGS "true" 0 +2 + Abort + +FunctionEnd + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Prep Installer Section +;; +;; Note: to add new languages, add a language file include to the list +;; at the top of this file, add an entry to the menu and then add an +;; entry to the language ID selector below +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +Function .onInit +!insertmacro MULTIUSER_INIT + +%%ENGAGEREGISTRY%% + +# SL-10506: Setting MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_KEY and +# MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_VALUENAME should +# read the current location of the install for this version into INSTDIR. +# However, SL-10506 complains about the resulting behavior, so the logic below +# is adapted from before we introduced MultiUser.nsh. + +# if $0 is empty, this is the first time for this viewer name +ReadRegStr $0 SHELL_CONTEXT "${INSTNAME_KEY}" "" + +# viewer with this name was installed before +${If} $0 != "" + # use the value we got from registry as install location + StrCpy $INSTDIR $0 +${EndIf} + +Call CheckCPUFlags # Make sure we have SSE2 support +Call CheckWindowsVersion # Don't install On unsupported systems + Push $0 + ${GetParameters} $COMMANDLINE # Get our command line + + ${GetOptions} $COMMANDLINE "/SKIP_DIALOGS" $0 + IfErrors +2 0 # If error jump past setting SKIP_DIALOGS + StrCpy $SKIP_DIALOGS "true" + + ${GetOptions} $COMMANDLINE "/SKIP_AUTORUN" $0 + IfErrors +2 0 ; If error jump past setting SKIP_AUTORUN + StrCpy $SKIP_AUTORUN "true" + + ${GetOptions} $COMMANDLINE "/LANGID=" $0 # /LANGID=1033 implies US English + +# If no language (error), then proceed + IfErrors lbl_configure_default_lang +# No error means we got a language, so use it + StrCpy $LANGUAGE $0 + Goto lbl_return + +lbl_configure_default_lang: +# If we currently have a version of SL installed, default to the language of that install +# Otherwise don't change $LANGUAGE and it will default to the OS UI language. + ReadRegStr $0 SHELL_CONTEXT "${INSTNAME_KEY}" "InstallerLanguage" + IfErrors +2 0 # If error skip the copy instruction + StrCpy $LANGUAGE $0 + +# For silent installs, no language prompt, use default + IfSilent 0 +3 + StrCpy $SKIP_AUTORUN "true" + Goto lbl_return + StrCmp $SKIP_DIALOGS "true" lbl_return + + Push "" +# Use separate file so labels can be UTF-16 but we can still merge changes into this ASCII file. JC + !include "%%SOURCE%%\installers\windows\language_menu.nsi" + + Push A # A means auto count languages for the auto count to work the first empty push (Push "") must remain + LangDLL::LangDialog $(InstallerLanguageTitle) $(SelectInstallerLanguage) + Pop $0 + StrCmp $0 "cancel" 0 +2 + Abort + StrCpy $LANGUAGE $0 + +# Save language in registry + WriteRegStr SHELL_CONTEXT "${INSTNAME_KEY}" "InstallerLanguage" $LANGUAGE +lbl_return: + Pop $0 + Return + +FunctionEnd + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Prep Uninstaller Section +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +Function un.onInit + # Save $INSTDIR -- it appears to have the correct value before + # MULTIUSER_UNINIT, but then gets munged by MULTIUSER_UNINIT?! + Push $INSTDIR + !insertmacro MULTIUSER_UNINIT + Pop $INSTDIR + + # Now read InstallMode.txt from $INSTDIR + Push $0 + ClearErrors + FileOpen $0 "$INSTDIR\InstallMode.txt" r + IfErrors skipread + FileRead $0 $MultiUser.InstallMode + FileClose $0 +skipread: + Pop $0 + +%%ENGAGEREGISTRY%% + +# Read language from registry and set for uninstaller. Key will be removed on successful uninstall + ReadRegStr $0 SHELL_CONTEXT "${INSTNAME_KEY}" "InstallerLanguage" + IfErrors lbl_end + StrCpy $LANGUAGE $0 +lbl_end: + +## MessageBox MB_OK "After restoring:$\n$$INSTDIR = '$INSTDIR'$\n$$MultiUser.InstallMode = '$MultiUser.InstallMode'$\n$$LANGUAGE = '$LANGUAGE'" + + Return + +FunctionEnd + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Checks for CPU valid (must have SSE2 support) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +Function CheckCPUFlags + Push $1 + System::Call 'kernel32::IsProcessorFeaturePresent(i) i(10) .r1' + IntCmp $1 1 OK_SSE2 + MessageBox MB_OKCANCEL $(MissingSSE2) /SD IDOK IDOK OK_SSE2 + Quit + + OK_SSE2: + Pop $1 + Return + +FunctionEnd + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Make sure this computer meets the minimum system requirements. +;; Currently: Windows Vista SP2 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +Function CheckWindowsVersion + ${If} ${AtMostWin2003} + MessageBox MB_OK $(CheckWindowsVersionMB) + Quit + ${EndIf} + + ${If} ${IsWinVista} + ${AndIfNot} ${IsServicePack} 2 + MessageBox MB_OK $(CheckWindowsVersionMB) + Quit + ${EndIf} + + ${If} ${IsWin2008} + ${AndIfNot} ${IsServicePack} 2 + MessageBox MB_OK $(CheckWindowsVersionMB) + Quit + ${EndIf} + +FunctionEnd + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Install Section +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +Section "" + +# SetShellVarContext is set by MultiUser.nsh initialization. + +# Start with some default values. +StrCpy $INSTNAME "${INSTNAME}" +StrCpy $INSTEXE "${INSTEXE}" +StrCpy $VIEWER_EXE "${VIEWER_EXE}" +StrCpy $INSTSHORTCUT "${SHORTCUT}" + +Call CheckIfAdministrator # Make sure the user can install/uninstall +Call CloseSecondLife # Make sure Second Life not currently running + +ClearErrors + +INSTALL_FILES_START: + +Call RemoveProgFilesOnInst # Remove existing files to prevent certain errors when running the new version of the viewer + +# This placeholder is replaced by the complete list of all the files in the installer, by viewer_manifest.py +%%INSTALL_FILES%% + +IfErrors 0 INSTALL_FILES_DONE + StrCmp $SKIP_DIALOGS "true" INSTALL_FILES_DONE + MessageBox MB_ABORTRETRYIGNORE $(ErrorSecondLifeInstallRetry) IDABORT INSTALL_FILES_CANCEL IDRETRY INSTALL_FILES_START + # MB_ABORTRETRYIGNORE does not accept IDIGNORE + Goto INSTALL_FILES_DONE + +INSTALL_FILES_CANCEL: + # We are quiting, cleanup. + # Silence warnings from RemoveProgFilesOnInst. + StrCpy $SKIP_DIALOGS "true" + Call RemoveProgFilesOnInst + MessageBox MB_OK $(ErrorSecondLifeInstallSupport) + Quit + +INSTALL_FILES_DONE: + +# Pass the installer's language to the client to use as a default +StrCpy $SHORTCUT_LANG_PARAM "--set InstallLanguage $(LanguageCode)" + +# Shortcuts in start menu +CreateDirectory "$SMPROGRAMS\$INSTSHORTCUT" +SetOutPath "$INSTDIR" +CreateShortCut "$SMPROGRAMS\$INSTSHORTCUT\$INSTSHORTCUT.lnk" \ + "$INSTDIR\$VIEWER_EXE" "$SHORTCUT_LANG_PARAM" "$INSTDIR\$VIEWER_EXE" + + +WriteINIStr "$SMPROGRAMS\$INSTSHORTCUT\SL Create Account.url" \ + "InternetShortcut" "URL" \ + "http://join.secondlife.com/" +WriteINIStr "$SMPROGRAMS\$INSTSHORTCUT\SL Your Account.url" \ + "InternetShortcut" "URL" \ + "http://www.secondlife.com/account/" +WriteINIStr "$SMPROGRAMS\$INSTSHORTCUT\SL Scripting Language Help.url" \ + "InternetShortcut" "URL" \ + "http://wiki.secondlife.com/wiki/LSL_Portal" +CreateShortCut "$SMPROGRAMS\$INSTSHORTCUT\Uninstall $INSTSHORTCUT.lnk" \ + '"$INSTDIR\uninst.exe"' '' + +# Other shortcuts +SetOutPath "$INSTDIR" +CreateShortCut "$DESKTOP\$INSTSHORTCUT.lnk" \ + "$INSTDIR\$VIEWER_EXE" "$SHORTCUT_LANG_PARAM" "$INSTDIR\$VIEWER_EXE" +CreateShortCut "$INSTDIR\$INSTSHORTCUT.lnk" \ + "$INSTDIR\$VIEWER_EXE" "$SHORTCUT_LANG_PARAM" "$INSTDIR\$VIEWER_EXE" +CreateShortCut "$INSTDIR\Uninstall $INSTSHORTCUT.lnk" \ + '"$INSTDIR\uninst.exe"' '' + +# Write registry +WriteRegStr SHELL_CONTEXT "${INSTNAME_KEY}" "" "$INSTDIR" +WriteRegStr SHELL_CONTEXT "${INSTNAME_KEY}" "Version" "${VERSION_LONG}" +WriteRegStr SHELL_CONTEXT "${INSTNAME_KEY}" "Shortcut" "$INSTSHORTCUT" +WriteRegStr SHELL_CONTEXT "${INSTNAME_KEY}" "Exe" "$VIEWER_EXE" +WriteRegStr SHELL_CONTEXT "${MSUNINSTALL_KEY}" "Publisher" "Alchemy Development Group" +WriteRegStr SHELL_CONTEXT "${MSUNINSTALL_KEY}" "URLInfoAbout" "https://alchemyviewer.org/pages/about.html" +WriteRegStr SHELL_CONTEXT "${MSUNINSTALL_KEY}" "URLUpdateInfo" "https://alchemyviewer.org/pages/downloads.html" +WriteRegStr SHELL_CONTEXT "${MSUNINSTALL_KEY}" "HelpLink" "https://alchemyviewer.org/" +WriteRegStr SHELL_CONTEXT "${MSUNINSTALL_KEY}" "DisplayName" "$INSTNAME" +WriteRegStr SHELL_CONTEXT "${MSUNINSTALL_KEY}" "UninstallString" '"$INSTDIR\uninst.exe"' +WriteRegStr SHELL_CONTEXT "${MSUNINSTALL_KEY}" "DisplayVersion" "${VERSION_LONG}" +WriteRegDWORD SHELL_CONTEXT "${MSUNINSTALL_KEY}" "EstimatedSize" "0x0001D500" # ~117 MB + +# from FS:Ansariel +WriteRegStr SHELL_CONTEXT "${MSUNINSTALL_KEY}" "DisplayIcon" '"$INSTDIR\$VIEWER_EXE"' + +# Write URL registry info +WriteRegStr HKEY_CLASSES_ROOT "${URLNAME}" "(default)" "URL:Second Life" +WriteRegStr HKEY_CLASSES_ROOT "${URLNAME}" "URL Protocol" "" +WriteRegStr HKEY_CLASSES_ROOT "${URLNAME}\DefaultIcon" "" '"$INSTDIR\$VIEWER_EXE"' + +# URL param must be last item passed to viewer, it ignores subsequent params to avoid parameter injection attacks. +# MAINT-8305: On SLURL click, directly invoke the viewer, not the launcher. +WriteRegExpandStr HKEY_CLASSES_ROOT "${URLNAME}\shell\open\command" "" '"$INSTDIR\$VIEWER_EXE" -url "%1"' + +WriteRegStr HKEY_CLASSES_ROOT "x-grid-info" "(default)" "URL:Hypergrid" +WriteRegStr HKEY_CLASSES_ROOT "x-grid-info" "URL Protocol" "" +WriteRegStr HKEY_CLASSES_ROOT "x-grid-info\DefaultIcon" "" '"$INSTDIR\$VIEWER_EXE"' + +# URL param must be last item passed to viewer, it ignores subsequent params to avoid parameter injection attacks. +WriteRegExpandStr HKEY_CLASSES_ROOT "x-grid-location-info\shell\open\command" "" '"$INSTDIR\$VIEWER_EXE" -url "%1"' + +WriteRegStr HKEY_CLASSES_ROOT "x-grid-location-info" "(default)" "URL:Hypergrid" +WriteRegStr HKEY_CLASSES_ROOT "x-grid-location-info" "URL Protocol" "" +WriteRegStr HKEY_CLASSES_ROOT "x-grid-location-info\DefaultIcon" "" '"$INSTDIR\$VIEWER_EXE"' + +# URL param must be last item passed to viewer, it ignores subsequent params to avoid parameter injection attacks. +WriteRegExpandStr HKEY_CLASSES_ROOT "x-grid-location-info\shell\open\command" "" '"$INSTDIR\$VIEWER_EXE" -url "%1"' + +WriteRegStr HKEY_CLASSES_ROOT "Applications\$INSTEXE" "IsHostApp" "" +##WriteRegStr HKEY_CLASSES_ROOT "Applications\${VIEWER_EXE}" "NoStartPage" "" + +# Write out uninstaller +WriteUninstaller "$INSTDIR\uninst.exe" + +SectionEnd + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Uninstall Section +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +Section Uninstall + +# Start with some default values. +StrCpy $INSTNAME "${INSTNAME}" +StrCpy $INSTEXE "${INSTEXE}" +StrCpy $VIEWER_EXE "${VIEWER_EXE}" +StrCpy $INSTSHORTCUT "${SHORTCUT}" + +# SetShellVarContext per the mode saved at install time in registry at +# MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_KEY +# MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_VALUENAME +# Couldn't get NSIS to expand $MultiUser.InstallMode into the function name at Call time +${If} $MultiUser.InstallMode == 'AllUsers' +##MessageBox MB_OK "Uninstalling for all users" + Call un.MultiUser.InstallMode.AllUsers +${Else} +##MessageBox MB_OK "Uninstalling for current user" + Call un.MultiUser.InstallMode.CurrentUser +${EndIf} + +# Make sure we're not running +Call un.CloseSecondLife + +# Clean up registry keys and subkeys (these should all be !defines somewhere) +DeleteRegKey SHELL_CONTEXT "${INSTNAME_KEY}" +DeleteRegKey SHELL_CONTEXT "${MSCURRVER_KEY}\Uninstall\$INSTNAME" +# BUG-2707 Remove entry that disabled SEHOP +DeleteRegKey SHELL_CONTEXT "${MSNTCURRVER_KEY}\Image File Execution Options\$VIEWER_EXE" +DeleteRegKey HKEY_CLASSES_ROOT "Applications\$INSTEXE" +DeleteRegKey HKEY_CLASSES_ROOT "Applications\${VIEWER_EXE}" + +# Clean up shortcuts +Delete "$SMPROGRAMS\$INSTSHORTCUT\*.*" +RMDir "$SMPROGRAMS\$INSTSHORTCUT" + +Delete "$DESKTOP\$INSTSHORTCUT.lnk" +Delete "$INSTDIR\$INSTSHORTCUT.lnk" +Delete "$INSTDIR\Uninstall $INSTSHORTCUT.lnk" + +# Remove the main installation directory +Call un.ProgramFiles + +# Clean up cache and log files, but leave them in-place for non AGNI installs. +Call un.UserSettingsFiles + +SectionEnd + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Make sure the user can install +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +Function CheckIfAdministrator + DetailPrint $(CheckAdministratorInstDP) + UserInfo::GetAccountType + Pop $R0 + StrCmp $R0 "Admin" lbl_is_admin + MessageBox MB_OK $(CheckAdministratorInstMB) + Quit +lbl_is_admin: + Return + +FunctionEnd + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Close the program, if running. Modifies no variables. +;; Allows user to bail out of install process. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +Function CloseSecondLife + Push $0 + FindWindow $0 "Alchemy" "" + IntCmp $0 0 DONE + + StrCmp $SKIP_DIALOGS "true" CLOSE + MessageBox MB_OKCANCEL $(CloseSecondLifeInstMB) IDOK CLOSE IDCANCEL CANCEL_INSTALL + + CANCEL_INSTALL: + Quit + + CLOSE: + DetailPrint $(CloseSecondLifeInstDP) + SendMessage $0 16 0 0 + + LOOP: + FindWindow $0 "Alchemy" "" + IntCmp $0 0 SLEEP + Sleep 500 + Goto LOOP + + SLEEP: + # Second life window just closed, but program might not be fully done yet + # and OS might have not released some locks, wait a bit more to make sure + # all file handles were released. + # If something still isn't unlocked, it will trigger a notification from + # RemoveProgFilesOnInst + Sleep 1000 + DONE: + Pop $0 + Return + +FunctionEnd + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Close the program, if running. Modifies no variables. +;; Allows user to bail out of uninstall process. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +Function un.CloseSecondLife + Push $0 + FindWindow $0 "Alchemy" "" + IntCmp $0 0 DONE + MessageBox MB_OKCANCEL $(CloseSecondLifeUnInstMB) IDOK CLOSE IDCANCEL CANCEL_UNINSTALL + + CANCEL_UNINSTALL: + Quit + + CLOSE: + DetailPrint $(CloseSecondLifeUnInstDP) + SendMessage $0 16 0 0 + + LOOP: + FindWindow $0 "Alchemy" "" + IntCmp $0 0 DONE + Sleep 500 + Goto LOOP + + DONE: + Pop $0 + Return + +FunctionEnd + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Delete files on install if previous install exists to prevent undesired behavior +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +Function RemoveProgFilesOnInst + +# We do not remove whole pervious install folder on install, since +# there is a chance that viewer was installed into some important +# folder by intent or accident +# RMDir /r $INSTDIR is especially unsafe if user installed somewhere +# like Program Files + +# Set retry counter. All integers are strings. +Push $0 +StrCpy $0 0 + +ClearErrors + +PREINSTALL_REMOVE: + +# Remove old SecondLife.exe to invalidate any old shortcuts to it that may be in non-standard locations. See MAINT-3575 +Delete "$INSTDIR\$INSTEXE" +Delete "$INSTDIR\$VIEWER_EXE" + +# Remove old shader files first so fallbacks will work. See DEV-5663 +RMDir /r "$INSTDIR\app_settings\shaders" + +# Remove folders to clean up files removed during development +RMDir /r "$INSTDIR\app_settings" +RMDir /r "$INSTDIR\skins" +RMDir /r "$INSTDIR\vmp_icons" + +# Remove llplugin, plugins can crash or malfunction if they +# find modules from different versions +RMDir /r "$INSTDIR\llplugin" + +IntOp $0 $0 + 1 + +IfErrors 0 PREINSTALL_DONE + IntCmp $0 1 PREINSTALL_REMOVE #try again once + StrCmp $SKIP_DIALOGS "true" PREINSTALL_DONE + MessageBox MB_ABORTRETRYIGNORE $(CloseSecondLifeInstRM) IDABORT PREINSTALL_FAIL IDRETRY PREINSTALL_REMOVE + # MB_ABORTRETRYIGNORE does not accept IDIGNORE + Goto PREINSTALL_DONE + +PREINSTALL_FAIL: + Quit + +PREINSTALL_DONE: + +# We are no longer including release notes with the viewer, so remove them. +Delete "$SMPROGRAMS\$INSTSHORTCUT\SL Release Notes.lnk" +Delete "$INSTDIR\releasenotes.txt" + +Pop $0 + +FunctionEnd + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Delete files in \Users\<User>\AppData\ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +Function un.UserSettingsFiles + +# Ask if user wants to keep data files or not +MessageBox MB_YESNO|MB_ICONQUESTION $(RemoveDataFilesMB) IDYES Remove IDNO Keep + +Remove: +Push $0 +Push $1 +Push $2 + + DetailPrint "Deleting Alchemy data files" + + StrCpy $0 0 # Index number used to iterate via EnumRegKey + + LOOP: + EnumRegKey $1 SHELL_CONTEXT "${MSNTCURRVER_KEY}\ProfileList" $0 + StrCmp $1 "" DONE # No more users + + ReadRegStr $2 SHELL_CONTEXT "${MSNTCURRVER_KEY}\ProfileList\$1" "ProfileImagePath" + StrCmp $2 "" CONTINUE 0 # "ProfileImagePath" value is missing + +# Required since ProfileImagePath is of type REG_EXPAND_SZ + ExpandEnvStrings $2 $2 + +# Delete files in \Users\<User>\AppData\Roaming\AlchemyNext +# Remove all settings files but leave any other .txt files to preserve the chat logs +; RMDir /r "$2\AppData\Roaming\AlchemyNext\logs" + RMDir /r "$2\AppData\Roaming\AlchemyNext\browser_profile" + RMDir /r "$2\AppData\Roaming\AlchemyNext\user_settings" + Delete "$2\AppData\Roaming\AlchemyNext\*.xml" + Delete "$2\AppData\Roaming\AlchemyNext\*.bmp" + Delete "$2\AppData\Roaming\AlchemyNext\search_history.txt" + Delete "$2\AppData\Roaming\AlchemyNext\plugin_cookies.txt" + Delete "$2\AppData\Roaming\AlchemyNext\typed_locations.txt" +# Delete files in \Users\<User>\AppData\Local\AlchemyNext + RmDir /r "$2\AppData\Local\AlchemyNext" #Delete the cache folder + + CONTINUE: + IntOp $0 $0 + 1 + Goto LOOP + DONE: + +Pop $2 +Pop $1 +Pop $0 + +# Delete files in ProgramData\Secondlife +Push $0 + ReadRegStr $0 SHELL_CONTEXT "${MSCURRVER_KEY}\Explorer\Shell Folders" "Common AppData" + StrCmp $0 "" +2 + RMDir /r "$0\Alchemy" +Pop $0 + +Keep: + +FunctionEnd + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Delete the installed files +;; This deletes the uninstall executable, but it works because it is copied to temp directory before running +;; +;; Note: You must list all files here, because we only want to delete our files, +;; not things users left in the program directory. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +Function un.ProgramFiles + +# This placeholder is replaced by the complete list of files to uninstall by viewer_manifest.py +%%DELETE_FILES%% + +# our InstallMode.txt +Delete "$INSTDIR\InstallMode.txt" + +# Optional/obsolete files. Delete won't fail if they don't exist. +Delete "$INSTDIR\autorun.bat" +Delete "$INSTDIR\dronesettings.ini" +Delete "$INSTDIR\message_template.msg" +Delete "$INSTDIR\newview.pdb" +Delete "$INSTDIR\newview.map" +Delete "$INSTDIR\Alchemy.pdb" +Delete "$INSTDIR\Alchemy.map" +Delete "$INSTDIR\comm.dat" +Delete "$INSTDIR\*.glsl" +Delete "$INSTDIR\motions\*.lla" +Delete "$INSTDIR\trial\*.html" +Delete "$INSTDIR\newview.exe" +Delete "$INSTDIR\Alchemy.exe" + +# MAINT-3099 workaround - prevent these log files, if present, from causing a user alert +Delete "$INSTDIR\VivoxVoiceService-*.log" + +# Remove entire help directory +RMDir /r "$INSTDIR\help" + +Delete "$INSTDIR\uninst.exe" +RMDir "$INSTDIR" + +IfFileExists "$INSTDIR" FOLDERFOUND NOFOLDER + +FOLDERFOUND: + MessageBox MB_OK $(DeleteProgramFilesMB) /SD IDOK IDOK NOFOLDER + +NOFOLDER: + +MessageBox MB_YESNO $(DeleteRegistryKeysMB) IDYES DeleteKeys IDNO NoDelete + +DeleteKeys: + DeleteRegKey SHELL_CONTEXT "SOFTWARE\Classes\x-grid-location-info" + DeleteRegKey SHELL_CONTEXT "SOFTWARE\Classes\secondlife" + DeleteRegKey HKEY_CLASSES_ROOT "x-grid-location-info" + DeleteRegKey HKEY_CLASSES_ROOT "x-grid-info" + DeleteRegKey HKEY_CLASSES_ROOT "secondlife" + +NoDelete: + +FunctionEnd + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; After install completes, launch app +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +Function .onInstSuccess + Push $0 + FileOpen $0 "$INSTDIR\InstallMode.txt" w + # No newline -- this is for our use, not for users to read. + FileWrite $0 "$MultiUser.InstallMode" + FileClose $0 + Pop $0 + + Push $R0 + Push $0 + ;; MAINT-7812: Only write nsis.winstall file with /marker switch + ${GetParameters} $R0 + ${GetOptionsS} $R0 "/marker" $0 + ;; If no /marker switch, skip to ClearErrors + IfErrors +4 0 + ;; $EXEDIR is where we find the installer file + ;; Put a marker file there so VMP will know we're done + ;; and it can delete the download directory next time. + ;; http://nsis.sourceforge.net/Write_text_to_a_file + FileOpen $0 "$EXEDIR\nsis.winstall" w + FileWrite $0 "NSIS done$\n" + FileClose $0 + + ClearErrors + Pop $0 + Pop $R0 + + Call CheckWindowsServPack # Warn if not on the latest SP before asking to launch. + StrCmp $SKIP_AUTORUN "true" +2; + # Assumes SetOutPath $INSTDIR + # Run INSTEXE (our updater), passing VIEWER_EXE plus the command-line + # arguments built into our shortcuts. This gives the updater a chance + # to verify that the viewer we just installed is appropriate for the + # running system -- or, if not, to download and install a different + # viewer. For instance, if a user running 32-bit Windows installs a + # 64-bit viewer, it cannot run on this system. But since the updater + # is a 32-bit executable even in the 64-bit viewer package, the + # updater can detect the problem and adapt accordingly. + # Once everything is in order, the updater will run the specified + # viewer with the specified params. + # Quote the updater executable and the viewer executable because each + # must be a distinct command-line token, but DO NOT quote the language + # string because it must decompose into separate command-line tokens. + Exec '"$INSTDIR\$INSTEXE" precheck "$INSTDIR\$VIEWER_EXE" $SHORTCUT_LANG_PARAM' +# +FunctionEnd + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Recommend Upgrading to Service Pack 1 for Windows 7, if not present +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +Function CheckWindowsServPack + ${If} ${IsWin7} + ${AndIfNot} ${IsServicePack} 1 + MessageBox MB_OK $(CheckWindowsServPackMB) + DetailPrint $(UseLatestServPackDP) + Return + ${EndIf} + + ${If} ${IsWin2008R2} + ${AndIfNot} ${IsServicePack} 1 + MessageBox MB_OK $(CheckWindowsServPackMB) + DetailPrint $(UseLatestServPackDP) + Return + ${EndIf} + +FunctionEnd + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Clobber user files - TEST ONLY +;; This is here for testing, DO NOT USE UNLESS YOU KNOW WHAT YOU ARE TESTING FOR! +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;Function ClobberUserFilesTESTONLY + +;Push $0 +;Push $1 +;Push $2 +; +; StrCpy $0 0 # Index number used to iterate via EnumRegKey +; +; LOOP: +; EnumRegKey $1 SHELL_CONTEXT "${MSNTCURRVER_KEY}\ProfileList" $0 +; StrCmp $1 "" DONE # no more users +; +; ReadRegStr $2 SHELL_CONTEXT "${MSNTCURRVER_KEY}\ProfileList\$1" "ProfileImagePath" +; StrCmp $2 "" CONTINUE 0 # "ProfileImagePath" value is missing +; +;# Required since ProfileImagePath is of type REG_EXPAND_SZ +; ExpandEnvStrings $2 $2 +; +; RMDir /r "$2\Application Data\SecondLife\" +; +; CONTINUE: +; IntOp $0 $0 + 1 +; Goto LOOP +; DONE: +; +;Pop $2 +;Pop $1 +;Pop $0 +; +;# Copy files in Documents and Settings\All Users\SecondLife +;Push $0 +; ReadRegStr $0 SHELL_CONTEXT "${MSCURRVER_KEY}\Explorer\Shell Folders" "Common AppData" +; StrCmp $0 "" +2 +; RMDir /r "$2\Application Data\SecondLife\" +;Pop $0 +; +;FunctionEnd + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; EOF ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/indra/newview/installers/windows/lang_da.nsi b/indra/newview/installers/windows/lang_da.nsi new file mode 100644 index 0000000000000000000000000000000000000000..73f23086be22efa016f61757a0246ad56a929a6c Binary files /dev/null and b/indra/newview/installers/windows/lang_da.nsi differ diff --git a/indra/newview/installers/windows/lang_de.nsi b/indra/newview/installers/windows/lang_de.nsi new file mode 100644 index 0000000000000000000000000000000000000000..f67a09f84c6f81d44099fcfab04729e8af9e0850 --- /dev/null +++ b/indra/newview/installers/windows/lang_de.nsi @@ -0,0 +1,90 @@ +; First is default +LoadLanguageFile "${NSISDIR}\Contrib\Language files\German.nlf" + +; Language selection dialog +LangString InstallerLanguageTitle ${LANG_GERMAN} "Installationssprache" +LangString SelectInstallerLanguage ${LANG_GERMAN} "Bitte wählen Sie die Installationssprache" + +; subtitle on license text caption (setup new version or update current one +LangString LicenseSubTitleUpdate ${LANG_GERMAN} " Update" +LangString LicenseSubTitleSetup ${LANG_GERMAN} " Setup" + +LangString MULTIUSER_TEXT_INSTALLMODE_TITLE ${LANG_GERMAN} "Installationsmodus" +LangString MULTIUSER_TEXT_INSTALLMODE_SUBTITLE ${LANG_GERMAN} "Für alle Benutzer (erfordert Administratorrechte) oder nur für den aktuellen Benutzer installieren?" +LangString MULTIUSER_INNERTEXT_INSTALLMODE_TOP ${LANG_GERMAN} "Wenn Sie dieses Installationsprogram mit Administratorrechten ausführen, können Sie auswählen, ob die Installation (beispielsweise) in c:\Programme oder unter AppData\Lokaler Ordner des aktuellen Benutzers erfolgen soll." +LangString MULTIUSER_INNERTEXT_INSTALLMODE_ALLUSERS ${LANG_GERMAN} "Für alle Benutzer installieren" +LangString MULTIUSER_INNERTEXT_INSTALLMODE_CURRENTUSER ${LANG_GERMAN} "Nur für den aktuellen Benutzer installieren" + +; installation directory text +LangString DirectoryChooseTitle ${LANG_GERMAN} "Installations-Ordner" +LangString DirectoryChooseUpdate ${LANG_GERMAN} "Wählen Sie den Second Life Ordner für dieses Update:" +LangString DirectoryChooseSetup ${LANG_GERMAN} "Pfad in dem Second Life installiert werden soll:" + +LangString MUI_TEXT_DIRECTORY_TITLE ${LANG_GERMAN} "Installationsverzeichnis" +LangString MUI_TEXT_DIRECTORY_SUBTITLE ${LANG_GERMAN} "Wählen Sie das Verzeichnis aus, in dem Second Life installiert werden soll:" + +LangString MUI_TEXT_INSTALLING_TITLE ${LANG_GERMAN} "Second Life wird installiert..." +LangString MUI_TEXT_INSTALLING_SUBTITLE ${LANG_GERMAN} "Der Second Life Viewer wird im Verzeichnis $INSTDIR installiert" + +LangString MUI_TEXT_FINISH_TITLE ${LANG_GERMAN} "Second Life wird installiert" +LangString MUI_TEXT_FINISH_SUBTITLE ${LANG_GERMAN} "Der Second Life Viewer wurde im Verzeichnis $INSTDIR installiert." + +LangString MUI_TEXT_ABORT_TITLE ${LANG_GERMAN} "Installation abgebrochen" +LangString MUI_TEXT_ABORT_SUBTITLE ${LANG_GERMAN} "Der Second Life Viewer wird nicht im Verzeichnis $INSTDIR installiert." + +; CheckStartupParams message box +LangString CheckStartupParamsMB ${LANG_GERMAN} "Konnte Programm '$INSTNAME' nicht finden. Stilles Update fehlgeschlagen." + +; installation success dialog +LangString InstSuccesssQuestion ${LANG_GERMAN} "Second Life starten?" + +; remove old NSIS version +LangString RemoveOldNSISVersion ${LANG_GERMAN} "Überprüfe alte Version ..." + +; check windows version +LangString CheckWindowsVersionDP ${LANG_GERMAN} "Überprüfung der Windows Version ..." +LangString CheckWindowsVersionMB ${LANG_GERMAN} 'Second Life unterstützt nur Windows Vista.$\n$\nDer Versuch es auf Windows $R0 zu installieren, könnte zu unvorhersehbaren Abstürzen und Datenverlust führen.$\n$\nTrotzdem installieren?' +LangString CheckWindowsServPackMB ${LANG_GERMAN} "Wir empfehlen, das neueste Service Pack für Ihr Betriebssystem zu installieren, um Second Life auszuführen.$\nDies unterstützt die Leistung und Stabilität des Programms." +LangString UseLatestServPackDP ${LANG_GERMAN} "Bitte verwenden Sie Windows Update, um das neueste Service Pack zu installieren." + +; checkifadministrator function (install) +LangString CheckAdministratorInstDP ${LANG_GERMAN} "Überprüfung der Installations-Berechtigungen ..." +LangString CheckAdministratorInstMB ${LANG_GERMAN} 'Sie besitzen ungenügende Berechtigungen.$\nSie müssen ein "administrator" sein, um Second Life installieren zu können.' + +; checkifadministrator function (uninstall) +LangString CheckAdministratorUnInstDP ${LANG_GERMAN} "Überprüfung der Entfernungs-Berechtigungen ..." +LangString CheckAdministratorUnInstMB ${LANG_GERMAN} 'Sie besitzen ungenügende Berechtigungen.$\nSie müssen ein "administrator" sein, um Second Life entfernen zu können..' + +; checkifalreadycurrent +LangString CheckIfCurrentMB ${LANG_GERMAN} "Anscheinend ist Second Life ${VERSION_LONG} bereits installiert.$\n$\nWürden Sie es gerne erneut installieren?" + +; checkcpuflags +LangString MissingSSE2 ${LANG_GERMAN} "Dieses Gerät verfügt möglicherweise nicht über eine CPU mit SSE2-Unterstützung, die für Second Life ${VERSION_LONG} benötigt wird. Möchten Sie fortfahren?" + +; closesecondlife function (install) +LangString CloseSecondLifeInstDP ${LANG_GERMAN} "Warten auf die Beendigung von Second Life ..." +LangString CloseSecondLifeInstMB ${LANG_GERMAN} "Second Life kann nicht installiert oder ersetzt werden, wenn es bereits läuft.$\n$\nBeenden Sie, was Sie gerade tun und klicken Sie OK, um Second Life zu beenden.$\nKlicken Sie CANCEL, um die Installation abzubrechen." +LangString CloseSecondLifeInstRM ${LANG_GERMAN} "Second Life failed to remove some files from a previous install." + +; closesecondlife function (uninstall) +LangString CloseSecondLifeUnInstDP ${LANG_GERMAN} "Warten auf die Beendigung von Second Life ..." +LangString CloseSecondLifeUnInstMB ${LANG_GERMAN} "Second Life kann nicht entfernt werden, wenn es bereits läuft.$\n$\nBeenden Sie, was Sie gerade tun und klicken Sie OK, um Second Life zu beenden.$\nKlicken Sie CANCEL, um abzubrechen." + +; CheckNetworkConnection +LangString CheckNetworkConnectionDP ${LANG_GERMAN} "Prüfe Netzwerkverbindung..." + +; error during installation +LangString ErrorSecondLifeInstallRetry ${LANG_GERMAN} "Second Life konnte nicht korrekt installiert werden, einige Dateien wurden eventuell nicht korrekt von der Installationroutine kopiert." +LangString ErrorSecondLifeInstallSupport ${LANG_GERMAN} "Bitte laden Sie den Viewer erneut von https://secondlife.com/support/downloads/ und versuchen Sie die Installation erneut. Sollte das Problem weiterhin bestehen, dann kontaktieren Sie unseren Support unter https://support.secondlife.com." + +; ask to remove user's data files +LangString RemoveDataFilesMB ${LANG_GERMAN} "Möchten Sie alle anderen zu Second Life gehörigen Dateien ebenfalls ENTFERNEN?$\n$\nWir empfehlen, die Einstellungen und Cache-Dateien zu behalten, wenn Sie andere Versionen von Second Life installiert haben oder eine Deinstallation durchführen, um Second Life auf eine neuere Version zu aktualisieren." + +; delete program files +LangString DeleteProgramFilesMB ${LANG_GERMAN} "Es existieren weiterhin Dateien in Ihrem SecondLife Programm Ordner.$\n$\nDies sind möglicherweise Dateien, die sie modifiziert oder bewegt haben:$\n$INSTDIR$\n$\nMöchten Sie diese ebenfalls löschen?" + +; uninstall text +LangString UninstallTextMsg ${LANG_GERMAN} "Dies wird Second Life ${VERSION_LONG} von Ihrem System entfernen." + +; ask to remove registry keys that still might be needed by other viewers that are installed +LangString DeleteRegistryKeysMB ${LANG_GERMAN} "Möchten Sie die Registrierungsschlüssel der Anwendung entfernen?$\n$\nWir empfehlen, die Registrierungsschlüssel zu behalten, wenn Sie andere Versionen von Second Life installiert haben." diff --git a/indra/newview/installers/windows/lang_en-us.nsi b/indra/newview/installers/windows/lang_en-us.nsi new file mode 100644 index 0000000000000000000000000000000000000000..9d00f1b4c0c2389604174f9343cf20fccea9288f Binary files /dev/null and b/indra/newview/installers/windows/lang_en-us.nsi differ diff --git a/indra/newview/installers/windows/lang_es.nsi b/indra/newview/installers/windows/lang_es.nsi new file mode 100644 index 0000000000000000000000000000000000000000..364cc9f67e2f9aa7b05498d848d38b56ab22e429 Binary files /dev/null and b/indra/newview/installers/windows/lang_es.nsi differ diff --git a/indra/newview/installers/windows/lang_fr.nsi b/indra/newview/installers/windows/lang_fr.nsi new file mode 100644 index 0000000000000000000000000000000000000000..2f34c0c87a1552dd0632baf63dd53cc9bf1edf7b Binary files /dev/null and b/indra/newview/installers/windows/lang_fr.nsi differ diff --git a/indra/newview/installers/windows/lang_it.nsi b/indra/newview/installers/windows/lang_it.nsi new file mode 100644 index 0000000000000000000000000000000000000000..51214d3a9ce88d5a594a6ab02ea3b8f4b09af8e2 Binary files /dev/null and b/indra/newview/installers/windows/lang_it.nsi differ diff --git a/indra/newview/installers/windows/lang_ja.nsi b/indra/newview/installers/windows/lang_ja.nsi new file mode 100644 index 0000000000000000000000000000000000000000..296703d1a3e94080fe18709d1e5ac3031887cde7 Binary files /dev/null and b/indra/newview/installers/windows/lang_ja.nsi differ diff --git a/indra/newview/installers/windows/lang_pl.nsi b/indra/newview/installers/windows/lang_pl.nsi new file mode 100644 index 0000000000000000000000000000000000000000..299645bbb78010298d43366cfa5dd3299081a096 Binary files /dev/null and b/indra/newview/installers/windows/lang_pl.nsi differ diff --git a/indra/newview/installers/windows/lang_pt-br.nsi b/indra/newview/installers/windows/lang_pt-br.nsi new file mode 100644 index 0000000000000000000000000000000000000000..542c8654b5bffbe4d6f57a90c878c329ce7eb997 Binary files /dev/null and b/indra/newview/installers/windows/lang_pt-br.nsi differ diff --git a/indra/newview/installers/windows/lang_ru.nsi b/indra/newview/installers/windows/lang_ru.nsi new file mode 100644 index 0000000000000000000000000000000000000000..4e53a4957d49d2cf9b11df0b1ac0849a3101dfaa Binary files /dev/null and b/indra/newview/installers/windows/lang_ru.nsi differ diff --git a/indra/newview/installers/windows/lang_tr.nsi b/indra/newview/installers/windows/lang_tr.nsi new file mode 100644 index 0000000000000000000000000000000000000000..bae5029ad1ce56a2fd347c95de656848400c052e Binary files /dev/null and b/indra/newview/installers/windows/lang_tr.nsi differ diff --git a/indra/newview/installers/windows/lang_zh.nsi b/indra/newview/installers/windows/lang_zh.nsi new file mode 100644 index 0000000000000000000000000000000000000000..7922d9df5228d652bf08955f00c0eb62b6794965 Binary files /dev/null and b/indra/newview/installers/windows/lang_zh.nsi differ diff --git a/indra/newview/installers/windows/language_menu.nsi b/indra/newview/installers/windows/language_menu.nsi new file mode 100644 index 0000000000000000000000000000000000000000..2f426a0f47c92aac0b8e17441243802da7ab79e7 Binary files /dev/null and b/indra/newview/installers/windows/language_menu.nsi differ diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index fee3068c820c22b9ed65b872ec4cdabec1663ba6..5d5ae15901ba7bca89f9fc77480f42c017f47846 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -29,9 +29,6 @@ #include "llappviewer.h" // Viewer includes -#if LL_WINDOWS -#include "alsquirrelupdater.h" -#endif #include "llregex.h" #include "llversioninfo.h" #include "llfeaturemanager.h" @@ -1142,13 +1139,7 @@ bool LLAppViewer::init() // Skip updater if this is a non-interactive instance if (!gSavedSettings.getBOOL("CmdLineSkipUpdater") && !gNonInteractive) { -#if LL_WINDOWS - // Init updater here - if (ALUpdateHandler::isSupported()) - { - ALUpdateHandler::getInstance()->check(); - } -#endif + } else { @@ -2568,12 +2559,6 @@ bool LLAppViewer::initConfiguration() return false; } -#if LL_WINDOWS - if (ALUpdateUtils::handleCommandLineParse(clp)) - { - return false; - } -#endif // - selectively apply settings // If the user has specified a alternate settings file name. @@ -3187,7 +3172,7 @@ LLSD LLAppViewer::getViewerInfo() const LLSD info; auto& versionInfo(LLVersionInfo::instance()); info["VIEWER_VERSION"] = llsd::array(versionInfo.getMajor(), versionInfo.getMinor(), - versionInfo.getPatch()); + versionInfo.getPatch(), versionInfo.getBuild()); info["VIEWER_VERSION_STR"] = versionInfo.getVersion(); info["CHANNEL"] = versionInfo.getChannel(); info["ADDRESS_SIZE"] = ADDRESS_SIZE; diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp index 8c496e4095bd4652d908f9349ddbcdf8369d41cd..0e308123fbf817d9f5cdc3a285536cd3b2801356 100644 --- a/indra/newview/llappviewerwin32.cpp +++ b/indra/newview/llappviewerwin32.cpp @@ -745,7 +745,7 @@ void LLAppViewerWin32::initCrashReporting(bool reportFreeze) sentry_options_set_dsn(options, SENTRY_DSN); sentry_options_set_release(options, LL_VIEWER_CHANNEL_AND_VERSION); - std::string crashpad_path = gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "sentry", "crashpad_handler.exe"); + std::string crashpad_path = gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "crashpad_handler.exe"); sentry_options_set_handler_pathw(options, ll_convert_string_to_wide(crashpad_path).c_str()); std::string database_path = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "sentry"); diff --git a/indra/newview/llfloaterabout.cpp b/indra/newview/llfloaterabout.cpp index 097598af3a65fd70f57f2c8b72ad422c8c539f46..646d9a670e48f9e829b7488a68de2afa0c9a3779 100644 --- a/indra/newview/llfloaterabout.cpp +++ b/indra/newview/llfloaterabout.cpp @@ -32,9 +32,6 @@ #include "llfloaterabout.h" // Viewer includes -#if LL_WINDOWS -#include "alsquirrelupdater.h" -#endif #include "llagent.h" #include "llagentui.h" #include "llappviewer.h" @@ -359,12 +356,7 @@ void LLFloaterAbout::onClickCopyToClipboard() void LLFloaterAbout::onClickUpdateCheck() { -#if LL_WINDOWS - if (ALUpdateHandler::isSupported()) - { - ALUpdateHandler::getInstance()->check(); - } -#endif + } void LLFloaterAbout::setSupportText(const std::string& server_release_notes_url) diff --git a/indra/newview/llversioninfo.cpp b/indra/newview/llversioninfo.cpp index c9e8e9b5c9755dc5dd94363d06bdf94bae450566..4c8c73fa188089b0a013f791f5cdeaf53421b6c0 100644 --- a/indra/newview/llversioninfo.cpp +++ b/indra/newview/llversioninfo.cpp @@ -35,7 +35,8 @@ #if ! defined(LL_VIEWER_CHANNEL) \ || ! defined(LL_VIEWER_VERSION_MAJOR) \ || ! defined(LL_VIEWER_VERSION_MINOR) \ - || ! defined(LL_VIEWER_VERSION_PATCH) + || ! defined(LL_VIEWER_VERSION_PATCH) \ + || ! defined(LL_VIEWER_VERSION_BUILD) #error "Channel or Version information is undefined" #endif @@ -93,7 +94,7 @@ S32 LLVersionInfo::getPatch() S32 LLVersionInfo::getBuild() { - return 0; + return LL_VIEWER_VERSION_BUILD; } const std::string& LLVersionInfo::getVersion() @@ -111,7 +112,7 @@ const std::string& LLVersionInfo::getChannelAndVersion() if (mVersionChannel.empty()) { // cache the version string - mVersionChannel = getChannel() + " " + getShortVersion(); + mVersionChannel = getChannel() + " " + getVersion(); } return mVersionChannel; diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index 2f76239c48d9cf9ac2de3e3a51b241486933e59e..40a86cc667d651b0838631f97644f22241f1dbe3 100644 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -964,7 +964,7 @@ bool LLVivoxVoiceClient::startAndLaunchDaemon() #if LL_WINDOWS // On windows use exe (not work or RO) directory std::string exe_path = gDirUtilp->getExecutableDir(); - gDirUtilp->append(exe_path, "voice", "SLVoice.exe"); + gDirUtilp->append(exe_path, "SLVoice.exe"); #elif LL_DARWIN // On MAC use resource directory std::string exe_path = gDirUtilp->getAppRODataDir(); diff --git a/indra/newview/res/viewerRes.rc b/indra/newview/res/viewerRes.rc index 09a518d28b6c68a4358d524770abeaa1c075a73d..5f4234c1bc8f41486bd2c0822672addba75e23c3 100755 --- a/indra/newview/res/viewerRes.rc +++ b/indra/newview/res/viewerRes.rc @@ -135,8 +135,8 @@ TOOLNO CURSOR "llno.cur" // VS_VERSION_INFO VERSIONINFO - FILEVERSION ${VIEWER_VERSION_MAJOR},${VIEWER_VERSION_MINOR},${VIEWER_VERSION_PATCH},0 - PRODUCTVERSION ${VIEWER_VERSION_MAJOR},${VIEWER_VERSION_MINOR},${VIEWER_VERSION_PATCH},0 + FILEVERSION ${VIEWER_VERSION_MAJOR},${VIEWER_VERSION_MINOR},${VIEWER_VERSION_PATCH},${VIEWER_VERSION_REVISION} + PRODUCTVERSION ${VIEWER_VERSION_MAJOR},${VIEWER_VERSION_MINOR},${VIEWER_VERSION_PATCH},${VIEWER_VERSION_REVISION} FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -153,13 +153,12 @@ BEGIN BEGIN VALUE "CompanyName", "Alchemy Development Group" VALUE "FileDescription", "${WIN_PRODUCT_NAME}" - VALUE "FileVersion", "${VIEWER_VERSION_MAJOR}.${VIEWER_VERSION_MINOR}.${VIEWER_VERSION_PATCH}" + VALUE "FileVersion", "${VIEWER_VERSION_MAJOR}.${VIEWER_VERSION_MINOR}.${VIEWER_VERSION_PATCH}.${VIEWER_VERSION_REVISION}" VALUE "InternalName", "${WIN_BINARY_NAME}" VALUE "LegalCopyright", "Copyright (C) 2013-2023 Alchemy Development Group" VALUE "OriginalFilename", "${WIN_BINARY_NAME}.exe" VALUE "ProductName", "${WIN_PRODUCT_NAME}" - VALUE "ProductVersion", "${VIEWER_VERSION_MAJOR}.${VIEWER_VERSION_MINOR}.${VIEWER_VERSION_PATCH}" - VALUE "SquirrelAwareVersion", "1" + VALUE "ProductVersion", "${VIEWER_VERSION_MAJOR}.${VIEWER_VERSION_MINOR}.${VIEWER_VERSION_PATCH}.${VIEWER_VERSION_REVISION}" END END BLOCK "VarFileInfo" diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 3536bdd55222e0aca6d5067913a13cb03aa6433e..662764fded7d7381e37c66159f126f0bcd20b488 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -12903,62 +12903,4 @@ Would you like to reset the graphic preferences? canceltext="Never reset"/> </notification> - <notification - icon="alertmodal.tga" - name="UpdateDownloadRequest" - type="alertmodal"> -A new version has been detected. -Would you like to download and install [VIEWER_VER] with following updates now? - -[VIEWER_UPDATES] - <tag>confirm</tag> - <usetemplate - name="okcancelbuttons" - notext="Remind Me Later" - yestext="Ok"/> - </notification> - - <notification - icon="alertmodal.tga" - name="UpdateDownloaded" - type="alertmodal"> -[VIEWER_VER] has been downloaded. -Would you like to install [VIEWER_VER] for following updates now? - -[VIEWER_UPDATES] - <tag>confirm</tag> - <usetemplate - name="okcancelbuttons" - notext="Remind Me Later" - yestext="Ok"/> - </notification> - - <notification - icon="alertmodal.tga" - name="UpdateInstalledRestart" - type="alertmodal"> -Your viewer has been updated to the following version: -[VIEWER_VER] => [VIEWER_UPDATES] - -Would you like to restart now? - <tag>confirm</tag> - <usetemplate - name="okcancelbuttons" - notext="Remind Me Later" - yestext="Ok"/> - </notification> - <notification - icon="notify.tga" - name="UpdateInstalledRestartToast" - type="notify"> -Your viewer has been updated to the following version: -[VIEWER_VER] => [VIEWER_UPDATES] - -Would you like to restart now? - <tag>confirm</tag> - <usetemplate - name="okcancelbuttons" - notext="Remind Me Later" - yestext="Ok"/> - </notification> </notifications> diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index 51853edc362189eda7b46ace718b5009f0b531a6..470036ee1bad6d84b433d9e901a665480de035a2 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -35,7 +35,7 @@ <!-- about dialog/support string--> <string name="AboutHeader"> -[CHANNEL] [VIEWER_VERSION_0].[VIEWER_VERSION_1].[VIEWER_VERSION_2] ([ADDRESS_SIZE]bit) +[CHANNEL] [VIEWER_VERSION_0].[VIEWER_VERSION_1].[VIEWER_VERSION_2].[VIEWER_VERSION_3] ([ADDRESS_SIZE]bit) [[VIEWER_RELEASE_NOTES_URL] [ReleaseNotes]] </string> <string name="AboutCompiler">Compiler Version: [COMPILER] [COMPILER_VERSION]</string> diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index f74a901b63ae2a6d509ae7bd8462b256257412a2..47dad6cacf212d67e4a976ea59bd4b84dfb45190 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -443,11 +443,14 @@ def construct(self): relpkgdir = os.path.join(pkgdir, "lib", "release") debpkgdir = os.path.join(pkgdir, "lib", "debug") + if self.is_packaging_viewer(): + # Find alchemy-bin.exe in the 'configuration' dir, then rename it to the result of final_exe. + self.path(src='%s/alchemy-bin.exe' % self.args['configuration'], dst=self.final_exe()) + # Plugin host application - with self.prefix(dst="llplugin"): - self.path2basename(os.path.join(os.pardir, - 'llplugin', 'slplugin', self.args['configuration']), - "slplugin.exe") + self.path2basename(os.path.join(os.pardir, + 'llplugin', 'slplugin', self.args['configuration']), + "slplugin.exe") # Get shared libs from the shared libs staging directory with self.prefix(src=os.path.join(self.args['build'], os.pardir, @@ -469,22 +472,21 @@ def construct(self): self.path(src="fmod.dll", dst="fmod.dll") # SLVoice executable - with self.prefix(dst="voice"): - with self.prefix(src=os.path.join(pkgdir, 'bin', 'release')): - self.path("SLVoice.exe") + with self.prefix(src=os.path.join(pkgdir, 'bin', 'release')): + self.path("SLVoice.exe") - # Vivox libraries - if (self.address_size == 64): - self.path("vivoxsdk_x64.dll") - self.path("ortp_x64.dll") - else: - self.path("vivoxsdk.dll") - self.path("ortp.dll") + # Vivox libraries + if (self.address_size == 64): + self.path("vivoxsdk_x64.dll") + self.path("ortp_x64.dll") + else: + self.path("vivoxsdk.dll") + self.path("ortp.dll") # Sentry if self.args['sentry'] == 'ON' or self.args['sentry'] == 'TRUE': self.path("sentry.dll") - with self.prefix(src=os.path.join(pkgdir, 'bin', 'release'), dst="sentry"): + with self.prefix(src=os.path.join(pkgdir, 'bin', 'release')): self.path("crashpad_handler.exe") if self.args['discord'] == 'ON' or self.args['discord'] == 'TRUE': @@ -598,58 +600,142 @@ def construct(self): if not self.is_packaging_viewer(): self.package_file = "copied_deps" - def package_finish(self): - nuget_exe = os.path.join(self.args['build'], os.pardir, 'packages', 'squirrel', 'nuget.exe') - self.run_command( - [nuget_exe, - 'pack', - '-Properties', 'NoWarn=NU5128', - os.path.join(self.args['build'], 'viewer.nuspec')]) - - #Build installer and update delta - squirrel_exe = os.path.join(self.args['build'], os.pardir, 'packages', 'squirrel', 'Squirrel.exe') - - # Download previous build for delta generation - temp_installdir = os.path.join(self.args['build'], 'Installer') - self.cmakedirs(temp_installdir) - if 'gendelta' in self.args and 'updateurl' in self.args: - if (self.address_size == 64): - updater_arch = 'x64' + def nsi_file_commands(self, install=True): + def wpath(path): + if path.endswith('/') or path.endswith(os.path.sep): + path = path[:-1] + path = path.replace('/', '\\') + return path + + result = "" + dest_files = [pair[1] for pair in self.file_list if pair[0] and os.path.isfile(pair[1])] + # sort deepest hierarchy first + dest_files.sort(key=lambda f: (f.count(os.path.sep), f), reverse=True) + out_path = None + for pkg_file in dest_files: + rel_file = os.path.normpath(pkg_file.replace(self.get_dst_prefix()+os.path.sep,'')) + installed_dir = wpath(os.path.join('$INSTDIR', os.path.dirname(rel_file))) + pkg_file = wpath(os.path.normpath(pkg_file)) + if installed_dir != out_path: + if install: + out_path = installed_dir + result += 'SetOutPath ' + out_path + '\n' + if install: + result += 'File ' + pkg_file + '\n' else: - updater_arch = 'x86' + result += 'Delete ' + wpath(os.path.join('$INSTDIR', rel_file)) + '\n' + + # at the end of a delete, just rmdir all the directories + if not install: + deleted_file_dirs = [os.path.dirname(pair[1].replace(self.get_dst_prefix()+os.path.sep,'')) for pair in self.file_list] + # find all ancestors so that we don't skip any dirs that happened to have no non-dir children + deleted_dirs = [] + for d in deleted_file_dirs: + deleted_dirs.extend(path_ancestors(d)) + # sort deepest hierarchy first + deleted_dirs.sort(key=lambda f: (f.count(os.path.sep), f), reverse=True) + prev = None + for d in deleted_dirs: + if d != prev: # skip duplicates + result += 'RMDir ' + wpath(os.path.join('$INSTDIR', os.path.normpath(d))) + '\n' + prev = d + + return result - try: - self.run_command( - [squirrel_exe, - 'http-down', - '--releaseDir', temp_installdir, - '--url', '{}/{}/win-{}/'.format(self.args['updateurl'], self.app_name_oneword(), updater_arch)]) - except (ManifestError, MissingError) as err: - pass + def package_finish(self): + # a standard map of strings for replacing in the templates + substitution_strings = { + 'version' : '.'.join(self.args['version']), + 'version_short' : '.'.join(self.args['version'][:-1]), + 'version_dashes' : '-'.join(self.args['version']), + 'version_registry' : '%s(%s)' % + ('.'.join(self.args['version']), self.address_size), + 'final_exe' : self.final_exe(), + 'flags':'', + 'app_name':self.app_name(), + 'app_name_oneword':self.app_name_oneword() + } - # Build installer files - temp_nupkg = os.path.join(self.args['build'], '{}.{}.nupkg'.format(self.app_name_oneword(), '.'.join(self.args['version']))) - self.run_command( - [squirrel_exe, - 'releasify', - '--releaseDir', temp_installdir, - '--framework', 'vcredist143-x64', - '--icon', os.path.join(self.args['source'], 'installers', 'windows', 'install_icon.ico'), - '--splashImage', os.path.join(self.args['source'], 'installers', 'windows', 'install_splash.gif'), - '--package', temp_nupkg]) - - # Copy to final installer destination installer_file = self.installer_base_name() + '_Setup.exe' - with self.prefix(src=temp_installdir, dst=os.path.join(self.args['build'], 'Deploy')): # everything goes in Contents - self.path(src=self.app_name_oneword() + 'Setup.exe', dst=installer_file) - self.path('{}-{}-*.nupkg'.format(self.app_name_oneword(), '.'.join(self.args['version']))) - self.path('RELEASES') - - # Clean up temporary files - os.remove(temp_nupkg) - shutil.rmtree(temp_installdir, True) + substitution_strings['installer_file'] = installer_file + + version_vars = """ + !define INSTEXE "SLVersionChecker.exe" + !define VERSION "%(version_short)s" + !define VERSION_LONG "%(version)s" + !define VERSION_DASHES "%(version_dashes)s" + !define VERSION_REGISTRY "%(version_registry)s" + !define VIEWER_EXE "%(final_exe)s" + """ % substitution_strings + + if self.channel_type() == 'release': + substitution_strings['caption'] = CHANNEL_VENDOR_BASE + else: + substitution_strings['caption'] = self.app_name() + ' ${VERSION}' + + inst_vars_template = """ + OutFile "%(installer_file)s" + !define INSTNAME "%(app_name_oneword)s" + !define SHORTCUT "%(app_name)s" + !define URLNAME "secondlife" + Caption "%(caption)s" + """ + + if(self.address_size == 64): + engage_registry="SetRegView 64" + program_files="!define MULTIUSER_USE_PROGRAMFILES64" + else: + engage_registry="SetRegView 32" + program_files="" + + tempfile = "alchemy_setup_tmp.nsi" + # the following replaces strings in the nsi template + # it also does python-style % substitution + self.replace_in("installers/windows/installer_template.nsi", tempfile, { + "%%VERSION%%":version_vars, + "%%SOURCE%%":self.get_src_prefix(), + "%%INST_VARS%%":inst_vars_template % substitution_strings, + "%%INSTALL_FILES%%":self.nsi_file_commands(True), + "%%PROGRAMFILES%%":program_files, + "%%ENGAGEREGISTRY%%":engage_registry, + "%%DELETE_FILES%%":self.nsi_file_commands(False)}) + + # If we're on a build machine, sign the code using our Authenticode certificate. JC + # note that the enclosing setup exe is signed later, after the makensis makes it. + # Unlike the viewer binary, the VMP filenames are invariant with respect to version, os, etc. + for exe in ( + self.final_exe(), + "SLVersionChecker.exe", + "llplugin/dullahan_host.exe", + ): + self.sign(exe) + + # Check two paths, one for Program Files, and one for Program Files (x86). + # Yay 64bit windows. + for ProgramFiles in 'ProgramFiles', 'ProgramFiles(x86)': + NSIS_path = os.path.expandvars(r'${%s}\NSIS\makensis.exe' % ProgramFiles) + if os.path.exists(NSIS_path): + break + installer_created=False + nsis_attempts=3 + nsis_retry_wait=15 + for attempt in range(nsis_attempts): + try: + self.run_command([NSIS_path, '/V2', self.dst_path_of(tempfile)]) + except ManifestError as err: + if attempt+1 < nsis_attempts: + print("nsis failed, waiting %d seconds before retrying" % nsis_retry_wait, file=sys.stderr) + time.sleep(nsis_retry_wait) + nsis_retry_wait*=2 + else: + # NSIS worked! Done! + break + else: + print("Maximum nsis attempts exceeded; giving up", file=sys.stderr) + raise - self.created_path(os.path.join(self.args['build'], 'Deploy', installer_file)) + self.sign(installer_file) + self.created_path(self.dst_path_of(installer_file)) self.package_file = installer_file def sign(self, exe):