2011-05-05 824 views
1

我试图建立一个NSIS安装,将做到以下几点:NSIS静默安装(通过代码开始)

1当normaly运行它会与通常的选择一个安装程序安装的应用程序。

2当安装程序使用/ S开关运行时,会静默安装,如果显示UI,则可以。但它应该是自动的。

在我看来,安装程序“工作”,因为它运行,然后再次正确启动应用程序。但它没有更新任何内容,它几乎就像运行,但不复制任何文件。

当它是一种无声的安装,它是由下面的代码开始(应用程序更新本身)

ProcessStartInfo Pro = new ProcessStartInfo(); 
    Pro.Verb = "runas"; 
    Pro.UseShellExecute = true; 
    Pro.FileName = gDownloadedFileName; 
    Pro.Arguments = "/S"; 
    Pro.WindowStyle = ProcessWindowStyle.Normal; 
    Pro.CreateNoWindow = true; 

NSIS脚本主(我可以张贴NSIS是定制的,如果脂肪酶的愿望的支持脚本)

; example2.nsi 
; 
; This script is based on example1.nsi, but it remember the directory, 
; has uninstall support and (optionally) installs start menu shortcuts. 
; 
; It will install example2.nsi into a directory that the user selects, 
!include MUI.nsh 
!include fileassoc.nsh 
!include Silent.nsh 


!define _AppName "My application" 
!define _AppExe "My application.exe" 
!define _AppVersion "1.0.0.0" 

;--------------------------------------------------------------------- Dont edit beloow 

; The name of the installer 
Name "${_AppName}" 

; The file to write 
OutFile "DFOInfo_Setup_beta.exe" 

; The default installation directory 
InstallDir "$PROGRAMFILES\${_AppName}" 

; Registry key to check for directory (so if you install again, it will 
; overwrite the old one automatically) 
InstallDirRegKey HKLM "Software\TheXSoft.com\${_AppName}" "Install_Dir" 

RequestExecutionLevel admin 

Function .onInit 
    Call GetDotNet 

    Call IsSilent 
    Pop $0 
    StrCmp $0 1 0 +3 
    Call SilentInstall 

FunctionEnd 

Function GetDotNet 
    IfFileExists "$WINDIR\Microsoft.NET\Framework\v4.0.30319\installUtil.exe" NextStep 
    MessageBox MB_OK|MB_ICONEXCLAMATION "You must have the Microsoft .NET Framework 4.0 Installed to use this application. $\n$\n The installer will now open the Microsft .NET Framework 4.0 webpage$\n$\n$\n$\nRemember this program will not function until you have installed the .NET Framework 4 (You will get a error message if you try to start it)" 
    ExecShell Open "http://www.microsoft.com/downloads/en/details.aspx?FamilyID=9cfb2d51-5ff4-4491-b0e5-b386f32c0992&displaylang=en" SW_SHOWNORMAL 
    Quit 
NextStep: 
FunctionEnd 

Section 
SectionEnd 
;-------------------------------- 

; Pages shown on none silent installer 

;!insertmacro MUI_PAGE_WELCOME 
!insertmacro MUI_PAGE_DIRECTORY 
!insertmacro MUI_PAGE_COMPONENTS 
!insertmacro MUI_PAGE_INSTFILES 

# These indented statements modify settings for MUI_PAGE_FINISH 

;If we want to display a run app function 
!define MUI_FINISHPAGE_NOAUTOCLOSE 
!define MUI_FINISHPAGE_RUN_TEXT "Run ${_AppName}" 
!define MUI_FINISHPAGE_RUN_CHECKED 
!define MUI_FINISHPAGE_RUN "$INSTDIR\${_AppExe}" 
!insertmacro MUI_PAGE_FINISH 

!insertmacro MUI_LANGUAGE "English" 
!insertmacro MUI_LANGUAGE "German" 
!insertmacro MUI_LANGUAGE "French" 


UninstPage uninstConfirm 
UninstPage instfiles 

;-------------------------------- 

; The stuff to install 
Section "${_AppName} (required)" 
    SectionIn RO 

    ; Set output path to the installation directory. 
    SetOutPath $INSTDIR 

    ; Put file there 
    File /R "Current\*.*" 

    ; Write the installation path into the registry 
    WriteRegStr HKLM "Software\TheXSoft.com\${_AppName}" "Install_Dir" "$INSTDIR" 

    ; Write the uninstall keys for Windows 
    WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${_AppName}" "DisplayName" "${_AppName} (Remove only)" 
    WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${_AppName}" "UninstallString" '"$INSTDIR\uninstall.exe"' 
    WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${_AppName}" "NoModify" 1 
    WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${_AppName}" "NoRepair" 1 
    WriteUninstaller "uninstall.exe" 

SectionEnd 

; Optional section (can be disabled by the user) 
Section "Start Menu Shortcuts" 

    SetShellVarContext all 

    CreateDirectory "$SMPROGRAMS\${_AppName}" 
    CreateShortCut "$SMPROGRAMS\${_AppName}\TheXSoft.com - Software page.url" "$INSTDIR\TheXSoft.com - Software page.url" 
    CreateShortCut "$SMPROGRAMS\${_AppName}\GuildStats.NET - Get the stats for your MMO.url" "$INSTDIR\GuildStats.NET - Get the stats for your MMO.url" 
    CreateShortCut "$SMPROGRAMS\${_AppName}\${_AppName}.lnk" "$INSTDIR\${_AppExe}" "" "$INSTDIR\${_AppExe}" 0 

