You are here

NSIS Help please.

7 posts / 0 new
Last post
Jacob Mastel
Offline
Last seen: 3 years 6 months ago
Developer
Joined: 2007-06-13 19:36
NSIS Help please.

I'm working on making a launcher for a app called Skinner. But I keep getting this annoying message. My Code is:

Outfile ..\..\SkinnerPortable.exe
Name "Skinner Portable"
Icon "..\..\App\AppInfo\appicon2.ico"
SilentInstall Silent
AutoCloseWindow True
RequestExecutionLevel user

!include "FileFunc.nsh"
!include "ReplaceInFile.nsh"
!include "Registry.nsh"
!insertmacro GetRoot

Var APPDIR
Var SETDIR

Section Main
	
		System::Call 'kernel32::CreateMutexA(i 0, i 0, t "SkinnerPortable"2) i .r1 ?e'
			Pop $0
			StrCmp $0 0 DefineVariables TheEnd
		
		DefineVariables:
			StrCpy $APPDIR "$EXEDIR\App\Skinner"
			StrCpy $SETDIR "$EXEDIR\Data\Settings"
			
		CheckINI:
			IfFileExists "$SETDIR\SkinnerPortable.ini" CheckReg
				CopyFiles "$EXEDIR\App\DefaultData" "$SETDIR\SkinnerPortable.ini"
				
		CheckReg:
			IfFileExists "$SETDIR\Skinner.reg" "" Splash
				${GetRoot} $EXEDIR $0
				ReadINIStr $1 "$SETDIR\Skinner.ini" "Settings" "LastDriveLetter"
				${ReplaceInFile} "$SETDIR\Skinner.reg" "$1\" "$0\"
				${registry::RestoreKey} "$SETDIR\Skinner.reg" $R0
				
		Splash:
			ReadINIStr $0 "$SETDIR\SkinnerPortable.ini" "Settings" "DisplaySplash"
			StrCpy $0 "false" LaunchApp
			newadvsplash::show /NOUNLOAD 1200 0 0 -1 /L "$EXEDIR\Other\Source\skinner portable.jpg"
		
		LaunchApp:
			SetOutPath "$APPDIR"
			ExecWait "$APPDIR\skinner.exe"
		
		SaveRegKeys:
			${registry::SaveKey} "HKEY_CURRENT_USER\Software\Zhorn" "$SETDIR\Skinner.reg" "" $R0
		
		TheEnd:
			newadvsplash::stop /WAIT
SectionEnd

And the error is:

Processed 1 file, writing output:
Adding plug-ins initializing function... Done!
Error: resolving install function "StrReplace" in function "RIF"
Note: uninstall functions must begin with "un.", and install functions must not
Error - aborting creation process
wraithdu
Offline
Last seen: 10 years 10 months ago
Developer
Joined: 2007-06-27 20:22
First you have an error here

First you have an error here -

System::Call 'kernel32::CreateMutexA(i 0, i 0, t "SkinnerPortable"2) i .r1 ?e'

that should probably be -

System::Call 'kernel32::CreateMutexA(i 0, i 0, t "SkinnerPortable2") i .r1 ?e'

instead.

Second, you need to include StrRep.nsh as well when using ReplaceInFile. Here it is in case you don't have it -

; StrReplace
; Replaces all ocurrences of a given needle within a haystack with another string
; Written by dandaman32
 
Var STR_REPLACE_VAR_0
Var STR_REPLACE_VAR_1
Var STR_REPLACE_VAR_2
Var STR_REPLACE_VAR_3
Var STR_REPLACE_VAR_4
Var STR_REPLACE_VAR_5
Var STR_REPLACE_VAR_6
Var STR_REPLACE_VAR_7
Var STR_REPLACE_VAR_8
 
