Using NSIS, How can the user modify it to contain more than 8192Bytes? - nsis

Thanks for reading my article :]
I received a response using http communication, but it was upgraded because it is more than 1024 bytes. So, the Byte of ${NSIS_MAX_STRLEN} became 8192. However, an error occurs because the return value of Json type that I receive exceeds 8192 bytes. What setting should I set to get more bytes?

You can't put the entire JSON in a NSIS string, you must use the plug-in to find the values you need:
This is able to parse more than 9000 bytes:
!macro prepare_example
FileOpen $1 "$temp\!tempjson.txt" w
FileWrite $1 "["
${For} $3 1 500
${IfThen} $3 U> 1 ${|} FileWrite $1 "," ${|}
FileWrite $1 '{"Return":"$3", "Out":"Any Request"}$\n'
${Next}
FileWrite $1 "]"
FileSeek $1 0 END $2
FileClose $1
DetailPrint "About to parse $2 bytes of JSON..."
!macroend
!include LogicLib.nsh
Section
!insertmacro prepare_example
ClearErrors
nsJSON::Set /file "$temp\!tempjson.txt"
${IfThen} ${Errors} ${|} Abort "nsJSON::Set failed" ${|}
nsJSON::Get /count /end
${IfThen} ${Errors} ${|} Abort "nsJSON::Get failed" ${|}
Pop $1
DetailPrint Count=$1
${IfThen} $1 <> 0 ${|} IntOp $1 $1 - 1 ${|}
${For} $3 0 $1
nsJSON::Get /index $3 /end
${IfThen} ${Errors} ${|} Abort "nsJSON::Get failed" ${|}
Pop $2
DetailPrint Object=$2
${Next}
${For} $3 0 $1
nsJSON::Get /index $3 "Return" /end
${IfThen} ${Errors} ${|} Abort "nsJSON::Get failed" ${|}
Pop $2
DetailPrint Object.Return=$2
${Next}
SectionEnd

Related

How to read into byte array file contents and then update them and write into another file?

I want in nsis to be able to read from file contents into byte array, update the array and then write the contents of the buffer into another file.
My Code
System::Call "kernel32::GetFileSize(i$0,i0)i.s"
Pop $7
System::Alloc $7 ;Reading file contents into a buffer
Pop $buffer
System::Call "kernel32::ReadFile(i$0,i$buffer,i$7,*i.r6,i0)i.s"
loop2:
StrCpy $2 $buffer 1 $1
StrCmp $2 '' end
IntOp $1 $1 + 1
goto loop2
I wanted to be able to iterate over the byte array that i read from the file and to be able to change its contents. (OR bytes for instance) and i wanted to save time from reading byte from a file directly and then writing single byte to a new file. So thats why wanted to use buffer byte array allocated.
Is that possible? I saw that nsis does not support arrays natively.
NSIS does not support byte arrays but the System plug-in struct syntax allows you to access raw bytes in a memory buffer:
!include LogicLib.nsh
!include Util.nsh
ShowInstDetails show
!macro DisplayTestFile
FileOpen $0 "$PluginsDir\Test.txt" r
FileRead $0 $1
FileClose $0
DetailPrint Line1=$1
!macroend
Section
InitPluginsDir
FileOpen $0 "$PluginsDir\Test.txt" w
${If} $0 P<> 0
FileWrite $0 "HELLO World$\r$\n"
FileClose $0
${EndIf}
!insertmacro DisplayTestFile
FileOpen $0 "$PluginsDir\Test.txt" a
${If} $0 P<> 0
FileSeek $0 0 Set
System::Call "KERNEL32::GetFileSize(pr0,p0)i.r1"
${IfThen} $1 = -1 ${|} Abort "Could not get file size" ${|}
System::Call '*(&i$1,i0)p.r2' ; Allocate the file size + a zero terminator just in case
${If} $2 P<> 0
System::Call "KERNEL32::ReadFile(pr0,pr2,ir1,*i,p0)i.r3"
${If} $3 <> 0
${For} $3 0 5 ; Change byte 0..5
System::Call '*$2(&i$3,&i1.r4)' ; Read a byte
IntOp $4 $4 | 32
System::Call '*$2(&i$3,&i1 r4)' ; Write a byte
${Next}
FileSeek $0 0 Set
System::Call "KERNEL32::WriteFile(pr0,pr2,ir1,*i,p0)i.r3"
${EndIf}
System::Free $2
${EndIf}
FileClose $0
${EndIf}
!insertmacro DisplayTestFile
SectionEnd

