Still in progress with NSIS Setup.
The thing is now I´m executing NSIS executables during my "main" setup. Those other setups, which I´m executing, generate uninstaller for themselve. When I´m performing the uninstaller in the main setup I would like to call those generated uninstaller files.
I´m doing the execution with nsExec::ExecToLog but if a executable is not from the decompressed from the .exe you won´t be able to execute it. Am I right? Is there any solution to solve this problem?
I´m very grateful for every answer!
You can use nsExec::ExecToLog with whatever you like.
It could be extracted:
SetOutPath $INSTDIR
File foo.exe
nsExec::ExecToLog $INSTDIR\foo.exe
It could be a path already known:
nsExec::ExecToLog $WINDIR\bar.exe
It could be calculated:
ReadINIStr $0 $INSTDIR\uninstaller-paths.ini UninstallerPaths baz
nsExec::ExecToLog $0
It really doesn't matter. As far as the script is concerned, it's purely a command string to execute.
Related
I'm creating one installer. I need VC++2013 runtime for my applicaiton. So i'm checking and if not found VC++ runtime i'm installing it from my installer.
To do that, I'm copying VC++ runtime exe into programfiles/myapplication and running it using
ExecWait '"$INSTDIR\vc.exe" /passive /norestart' $0
Delete "$INSTDIR\vc.exe"
But the problem is vc.exe is not getting deleted. It remains in programfiles/myapplication folder.
I use IfErrors command and found that error occurs.
Please suggest me how to solve this
ExecWait always waits until the child process ends but just because the process has ended does not mean you can delete the .EXE file. It should ideally mean that but in some cases Explorer or Anti-Virus will keep files locked for a couple of seconds. Without more information it is hard to say why it can't be deleted, Process Monitor will probably provide some clues.
You could try
ExecWait '"$INSTDIR\vc.exe" /passive /norestart' $0
Sleep 2500
Delete "$INSTDIR\vc.exe"
but since you are just going to delete it anyway, I would suggest extracting it somewhere else that NSIS will try to clean up for you instead:
Section
InitPluginsDir
File "/oname=$PLUGINSDIR\vc.exe" "c:\myredistfiles\vc.exe"
ExecWait '"$PLUGINSDIR\vc.exe" /passive /norestart' $0
SectionEnd
Trying to run a batch file at the end of an installation, everything works great except this file won't run.
section "Startup"
Exec '"$0" /C "C:\Program Files\placeholder\startup\startup.bat"'
sectionEnd
Everything gets deposited in the right spot, using absolute pathing to call this. I asked for administrator privileges at the start,
RequestExecutionLevel admin ;Require admin rights on NT6+ (When UAC is turned on)
Just copying from the example NSIS installer provided here
The file is there so I must be making a mistake with the file path or missing some parameter. Been trying a lot of permutations like nsExec but not sure my mistake. Hopefully this is a simple mistake and will aid others in the same boat at some time.
Without more information I would guess that this is a 64-bit Windows machine and filesystem redirection is causing your 32-bit installer to access the wrong program files directory.
The code you posted is also problematic because we don't know what $0 is. I assume you failed to post the code where it expands %comspec%. To rule out this, replace $0 with $sysdir\cmd.exe.
Ideally your installer should extract the batch file to the destination directory:
Section
SetOutPath $InstDir
File batch.bat
ExecWait '"$sysdir\cmd.exe" /C if 1==1 "$InstDir\batch.bat"'
SectionEnd
If you must access the 64-bit folder you can disable the redirection but this is not recommended:
!include x64.nsh
Section
${DisableX64FSRedirection}
ExecWait ... $ProgramFiles64\...
${EnableX64FSRedirection}
SectionEnd
I think that you should give us more information to solve this problem.
Based on current information, I guess there are two reasons:
"C:\Program Files" is a path for 64-bit programs, but NSIS installer is a 32-bit program, so this path will be redirected to "C:\Program Files (x86)". You can use the solution from Anders to solve it.
Your batch file may contains relative paths. When you run your batch file from the NSIS installer, your working directory is not as same as your batch file. Due to this, some command cannot run correctly. You can use %~dp0 to solve it.
I have an application which has development, testing and live versions. I have a command procedure which currently creates 3 different versions of the installer, which can be installed on 3 separate computers.
What I would like to do would be to have one NSIS script which I pass in a parameter to, which will create one of the versions of the installer changing the name of the product and the installation folder. This will allow me to install all 3 versions on the same computer.
What I have tried so far is;
Function .onInit
Var /GLOBAL INSTALL_TYPE
${GetOptions} $CMDLINE "/t" $INSTALL_TYPE
${if} $INSTALL_TYPE == ""
StrCpy $INSTALL_TYPE "Live"
ReadEnvStr $R0 SYSTEMDRIVE
StrCpy $INSTDIR "$LOCALAPPDATA\Programs\MyComp\MyApp$INSTALL_TYPE\"
FunctionEnd
!define MUI_PRODUCT "FCDS-RECAP$INSTALL_TYPE"
OutFile "MyApp-$INSTALL_TYPEinstaller.exe"
One of the main errors I get has to do with MUI_PRODUCT and look similar to;
warning 6000: unknown variable/constant "INSTALL_TYPE.lnk" detected, ignoring (FullDeploymentUser.nsi:121)
warning 6000: unknown variable/constant "INSTALL_TYPE" detected, ignoring (FullDeploymentUser.nsi:124)
Two types of comments would be useful;
This is what you are doing wrong...
This is what you should be doing...
As always any help is appreciated.
MUI_PRODUCT is technically not an official NSIS define, some guy just invented it and used it in a guide.
All instructions starting with ! are preprocessor instructions, those and OutFile and File cannot be controlled by ${GetOptions} because they happen at compile time on your developer machine.
I don't really recommend this 3 in 1 installer solution, it is a bit complicated. It is much better to just create 3 different installers:
!ifndef APPTYPE
!error "APPTYPE not defined"
!endif
Name "MyApp ${APPTYPE}"
OutFile "MyApp ${APPTYPE} setup.exe"
InstallDir "$ProgramFiles\MyApp ${APPTYPE}"
Page Directory
Page InstFiles
Section
SetOutPath $InstDir
File /r "c:\myfiles\MyApp\${APPTYPE}\*"
SectionEnd
and then just generate them with makensis -DAPPTYPE=Beta myapp.nsi etc.
If you really want this 3 in 1 style then you need to use the macros in Sections.nsh to manipulate the sections so that only one of them is visible and active. You also need to mark the install somehow (.ini file?) so that your uninstaller also knows which install type it is uninstalling.
I have a question related to NSIS.
I have an installer created by NSIS in ("c:/Installer/Installer.exe" folder).
When I run the installer it creates a log file("c:/Installer/installlog.txt") in the installation folder. After I successfully run Installer.exe I want only the installlog.txt to be deleted from "c:/Installer" .
I have the following function
Function .onInstSuccess
call cleanUp
ifSilent 0 +2
${LogText} "INFO :: Application has been installed"
CopyFiles "$EXEDIR\${INSTALL_LOG}" "$Dir\LogFiles\"
IfFileExists "$Dir\LogFiles\{INSTALL_LOG}" DoNothing CopyAgain
CopyAgain:
CopyFiles "$DIR\${INSTALL_LOG}" "$Dir\LogFiles\"
Delete "$DIR\${INSTALL_LOG}"
goto DoNothing
DoNothing:
SetOutPath $EXEDIR
Delete "$EXEDIR\*.log" ;....................**but the file does not get deleted**
FunctionEnd
can some one please tell me how can I make this work.
I need to fix this as soon as possible, help on this is greatly appreciated
I assume you are using these logging macros. You should call ${LogSetOff} after the last call to ${LogText} so the file handle is closed, you should then be able to delete the file.
Also, using Delete "$EXEDIR\*.log" is not a good idea, you already know the filename...
During the installation of my application I install a library used to export various functions to $INSTDIR. During uninstallation I want to call a function in this library to perform a task and return. Based on what I've tried so far it seems that the call to the function fails and I always get back 'error' as $0.
This is what I'm running in my uninstallation script:
SetPluginUnload alwaysoff
SetOutPath $INSTDIR
System::Call "myutils::uninstalling() i.r0"
DetailPrint 'RETURN CODE: "$0"'
SetPluginUnload manual
The few examples I've found copied the .dll to a temp directory and then ran System:Call but the library is already in $INSTDIR. Thoughts?
Wasn't an issue with the NSIS code, the function needed to be exported in the .def file so NSIS could resolve it sans decoration.