Function StrReplace
  Exch $STR_REPLACE_VAR_2
  Exch 1
  Exch $STR_REPLACE_VAR_1
  Exch 2
  Exch $STR_REPLACE_VAR_0
    StrCpy $STR_REPLACE_VAR_3 -1
    StrLen $STR_REPLACE_VAR_4 $STR_REPLACE_VAR_1
    StrLen $STR_REPLACE_VAR_6 $STR_REPLACE_VAR_0
    loop:
      IntOp $STR_REPLACE_VAR_3 $STR_REPLACE_VAR_3 + 1
      StrCpy $STR_REPLACE_VAR_5 $STR_REPLACE_VAR_0 $STR_REPLACE_VAR_4 $STR_REPLACE_VAR_3
      StrCmp $STR_REPLACE_VAR_5 $STR_REPLACE_VAR_1 found
      StrCmp $STR_REPLACE_VAR_3 $STR_REPLACE_VAR_6 done
      Goto loop
    found:
      StrCpy $STR_REPLACE_VAR_5 $STR_REPLACE_VAR_0 $STR_REPLACE_VAR_3
      IntOp $STR_REPLACE_VAR_8 $STR_REPLACE_VAR_3 + $STR_REPLACE_VAR_4
      StrCpy $STR_REPLACE_VAR_7 $STR_REPLACE_VAR_0 "" $STR_REPLACE_VAR_8
      StrCpy $STR_REPLACE_VAR_0 $STR_REPLACE_VAR_5$STR_REPLACE_VAR_2$STR_REPLACE_VAR_7
      StrLen $STR_REPLACE_VAR_6 $STR_REPLACE_VAR_0
      Goto loop
    done:
  Pop $STR_REPLACE_VAR_1 ; Prevent "invalid opcode" errors and keep the
  Pop $STR_REPLACE_VAR_1 ; stack as it was before the function was called
  Exch $STR_REPLACE_VAR_0
FunctionEnd
 
!macro _strReplaceConstructor OUT NEEDLE NEEDLE2 HAYSTACK
  Push "${HAYSTACK}"
  Push "${NEEDLE}"
  Push "${NEEDLE2}"
  Call StrReplace
  Pop "${OUT}"
!macroend
 
!define StrReplace '!insertmacro "_strReplaceConstructor"'
digitxp
digitxp's picture
Offline
Last seen: 12 years 7 months ago
Joined: 2007-11-03 18:33
I don't get system::call .

I don't get system::call .

Insert original signature here with Greasemonkey Script.

Jacob Mastel
Offline
Last seen: 3 years 6 months ago
Developer
Joined: 2007-06-13 19:36
System::Call

Allows you to check if you app is currently running. And if it is to then not start again.

Release Team Member

wraithdu
Offline
Last seen: 10 years 10 months ago
Developer
Joined: 2007-06-27 20:22
System::Call allows you to

System::Call allows you to call functions in other DLLs, like Windows API functions. This particular function, CreateMutex, creates....a mutex. I don't fully understand the programming concept, but here's what I got -

In a multi-threaded process, it's bad to have more than one thread access the same piece of data at the same time. This can lead to corruption and inconsistent states. So a program can create a mutex (mutual exclusion). Only one thread can access a mutual exclusion at a time, therefore alleviating the problem.

As it relates to our purposes, the ERROR_ALREADY_EXISTS flag is returned by GetLastError() if a program tries to create a named mutex that already exists, ie the second time the launcher is run. The System::Call.... command creates this mutex, then calls GetLastError() and puts the value on the NSIS stack. We get this value with the "Pop $0" command. If this value is non-zero, then the mutex already exists and we know our launcher is being run a second time.

Why do it this way? Becuase if we just check for the launcher's process name, it will always return true, even the first time it's run.

Hope that makes a little sense.

Bruce Pascoe
Offline
Last seen: 12 years 3 months ago
Joined: 2006-01-15 16:14
...

Also the process name will change if someone renames the launcher. Smile

Jacob Mastel
Offline
Last seen: 3 years 6 months ago
Developer
Joined: 2007-06-13 19:36
Thanks

I got it working perfectly now.

Release Team Member

Log in or register to post comments