【问题标题】:How to check the software installed folder and do the silent update in same path in NSIS如何检查软件安装文件夹并在 NSIS 的同一路径中进行静默更新
【发布时间】:2018-05-16 00:19:13
【问题描述】:

我们有 .Net WPF 应用程序,当更新可用 NSIS 时,它会自行更新。但是现在 NSIS 直接在 ProgramFiles 中安装软件,即使该软件已经安装在其他路径中。 如何让它安装在与以前版本相同的路径中。

    ; Script generated by the HM NIS Edit Script Wizard.

; http://nsis.sourceforge.net/NsProcess_plugin is needed now for killing the client process!

RequestExecutionLevel admin
!define MULTIUSER_EXECUTIONLEVEL Admin
;!define MULTIUSER_NOUNINSTALL ;Uncomment if no uninstaller is created
!include MultiUser.nsh

!ifndef BUILD_TARGET
    !define BUILD_TARGET "Release"
!endif

; HM NIS Edit Wizard helper defines
!ifndef PRODUCT_VERSION
  !define PRODUCT_VERSION "0.0.0.0"
!endif

!define PRODUCT_PUBLISHER "MYcompany"
!define PRODUCT_DIR_REGKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\MyApp.exe"
!define RUN_REG_KEY "SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Run"
!define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}"
!define PRODUCT_UNINST_ROOT_KEY "HKLM"
;BUILD_DIR has to be in relation to the .nsi file

!define BUILD_DIR "..\..\Bin\${BUILD_TARGET}"

!if ${BUILD_TARGET} == "Debug"
!define PRODUCT_NAME "MyApp  2.0 Debug"
!define PRODUCT_WEB_SITE "https://127.0.0.1:3000/"
!define MUI_ICON "..\MyApp\Resources\Icons\IconRed.ico"
!endif

!if ${BUILD_TARGET} == "ReleaseTest"
!define PRODUCT_NAME "MyApp  2.0 Staging"
!define PRODUCT_WEB_SITE "www.ggle.com"
!define MUI_ICON "..\MyApp\Resources\Icons\IconBlue.ico"
!endif

!if ${BUILD_TARGET} == "Release"
!define PRODUCT_NAME "MyApp  2.0"
!define PRODUCT_WEB_SITE "www.gole.com"
!define MUI_ICON "..\MyApp\Resources\Icons\IconBlack.ico"
!endif


!include "MUI2.nsh"

; 64 bit support
!include x64.nsh

; MUI Settings
!define MUI_ABORTWARNING

!define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\modern-uninstall.ico"
!define MUI_WELCOMEFINISHPAGE_BITMAP "..\MyApp\Resources\Icons\installer.bmp"
!define MUI_UNWELCOMEFINISHPAGE_BITMAP "..\MyApp\Resources\Icons\installer.bmp"

; Welcome page
!insertmacro MUI_PAGE_WELCOME
;Custom page
Page custom DirectoryLeave 
; Directory page
!insertmacro MUI_PAGE_DIRECTORY
; Instfiles page
!insertmacro MUI_PAGE_INSTFILES
; Finish page
; Use the SHOWREADME for creating Desktop shortcut
;Function createDesktopShortcut
 ; CreateShortCut "$DESKTOP\${PRODUCT_NAME}.lnk" "$INSTDIR\MyApp.exe" "-shortcut"
;FunctionEnd

Function DirectoryLeave
  MessageBox MB_OK|MB_ICONEXCLAMATION "MY App requires a large amount of space for storing builds. Please install MyApp Mate on a drive that has a large amount of space free."  IDOK yes 
  yes: Abort
FunctionEnd

;!define MUI_FINISHPAGE_SHOWREADME ""
;!define MUI_FINISHPAGE_SHOWREADME_NOTCHECKED
;!define MUI_FINISHPAGE_SHOWREADME_TEXT "Create Desktop Shortcut"
;!define MUI_FINISHPAGE_SHOWREADME_FUNCTION createDesktopShortcut

!define MUI_FINISHPAGE_RUN "$INSTDIR\MyApp.exe"

!insertmacro MUI_PAGE_FINISH

; Uninstaller pages
!define MUI_PAGE_CUSTOMFUNCTION_SHOW un.ModifyUnWelcome
!define MUI_PAGE_CUSTOMFUNCTION_LEAVE un.LeaveUnWelcome
!insertmacro MUI_UNPAGE_WELCOME
!insertmacro MUI_UNPAGE_INSTFILES