NSIS window disappear

I have tried a lot of possibility with this code but it doesn't work. I need to check a VPN connection. If I run the code firs time it works, but if I don't restart the program and push the button secondly then the program just disappear. Any idea how to fix it? thanks.
Function VpnLoginWindow
${Do}
!insertmacro VpnLoginWindow
StrCpy $4 0
${If} $3 == 1
${Do}
!insertmacro VpnLoginWindow
StrCpy $4 1
StrCmp $3 "0" 0 +2
${ExitDo}
${Loop}
${EndIf}
${If} $4 == 1
${ExitDo}
${EndIf}
${Loop}
FunctionEnd
!macro VpnLoginWindow
StrCpy $5 $1
System::Get "(i.r1) iss"
Pop $R0
System::Call "user32::EnumWindows(k R0, i) i.s"
${Do}
Pop $0
StrCmp $0 "1" 0 +2
${ExitDo}
System::Call "user32::GetWindowText(ir1,t.r2,i ${NSIS_MAX_STRLEN})"
StrCpy $2 $2 7
StrCpy $3 0
${If} $2 == "SSL VPN"
StrCpy $3 1
${ExitDo}
${EndIf}
Push 1 # callback's return value
System::Call "$R0"
${Loop}
System::Free $R0
StrCpy $1 $5
!macroend
Callbacks are tricky to get right and the plug-in is a little buggy. Also, you should not use relative jumps to jump over macros like ${ExitDo}!
!include LogicLib.nsh
!macro FindVpnLoginWindow
Push "" ; Result: Window not found
System::Store S
System::Get '(p.r1, p)ir0r0'
Pop $9
System::Call 'USER32::EnumWindows(k r9, p 0)'
${Do}
${IfThen} $0 != "callback1" ${|} ${ExitDo} ${|} ; <-- adjust the callback# if required
StrCpy $0 1 ; Set callback return value, continue search
System::Call "USER32::GetWindowText(pr1, t.r2, i ${NSIS_MAX_STRLEN})"
StrCpy $2 $2 7
${If} $2 == "SSL VPN"
Pop $2 ; Throw away old result
Push $1 ; Result: HWND
StrCpy $0 0 ; Set callback return value, stop enum with 0
${EndIf}
System::Call $9 ; Return from callback function
${Loop}
System::Free $9
System::Store L
!macroend
Function BackgroundFindWindow
!insertmacro FindVpnLoginWindow
Pop $0
DetailPrint "Result:$0"
FunctionEnd
...
GetFunctionAddress $0 BackgroundFindWindow
BgWorker::CallAndWait
GetFunctionAddress $0 BackgroundFindWindow
BgWorker::CallAndWait

nsis refresh environment during setup

