2012-12-08 86 views
2

我们目前使用NSIS打包Bitfighter为Windows,和(有时)手动创建一个单独的存档可移植运行游戏。我希望简化流程,使构建便携版本变得更容易,从而鼓励我们定期进行。使用NSIS创建正常安装和便携式安装

我们创建了便携式安装当前的办法是正常安装游戏(使用NSIS生成的安装程序),然后压缩安装文件夹,并添加一个名为标记的文件“随身携带”。我想绕过安装步骤,并直接构建便携式归档。

这与NSIS安装程序相结合的主要优点是,它会简化构建过程,并且将使我们能够保持被列入文件的一个列表。

有没有人做过类似的事情?


最后,我用公认的答案的变化,并用NSIS!IFDEF指令使用相同的代码库建立两个安装程序。通过指定/ DPORTALBE,我将得到一个便携式安装程序。

该代码可在我们的Google Code repository中找到。

回答

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 

如果你想,你很可能创建一个设置,可以生成压缩文件:mysetup.exe /GENERATEPORTABLEPKG=c:\path\to\7z.exe然后设置将文件解压使用ExecWait调用7zip的再清理并退出...

+0

所以第一个解决方案,我得到的,并且是一个想法,我hand't充分考虑。第二个似乎没有解决我提出的问题(或者至少试图构成:-),这是如何从一个脚本创建两个安装程序,或者至少从单个文件规范创建两个安装程序,以便不发散安装。或者我错过了什么?我也很好奇,为什么你指定一个便携式应用程序的卸载程序? – Watusimoto

+0

它安装为普通应用程序或(提取)便携式应用程序,foobar2000安装程序就像这样工作,例如... – Anders

0

注意:我发布了一个基于使用7Zip的解决方案来从安装程序中提取文件并构建一个可移植的存档。不幸的是,我发现,无论出于什么原因,7Zip都没有看到安装程序中的每个文件,因此它创建的zip文件缺少一些文件。因为它不可靠(并且可能会巧妙地失败),所以我删除了代码。

相关问题