; Language files
!insertmacro MUI_LANGUAGE "English"

; MUI end ------
Name "${PRODUCT_NAME}"
OutFile "MyAppSetup.exe"
VIProductVersion ${PRODUCT_VERSION}

VIAddVersionKey ProductName "${PRODUCT_NAME} Installer"
VIAddVersionKey CompanyName "${PRODUCT_PUBLISHER}"
VIAddVersionKey LegalCopyright "MyCompany 2018"
VIAddVersionKey FileDescription "Installs ${PRODUCT_NAME}"
VIAddVersionKey FileVersion ${PRODUCT_VERSION}
VIAddVersionKey ProductVersion ${PRODUCT_VERSION}
VIAddVersionKey OriginalFilename "MyAppSetup.exe"

InstallDir "$PROGRAMFILES\${PRODUCT_NAME}"
InstallDirRegKey HKLM "${PRODUCT_DIR_REGKEY}" ""
ShowInstDetails show
ShowUnInstDetails show

Function .onInit
  !insertmacro MULTIUSER_INIT
  ReadRegStr $R0 HKLM "${PRODUCT_UNINST_KEY}" "QuietUninstallString"
  StrCmp $R0 "" done uninst


  ;Run the uninstaller
  uninst:
  ClearErrors
  Exec '$R0' ; instead of the ExecWait line

  done:
  ${If} ${RunningX64}
    ; disable registry redirection (enable access to 64-bit portion of registry)
    SetRegView 64
    ; change install dir 
    StrCpy $INSTDIR "$PROGRAMFILES64\${PRODUCT_NAME}"
  ${Else}
    MessageBox MB_OK "${PRODUCT_NAME} needs 64bit Windows!"
    Abort
  ${EndIf}
FunctionEnd

Function .onInstSuccess
  RMDir /r "$LOCALAPPDATA\${PRODUCT_NAME}"

  IfSilent startlauncher finished
  startlauncher:
    Exec '"$INSTDIR\MyApp.exe"'
  finished:
FunctionEnd

Section "MainSection" SEC01
  Call EnsureNotRunning



  Delete "$INSTDIR\INIFileParser.dll"
  Delete "$INSTDIR\log4net.config"
  Delete "$INSTDIR\log4net.dll"
  Delete "$INSTDIR\log4net.xml"
  Delete "$INSTDIR\Newtonsoft.Json.dll"
  Delete "$INSTDIR\Newtonsoft.Json.xml"
  Delete "$INSTDIR\MyApp.Core.dll"
  Delete "$INSTDIR\MyApp.Core.dll.config"
  Delete "$INSTDIR\MyApp.exe"
  Delete "$INSTDIR\MyApp.exe.config"
  Delete "$INSTDIR\SocketIoClientDotNet.dll"
  Delete "$INSTDIR\WebSocket4Net.dll"
  Delete "$INSTDIR\uninstall.exe"
  Delete "$INSTDIR\Show log files.lnk"
  Delete "$INSTDIR\${PRODUCT_NAME}.lnk"


  SetOutPath "$INSTDIR"
  SetOverwrite on
  File "${BUILD_DIR}\EngineIoClientDotNet.dll"
  File "${BUILD_DIR}\INIFileParser.dll"
  File "${BUILD_DIR}\log4net.config"
  File "${BUILD_DIR}\log4net.dll"
  File "${BUILD_DIR}\log4net.xml"
  File "${BUILD_DIR}\Newtonsoft.Json.dll"
  File "${BUILD_DIR}\Newtonsoft.Json.xml"
  File "${BUILD_DIR}\MyApp.Core.dll"
  File "${BUILD_DIR}\MyApp.Core.dll.config"
  File "${BUILD_DIR}\MyApp.exe"
  File "${BUILD_DIR}\MyApp.exe.config"
  File "${BUILD_DIR}\SocketIoClientDotNet.dll"
  File "${BUILD_DIR}\WebSocket4Net.dll"

  SetOverwrite on
  CreateShortCut "$DESKTOP\${PRODUCT_NAME}.lnk" "$INSTDIR\MyApp.exe" "-shortcut"
  CreateDirectory "$SMPROGRAMS\${PRODUCT_NAME}"
  CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\${PRODUCT_NAME}.lnk" "$INSTDIR\MyApp.exe" "-shortcut"

  CreateShortCut "$INSTDIR\Show log files.lnk" "$WINDIR\explorer.exe" "%USERPROFILE%\Documents\MyApp" "$WINDIR\system32\imageres.dll" 172
