NSIS 簡易教程(二)
!include "MUI.nsh"
!include "Sections.nsh"
!include "LogicLib.nsh"
#=========================================================================================
#=========================================================================================
; 巨集定義
!define STR_AppName "易極OA協同辦公系統"
!define STR_Version "1.0"
!define STR_Publisher "億級空間"
!define STR_HomepageUrl "http://www.eg-oa.com"
!define REG_AppBase "Software\EgOA"
!define REG_Uninstall "Software\Microsoft\Windows\CurrentVersion\Uninstall\${STR_AppName}"
#=========================================================================================
#=========================================================================================
; MUI 設定
!define MUI_ABORTWARNING
!define MUI_ICON "${NSISDIR}\Contrib\Graphics\Icons\orange-install.ico"
!define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\orange-uninstall.ico"
!define MUI_WELCOMEFINISHPAGE_BITMAP "${NSISDIR}\Contrib\Graphics\Wizard\orange.bmp"
!define MUI_UNWELCOMEFINISHPAGE_BITMAP "${NSISDIR}\Contrib\Graphics\Wizard\orange-uninstall.bmp"
!define MUI_HEADERIMAGE
!define MUI_HEADERIMAGE_BITMAP "${NSISDIR}\Contrib\Graphics\Header\orange.bmp"
!define MUI_HEADERIMAGE_UNBITMAP "${NSISDIR}\Contrib\Graphics\Header\orange-uninstall.bmp"
; 語言選擇設定
!define MUI_LANGDLL_REGISTRY_ROOT "HKCU"
!define MUI_LANGDLL_REGISTRY_KEY "${REG_Uninstall}"
!define MUI_LANGDLL_REGISTRY_VALUENAME "NSIS:Language"
; 元件頁面設定
!define MUI_COMPONENTSPAGE_SMALLDESC
; 開始選單頁面設定
var STR_GroupName
var TMP_GroupName
!define MUI_STARTMENUPAGE_REGISTRY_ROOT "HKCU"
!define MUI_STARTMENUPAGE_REGISTRY_KEY "${REG_Uninstall}"
!define MUI_STARTMENUPAGE_DEFAULTFOLDER "${STR_AppName}"
!define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "NSIS:StartMenuDir"
; 完成安裝頁面設定
!define MUI_FINISHPAGE_RUN "C:\Program Files\Internet Explorer\iexplore.exe -new www.google.com"
!define MUI_FINISHPAGE_SHOWREADME "$INSTDIR/help/index.html"
!define MUI_FINISHPAGE_SHOWREADME_TEXT "$(LNG_ShowHelp)"
!define MUI_FINISHPAGE_LINK "${STR_AppName} $(LNG_Homepage): ${STR_HomepageUrl}"
!define MUI_FINISHPAGE_LINK_LOCATION "${STR_HomepageUrl}"
; 安裝頁面
!insertmacro MUI_PAGE_WELCOME
!insertmacro MUI_PAGE_LICENSE "$(LNG_License)"
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_COMPONENTS
!insertmacro MUI_PAGE_STARTMENU Application $STR_GroupName
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_PAGE_FINISH
; 解除安裝頁面
!insertmacro MUI_UNPAGE_WELCOME
!insertmacro MUI_UNPAGE_CONFIRM
!insertmacro MUI_UNPAGE_INSTFILES
!insertmacro MUI_UNPAGE_FINISH
; 語言支援
!insertmacro MUI_LANGUAGE "SimpChinese"
;!insertmacro MUI_LANGUAGE "English"
#=========================================================================================
#=========================================================================================
; 語言相關字串
LicenseLangString LNG_License ${LANG_ENGLISH} ".\resource\EULA.txt"
LangString LNG_BrandingText ${LANG_ENGLISH} "haijd Software"
LangString LNG_DefaultInstation ${LANG_ENGLISH} "Default installtion"
LangString LNG_FullInstation ${LANG_ENGLISH} "Full installtion"
LangString LNG_MinimalInstation ${LANG_ENGLISH} "Minimal installtion"
LangString LNG_Help ${LANG_ENGLISH} "Help"
LangString LNG_Homepage ${LANG_ENGLISH} "Homepage"
LangString LNG_Uninstall ${LANG_ENGLISH} "Uninstall"
LangString LNG_ShowHelp ${LANG_ENGLISH} "Show Help"
LangString LNG_ProgramFile ${LANG_ENGLISH} "Program Files"
LangString LNG_EgOA ${LANG_ENGLISH} "Main program"
LangString LNG_ServerEnv ${LANG_ENGLISH} "Services environment."
LangString LNG_CreateShortcut ${LANG_ENGLISH} "Create Shortcut"
LangString LNG_ProgramMenuShortcutGroup ${LANG_ENGLISH} "Program Menu Shortcut Group"
LangString LNG_DesktopShortcut ${LANG_ENGLISH} "Desktop Shortcut"
LangString LNG_QuickLaunchShortcut ${LANG_ENGLISH} "Quick Launch Bar Shortcut"
LangString LNG_ProgramFileDesc ${LANG_ENGLISH} "Install ${STR_AppName} program files."
LangString LNG_EgOADesc ${LANG_ENGLISH} "Install ${STR_AppName} main program files."
LangString LNG_ServerEnvDesc ${LANG_ENGLISH} "Install ${STR_AppName} services environment."
LangString LNG_CreateShortcutDesc ${LANG_ENGLISH} "Create shortcuts to launch the program easy."
LicenseLangString LNG_License ${LANG_SIMPCHINESE} ".\resource\EULA.txt"
LangString LNG_BrandingText ${LANG_SIMPCHINESE} "haijd Software"
LangString LNG_DefaultInstation ${LANG_SIMPCHINESE} "預設安裝"
LangString LNG_FullInstation ${LANG_SIMPCHINESE} "完全安裝"
LangString LNG_MinimalInstation ${LANG_SIMPCHINESE} "最小安裝"
LangString LNG_Help ${LANG_SIMPCHINESE} "幫助"
LangString LNG_Homepage ${LANG_SIMPCHINESE} "主頁"
LangString LNG_Uninstall ${LANG_SIMPCHINESE} "解除安裝"
LangString LNG_ShowHelp ${LANG_SIMPCHINESE} "檢視幫助"
LangString LNG_ProgramFile ${LANG_SIMPCHINESE} "程式檔案"
LangString LNG_EgOA ${LANG_SIMPCHINESE} "主程式"
LangString LNG_ServerEnv ${LANG_SIMPCHINESE} "服務環境"
LangString LNG_CreateShortcut ${LANG_SIMPCHINESE} "建立快捷方式"
LangString LNG_ProgramMenuShortcutGroup ${LANG_SIMPCHINESE} "程式選單快捷方式組"
LangString LNG_DesktopShortcut ${LANG_SIMPCHINESE} "桌面快捷方式"
LangString LNG_QuickLaunchShortcut ${LANG_SIMPCHINESE} "快速啟動欄快捷方式"
LangString LNG_ProgramFileDesc ${LANG_SIMPCHINESE} "安裝 ${STR_AppName} 程式檔案。"
LangString LNG_EgOADesc ${LANG_SIMPCHINESE} "安裝 ${STR_AppName} 主程式檔案"
LangString LNG_ServerEnvDesc ${LANG_SIMPCHINESE} "安裝 ${STR_AppName} 服務環境"
LangString LNG_CreateShortcutDesc ${LANG_SIMPCHINESE} "建立用於快速訪問的快捷方式。"
#=========================================================================================
#=========================================================================================
; 雜項
Name "${STR_AppName} ${STR_Version}"
OutFile "${STR_AppName}_${STR_Version}.exe"
InstallDir "$PROGRAMFILES\egoa"
InstallDirRegKey HKCU "${REG_AppBase}" "InstallDir"
ShowInstDetails SHOW
ShowUnInstDetails SHOW
BrandingText "$(LNG_BrandingText)"
#=========================================================================================
#=========================================================================================
; 安裝型別
!ifndef NOINSTTYPES
InstType "$(LNG_DefaultInstation)"
InstType "$(LNG_FullInstation)"
InstType "$(LNG_MinimalInstation)"
!endif
#=========================================================================================
#=========================================================================================
; 程式檔案
Section
LogSet on
SectionEnd
SectionGroup /e "$(LNG_ProgramFile)" SEC_ProgramFile
Section "$(LNG_EgOA)" SEC_EgOA
SectionIn 1 2 3 RO
SetOverwrite ON
SetOutPath "$INSTDIR"
File ".\resource\egoa.ico"
File /r ".\resource\program"
SectionEnd
Section "$(LNG_ServerEnv)" SEC_ServerEnv
SectionIn 1 2 3 RO
SetOutPath "$INSTDIR"
File /r ".\resource\server"
File /r ".\resource\database"
SectionEnd
Section "$(LNG_Help)" SEC_Help
SectionIn 1 2
SetOutPath "$INSTDIR"
File /r ".\resource\help"
SectionEnd
SectionGroupEnd
#=========================================================================================
#=========================================================================================
; 快捷方式
SectionGroup "$(LNG_CreateShortcut)" SEC_Shortcut
; 建立開始選單程式組
SectionGroup "$(LNG_ProgramMenuShortcutGroup)" SEC_ProgramMenuShortcutGroup
Section "${STR_AppName}" SEC_AppNameShortcut
SectionIn 1 2
CreateDirectory "$SMPROGRAMS\$STR_GroupName"
WriteINIStr "$SMPROGRAMS\$STR_GroupName\${STR_AppName}.url" "InternetShortcut" "URL" "$INSTDIR/program/www/index.html"
SectionEnd
Section "${STR_AppName} $(LNG_Help)" SEC_HelpShortcut
SectionIn 1 2
CreateDirectory "$SMPROGRAMS\$STR_GroupName"
WriteINIStr "$SMPROGRAMS\$STR_GroupName\${STR_AppName} $(LNG_Help).url" "InternetShortcut" "URL" "$INSTDIR/program/www/help/index.html"
SectionEnd
Section "${STR_AppName} $(LNG_Homepage)" SEC_HomePageShortcut
SectionIn 1 2
CreateDirectory "$SMPROGRAMS\$STR_GroupName"
WriteINIStr "$SMPROGRAMS\$STR_GroupName\${STR_AppName} $(LNG_Homepage).url" "InternetShortcut" "URL" "${STR_HomepageUrl}"
SectionEnd
Section "$(LNG_Uninstall) ${STR_AppName}" SEC_UninstallShortcut
SectionIn 1 2
CreateDirectory "$SMPROGRAMS\$STR_GroupName"
CreateShortCut "$SMPROGRAMS\$STR_GroupName\$(LNG_Uninstall) ${STR_AppName}.lnk" "$INSTDIR\Uninstall.exe"
SectionEnd
SectionGroupEnd
; 桌面
Section "$(LNG_DesktopShortcut)" SEC_DesktopShortcut
SectionIn 1 2
WriteINIStr "$DESKTOP\${STR_AppName}.url" "InternetShortcut" "URL" "http://127.0.0.1/"
SectionEnd
; 快速啟動
Section "$(LNG_QuickLaunchShortcut)" SEC_QuickLaunchShortcut
SectionIn 2
WriteINIStr "$QUICKLAUNCH\${STR_AppName}.url" "InternetShortcut" "URL" "http://127.0.0.1/"
SectionEnd
SectionGroupEnd
#=========================================================================================
#=========================================================================================
# 替換檔案內容用的巨集
!macro ReplaceConfig FileName StringOld StringNew
Push `${StringOld}` #text to be replaced
Push `${StringNew}` #replace with
Push all #replace all occurrences
Push all #replace all occurrences
Push `${FileName}` #file to replace in
Call AdvReplaceInFile
!macroend
#=========================================================================================
#=========================================================================================
; 配置服務
Section "-SettingServer"
; 修改配置檔案
!insertmacro ReplaceConfig "$INSTDIR\server\Apache2.2\conf\httpd.conf" "EGOA_BASE_PATH" "$INSTDIR"
!insertmacro ReplaceConfig "$INSTDIR\server\MySQL4.1\my.ini" "EGOA_BASE_PATH" "$INSTDIR"
!insertmacro ReplaceConfig "$INSTDIR\server\php5\php.ini" "EGOA_BASE_PATH" "$INSTDIR"
; 建立服務
nsExec::ExecToLog '"$INSTDIR\server\MySQL4.1\bin\mysqld-nt.exe" --install MySQL4.1 --defaults-file="$INSTDIR\server\MySQL4.1\my.ini"'
nsExec::ExecToLog '"$INSTDIR\server\Apache2.2\bin\httpd.exe" -k install'
; 啟動服務
nsExec::ExecToLog 'net start MySQL4.1'
nsExec::ExecToLog 'net start Apache2.2'
SectionEnd
#=========================================================================================
#=========================================================================================
; 完成安裝
Section "-PostInstall"
; 輸出解除安裝程式
WriteUninstaller "$INSTDIR\Uninstall.exe"
; 寫登錄檔
WriteRegStr HKCU "${REG_AppBase}" "InstallDir" "$INSTDIR" ; 安裝的目錄
WriteRegStr HKCU "${REG_AppBase}" "GroupName" "$STR_GroupName" ; 軟體在開始選單中的名稱
WriteRegStr HKCU "${REG_AppBase}" "Version" "${STR_Version}" ; 版本號
WriteRegStr HKCU "${REG_Uninstall}" "DisplayName" "$(^Name)"
WriteRegStr HKCU "${REG_Uninstall}" "UninstallString" "$INSTDIR\Uninstall.exe"
WriteRegStr HKCU "${REG_Uninstall}" "DisplayIcon" "$INSTDIR\EgOA.ico"
WriteRegStr HKCU "${REG_Uninstall}" "DisplayVersion" "${STR_Version}"
WriteRegStr HKCU "${REG_Uninstall}" "URLInfoAbout" "${STR_HomepageUrl}"
WriteRegStr HKCU "${REG_Uninstall}" "Publisher" "${STR_Publisher}"
SectionEnd
#=========================================================================================
#=========================================================================================
; 初始化回撥函式
Function .onInit
!insertmacro MUI_LANGDLL_DISPLAY
; 判斷是否已安裝
Var /GLOBAL OLD_REG_Version
ReadRegStr $OLD_REG_Version "HKCU" "${REG_APPBASE}" "Version"
${If} $OLD_REG_Version <> ''
Abort '系統中已安裝有本程式,請先解除安裝後再安裝!'
${EndIf}
FunctionEnd
#=========================================================================================
#=========================================================================================
# 替換檔案中的字串
Function AdvReplaceInFile
Exch $0 ;file to replace in
Exch
Exch $1 ;number to replace after
Exch
Exch 2
Exch $2 ;replace and onwards
Exch 2
Exch 3
Exch $3 ;replace with
Exch 3
Exch 4
Exch $4 ;to replace
Exch 4
Push $5 ;minus count
Push $6 ;universal
Push $7 ;end string
Push $8 ;left string
Push $9 ;right string
Push $R0 ;file1
Push $R1 ;file2
Push $R2 ;read
Push $R3 ;universal
Push $R4 ;count (onwards)
Push $R5 ;count (after)
Push $R6 ;temp file name
GetTempFileName $R6
FileOpen $R1 $0 r ;file to search in
FileOpen $R0 $R6 w ;temp file
StrLen $R3 $4
StrCpy $R4 -1
StrCpy $R5 -1
loop_read:
ClearErrors
FileRead $R1 $R2 ;read line
IfErrors exit
StrCpy $5 0
StrCpy $7 $R2
loop_filter:
IntOp $5 $5 - 1
StrCpy $6 $7 $R3 $5 ;search
StrCmp $6 "" file_write2
StrCmp $6 $4 0 loop_filter
StrCpy $8 $7 $5 ;left part
IntOp $6 $5 + $R3
IntCmp $6 0 is0 not0
is0:
StrCpy $9 ""
Goto done
not0:
StrCpy $9 $7 "" $6 ;right part
done:
StrCpy $7 $8$3$9 ;re-join
IntOp $R4 $R4 + 1
StrCmp $2 all file_write1
StrCmp $R4 $2 0 file_write2
IntOp $R4 $R4 - 1
IntOp $R5 $R5 + 1
StrCmp $1 all file_write1
StrCmp $R5 $1 0 file_write1
IntOp $R5 $R5 - 1
Goto file_write2
file_write1:
FileWrite $R0 $7 ;write modified line
Goto loop_read
file_write2:
FileWrite $R0 $R2 ;write unmodified line
Goto loop_read
exit:
FileClose $R0
FileClose $R1
SetDetailsPrint none
Delete $0
Rename $R6 $0
Delete $R6
SetDetailsPrint both
Pop $R6
Pop $R5
Pop $R4
Pop $R3
Pop $R2
Pop $R1
Pop $R0
Pop $9
Pop $8
Pop $7
Pop $6
Pop $5
Pop $0
Pop $1
Pop $2
Pop $3
Pop $4
FunctionEnd
#=========================================================================================
#=========================================================================================
# 根據安裝日誌解除安裝檔案的呼叫巨集
!macro DelFileByLog LogFile
ifFileExists `${LogFile}` 0 +4
Push `${LogFile}`
Call un.DelFileByLog
Delete `${LogFile}`
!macroend
#=========================================================================================
#=========================================================================================
; 解除安裝
Section "Uninstall"
; 停止服務
nsExec::ExecToLog 'net stop Apache2.2'
nsExec::ExecToLog 'net stop MySQL4.1'
; 解除安裝服務
nsExec::ExecToLog '"$INSTDIR\server\MySQL4.1\bin\mysqld-nt.exe" --remove MySQL4.1'
nsExec::ExecToLog '"$INSTDIR\server\Apache2.2\bin\httpd.exe" -k uninstall'
; 從登錄檔中取得軟體在開始選單中的名稱
ReadRegStr $TMP_GroupName HKCU "${REG_AppBase}" "GroupName"
; 刪除開始選單中的快捷方式與目錄
Delete "$SMPROGRAMS\$TMP_GroupName\${STR_AppName}.url"
Delete "$SMPROGRAMS\$TMP_GroupName\${STR_AppName} $(LNG_Help).url"
Delete "$SMPROGRAMS\$TMP_GroupName\${STR_AppName} $(LNG_Homepage).url"
Delete "$SMPROGRAMS\$TMP_GroupName\$(LNG_Uninstall) ${STR_AppName}.lnk"
RMDir "$SMPROGRAMS\$TMP_GroupName"
Delete /REBOOTOK "$DESKTOP\${STR_AppName}.url" ; 刪除桌面快捷方式
Delete /REBOOTOK "$QUICKLAUNCH\${STR_AppName}.url" ; 刪除快速啟動快捷方式
; 呼叫巨集根據安裝日誌解除安裝安裝程式自己安裝過的檔案
!insertmacro DelFileByLog "$INSTDIR\install.log"
; 刪除安裝目錄中的檔案
RMDir "$INSTDIR"
RMDir "$INSTDIR\help"
RMDir "$INSTDIR\program"
RMDir /r /REBOOTOK "$INSTDIR\server"
RMDir /r /REBOOTOK "$INSTDIR\help"
; 刪除登錄檔內容
DeleteRegKey HKCU "${REG_Uninstall}"
DeleteRegKey HKCU "${REG_AppBase}"
SetAutoClose True
SectionEnd
#=========================================================================================
#=========================================================================================
; 解除安裝初始化
Function un.onInit
!insertmacro MUI_UNGETLANGUAGE
FunctionEnd
#=========================================================================================
#=========================================================================================
# 解除安裝程式通過安裝日誌解除安裝檔案函式
Function un.DelFileByLog
Exch $R0
Push $R1
Push $R2
Push $R3
FileOpen $R0 $R0 r
${Do}
FileRead $R0 $R1
${IfThen} $R1 == `` ${|} ${ExitDo} ${|}
StrCpy $R1 $R1 -2
StrCpy $R2 $R1 11
StrCpy $R3 $R1 20
${If} $R2 == "File: wrote"
${OrIf} $R2 == "File: skipp"
${OrIf} $R3 == "CreateShortCut: out:"
${OrIf} $R3 == "created uninstaller:"
Push $R1
Push `"`
Call un.DelFileByLog.StrLoc
Pop $R2
${If} $R2 != ""
IntOp $R2 $R2 + 1
StrCpy $R3 $R1 "" $R2
Push $R3
Push `"`
Call un.DelFileByLog.StrLoc
Pop $R2
${If} $R2 != ""
StrCpy $R3 $R3 $R2
Delete /REBOOTOK $R3
${EndIf}
${EndIf}
${EndIf}
StrCpy $R2 $R1 7
${If} $R2 == "Rename:"
Push $R1
Push "->"
Call un.DelFileByLog.StrLoc
Pop $R2
${If} $R2 != ""
IntOp $R2 $R2 + 2
StrCpy $R3 $R1 "" $R2
Delete /REBOOTOK $R3
${EndIf}
${EndIf}
${Loop}
FileClose $R0
Pop $R3
Pop $R2
Pop $R1
Pop $R0
FunctionEnd
Function un.DelFileByLog.StrLoc
Exch $R0
Exch
Exch $R1
Push $R2
Push $R3
Push $R4
Push $R5
StrLen $R2 $R0
StrLen $R3 $R1
StrCpy $R4 0
${Do}
StrCpy $R5 $R1 $R2 $R4
${If} $R5 == $R0
${OrIf} $R4 = $R3
${ExitDo}
${EndIf}
IntOp $R4 $R4 + 1
${Loop}
${If} $R4 = $R3
StrCpy $R0 ""
${Else}
StrCpy $R0 $R4
${EndIf}
Pop $R5
Pop $R4
Pop $R3
Pop $R2
Pop $R1
Exch $R0
FunctionEnd
#=========================================================================================
#=========================================================================================
# 節描述
!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN
!insertmacro MUI_DESCRIPTION_TEXT ${SEC_ProgramFile} "$(LNG_ProgramFileDesc)"
!insertmacro MUI_DESCRIPTION_TEXT ${SEC_EgOA} "$(LNG_EgOADesc)"
!insertmacro MUI_DESCRIPTION_TEXT ${SEC_ServerEnv} "$(LNG_ServerEnvDesc)"
!insertmacro MUI_DESCRIPTION_TEXT ${SEC_Shortcut} "$(LNG_CreateShortcutDesc)"
!insertmacro MUI_DESCRIPTION_TEXT ${SEC_DesktopShortcut} "$(LNG_CreateShortcutDesc)"
!insertmacro MUI_DESCRIPTION_TEXT ${SEC_QuickLaunchShortcut} "$(LNG_CreateShortcutDesc)"
!insertmacro MUI_DESCRIPTION_TEXT ${SEC_AppNameShortcut} "$(LNG_CreateShortcutDesc)"
!insertmacro MUI_DESCRIPTION_TEXT ${SEC_HelpShortcut} "$(LNG_CreateShortcutDesc)"
!insertmacro MUI_DESCRIPTION_TEXT ${SEC_HomePageShortcut} "$(LNG_CreateShortcutDesc)"
!insertmacro MUI_DESCRIPTION_TEXT ${SEC_UninstallShortcut} "$(LNG_CreateShortcutDesc)"
!insertmacro MUI_FUNCTION_DESCRIPTION_END