How to read the contents of a packed file when the uses cancels an NSIS installation? - nsis

I want to report to a Web Service whether the installation completed successfully or not. The identifiers that need to be passed to the service are stored in an uncompressed text file along with the other (compressed) files. Everything works on a successful installation, but when the user cancels the installation, no files are extracted (as expected) and I am unable to find a way to extract a specific file from the archive.
I have considered some other options (writing a custom plugin, parsing through the installer executable file), but I hope there is a cleaner solution.

You can extract files at any point in the installer, in your case probably in .onInstFailed or .onUserAbort:
Function .onInstFailed
InitPluginsDir
SetOutPath $pluginsdir
File something.ext
; Do something with "$pluginsdir\something.ext"
; Note: $pluginsdir is automatically deleted when installer quits...
FunctionEnd

Related

Can NSIS's $TEMP value be over-ridden?

I have a customer using Host Intrusion Protection and has set every User's temp folder not to allow execution (C:\users\\AppData\Local\Temp). NSIS extracts all plugin dlls and its own dlls into a folder below %TEMP%. The problem is nothing is allow to execute from temp so the entire install fails. What I need to know is how to tell NSIS to use a different folder. The only work around I can find is to edit the TEMP and TMP values under the registry key HCU\Environment from "%USERPROFILE%\AppData\Local\Temp" to something like C:\NSISTEMP. However even though this works changing the registry and then putting it back is not really an option. I also cannot just redirect InitPluginDir as that only effects plug-ins and not the rest of what NSIS extracts (icons xml files etc...). Any ideas?s
You can set %TMP% in a terminal/console window before running the installer, there is no need to edit the registry.
In NSIS v3+ you can use UnsafeStrCpy:
Function .onInit
UnsafeStrCpy $Temp "c:\foo\bar"
CreateDirectory "$Temp"
FunctionEnd
The real problem is the security "solution", why would preventing execution from %Temp% but not from other directories really provide any protection after the bad guys find out about this restriction?
If the installer is started with the special _?=$InstDir parameter then it is not copied to %Temp%.
Try this (look for more info in documentation) maybe it is safer than overriding $Temp folder and so on.

Identifying file updations in NSIS

In NSIS is there any way to identify whether the application file is modified from the user side while updating the application using installer?
My requirement is while updating the application, we need to give warning message in case of user modify the application file. If 'Yes' we need to update the file, otherwise we should not update.
You probably have two options; you can get the modified time with GetFileTime or use something like the MD5 plugin (md5dll::GetMD5File).
You could save the original values in a .ini when you install and then compare with these values when updating...
Use archive attribute. Archive attribute is there especially for such purpose.
Below steps demonstrates the behaviour of archive bit:
Unset archive bit of any file in your pc, using Properties > advanced > untick "File is ready for archiving"
Edit and save the file with an appropriate tool. For example Notepad for a text file.
Note that archive bit of the file is set, signalling that this file is modified.
So the method will be like this:
Unset archive bit of all necessary source files in NSIS compiler PC
In NSIS script use [File /a] to extract the source files to destination computer preserving attributes
While reinstalling use GetFileAttributes to detect if the file is modified or original and take steps accordingly.

How to check if file locked/used by other process NSIS

Hi I am writing nsis script for a patch installer. Before installer copies new files I need to check if any process is using the files I want to replace and I want rename those files to tmp and delete them on reboot.
Is there any way installer can detect that if any process is using those files (in my case the files I am going to install are dlls).
There is no native way in NSIS how to do this. But there are third party tools which can detect dlls used by certain process - maybe you could use them in your installer.
But my question is: Do you really need to detect this?
What about deleting files directly with Delete /REBOOTOK file command? (http://nsis.sourceforge.net/Docs/Chapter4.html#4.9.4.11)
If /REBOOTOK is specified and the file cannot be deleted then the file is deleted when the system reboots.

is it possible to tell NSIS to setof files listed in a config file?

I have to download different files from a location on the network, http, but the file names versions I want to supply in a configuration file. is this possible ?
You can read from files with the NSIS ini instructions, manual parsing with FileRead or use one of the helper macros.
You can download files with the INetC plugin...

NSIS: How to check whether *.dll from my installation is in $SYSDIR?

I wanted to write an NSIS script, let's call it for now setup.nsi, and check
if several required dll files already exists in $SYSDIR
Let me emphasize on the word "several"
What I understand from nsis IfFileExists documentation is that if I type in:
IfFileExists $SYSDIR\blabla.dll +2 +1
then it checks if blabla.dll is in $SYSDIR .. but what if I want to know if *.dll from where setup.nsi copies the file (i.e. the *.dll's that I am interested in installing in.. and they are a lot of them.. so I can't just go around checking for all the names) exists in $SYSDIR
During uninstallation I want to then be able to delete them from $SYSDIR (using some uninstall.log to see if I really copied them in $SYSDIR.. and again the wildcard question).
Please be patient with me as I am really new to NSIS scripts.
Is it REALLY necessary to write and delete in $SYSDIR ? Unless yours is a system file, there's no reason for it to be in $__SYS__DIR. If you need to use a specific version of a library, consider DLL redirection (put your DLL in your app dir and use the .local feature) - see the MSDN article on DLL redirection and Side-by-side assemblies.
Plus, you are one typo away from wrecking the user's computer ("Deleted: C:\Windows\System32\user32.dll").
As Piskvor mentions, I don't think you should be worrying about deleting system DLLs in the uninstaller. In case you want to overwrite system DLLs with an updated version, you may want to look at the SetOverwrite command. It lets you overwrite files if what you've got is newer.
Windows XP (SP2?) and up has file protection for system32, so you can't overwrite system critical files in there.
Do try to stay away from that.
Also, to check for your file specifically, see if there's a plugin for NSIS that can calculate checksums and compare that on uninstall. That's probably the safest, IF you really need to do it.
I'd suggest install files somewhere else and add that to PATH.

Resources