SectionEnd

Section -AdditionalIcons
  WriteIniStr "$INSTDIR\${PRODUCT_NAME}.URL" "InternetShortcut" "URL" "${PRODUCT_WEB_SITE}"
  CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\Website.lnk" "$INSTDIR\${PRODUCT_NAME}.url"
  CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\Uninstall.lnk" "$INSTDIR\uninstall.exe"
SectionEnd

Section -Post
  WriteUninstaller "$INSTDIR\uninstall.exe"
  WriteRegStr HKLM "${PRODUCT_UNINST_KEY}" "DisplayName" "$(^Name)"
  WriteRegStr HKLM "${PRODUCT_UNINST_KEY}" "UninstallString" "$\"$INSTDIR\uninstall.exe$\""
  WriteRegStr HKLM "${PRODUCT_UNINST_KEY}" "QuietUninstallString" "$\"$INSTDIR\uninstall.exe$\" /S"
  WriteRegStr HKLM "${PRODUCT_UNINST_KEY}" "InstallLocation" "$INSTDIR"
  WriteRegStr HKLM "${PRODUCT_UNINST_KEY}" "DisplayIcon" "$INSTDIR\MyApp.exe"
  WriteRegStr HKLM "${PRODUCT_UNINST_KEY}" "DisplayVersion" "${PRODUCT_VERSION}"
  WriteRegStr HKLM "${PRODUCT_UNINST_KEY}" "Publisher" "${PRODUCT_PUBLISHER}"

    ; estimated size
  ${GetSize} "$INSTDIR" "/S=0K" $0 $1 $2
  IntFmt $0 "0x%08X" $0
  WriteRegDWORD HKLM "${PRODUCT_UNINST_KEY}" "EstimatedSize" "$0"

  WriteRegDWORD HKLM "${PRODUCT_UNINST_KEY}" "VersionMajor" 2
  WriteRegDWORD HKLM "${PRODUCT_UNINST_KEY}" "VersionMinor" 0



  ; Runs on Windows start-up
  WriteRegStr HKLM "${RUN_REG_KEY}" "MyApp" "$INSTDIR\MyApp.exe"
SectionEnd


!macro NOTRUNNINGMACRO un
Function ${un}EnsureNotRunning
  ${DisableX64FSRedirection}
  SetOutPath "$INSTDIR"
  nsExec::ExecToStack 'Powershell.exe -inputformat none -noprofile "(get-process -name MyApp).Kill()"'

  nsExec::ExecToStack 'Powershell.exe -inputformat none -noprofile "net share ayapp /delete"'

  ${EnableX64FSRedirection}

  Sleep 500
  performCheck:
  System::Call 'kernel32::OpenMutex(i 0x100000, b 0, t "Global\{${BUILD_TARGET} }") i .R0'
  IntCmp $R0 0 backupCheck isRunning isRunning
  backupCheck:
  System::Call 'kernel32::OpenMutex(i 0x100000, b 0, t "Global\{0}") i .R0'
  IntCmp $R0 0 notRunning isRunning isRunning
  isRunning:
  System::Call 'kernel32::CloseHandle(i $R0)'
  MessageBox MB_OKCANCEL|MB_ICONEXCLAMATION "${PRODUCT_NAME} is running. Please close it first" /SD IDCANCEL IDOK performCheck
  Abort
  notRunning:
FunctionEnd
!macroend

!insertmacro NOTRUNNINGMACRO ""
!insertmacro NOTRUNNINGMACRO "un."

Function un.onUninstSuccess
  HideWindow
  IfSilent finished
    MessageBox MB_ICONINFORMATION|MB_OK "${PRODUCT_NAME} was successfully removed from your computer."
  finished:
FunctionEnd

Function un.onInit
  !insertmacro MULTIUSER_UNINIT
FunctionEnd

Var keepUserSettingsCheckbox
Var keepUserSettingsBool

Function un.ModifyUnWelcome
${NSD_CreateCheckbox} 120u -18u 50% 12u "Remove user settings"
Pop $keepUserSettingsCheckbox
SetCtlColors $keepUserSettingsCheckbox "" ${MUI_BGCOLOR}
${NSD_Check} $keepUserSettingsCheckbox ; Check it by default
FunctionEnd

Function un.LeaveUnWelcome
${NSD_GetState} $keepUserSettingsCheckbox $0
${If} $0 <> 0
    StrCpy $keepUserSettingsBool "True"
