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
First you have an error here -
that should probably be -
instead.
Second, you need to include StrRep.nsh as well when using ReplaceInFile. Here it is in case you don't have it -
I don't get system::call .
Insert original signature here with Greasemonkey Script.
Allows you to check if you app is currently running. And if it is to then not start again.
Release Team Member
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.
Also the process name will change if someone renames the launcher.
I got it working perfectly now.
Release Team Member