2011-05-05 822 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