SectionEnd 


;-------------------------------- 

; Uninstaller 

Section "Uninstall" 

    ; Remove registry keys 
    DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${_AppName}" 
    DeleteRegKey HKLM "SOFTWARE\${_AppName}" 

    ; Remove files and uninstaller 
    Delete "$INSTDIR\*.exe" 
    Delete $INSTDIR\uninstall.exe 

    ; Remove shortcuts, if any 
    Delete "$SMPROGRAMS\${_AppName}\*.*" 

    ; Remove directories used 
    RMDir "$INSTDIR" 

SectionEnd 


;-------------------------------- 
; Silent install logic 

Function SilentInstall 
    ; Set output path to the installation directory. 
    SetOutPath $INSTDIR 

    ; Put file there 
    File /R "Current\*.*" 

    ; Write the installation path into the registry 
    WriteRegStr HKLM "Software\TheXSoft.com\${_AppName}" "Install_Dir" "$INSTDIR" 

    ; Write the uninstall keys for Windows 
    WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${_AppName}" "DisplayName" "${_AppName} (Remove only)" 
    WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${_AppName}" "UninstallString" '"$INSTDIR\uninstall.exe"' 
    WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${_AppName}" "NoModify" 1 
    WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${_AppName}" "NoRepair" 1 
    WriteUninstaller "uninstall.exe" 


    SetShellVarContext all 

    CreateDirectory "$SMPROGRAMS\${_AppName}" 
    CreateShortCut "$SMPROGRAMS\${_AppName}\TheXSoft.com - Software page.url" "$INSTDIR\TheXSoft.com - Software page.url" 
    CreateShortCut "$SMPROGRAMS\${_AppName}\GuildStats.NET - Get the stats for your MMO.url" "$INSTDIR\GuildStats.NET - Get the stats for your MMO.url" 
    CreateShortCut "$SMPROGRAMS\${_AppName}\${_AppName}.lnk" "$INSTDIR\${_AppExe}" "" "$INSTDIR\${_AppExe}" 0 

    Exec ${_AppExe} 
    Quit 
FunctionEnd 

回答

5

StrCmp $ 0 1 0 +3是错误的,它应该是+2(在这个例子中+3可能是未定义的行为,因为你正在跳过隐藏的返回指令)。

使用相对跳跃是容易出错的,你应该使用一个标签或使用逻辑的lib改写:

!include LogicLib.nsh 
... 
Function .onInit 
    Call GetDotNet 

    ${If} ${Silent} 
    call SilentInstall 
    ${EndIf} 
FunctionEnd 

但是当正常安装的逻辑是把沉默的一个单独的函数安装逻辑加倍你的工作几乎相等。您应该能够删除SilentInstall功能,只需使用一个隐藏的部分中静默安装,执行:

Section "${_AppName} (required)" 
#shared install code 
SectionEnd 

Section "Start Menu Shortcuts" 
#shared startmenu code 
SectionEnd 

Section 
${If} ${Silent} 
    Exec ${_AppExe} 
${EndIf} 
Section 

这是很难说为什么不更新你的文件,但如果您使用的共享代码,你可以运行它没有/ S并检查详细记录。我唯一的猜测是InstallDirRegKey正在拾取一个非默认的installdir,并且你正在查看错误的文件。您可以Process Monitor来监视安装。


您的代码有一些其它无关的问题:

  • RequestExecutionLevel管理是不够的,你需要处理NT5和NT6与UAC关闭(UserInfo::GetAccountType
  • 您不必当图标与目标程序相同时指定快捷图标
  • 调用Exec时应引用路径:Exec '"$instdir\${_AppExe}"'
  • 混合UAC/run因为使用Exec的/ RequestExecutionLevel管理员有问题,因为您最终可能会以错误的用户身份运行该程序。
+0

是否有可能有一个非静音部分或功能一个否则安静的安装程序。假设我想显示下载进度,但没有其他步骤。 – foobar 2016-09-30 20:23:16

+0

@foobar是的,但您不能设置无声标志,您必须通过在页面预回调函数中调用Abort来手动跳过所有其他页面。 – Anders 2016-09-30 22:29:58

0

这是一个棘手的问题。我使用相同的方法来更新我的应用程序,静静地调用NSIS安装程序。在我的情况下,问题并不在于NSIS脚本,而在于我使用WebClient类将包含我的安装程序的zip文件下载到临时目录,然后在那里提取它并从那里运行它。问题是如果提取的安装文件存在,ZipFile类会生成一个异常,因此旧的安装程序仍然存在,除了卸载可执行文件以外的任何内容都不会在程序目录中更新。

对我来说,解决办法是下载新的(在VB.NET)之前,收拾旧ZIP和EXE文件:

If File.Exists(Path.Combine(Path.GetTempPath(), "Setup.zip")) Then 
     File.Delete(Path.Combine(Path.GetTempPath(), "Setup.zip")) 
    End If 
    If File.Exists(Path.Combine(Path.GetTempPath(), "Setup.exe")) Then 
     File.Delete(Path.Combine(Path.GetTempPath(), "Setup.exe")) 
    End If