我们目前使用NSIS为Windows打包Bitfighter,并且(有时)手动创建一个单独的存档,以便可移植地运行游戏。我希望简化流程,使构建便携版本变得更容易,从而鼓励我们定期进行。
我们创建便携式安装的当前方式是正常安装游戏(使用NSIS构建的安装程序),然后压缩安装文件夹,并添加一个名为“portable”的标记文件。我想绕过安装步骤,直接构建可移植存档。
将此与NSIS安装程序相结合的主要优点是它将简化构建过程,并允许我们维护一个要包含的文件列表。
有没有人做过这样的事情?
最后,我使用了接受答案的变体,并使用NSIS!ifdef指令使用相同的代码库构建两个安装程序。通过指定/ DPORTALBE,我将获得一个便携式安装程序。
可以在我们的Google Code repository。
中找到该代码答案 0 :(得分:3)
为什么不在一个安装程序中组合普通模式和便携模式?
!define NAME "foobarbaz"
!define UNINSTKEY "${NAME}" ; Using a GUID here is not a bad idea
!define DEFAULTNORMALDESTINATON "$ProgramFiles\${NAME}"
!define DEFAULTPORTABLEDESTINATON "$Desktop\${NAME}"
Name "${NAME}"
Outfile "${NAME} setup.exe"
RequestExecutionlevel highest
SetCompressor LZMA
Var NormalDestDir
Var PortableDestDir
Var PortableMode
!include LogicLib.nsh
!include FileFunc.nsh
!include MUI2.nsh
!insertmacro MUI_PAGE_WELCOME
Page Custom PortableModePageCreate PortableModePageLeave
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_PAGE_FINISH
!insertmacro MUI_LANGUAGE English
Function .onInit
StrCpy $NormalDestDir "${DEFAULTNORMALDESTINATON}"
StrCpy $PortableDestDir "${DEFAULTPORTABLEDESTINATON}"
${GetParameters} $9
ClearErrors
${GetOptions} $9 "/?" $8
${IfNot} ${Errors}
MessageBox MB_ICONINFORMATION|MB_SETFOREGROUND "\
/PORTABLE : Extract application to USB drive etc$\n\
/S : Silent install$\n\
/D=%directory% : Specify destination directory$\n"
Quit
${EndIf}
ClearErrors
${GetOptions} $9 "/PORTABLE" $8
${IfNot} ${Errors}
StrCpy $PortableMode 1
StrCpy $0 $PortableDestDir
${Else}
StrCpy $PortableMode 0
StrCpy $0 $NormalDestDir
${If} ${Silent}
Call RequireAdmin
${EndIf}
${EndIf}
${If} $InstDir == ""
; User did not use /D to specify a directory,
; we need to set a default based on the install mode
StrCpy $InstDir $0
${EndIf}
Call SetModeDestinationFromInstdir
FunctionEnd
Function RequireAdmin
UserInfo::GetAccountType
Pop $8
${If} $8 != "admin"
MessageBox MB_ICONSTOP "You need administrator rights to install ${NAME}"
SetErrorLevel 740 ;ERROR_ELEVATION_REQUIRED
Abort
${EndIf}
FunctionEnd
Function SetModeDestinationFromInstdir
${If} $PortableMode = 0
StrCpy $NormalDestDir $InstDir
${Else}
StrCpy $PortableDestDir $InstDir
${EndIf}
FunctionEnd
Function PortableModePageCreate
Call SetModeDestinationFromInstdir ; If the user clicks BACK on the directory page we will remember their mode specific directory
!insertmacro MUI_HEADER_TEXT "Install Mode" "Choose how you want to install ${NAME}."
nsDialogs::Create 1018
Pop $0
${NSD_CreateLabel} 0 10u 100% 24u "Select install mode:"
Pop $0
${NSD_CreateRadioButton} 30u 50u -30u 8u "Normal install"
Pop $1
${NSD_CreateRadioButton} 30u 70u -30u 8u "Portable"
Pop $2
${If} $PortableMode = 0
SendMessage $1 ${BM_SETCHECK} ${BST_CHECKED} 0
${Else}
SendMessage $2 ${BM_SETCHECK} ${BST_CHECKED} 0
${EndIf}
nsDialogs::Show
FunctionEnd
Function PortableModePageLeave
${NSD_GetState} $1 $0
${If} $0 <> ${BST_UNCHECKED}
StrCpy $PortableMode 0
StrCpy $InstDir $NormalDestDir
Call RequireAdmin
${Else}
StrCpy $PortableMode 1
StrCpy $InstDir $PortableDestDir
${EndIf}
FunctionEnd
Section
SetOutPath "$InstDir"
;File "source\myapp.exe"
${If} $PortableMode = 0
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${UNINSTKEY}" "DisplayName" "${NAME}"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${UNINSTKEY}" "UninstallString" '"$INSTDIR\uninstall.exe"'
WriteUninstaller "$INSTDIR\uninstall.exe"
${Else}
; Create the file the application uses to detect portable mode
FileOpen $0 "$INSTDIR\portable.dat" w
FileWrite $0 "PORTABLE"
FileClose $0
${EndIf}
SectionEnd
Section Uninstall
DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${UNINSTKEY}"
Delete "$INSTDIR\uninstall.exe"
;Delete "$INSTDIR\myapp.exe"
RMDir "$InstDir"
SectionEnd
或者没有GUI支持的简单版本:
!include LogicLib.nsh
!include FileFunc.nsh
!include Sections.nsh
Section
SetOutPath "$InstDir"
;File "source\myapp.exe"
SectionEnd
Section "" SID_CREATEUNINSTALLER
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${UNINSTKEY}" "DisplayName" "${NAME}"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${UNINSTKEY}" "UninstallString" '"$INSTDIR\uninstall.exe"'
WriteUninstaller "$INSTDIR\uninstall.exe"
SectionEnd
Section Uninstall
;...
SectionEnd
Function .onInit
${GetParameters} $9
ClearErrors
${GetOptions} $9 "/PORTABLE" $8
${IfNot} ${Errors}
SetSilent silent
${If} $InstDir == ""
StrCpy $InstDir "$Desktop\${NAME}"
${EndIf}
!insertmacro UnselectSection ${SID_CREATEUNINSTALLER}
SetOutPath $InstDir
WriteIniStr "$InstDir\Config.ini" "Install" "Portable" "yes" ; Mark as portable install
${EndIf}
FunctionEnd
如果你愿意,你可以创建一个可以生成zip文件的设置:mysetup.exe /GENERATEPORTABLEPKG=c:\path\to\7z.exe
然后安装程序将提取文件,使用ExecWait
调用7zip然后清理并退出...
答案 1 :(得分:0)
注意:我发布了一个基于使用7Zip的解决方案从安装程序中提取文件并构建可移植存档。不幸的是,我发现,无论出于何种原因,7Zip都没有看到安装程序中的每个文件,因此它创建的zip文件缺少一些文件。因为它不可靠(并且可能会巧妙地失败),所以我删除了代码。