Upload
toby-sherman
View
219
Download
0
Tags:
Embed Size (px)
Citation preview
More on NSIS
As I eluded to last day, the NSIS is an insanely powerful.
To demonstrate that, we’re going to run with it some more and create some new NSI scripts that edit the registry, create uninstallers and edit ini files.
Adding Registry Entries
Thus, getting down to it, editing the Registry is the first step to creating an uninstaller.
In effect, we store some data in it which we can later access to find out what files we put where.
Adding Registry Entries
So first, a quick look at what the registry looks like.
You can access yours by typing regedit at the command prompt.
Adding Registry Entries
Registry keys Stored values
Adding Registry Entries
The NSIS gives us acronyms for accessing these:
HKCR or HKEY_CLASSES_ROOT HKLM or HKEY_LOCAL_MACHINE HKCU or HKEY_CURRENT_USER HKU or HKEY_USERS HKCC or HKEY_CURRENT_CONFIG HKDD or HKEY_DYN_DATA HKPD or HKEY_PERFORMANCE_DATA
Adding Registry Entries
Having a quick look we see that we can store all sorts of information in here.
My UT 2003 reg entry:
Adding Registry Entries
Now, you can edit this by hand if you like by right clicking the REF_SZ value, but this IS playing with fire... You will likely break stuff.
The registry is how windows know what, and where things are!
Adding Registry Entries
So what tools does NSIS give us then?
Well, if you refer to the docs, there’s a list of like a dozen items. We don’t need all of this functionality so we’ll just look at what we are going to use here.
Adding Registry Entries
InstallDirRegKey is the first item we need.
This attribute tells the installer to check a string in the registry, and use it for the install dir if that string is valid.
Adding Registry Entries
If this attribute is present, it will override the InstallDir attribute if the registry key is valid, otherwise it will fall back to the InstallDir default.
Adding Registry Entries
Usage:
InstallDirRegKey HKLM SOFTWARE\EZE_INSTALL "Install_Dir"
Registry path Value nameWhich key to install under
Adding Registry Entries
What this gives us…
A new registry directory under local machine
A variable to store our path in
Adding Registry Entries
HKLM: is HKEY_LOCAL_MACHINE key and we’ll be using this the most.
However, there’s no reason why you couldn’t store some of your data elsewhere.
Adding Registry Entries
SOFTWARE\EZE_INSTALL is literally the path in the registry (under HKLM) where to store our data
And the Install_Dir is the variable we create to hold out install path. It’s currently uninitalized.
Editing Registry Entries
Next we’ll need to set our value with WriteRegStr
Simply writes a string into the registry.
Notice the path and parameter is the same as above.
WriteRegStr HKLM SOFTWARE\EZE_INSTALL "Install_Dir" "$INSTDIR"
Editing Registry Entries
In this case, we store the path to our install directory.
WriteRegStr HKLM SOFTWARE\EZE_INSTALL "Install_Dir" "$INSTDIR"
Editing Registry Entries
So the next step towards building an uninstaller is to let the windows uninstaller know about it.
Editing Registry Entries
We achieve this by adding uninstall information into the windows uninstall registry.
SoftwareMicrosoftWindowsCurrentVersionUninstall
Editing Registry Entries
We simply use the same WriteRegStr command and specify a different path
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Goober" "DisplayName" " EZE Installer (REMOVE ME)"
Editing Registry Entries
However in this case, we need to define our uninstall string also.
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Goober" "UninstallString" '"$INSTDIR\uninstall.exe"'
Creating the Uninstaller
The actual creation of the uninstaller surprisingly simple…a one liner.
Where uninstall.exe is the desired name of the output uninstall program.
WriteUninstaller "uninstall.exe"
Creating the Uninstaller
Well, yeah, this will create the program for us, but it’s won’t do anything because we’ve not told it about where to get it’s uninstall information.
Creating the Uninstaller
Well, funnily enough, NSIS has commands for this too:
DeleteRegKey: Deletes a registry key. If “/ifempty” is
specified, the registry key will only be deleted if it has no subkeys (otherwise, the whole registry tree will be removed).
Creating the Uninstaller
So, in this case, we’ll need to specify DeleteRegKey command for both our dir and the windows uninstall dir.
Creating the Uninstaller
Notice the paths are the same as when we used the WriteRegStr.
DeleteRegKey HKLM "Software\Microsoft\Windows\ CurrentVersion\Uninstall\Goober"
DeleteRegKey HKLM SOFTWARE\EZE_INSTALL
Windows uninstall dir
Our Install registry entry
Creating the Uninstaller
And this will do just what it promises and remove the entries in the registry.
But what about the files? An uninstaller is no good if we don’t get ride of those!
Creating the Uninstaller
To simply delete a file is nothing more than: Delete $INSTDIR\Goober\Notepad.exe
Delete command: Delete file (which can be a file or wildcard, but
should be specified with a full path) from the target system.
Creating the Uninstaller
Hrmmm…”Wild card”?
Sure we can delete files one by one…But that’s lame. If we go back to the old DOS prompt days, we would use * operators to indicate “all”
Creating the Uninstaller
So if we go with the *.* we tell it the delete all files with any postfix
Will purge everything in this folder.
This also works for copying.
Delete $INSTDIR\Goober\*.*
Creating the Uninstaller
So then we just need to get ride of the uninstaller program and the directory.
Delete $INSTDIR\uninstall.exe
RMDir "$INSTDIR\Goober
Kill off the uninstaller
Remove the folder
Creating the Uninstaller
RMDir command: Remove the specified directory (which should
be a full path). Without /r, the directory will only be removed
if it is completely empty. If /r is specified, the directory will be removed
recursively, so all directories and files in the specified directory will be removed.
Creating the Uninstaller
So lets whip one up, and from there we’ll look at Editing ini files with NSIS
But this time, lets use something other than notepad to get started…
Slate Blue
I discovered this great scripting tool called Slate Blue which is super handy for setting up your nsi scripts.
There are 2 versions both available from http://www.morphedmedia.com/ …both are free.
Slate Blue
Version 1.0 is a really handy GUI for creating simple nsi scripts that can save you from the mundane tasks of setup…like name and color and what not.
Slate Blue
Then there’s version 1.07 which is a really nice scripting program which allows you to create and edit nsi scripts.
However, the last time I looked, it was a bit unstable.
Slate Blue
Not to mention that it has a full list of NSIS commands in the left window.
The right side is where you do your scripting…very handy.
Editing INI files
So on with INI files
Editing INI files
Once again, the actual editing of an existing ini file is surprisingly easy and NSIS have given us a nice tool to do it.
WriteINIStr Writes entry_name=value into [section_name]
of ini_filename. The error flag is set if the string could not be written to the ini file.
Editing INI files
In other words, this will seek a section head in a file and add an entry.
Eg, if I wanted to add an entry to section [public] in test.ini I could use
Editing INI files
WriteINIStr $INSTDIR\Goober\test.ini public "num1" "Something 1"
File name and full pathSection name[public]
Variable nameValue to be set
Editing INI files
Note: You can also use the WriteINIStr to create an ini file that is of the name in the path.
Editing INI files
OK, this is good and all, but there has to be some way to not have to enter ALL the ini edit commands into the installer…
’cause all that typing would suck.
Editing INI files
Rest easy, there is.
We can read from existing ini files using the ReadIniStr.
Editing INI files
ReadIniStr $1 "C:\...Folder\READtest.ini" Mo "num"
File name and full pathSection name[public] to read from
Variable name to readRegister in which to store the data
Editing INI files
Ok great, we can read from one file to another…one line at a time…still lots of typing involved in this.
But NSIS as you recall has piles of functionality with it. We can do string operations and even branching!
Editing INI files
So here’s what I have in mind. We’ll read data from an existing ini and store it in a variable.
We’ll then copy this data from the variable into the target ini file.
Loop until we reach the end of the read file.
Editing INI files
The data will be appended to the end of the test.ini file.
The only requirement in this case is that the variables in the read file must be named similar to num1, num2, num3…numX.
Editing INI files
Functionally, this is a really simple loop with a counter.
Editing INI files
Some functionality that we’ll need:
StrCpy Sets the user variable $x with str. Note that
str can contain other variables, or the user variable being set (concatenating strings this way is possible, etc).
Editing INI files
IntOp Combines value1 and (depending on OP)
value2 into the user variable $x Note: there’s a long list of operator that work
with this…consult the docs.
Editing INI files
StrCmp Compares (case insensitively) str1 to str2. If
str1 and str2 are equal, Gotos jump_if_equal, otherwise Gotos jump_if_not_equal.
Goto Being programmers, I’d be worried if you
didn’t know this one…Here’s the NSIS def:
Editing INI files
If label is specified, goto the label 'label_to_jump_to:'. If +offset or -offset is specified, jump is relative by
offset instructions. Goto +1 goes to the next instruction, Goto -1 goes to the previous instruction, etc.
If a user variable is specified, jumps to absolute address (generally you will want to get this value from a function like GetLabelAddress. Compiler flag commands and SectionIn aren't instructions so jumping over them has no effect.
Editing INI files
So, tying this together, we can start with this:
StrCpy $0 0
loop:IntOp $0 $0 + 1
Set register $0 to 0
Jump here if we loop
Increment by one…just like ++
Editing INI files
ReadIniStr $1 "C:\... Folder\READtest.ini" Mo "num$0"StrCmp $1 "" ExitLoop
Read in our data
Compare the stings.
If we read in nothing, it’s the end of the file so jump to the ExitLoop
Editing INI files
WriteINIStr $INSTDIR\Goober\test.ini Mo "Goob$0" "$1"
Goto loopExitloop:
Write our data to the new ini file
Jump to the loop case if we hit this
If we hit the exit loop, continue and exit. We’re done
Editing INI files
So lets give this a shot then we’ll move on to something a bit more funky with the ini editing.
More INI file control
Now for a little more power… The plan this time around is to directly access both files and copy only the first section out.
We’re only going the copy over the [Mo] section to the new file.
More INI file control
So what’s needed? Yup you guessed it, more commands.
More INI file control
FileOpen Opens a file named "filename", and sets the handle
output variable with the handle. The openmode should be one of "r" (read) "w" (write, all contents of file are destroyed) or "a" (append, meaning opened for both read and write, contents preserved).
In all open modes, the file pointer is placed at the beginning of the file.
If the file cannot be opened, the handle output is set to empty, and the error flag is set.
More INI file control
FileOpen $1 $INSTDIR\goober\test.ini w
Handle stored in register
Full path to file
Open method write (w)
More INI file control
FileRead Reads a string from a file opened with
FileOpen. The string is read until either a newline (or carriage return newline pair) occurs, or until a null byte is read, or until maxlen is met (if specified).
Strings are limited to 1024 characters. If the end of file is read and no more data is
available, the output string will be empty, and the error flag will be set.
More INI file control
FileRead $0 $2
Reads data from file handle $0 and stores it in register $2
More INI file control
FileWrite Writes a string to a file opened with FileOpen.
If an error occurs writing, the error flag will be set.
FileWrite $1 $2
Writes data from file handle $2 and stores it in register $1
More INI file control
FileClose Closes a file handle opened with FileOpen.
FileClose $0
Close the file with this handle $0
More INI file control
The program flow we’ll use here is the same as it was for the last example…
However, there are some differences in the usage of the StrCmp.
More INI file control
Since we are no longer looking for the end of file, the “” search key no longer works.
We need to search for *something*.
In this case “[meh]”
More INI file control
Now one would expect that simply plugging in “[meh]” would work…but it doesn’t.
The NSIS script reads the whole file. Including the non printing characters which is what gimps us.
More INI file control
This little item is not mentioned in the docs. I found the answer on the forums…after about 2 hours of twiddling with the NSI and searching.
More INI file control
In essence, we need to include the line feed and carriage return in the condition.
Or, no worky…
StrCmp $2 "[meh]$\r$\n" ExitLoopEND
More INI file control
There’s also one other neat little command that’s not mentioned in the docs which is DetailPrint.
This allows information to be displayed in the details window.
More INI file control
DetailPrint "$5 lines copied from READTest.ini to test.ini"
More INI file control
So our whole custom ini edit section will be something like:
Section "Playing with INI's"
;open out read write filesFileOpen $0 "C:\... Folder\READtest.ini" r ;read fromFileOpen $1 $INSTDIR\goober\test.ini w ;write to
;Our line counter set to 0Strcpy $5 0 ;
More INI file control
Loop:FileRead $0 $2 ;read a line into register 2
IntOp $5 $5 + 1 ; inc line counter
StrCmp $2 "[meh]$\r$\n" ExitLoopEND ; our exit conditionFileWrite $1 $2 ; write the line if I don't end
Goto Loop
More INI file control
ExitLoopEND:DetailPrint "$5 lines copied from READTest.ini to test.ini"
ExitLoop:;close the files...good house keeping.FileClose $0FileClose $1
SectionEnd ;
More INI file control
This conclude the presentation part for today.
And once again, we’ve not even scratched the surface of what the NSIS system can do…
Read the docs, visit the forums…make NSIS your friend!