During my setup i install redistributables. After installing my program i want to execute the program during the setup. For that the redistributables are needed. But the environment is not refreshed during setup, so i can't start the program. Can i refresh the environtment during the setup, or reread the environment? Or read the system environment which has changed after the redistributable installation?
I need the environment changes made during the installation of the redistributables during the setup.
Thanks for your help.
I had your same issue, that I solved with a workaround, but I came across this solution and I would like to share with you.
This should reload environment variables during setup:
!include LogicLib.nsh
!include WinCore.nsh
!ifndef NSIS_CHAR_SIZE
!define NSIS_CHAR_SIZE 1
!define SYSTYP_PTR i
!else
!define SYSTYP_PTR p
!endif
!ifndef ERROR_MORE_DATA
!define ERROR_MORE_DATA 234
!endif
/*!ifndef KEY_READ
!define KEY_READ 0x20019
!endif*/
Function RegReadExpandStringAlloc
System::Store S
Pop $R2 ; reg value
Pop $R3 ; reg path
Pop $R4 ; reg hkey
System::Alloc 1 ; mem
StrCpy $3 0 ; size
loop:
System::Call 'SHLWAPI::SHGetValue(${SYSTYP_PTR}R4,tR3,tR2,i0,${SYSTYP_PTR}sr2,*ir3r3)i.r0' ; NOTE: Requires SHLWAPI 4.70 (IE 3.01+ / Win95OSR2+)
${If} $0 = 0
Push $2
Push $0
${Else}
System::Free $2
${If} $0 = ${ERROR_MORE_DATA}
IntOp $3 $3 + ${NSIS_CHAR_SIZE} ; Make sure there is room for SHGetValue to \0 terminate
System::Alloc $3
Goto loop
${Else}
Push $0
${EndIf}
${EndIf}
System::Store L
FunctionEnd
Function RefreshProcessEnvironmentPath
System::Store S
Push ${HKEY_CURRENT_USER}
Push "Environment"
Push "Path"
Call RegReadExpandStringAlloc
Pop $0
${IfThen} $0 <> 0 ${|} System::Call *(i0)${SYSTYP_PTR}.s ${|}
Pop $1
Push ${HKEY_LOCAL_MACHINE}
Push "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"
Push "Path"
Call RegReadExpandStringAlloc
Pop $0
${IfThen} $0 <> 0 ${|} System::Call *(i0)${SYSTYP_PTR}.s ${|}
Pop $2
System::Call 'KERNEL32::lstrlen(t)(${SYSTYP_PTR}r1)i.R1'
System::Call 'KERNEL32::lstrlen(t)(${SYSTYP_PTR}r2)i.R2'
System::Call '*(&t$R2 "",&t$R1 "",i)${SYSTYP_PTR}.r0' ; The i is 4 bytes, enough for a ';' separator and a '\0' terminator (Unicode)
StrCpy $3 ""
${If} $R1 <> 0
${AndIf} $R2 <> 0
StrCpy $3 ";"
${EndIf}
System::Call 'USER32::wsprintf(${SYSTYP_PTR}r0,t"%s%s%s",${SYSTYP_PTR}r2,tr3,${SYSTYP_PTR}r1)?c'
System::Free $1
System::Free $2
System::Call 'KERNEL32::SetEnvironmentVariable(t"PATH",${SYSTYP_PTR}r0)'
System::Free $0
System::Store L
FunctionEnd
Section
Call RefreshProcessEnvironmentPath
SectionEnd
Source: http://forums.winamp.com/showpost.php?p=3028153&postcount=12

CPU Features.GetCount return incorrect number for CPU Cores

