2

現在、NSIS を使用してBitfighter for Windows をパッケージ化しており、(場合によっては) ゲームを移植可能に実行するための別のアーカイブを手動で作成しています。プロセスを合理化して移植可能なバージョンをより簡単に構築できるようにしたいと考えています。

ポータブル インストールを作成する現在の方法は、ゲームを通常どおり (NSIS ビルドのインストーラーを使用して) インストールし、インストール フォルダーを圧縮して、"portable" というマーカー ファイルを追加することです。インストール手順を省略して、ポータブル アーカイブを直接ビルドしたいと思います。

これを NSIS インストーラーと組み合わせることの主な利点は、ビルド プロセスが合理化され、含まれるファイルの単一のリストを維持できるようになることです。

誰かがこのようなことをしたことがありますか?


最後に、受け入れられた回答のバリエーションを使用し、NSIS !ifdef ディレクティブを使用して、同じコードベースを使用して 2 つのインストーラーをビルドしました。/DPORTALBE を指定すると、ポータブル インストーラーが取得されます。

コードはGoogle コード リポジトリにあります。

4

2 に答える 2

4

1 つのインストーラーで通常モードとポータブル モードを組み合わせてみませんか?

!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 を呼び出し、クリーンアップして終了します...

于 2012-12-08T18:41:11.090 に答える
0

注: 7Zip を使用してインストーラーからファイルを抽出し、ポータブル アーカイブを構築することに基づくソリューションを投稿しました。残念ながら、何らかの理由で 7Zip がインストーラー内のすべてのファイルを認識していないことがわかりました。そのため、7Zip が作成していた zip ファイルにいくつかのファイルがありませんでした。信頼性が低い (そして微妙に失敗する可能性がある) ため、コードを削除しました。

于 2012-12-08T16:08:41.237 に答える