2009-06-12 3 views

답변

1

샘플 코드를 확인하지만, Win9x의 경우에 호출 $ {디스크 공간 늘림} 실패 할 수 있습니다 :

는 여기 샘플 설치에 있습니다. 나는 또한 지정의 필요성을 제거 섹션 ID의

!define APPNAME "CalcEnoughSpace" 
name "${APPNAME}" 
outfile "$%temp%\${APPNAME}.exe" 
ShowInstDetails show 
RequestExecutionLevel user 
installdir "$Temp" 
AllowRootDirInstall true 

!include Sections.nsh 
!include LogicLib.nsh 

Function .onInit 
push $instdir 
call VerifyFreeSpace 
pop $0 
${If} $0 < 1 
    MessageBox mb_iconstop "Not enough free space!" 
${EndIf} 
FunctionEnd 

page instfiles 

Section !a 
AddSize 10000 
SectionEnd 
Section /o b 
AddSize 10000 
SectionEnd 

SectionGroup grp 
Section c 
AddSize 10000 
SectionEnd 
SectionGroupEnd 



Function VerifyFreeSpace 
System::Store s 
pop $0 ;path to check 
Push 0 ;default to no 
System::Call 'kernel32::GetDiskFreeSpaceEx(tr0,*l.r1,*l,*l)i.r2' 
${If} $2 < 1 
    StrCpy $0 $0 3 
    System::Call 'kernel32::GetDiskFreeSpace(tr0,*i.r1,*i.r2,*i.r3,*i)i.r4' 
    IntCmpU $4 0 ret 
    IntOp $1 $1 * $2 
    System::Int64Op $1 * $3 
    pop $1 
${EndIf} 
System::Int64Op $1/1024 ;to kb 
pop $1 
StrCpy $4 0 ;size 
StrCpy $2 0 ;section idx 
loop: 
    ClearErrors 
    SectionGetFlags $2 $3 
    IfErrors testspace 
    IntOp $3 $3 & ${SF_SELECTED} 
    ${If} $3 <> 0 
     SectionGetSize $2 $3 
     IntOp $4 $4 + $3 
     ${EndIf} 
    IntOp $2 $2 + 1 
    goto loop 
testspace: 
pop $2 ;throw away default return value 
System::Int64Op $1 > $4 
ret: 
System::Store l 
FunctionEnd 

난 단지, 잘하면 더 버그 :

+0

감사합니다. 나는 Win95를 위해 아무 것도 쓰지 않지만, 준비하는 것이 더 좋다 ... –

1

이렇게하려면 NSIS에 CheckFreeSpace이라는 함수를 작성했습니다. 불행하게도 그것은 다음과 같은 제한이 있습니다

  • 이 설치에서 모든 섹션의 크기를 계산하려면 각 섹션 ID가에 기록 된 각 변수를 알고에 의해, 각 섹션을 추가 CheckFreeSpace을 수정해야합니다. NSIS를 사용하여 설치 될 모든 섹션을 반복하는 방법을 찾을 수 없습니다.
  • ${DriveSpace}에 임의의 디렉터리 경로가 아닌 드라이브 문자가 필요하므로 설치 드라이브를 계산해야합니다. 드라이브 문자 문자열은 StrCpy $instdrive $INSTDIR 3으로 계산됩니다. $INSTDIR 변수가 상대 경로이거나 C:\과 같은 문자열로 시작하지 않으면이 작업은 실패합니다.
  • 설치를 계속할 수없는 경우 MessageBox가 생성됩니다. 성명 끝에 /SD IDOK을 추가하여 MessageBox을 표시하지 않을 수 있지만 설치 실패를 사용자에게 알리지는 않습니다. NSIS에서 stdout (으)로 방출 할 수있는 방법을 찾을 수 없습니다. 아마도 설치 프로그램의 반환 코드로 충분할까요?
  • 디스크 여유 공간이 매우 부족한 경우 (예 : 10KB) 설치 프로그램이 전혀 실행되지 않습니다. 임시 DLL을 \tmp 디렉토리에 압축을 푸는 공간이 없습니다.

아래의 구현에서 CheckFreeSpace은 설치 후 여유 공간에 대한 하드 코드 된 값을가집니다. 분명히 그것은 매개 변수화 될 수 있습니다.

!include FileFunc.nsh 
!insertmacro DriveSpace 

Name "CheckFreeSpace" 
OutFile "C:\CheckFreeSpace.exe" 

InstallDir C:\tmp\checkfreespace 

Page instfiles 

Section "install_section" install_section_id 
    Call CheckFreeSpace 

    CreateDirectory $INSTDIR 
    SetOutPath $INSTDIR 
    File "C:\installme.bat" 

    WriteUninstaller "$INSTDIR\Uninstall.exe" 

    DetailPrint "Installation Successful." 
SectionEnd 

Section "Uninstall" 

    RMDIR /r "$INSTDIR" 

SectionEnd 

Function CheckFreeSpace 

    var /GLOBAL installsize 
    var /GLOBAL adjustedinstallsize 
    var /GLOBAL freespace 
    var /GLOBAL instdrive 

    ; Verify that we have sufficient space for the install 

    ; SectionGetSize returns the size of each section in kilobyte. 
    SectionGetSize ${install_section_id} $installsize 

    ; Adjust the required install size by 10mb, as a minimum amount 
    ; of free space left after installation. 
    IntOp $adjustedinstallsize $installsize + 10240 

    ; Compute the drive that is the installation target; the 
    ; ${DriveSpace} macro will not accept a path, it must be a drive. 
    StrCpy $instdrive $INSTDIR 3 

    ; Compute drive space free in kilobyte 
    ${DriveSpace} $instdrive "/D=F /S=K" $freespace 

    DetailPrint "Determined installer needs $adjustedinstallsize kb ($installsize kb) while $freespace kb is free" 

    IntCmp $adjustedinstallsize $freespace spaceok spaceok 

    MessageBox MB_OK|MB_ICONSTOP "Insufficient space for installation. Please free space for installation directory $INSTDIR and try again." 
    DetailPrint "Insufficient space for installation. Installer needs $adjustedinstallsize kb, but freespace is only $freespace kb." 
    Abort "Insufficient space for installation." 

    spaceok: 
    DetailPrint "Installation target space is sufficient" 

FunctionEnd 
+0

내 질문이나 대답의 가정이 잘못 되었다면 수정하십시오. 현재이 코드는 낮은 여유 공간 조건에서 작동하는 것으로 보입니다. –

+0

섹션 ID는 0부터 시작하는 숫자 일 뿐이므로 모든 섹션을 검사하는 루프를 만들 수 있으며, SectionGetFlags를 호출하여 섹션이 선택/선택되었는지 확인하고, 해당 섹션이있는 경우 오류 플래그가 설정된 경우 SectionGetSize를 호출합니다 SectionGetFlags를 호출하면 끝 부분에 도달했습니다 – Anders

+0

stdout에 대한 출력이가는 한 NSIS는 GUI 응용 프로그램이므로 실제로 콘솔 처리가 없습니다. 시스템 플러그 인을 사용하면 XP 및 이후 버전에서 가능합니다. http://forums.winamp.com/showthread.php?postid=2303779#post2303779 – Anders

0

당신이 침묵에 대한 샘플 스크립트가 설치 한 마십시오 제한된 테스트를 존재하지 않았다?