I'm using CPU Features plug-in to get CPU core and this is the code:
${CPUFeatures.GetCount} $CPUCore
Apparently, there is a computer with 12 CPU Cores and the $CPUCore shows only 1 core. I think maybe there is a possibility that the $CPUCore only return the first digit, but how can I know it for sure?
Or, is there any other way to get the CPU Core numbers?
I don't know why the plugin is failing but you could ask Windows with something like this:
!include LogicLib.nsh
!ifndef ERROR_INSUFFICIENT_BUFFER
!define ERROR_INSUFFICIENT_BUFFER 122
!endif
!define RelationProcessorCore 0
!if "${NSIS_PTR_SIZE}" <= 4
Function GetProcessorPhysCoreCount
System::Store S
StrCpy $9 0 ; 0 if we fail
System::Call 'kernel32::GetLogicalProcessorInformationEx(i${RelationProcessorCore},i,*i0r2)i.r0?e'
Pop $3
${If} $3 = ${ERROR_INSUFFICIENT_BUFFER}
${AndIf} $2 <> 0
System::Alloc $2
System::Call 'kernel32::GetLogicalProcessorInformationEx(i${RelationProcessorCore},isr1,*ir2r2)i.r0'
Push $1
${If} $0 <> 0
loop_7:
IntOp $9 $9 + 1
System::Call *$1(i,i.r3)
IntOp $1 $1 + $3
IntOp $2 $2 - $3
IntCmp $2 0 "" loop_7 loop_7
${EndIf}
Pop $1
System::Free $1
${Else}
System::Call 'kernel32::GetLogicalProcessorInformation(i,*i0r2)i.r0?e'
Pop $3
${If} $3 = ${ERROR_INSUFFICIENT_BUFFER}
System::Alloc $2
System::Call 'kernel32::GetLogicalProcessorInformation(isr1,*ir2r2)i.r0'
Push $1
${If} $0 <> 0
loop_v:
System::Call *$1(i,i.r3)
${If} $3 = ${RelationProcessorCore}
IntOp $9 $9 + 1
${EndIf}
IntOp $1 $1 + 24
IntOp $2 $2 - 24
IntCmp $2 0 "" loop_v loop_v
${EndIf}
Pop $1
System::Free $1
${EndIf}
${EndIf}
Push $9
System::Store L
FunctionEnd
Function CountSetBits32
Exch $0
Push $1
Push $2
Push $3
StrCpy $3 0
StrCpy $1 0
loop:
IntOp $2 1 << $1
IntOp $2 $2 & $0
${IfThen} $2 <> 0 ${|} IntOp $3 $3 + 1 ${|}
IntOp $1 $1 + 1
StrCmp $1 32 "" loop
StrCpy $0 $3
Pop $3
Pop $2
Pop $1
Exch $0
FunctionEnd
Function GetProcessorLogicalCoreCount
System::Store S
StrCpy $9 0 ; 0 if we fail
System::Call 'kernel32::GetLogicalProcessorInformationEx(i${RelationProcessorCore},i,*i0r2)i.r0?e'
Pop $3
${If} $3 = ${ERROR_INSUFFICIENT_BUFFER}
${AndIf} $2 <> 0
System::Alloc $2
System::Call 'kernel32::GetLogicalProcessorInformationEx(i${RelationProcessorCore},isr1,*ir2r2)i.r0'
Push $1
${If} $0 <> 0
loop_7:
System::Call *$1(i,i.r3,&i22,&i2,i.r5)
Push $5
Call CountSetBits32
Pop $5
IntOp $9 $9 + $5
IntOp $1 $1 + $3
IntOp $2 $2 - $3
IntCmp $2 0 "" loop_7 loop_7
${EndIf}
Pop $1
System::Free $1
${Else}
System::Call 'kernel32::GetLogicalProcessorInformation(i,*i0r2)i.r0?e'
Pop $3
${If} $3 = ${ERROR_INSUFFICIENT_BUFFER}
System::Alloc $2
System::Call 'kernel32::GetLogicalProcessorInformation(isr1,*ir2r2)i.r0'
Push $1
${If} $0 <> 0
loop_v:
System::Call *$1(i,i.r3)
${If} $3 = ${RelationProcessorCore}
System::Call *$1(i.r3)
Push $3
Call CountSetBits32
Pop $3
IntOp $9 $9 + $3
${EndIf}
IntOp $1 $1 + 24
IntOp $2 $2 - 24
IntCmp $2 0 "" loop_v loop_v
${EndIf}
Pop $1
System::Free $1
${EndIf}
${EndIf}
Push $9
System::Store L
FunctionEnd
!endif
Section
Call GetProcessorPhysCoreCount
Pop $0
Call GetProcessorLogicalCoreCount
Pop $1
DetailPrint PhysCores=$0,LogicalCores=$1
SectionEnd
You should still use ${CPUFeatures.GetCount} as a fallback because GetLogicalProcessorInformation[Ex] does not exist on all versions of Windows...
I try to use the code from this forum and modified it a little bit so I only get the processor core numbers:
!include "LogicLib.nsh"
!define ERROR_INSUFFICIENT_BUFFER 122
; Size of SYSTEM_LOGICAL_PROCESSOR_INFORMATION on 32-bit systems
!define SYS_LOG_PROC_INFO_SIZE 24
; Offset of Relationship in the SYSTEM_LOGICAL_PROCESSOR_INFORMATION structure
!define RELATIONSHIP_OFFSET 4
; Enum value of Relationship identifying Processor Core
!define RELATIONPROCESSORCORE 0
; Count the number of bits set in given value
; Parameters: value
; Returns: number of bits set in given value
Function countbits
Exch $0
Push $1
Push $2
; Set initial value for number of bits set in $0
StrCpy $1 0
${While} $0 > 0
; Clear least significant bit set
IntOp $2 $0 - 1
IntOp $0 $0 & $2
; Increment number of bits set
IntOp $1 $1 + 1
${EndWhile}
; Return number of bits set
StrCpy $0 $1
Pop $2
Pop $1
Exch $0
FunctionEnd
; Evaluate processor information
; Paramaters: buffer, length
; Returns: number of cores
Function evalcpuinfo
Exch $0 ; length
Exch
Exch $1 ; buffer
Push $2
Push $3
Push $4
Push $5 ; Processor Cores
Push $6 ; Logical Processors
; Set buffer offset at the end of the buffer
StrCpy $2 $0
; Initialize number of Processor Cores and Logical Processors
StrCpy $5 0
StrCpy $6 0
; Iterate through buffer starting from end
${While} $2 >= ${SYS_LOG_PROC_INFO_SIZE}
; Calculate start address of an element
IntOp $2 $2 - ${SYS_LOG_PROC_INFO_SIZE}
IntOp $3 $1 + $2
; Get ProcessorMask value from element
System::Call "*$3(i.r4)"
Push $4
IntOp $3 $3 + ${RELATIONSHIP_OFFSET}
; Get Relationship value from element
System::Call "*$3(i.r4)"
${If} $4 == ${RELATIONPROCESSORCORE}
; Increment Processor cores
IntOp $5 $5 + 1
; Determine number of Logical Processor by counting the bits
; set in the value of ProcessorMask
Call countbits
Pop $4
; Sum up Logical Processors
IntOp $6 $6 + $4
${Else}
Pop $4
${EndIf}
${EndWhile}
; Set processor information as return value
StrCpy $0 $5
Pop $6
Pop $5
Pop $4
Pop $3
Pop $2
Pop $1
Exch $0
FunctionEnd
; Get processor information
; Returns: number of Processor Cores and Logical Processors
Function getcpuinfo
Push $0
Push $1
Push $2
Push $3
Push $4
; GetLogicalProcessorInformation is only available on
; Windows XP SP3 or its successors.
; Initialize buffer and its length
StrCpy $1 0
StrCpy $2 0
; Determine required length of buffer
System::Call "kernel32::GetLogicalProcessorInformation(ir1, *ir2r2) i.r3 ? e"
Pop $4
${If} $3 == 0
${If} $4 == ${ERROR_INSUFFICIENT_BUFFER}
; Allocate buffer
System::Alloc $2
Pop $1
${If} $1 != 0
; Get processor information
System::Call "kernel32::GetLogicalProcessorInformation(ir1, *ir2r2) i.r3 ? e"
Pop $4
${If} $3 != 1
StrCpy $0 "Error: $4"
${Else}
Push $1 ; buffer
Push $2 ; length
Call evalcpuinfo
Pop $0
${EndIf}
; Deallocate buffer
System::Free $1
${Else}
StrCpy $0 "Error: memory allocation failed!"
${EndIf}
${Else}
StrCpy $0 "Error: $4"
${EndIf}
${Else}
StrCpy $0 "GetLogicalProcessorInformation is not available on your system!"
${EndIf}
Pop $4
Pop $3
Pop $2
Pop $1
Exch $0
FunctionEnd
I think the code is quite similar with Anders code. I have tried it in three different PCs and get the correct numbers for processor core.