${Else}
    StrCpy $keepUserSettingsBool "False"
${EndIf}
FunctionEnd

Function un.GetMyDocs
  ReadRegStr $0 HKCU \
             "SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders" \
             Personal
FunctionEnd

Section Uninstall
  Call un.EnsureNotRunning

  Delete "$INSTDIR\INIFileParser.dll"
  Delete "$INSTDIR\log4net.config"
  Delete "$INSTDIR\log4net.dll"
  Delete "$INSTDIR\log4net.xml"
  Delete "$INSTDIR\Newtonsoft.Json.dll"
  Delete "$INSTDIR\Newtonsoft.Json.xml"
  Delete "$INSTDIR\MyApp.Core.dll"
  Delete "$INSTDIR\MyApp.Core.dll.config"
  Delete "$INSTDIR\MyApp.exe"
  Delete "$INSTDIR\MyApp.exe.config"
  Delete "$INSTDIR\SocketIoClientDotNet.dll"
  Delete "$INSTDIR\WebSocket4Net.dll"
  Delete "$INSTDIR\uninstall.exe"
  Delete "$INSTDIR\Show log files.lnk"


  Delete "$INSTDIR\${PRODUCT_NAME}.lnk"
  Delete "$SMPROGRAMS\${PRODUCT_NAME}\*.*"
  RMDir /r "$SMPROGRAMS\${PRODUCT_NAME}"

  StrCmp $keepUserSettingsBool "True" 0 +11
  Delete "$LOCALAPPDATA\${PRODUCT_NAME}\*.*"
  RMDir /r "$LOCALAPPDATA\${PRODUCT_NAME}"

  Call un.GetMyDocs
  RMDir /r "$0\${PRODUCT_NAME}"

  Delete "$DESKTOP\${PRODUCT_NAME}.lnk"

  DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}"
  DeleteRegKey HKLM "${PRODUCT_DIR_REGKEY}"
  DeleteRegValue HKLM "Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Run" "${PRODUCT_NAME}"
  SetAutoClose true
SectionEnd

【问题讨论】:

  • 发布没有相关包含和定义的代码不是很有帮助!
  • @Anders 编辑了代码,你现在可以检查一下吗,

标签: c# wpf nsis


【解决方案1】:

InstallDirRegKey 将在调用.onInit 之前从指定的注册表值读取并使用读取路径(覆盖InstallDir 属性)初始化$InstDir,但您必须自己将此注册表值写入您的@ 之一987654325@s.

你还没有发布你所有的代码,所以很难说到底发生了什么,但你似乎出于某种原因在使用 MultiUser,它有自己的定义,你需要设置:MULTIUSER_INSTALLMODE_INSTDIRMULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_KEYMULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_VALUENAME.

Section
!ifdef MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_KEY & MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_VALUENAME
  ${If} $MultiUser.InstallMode == CurrentUser
    WriteRegStr HKCU "${MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_KEY}" "${MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_VALUENAME}" "$InstDir"
  ${Else}
    WriteRegStr HKLM "${MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_KEY}" "${MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_VALUENAME}" "$InstDir"
  ${EndIf}
!else
  WriteRegStr HK?? Software\?? ?? "$InstDir" ; Must match key used in InstallDirRegKey
!endif
SectionEnd

【讨论】:

  • 我已经更新了我的代码,请您现在检查一下并告诉我如何继续。
  • 您没有在您的部分中写入注册表值
  • 我不知道这个 NSIS 脚本,我正在研究 ASP.NET MVC,作为我时间的一部分,他们有这个 WPF 应用程序,基本上这是由其他人编写的,所以不确定是什么正在这个脚本中发生,所以请你帮我在哪里以及如何写这些东西。提前致谢
  • 您只需要在您的某个部分中添加WriteRegStr HKLM "${PRODUCT_DIR_REGKEY}" "" $InstDir 指令。当您使用 MultiUser.nsh 时,您应该使用它的定义,但我不知道如何进一步解释这一点。
  • 我已经按照你说的添加了,但它只安装 Programfiles\MyApp 路径而不是 E://MyApp 路径。
猜你喜欢
  • 1970-01-01
  • 2012-05-13
  • 2013-05-25
  • 1970-01-01
  • 1970-01-01
  • 2011-02-05
  • 2021-01-01
  • 1970-01-01
  • 2012-01-23
相关资源
最近更新 更多