NSIS example of auto-update the installer itself?

I am looking for a NSIS example that is able to update itself with the latest version of the installer.
The logic is simple: check if the publish URL is newer than the current executable and download it and recall itself with the same parameters.
Mainly that's would me something like "wget --timestamp URL" but so far I wasn't able to find any NSIS file download extension that is able to download a file only if is newer.
INetC::head will grab just the HTTP headers from the server but IMHO downloading a .ini file with version info from the server is better...
Here's something I wrote that might be of help to you. I have not tested this thoroughly but it did work on the first couple tests I ran. This is just an example I threw together for a project I'm working on. Hope it's of use to you. =)
VersionCompare Function
;=#
;= Taken and modified from:
;= http://nsis.sourceforge.net/VersionCompare
Function VersionCompare
!define VersionCompare `!insertmacro _VersionCompare`
!macro _VersionCompare _VER1 _VER2 _RESULT
Push `${_VER1}`
Push `${_VER2}`
Call VersionCompare
Pop ${_RESULT}
!macroend
Exch $1
Exch
Exch $0
Exch
Push $2
Push $3
Push $4
Push $5
Push $6
Push $7
BEGIN:
StrCpy $2 -1
IntOp $2 $2 + 1
StrCpy $3 $0 1 $2
StrCmp $3 '' +2
StrCmp $3 '.' 0 -3
StrCpy $4 $0 $2
IntOp $2 $2 + 1
StrCpy $0 $0 '' $2
StrCpy $2 -1
IntOp $2 $2 + 1
StrCpy $3 $1 1 $2
StrCmp $3 '' +2
StrCmp $3 '.' 0 -3
StrCpy $5 $1 $2
IntOp $2 $2 + 1
StrCpy $1 $1 '' $2
StrCmp $4$5 '' EQUAL
StrCpy $6 -1
IntOp $6 $6 + 1
StrCpy $3 $4 1 $6
StrCmp $3 '0' -2
StrCmp $3 '' 0 +2
StrCpy $4 0
StrCpy $7 -1
IntOp $7 $7 + 1
StrCpy $3 $5 1 $7
StrCmp $3 '0' -2
StrCmp $3 '' 0 +2
StrCpy $5 0
StrCmp $4 0 0 +2
StrCmp $5 0 BEGIN NEWER2
StrCmp $5 0 NEWER1
IntCmp $6 $7 0 NEWER1 NEWER2
StrCpy $4 '1$4'
StrCpy $5 '1$5'
IntCmp $4 $5 BEGIN NEWER2 NEWER1
EQUAL:
StrCpy $0 0
Goto FINISH
NEWER1:
StrCpy $0 1
Goto FINISH
NEWER2:
StrCpy $0 2
FINISH:
Pop $7
Pop $6
Pop $5
Pop $4
Pop $3
Pop $2
Pop $1
Exch $0
FunctionEnd
UpdateCheck Function
;=#
;= Author: demon.devin
;= http://softables.tk/
Function UpdateCheck
!define UpdateCheck `!insertmacro _UpdateCheck`
!macro _UpdateCheck _NAME _LINK _URL _VERSION
Push `${_URL}`
Push `${_VERSION}`
Call UpdateCheck
Pop `${_NAME}`
Pop `${_LINK}`
!macroend
Exch $1
Exch
Exch $0
Push $0
Push $1
DetailPrint "Current Version: $1"
GetTempFileName $R1
NSISdl::download $0 $R1
ReadINIStr $R0 "$R1" "PAFInfo" "Version"
DetailPrint "Latest Version: $R0"
${VersionCompare} $1 $R0 $R4
${If} $R4 == 0
${OrIf} $R4 == 1
ReadINIStr $R3 "$R1" "PAFInfo" "Name"
StrCpy $File `$R3`
StrCpy $R2 ""
StrCpy $Link ``
${Else}
ReadINIStr $R2 "$R1" "PAFInfo" "DownloadLink"
StrCpy $Link `$R2`
ReadINIStr $R3 "$R1" "PAFInfo" "Filename"
StrCpy $File `$R3`
${EndIf}
SetDetailsPrint none
Delete $R1
SetDetailsPrint lastused
Pop $1
Pop $0
Exch $R2
Exch
Exch $R3
FunctionEnd
WGetDownload Function
;=#
;= Author: demon.devin
;= http://softables.tk/
Function WGetDownload
!define WGetDownload "!insertmacro _WGetDownload"
!macro _WGetDownload _RETURN _TEMPFILE _URL _FILENAME
Push ${_URL}
Push ${_FILENAME}
Call WGetDownload
Pop ${_TEMPFILE}
Pop ${_RETURN}
!macroend
Exch $1
Exch
Exch $2
Push $1
Push $2
!define WGET `$PLUGINSDIR\wget.exe`
!define WGETCMD `"${WGET}" --html-extension --referer="http://www.google.com" --user-agent="Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.6) Gecko/20070725 Firefox/2.0.0.6" -T 10 --no-check-certificate "$Link" --output-document=$File`
MessageBox MB_OK|MB_USERICON|MB_TOPMOST "Package: $File$\r$\nLink: $Link$\r$\n$\r$\nClick OK to start download."
DetailPrint "Downloading: $Link"
SetOutPath `$PLUGINSDIR`
File `${NSISDIR}\Contrib\7zip\wget.exe`
WGET:
SetOutPath `$PLUGINSDIR`
ExecDos::Exec /TOSTACK `${WGETCMD}`
Pop $0
Pop $1
${If} $0 = 1
StrCmp $2 1 +3
StrCpy $2 1
Goto WGET
Goto FAIL
${EndIf}
${If} ${FileExists} "$PLUGINSDIR\$File"
ClearErrors
StrCpy $R5 true
StrCpy $R7 "$PLUGINSDIR\$File"
${GetSize} "$PLUGINSDIR" "/M=$File /S=0K" $0 $1 $2
IfErrors 0 +2
StrCpy $0 $0 * 1024
IntCmp $0 100 +3 0 +3
IntCmp $0 0 +2 +2 0
IntOp $0 103 + 0
IntOp $0 $0 * 10
IntOp $0 $0 / 1024
StrCpy $1 "$0" "" -1
IntCmp $0 9 +3 +3 0
StrCpy $0 "$0" -1 ""
Goto +2
StrCpy $0 "0"
MessageBox MB_OK|MB_USERICON|MB_TOPMOST "Your file $File was successfully downloaded! ($0.$1 MiB)"
Goto DONE
${Else}
FAIL:
StrCpy $R5 "Your file $File has failed to download using the WGet utility!"
Goto CANCEL
${EndIf}
CANCEL:
MessageBox MB_OK|MB_ICONSTOP|MB_TOPMOST "ERROR!$\r$\n$\r$\n$R5"
StrCpy $R5 false
StrCpy $R7 ""
SetErrors
DONE:
Pop $2
Pop $1
Exch $R5
Exch
Exch $R7
FunctionEnd
OpenWebPage Macro
;=#
;= Author: demon.devin
;= http://softables.tk/
!define OpenWebPage '!insertmacro "_OpenWebPage"'
!macro _OpenWebPage _URL
ExecShell open "${_URL}"
!macroend
EXAMPLE USAGE:
;=#
;= Author: demon.devin
;= More NSIS help:
;= http://softables.tk/docs
Section "MAIN"
ClearErrors
MessageBox MB_USERICON|MB_YESNO|MB_TOPMOST `Would you like to check for any possible upgrades?` IDYES CHECK IDNO NOCHECK
NOCHECK:
DetailPrint "What?! How can you improve if you don't check for upgrades?"
Goto DONE
CHECK:
DetailPrint "Checking for new version..."
${UpdateCheck} $0 $1 "http://softables.tk/repository/docs/manifests.ini" "6.25.11.0"
StrCmp $1 "" 0 +5
DetailPrint "You have the most recent version..."
MessageBox MB_USERICON|MB_OK|MB_TOPMOST `$0 is up to date!`
DetailPrint "Continuing with the rest of the operation..."
Goto DONE
DetailPrint "There's a new version available..."
MessageBox MB_ICONEXCLAMATION|MB_YESNO|MB_TOPMOST "New version of $File available.$\r$\nDownload now?" IDYES YES IDNO NO
NO:
DetailPrint "Fine! Stick with the old stuff. See if I care..."
Goto DONE
YES:
DetailPrint "Great! Downloading new updates now..."
${WGetDownload} $R0 $R1 "$Link" "$File"
${If} $R0 == true
${AndIf} $R1 != ""
DetailPrint "Downloaded: $R1"
DetailPrint "Awesome! The download was successful..."
CopyFiles /SILENT `$R1` `$INSTDIR\WGET\$R1`
DetailPrint "Extracting the contents now..."
File '/oname=$PLUGINSDIR\7z.dll' `${NSISDIR}\Contrib\7zip\7z.dll`
File '/oname=$PLUGINSDIR\7z.exe' `${NSISDIR}\Contrib\7zip\7z.exe`
ExecDos::Exec /TOSTACK `"$PLUGINSDIR\7z.exe" x "$R1" -o"$INSTDIR" -aoa -y` "" ""
Pop $0
DetailPrint "All done! Cleaning up temporary files..."
Delete `$R1`
DetailPrint "Finished. Enjoy..."
${Else}
DetailPrint "Something went wrong! The download was unsuccessful..."
MessageBox MB_ICONEXCLAMATION|MB_YESNO|MB_TOPMOST "You can manually download the upgrades by visiting:$\r$\n$Link$\r$\n$\r$\nGo there now?" IDYES WEB IDNO DONE
WEB:
DetailPrint "Launching web page now... "
SetDetailsPrint none
${OpenWebPage} "$Link"
SetDetailsPrint lastused
${EndIf}
DONE:
DetailPrint "Moving right along..."
SectionEnd

Resources