Contents
I
Table of Contents Part I Home
3
Part II Chapter I - General Information
3
1 1. Foreword ................................................................................................................................... 3 2 2. About Portables ................................................................................................................................... 4 3 3. Required Level ................................................................................................................................... Of Knowledge 5 4 4. Softwares Used ................................................................................................................................... 5 5 5. Overview Of................................................................................................................................... The Launcher 6 6 6. Choosing The ................................................................................................................................... Software 6 7 7. Safe Portable ................................................................................................................................... 7
Part III Chapter II - The Basics
8
1 1. Selecting Software ................................................................................................................................... 8 2 2. Capturing Changes ................................................................................................................................... 9 3 3. Interpreting ................................................................................................................................... Results 15 4 4. File System ................................................................................................................................... Changes 17 5 5. Windows Registry ................................................................................................................................... 19 6 6. Registry Changes ................................................................................................................................... 20 7 7. Validating ................................................................................................................................... Results 25 8 8. Bringing NSIS ................................................................................................................................... To The Game 27 9 9. Modifying ................................................................................................................................... The Template 28 10 10. Compiling ................................................................................................................................... The Launcher 32 11 11. Keeping Local ................................................................................................................................... Installation 34 12 12. Testing, Testing, ................................................................................................................................... Testing... 38 13 13. Conclusion ................................................................................................................................... 38
Part IV Chapter III - Advanced Topics
39
1 1. Relative Paths ................................................................................................................................... 39 2 2. Reg2Nsis ................................................................................................................................... 41 3 3. Universal Extractor ................................................................................................................................... 43 4 4. Settings In................................................................................................................................... Registry 44 5 5. Hidden Registration ................................................................................................................................... Data 46 6 6. File Management ................................................................................................................................... 47 7 7. More File Management ................................................................................................................................... 51 8 8. Registering ................................................................................................................................... Libraries 53 9 9. Installing MSI ................................................................................................................................... Files 54 10 10. Time and................................................................................................................................... Date 55 © tpr 2007
I
II
How to make portables with NSIS 11 11. .NET and................................................................................................................................... Java 56 12 12. Reducing................................................................................................................................... Size 57 13 13. Failures ................................................................................................................................... 58
Part V Final Words
59
Index
0
© tpr 2007
Home
1
3
Home Chapter I - General Information
Chapter II - The Basics
Chapter III - Advanced Topics
1. Foreword
1. Selecting Software
1. Relative Paths
2. About Portables
2. Capturing Changes
2. Reg2Nsis
3. Required Level Of Knowledge
3. Interpreting Results
3. Universal Extractor
4. Softwares Used
4. File System Changes
4. Settings In Registry
5. Overview Of The Launcher 5. Windows Registry
5. Hidden Registration Data
6. Choosing The Software
6. Registry Changes
6. File Management
7. Safe Portable
7. Validating Results
7. More File Management
8. Bringing NSIS To The Game
8. Registering Libraries
9. Modifying The Template
9. Installing MSI Files
10. Compiling The Launcher 10. Time and Date 11. Keeping Local Installation 11. .NET and Java 12. Testing, Testing, Testing...
12. Reducing Size
13. Conclusion
13. Failures
Final Words
2
Chapter I - General Information 1. About Portables 2. Required Level Of Knowledge 3. Softwares Used 4. Overview Of The Launcher 5. Choosing The Software 6. Safe Portable
2.1
1. Foreword First of all, I have to tell you that making a portable program is software developers' privilege. Only they can design a software not to use the Windows registry, to store its configuration files in their own directory and not to depend on the host computer's system files, etc. In this guide I will show you how to make a launcher for a program. The launcher prepares
© tpr 2007
4
How to make portables with NSIS
the host computer so when the program launches, all of its configuration files and registry entries, etc. are already present on the host computer. Thus the result won't be a portable software at all but a software which will make the original application seem to be portable. When you close the non-portable application, the launcher removes traces from the host computer and saves the configuration settings, so if you launch it on another computer, all your settings will come back. It also restores the settings of a local installation of the program, if any.
2.2
2. About Portables There's a nice introduction about what does portable application mean at PortableApps.com: What is a portable app? portable - carried or moved with ease app - a computer program like a web browser or word processor A portable app is a computer program that you can carry around with you on a portable device and use on any Windows computer. When your USB flash drive, portable hard drive, iPod or other portable device is plugged in, you have access to your software and personal data just as you would on your own PC. And when you unplug the device, none of your personal data is left behind. No Special Hardware - Use any USB flash drive, portable hard drive, iPod/MP3 player, etc No Additional Software - Just download the portable app, extract it and go No Kidding - It's that easy Consider the Possibilities...
Carry your web browser with all your favorite bookmarks Carry your calendar with all your appointments Carry your email client with all your contacts and settings Carry your instant messenger and your buddy list Carry your whole office suite along with your documents and presentations Carry your antivirus program and other computer utilities Carry all your important passwords and account information securely Consider the Convenience... Have your favorite websites handy to recommend to a friend or colleague Have your presentation AND the required software ready to go for that big meeting Have your password with you if you want to bank online while traveling Have utilities handy when visiting family or friends that are having PC problems
But I'm sure if you are reading these guide you are familiar with all the things I cited above. In this guide I'll show you how to create a portable launcher (or often called as wrapper) to a software which is originally not portable, so you'll be able to run it without installing them.
© tpr 2007
Chapter I - General Information
2.3
5
3. Required Level Of Knowledge Basic computer knowledge will do (installing and uninstalling softwares, opening, browsing and saving files, copy and paste operations, etc.). I think if you can cope with a text editor you know enough to complete this guide. However, basic English is a must (if you can read and understand this text, you're ready to go). As you can see, my English is also basic and I'm sure you'll find some sentences which you may not understand. Sorry for that in advance; I tried to do my best to be clear and understandable. There are some nice screenshots which will helpfully help you to understand what's going on. You don't have to worry about the softwares we'll use in this guide. It will be distributed within a package which contains all the tools that we'll need to create portable applications (softwares, template scripts, finished portables, etc.). All the code in this guide is written with yellow background so you can easily distinguish them from the normal text. I usually use double quotes to make sure where's the beginning and the end of the path or the code. However, single and double quotes in scripts are important so you shouldn't delete them.
2.4
4. Softwares Used You can find all the tools listed here in the "Tools" directory. NSIS I make my portables using NSIS (Nullsoft Scriptable Install System). It is basically an install maker and very easy to use. I'm not a programmer and if you follow my instructions I can assure you that you'll be able to make your portable launchers whether you are a programmer or not. Installing NSIS is very simple - go to their homepage and download the installer. You can also find a portable version over the internet. You'll also need the registry plugin for NSIS. It comes with an installer so it is easy to install. There is a tiny software called Reg2NSIS, which can convert .reg files to NSIS scripts. It often makes writing scripts easier. Total Uninstall This software enables to monitor installations easily, including monitoring of registry and file system changes. After the monitoring process registry changes can be exported. Unfortunately version 3 and upwards Total Uninstall is shareware but I'm sure you can get a "fix" for managing this if you are reading this guide. Registry Workshop For registry work I can recommend you to use Registry Workshop. I like this one because it makes registry searching and tweaking easy. It has a nice Undo-Redo feature which is often comes handy. Icons From File For extracting icons from the original application is very easy with the freeware tool called Icons From File. It is straightforward to use and does what its name suggests. SciTE
© tpr 2007
6
How to make portables with NSIS
You'll need a text editor for making the NSIS script. The built-in Windows Notepad will do but I recommend you to use SciTE. It is tiny but powerful and what's more, it's also portable. Universal Extractor Universal Extractor software allows you to extract setup files. This may come handy because you can eliminate the setup process, and thus no modification is made to the system before the first launch. However, it's drawback is that you have to find out where does it save its settings (registry or in other files). RegMon Regmon is a Registry monitoring utility that will show you which applications are accessing your Registry, which keys they are accessing, and the Registry data that they are reading and writing - all in real-time. It is useful when you want to find which registry keys the program is using, where does it store the registration data, etc. FileMon FileMon monitors and displays file system activity on a system in real-time. You can use it if you want to monitor your file system (what files were accessed, created, deleted, etc.). You'll also need a file manager and you'll have to have admin rights on your computer but these are obvious, I think. Of course, you can use other softwares if you wish.
2.5
5. Overview Of The Launcher In the following chapters we'll build a launcher which will do the following: Step 1
Step 3
Makes a backup of the program's settings found in the registry (if any) Makes a backup of the program's settings found in other files outside the program's directory (if any) Imports program settings to the registry
Step 4
Imports username and serial to the registry
Step 5
Changes paths to the program in the registry
Step 6
Launches the software and waits until it's closed
Step 7
Saves (exports) program settings from the registry
Step 8
Cleans up program traces
Step 9
Restores original registry settings found in step 1
Step 2
Step 10 Restores other settings files (see step 2) Of course, this is only a general scheme. Sometimes you'll need only 3 or 5 steps; it all depends on the candidate program's behaviour. And sometimes you have to tuck more steps into this scheme to be able to create the portable version of the program.
2.6
6. Choosing The Software First of all, you have to choose a software which you would like to put on your USB stick and use it wherever you go. You should choose a software which could be used as portable. I © tpr 2007
Chapter I - General Information
7
mean there's no sense creating a portable version of a software which is heavily tied to the machine (i.e. media catalogue software when the media files are stored on the local computer, etc.). The easy case is when the software is freeware, then you won't have to find a crack or a serial to turn it to a full version. I won't discuss about this case because if you go through this guide you'll be able to make them portable. So, back to trial limitations... Basically two situations can occur: 1. Serial protection 2. Other protection (crack, patch or cracked files, licence files, etc). The best situation is when you have a cracked exe (or other file). After replacing the original file(s) you're almost ready in most cases, you shouldn't bother with registration or license issues. But even if the program starts up and runs fine, you have to examine the software's behaviour - where does it store its configuration files (registry or in some directory), how deeply it integrates to the host computer's system and so on. Only this way can you make sure that your portable is going to work as expected. You should get familiar with the software and you should know everything about how it works, if it's possible. If the software is protected by a serial number and it is stored in the registry or in other location beside the program's directory, you must create a launcher that restores the registration info before the software is launched. In Chapter II we'll create a launcher for this kind of software.
2.7
7. Safe Portable The terminology of portable applications is not so large because it's a relatively new phenomenon. I don't want to add new words or phrases to it but I think "Safe" and "Unsafe" portables must be distinguished. In my opinion "Safe Portables" are portable applications (or launchers) that keep the local installation on the host computer intact. So if someone runs the portable version and then closes it, the launcher should remove its traces and restore all settings in the registry and in the file system that has been modified. If you'll follow this guide you'll create safe portables. To tell you the truth, safe portables are very rare to find. Unfortunately unsafe portables prevails the portable world at this time. They are working good, one can use them exactly the same way as they were safe ones. But if there's any local installation of the software, these portables would modify or destroy them so they won't work after you've run them. I think creating unsafe portables instead of safe ones is the biggest mistake the creator can make. If you share them with others, you'll come across angry users who are complaining that your portables destroyed the locally installed softwares on their computer. You really should avoid this. I came across portables that were so unsafe that they turned my XP into a crap so I wasn't even able to boot it up. If you use an unsafe portable you should be aware that some unwanted files and/or directories (in Application Data, Documents and other directories) and/or some registry keys will be left on your computer. If you use many unsafe portables, your computer may become
© tpr 2007
8
How to make portables with NSIS
slower and slower. But this is the smallest problem. Unsafe portables may overwrite (or even delete) some important system files or registry keys, which may cause undesirable results, such as some installed programs won't run, your system may become unstable, you'll get strange error messages and so on, provided if your computer is able to boot up. I think it's unnecessary to say that we should avoid all these things. There are cases when you cannot create a safe portable but only unsafe version of the software. If you are about to share them, notify the users that it may destroy the local install of the same software. I have to admit that my earlier portables weren't safe. Although they did a clean-up after closing them, settings of the local installation (if any) weren't restored. To sum it up: take care to create safe portables. After all, you have to create them only once, so make it as perfect as you can.
3
Chapter II - The Basics 1. Selecting Software 2. Capturing Changes 3. Interpreting Results 4. File System Changes 5. Windows Registry 6. Registry Changes 7. Validating Results 8. Bringing NSIS To The Game 9. Modifying The Template 10. Compiling The Launcher 11. Keeping Local Installation 12. Testing, Testing, Testing... 13. Conclusion
3.1
1. Selecting Software Let's warm-up with an easy one, My Notes Keeper 1.7.0.771. It is a commercial software and it can be activated with a serial number. Info about the software from its website: My Notes Keeper is the premier note/outliner application for Windows 9x/2000/XP/NT. It allows you to store all of your notes and information in an easy-to-use outline, where you can quickly find what you need.
© tpr 2007
Chapter II - The Basics
9
I selected this one because it uses the registry to store the registration info only, so we shouldn't bother with saving and restoring settings. Before you start, make sure you're logged in as an administrator (or as a user with admin rights). For best results, use a clean operating system. Note: this chapter will be somewhat lengthy because the next chapters will use the information discussed here.
3.2
2. Capturing Changes First, we have to examine what files are copied and what registry keys are created during the normal installation process. To do this, we will need Total Uninstall (TU).
You will find TU in the "Tools" directory. Launch it with "Portable Total Uninstall 3.exe". © tpr 2007
10
How to make portables with NSIS
However, it is not portable, you should enter the serial number after launching it (see serial.txt in "Tools\Total Uninstall" directory). You can enter the registration info in Help Register submenu.
Start up Total Uninstall and click on the first icon in the top-left corner (Install). If TU disappears, you'll find it minimized in the system tray (next to your system clock). In the window that appears, click on the Browse... button and select the setup file of My Notes Keeper, "mnk.exe" (you'll find it in "Install\My.Notes.Keeper.v1.7.0.771" directory). You can also drag and drop this file to TU's Install window.
© tpr 2007
Chapter II - The Basics
11
When you're done, click on Next button in TU. Now TU examines your system status so after the installation it will be able to find the changes that were made during the installation process.
© tpr 2007
12
How to make portables with NSIS
When the system scan is ready, click on Next button. Be sure that "Launch setup application now" is selected. Now TU launches the setup file, mnk.exe. Follow the instruction and install MNK as you normally would do. Do not close TU during the installation process but you can minimize it. Leave everything at its default settings during the install process.
© tpr 2007
Chapter II - The Basics
13
At the end of the install process click on the Finish button and let the setup file launch MNK. If MNK won't start, launch it manually (i.e. with its desktop icon or from the Start menu). Do not close TU now. When MNK starts up, go to Help-Enter Serial Number. We'll now use the keygen from "Install\My.Notes.Keeper.v1.7.0.771" to generate a serial. To simplify this process, I'll use "Portable" as Name and the generated Registration key is "35AE664E73E18872". So paste this info to MNK's registration box.
© tpr 2007
14
How to make portables with NSIS
Now MNK is registered, you can close it. Go back to TU and click on the Next button. Now TU examines what changes were made to your system. When the scan finishes, click on the Close button.
© tpr 2007
Chapter II - The Basics
3.3
15
3. Interpreting Results Now we'll examine the results. If you can see nothing in TU's main window, then click on the Details icon in the toolbar or from the menu (View-Details) and be sure that on the left-side panel MNK is selected.
© tpr 2007
16
How to make portables with NSIS
If you fold in the branches under My Computer in TU, you can see that changes are grouped in three categories: 1. File System 2. Registry 3. Installed Services and Devices
© tpr 2007
Chapter II - The Basics
17
The third one, Installed Services and Devices can't be unfolded because during the setup process no services or drivers were installed. That's good because it is very hard or impossible to create a launcher for a software which installs a service or a driver.
3.4
4. File System Changes Now let's examine the changes in File System, so unfold the branch "File System" in Total Uninstall's results window. The first branch is "C:\Documents and Settings\All Users\Start Menu\Programs\My Notes Keeper".
© tpr 2007
18
How to make portables with NSIS
These are only links (.lnk files), so nothing important for us. This branch can be deleted from this list (select these links or the folder "My Notes Keeper" above them and hit the Delete button). There's another link on your Desktop if you choose this option during the install process. Now you can delete this also. You'll find at least two files under "C:\Documents and Settings\YOUR USER NAME" in the list, named NTUSER.DAT and NTUSER.DAT.LOG. These files aren't important for us, delete them from the list. The next branch is "C:\Program Files\MyNotesKeeper". Here are the main program files, we'll need them. So go to your file manager and copy this directory somewhere (i.e. "C:\Portable My Notes Keeper"). Now you can delete this list item in TU's list if you wish. I usually delete it to keep the list more simple. Next one is "C:\WINDOWS\Debug\UserMode\userenv.log". Just a log file, delete this branch. Next item is system32 with sub-items like software.LOG, SOFTWARE in the "Config" © tpr 2007
Chapter II - The Basics
19
directory and some other files "wbem\Repository\FS" directory. These aren't important for MNK to run, so can be deleted. Now the File System branch has no other items, we can continue to the Registry section.
3.5
5. Windows Registry For those who don't know too much about the Windows registry, here is some very basic info about it from Wiki. Windows registry The Windows registry is a database which stores settings and options for the operating system for Microsoft Windows 32-bit versions, 64-bit versions and Windows Mobile. It contains information and settings for all the hardware, operating system software, most non-operating system software, users, preferences of the PC, etc. Whenever a user makes changes to Control Panel settings, file associations, system policies, or installed software, the changes are reflected and stored in the registry. The Windows registry was introduced to tidy up the profusion of per-program INI files that had previously been used to store configuration settings for Windows programs. These files tended to be scattered all over the system, which made them difficult to track. Registry structure The Registry is split into a number of logical sections, or "keys". These are generally known by the names of the definitions used to access them in the Windows API, which all begin "HKEY" (an abbreviation for "Handle to Key"); often, they are abbreviated to a three- or four-letter short name starting with "HK" (e.g. HKCU and HKLM). Each of these keys is divided into subkeys, which may contain further subkeys, and so on. Any key may contain entries with various types of values. The values of these entries can be: String Value Binary Value (any arbitrary data) DWORD Value, a 32 bit unsigned integer (numbers between 0 and 4,294,967,295 [232 – 1]) Multi-String Value Expandable String Value Registry keys are specified with a syntax similar to Windows' path names, using backslashes to indicate levels of hierarchy. E.g. HKEY_LOCAL_MACHINE\Software\Microsoft\Windows refers to the subkey "Windows" of the subkey "Microsoft" of the subkey "Software" of the HKEY_LOCAL_MACHINE key. Values are not referenced via this syntax. Value names can contain backslashes which would lead to ambiguities were they referred to this way. The win32 functions that query and manipulate registry values take value names separately from the key path and/or handle that identifies the parent key. The HKEY_LOCAL_MACHINE and HKEY_CURRENT_USER nodes have a similar structure to each other; applications typically look up their settings by first checking for them in
© tpr 2007
20
How to make portables with NSIS
"HKEY_CURRENT_USER\Software\Vendor's name\Application's name\Version\Setting name", and if the setting is not found looking instead in the same location under the HKEY_LOCAL_MACHINE key. When writing settings back, the reverse approach is used — HKEY_LOCAL_MACHINE is written first, but if that cannot be written to (which is usually the case if the logged in user is not an administrator), the setting is stored in HKEY_CURRENT_USER instead. HKEY_CLASSES_ROOT Abbreviated HKCR, HKEY_CLASSES_ROOT stores information about registered applications, including associations from file extensions and OLE object class ids to the applications used to handle these items. On Windows 2000 and above, HKCR is a compilation of HKCU\Software\Classes and HKLM\Software\Classes. If a given value exists in both of the subkeys above, the one in HKCU\Software\Classes is used. HKEY_CURRENT_USER Abbreviated HKCU, HKEY_CURRENT_USER stores settings that are specific to the currently logged in user. HKCU mirrors the current user's subkey of HKEY_USERS. HKEY_LOCAL_MACHINE Abbreviated HKLM, HKEY_LOCAL_MACHINE stores settings that are general to all users on the computer. This key is found within the file %SystemRoot%\System32\Config\system on NT-based versions of Windows. Information about system hardware is located under the SYSTEM key. HKEY_USERS Abbreviated HKU, HKEY_USERS contains subkeys corresponding to the HKEY_CURRENT_USER keys for each user registered on the machine. HKEY_CURRENT_CONFIG Abbreviated HKCC, HKEY_CURRENT_CONFIG contains information gathered at runtime; information stored in this key is not permanently stored on disk, but rather regenerated at boot time. Of course, you can find more info about on the Wiki site but you don't have to be a registry expert to create portables. To tell you the truth, some info I cited above was new to me also. What is more important, you should bother only with HKCR, HKCU and HKLM when creating portables. Now everybody should know what does Windows Registry mean and what sections it has, so let's continue examining changes in the registry.
3.6
6. Registry Changes First let's export all the registry changes that were made during the install process. To do this, go to "File-Export-Registry to re-apply Changes" in TU.
© tpr 2007
Chapter II - The Basics
21
In the appearing dialog box select "All" instead of "Selected branch" and select Created Keys, Created Values and Modified Values (new data), and set File Type to Win9x/NT4 Registration file. Click on OK. Save it to "C:\Portable My Notes Keeper\" and name it to "FullReg.reg". If you saved MNK's main program files to another place, then save this reg file also there. Now unfold all sub-groups in the Registry branch. Now you can see 3 items:
© tpr 2007
22
How to make portables with NSIS
1. HKEY_CLASSES_ROOT (HKCR) 2. HKEY_CURRENT_USER (HKCU) 3. HKEY_LOCAL_MACHINE (HKLM) HKEY_CLASSES_ROOT The first, HKEY_CLASSES_ROOT is a place where Windows stores file associations and other things. Some application also stores registration info here. Now it has three items: 1. .mnk 2. CLSID 3. mnkfile. The first and the third are file type associations, you can delete them (we'll use them later when cleaning up registry but we can remove it from the list because we exported the full registry changes to FullReg.reg). © tpr 2007
Chapter II - The Basics
23
Expand the second one (CLSID) and its sub-branch ("{B0CC8D3F-EF1A-4400-A5C7-1A2230AA0B8C}"). It has three entries: Code, Days and Name.
Yes, this is the registration info, and we should save it to a safe place. So select its parent key ("{B0CC8D3F-EF1A-4400-A5C7-1A2230AA0B8C}") and go to "File-Export-Registry to re-apply changes". Save it to "C:\Portable My Notes Keeper\" and name it to "RegInfo.reg".
© tpr 2007
24
How to make portables with NSIS
Now you can delete it from the list if you wish but I recommend you to keep it because it is a very important data. HKEY_CURRENT_USER Next branch is HKEY_CURRENT_USER. This branch, unlike the other two, is accessible when the user has no admin rights on the PC. If a software stores its settings here, it can be run when the user has no admin rights (provided there's no other restriction on the PC). Here's only one branch: "HKEY_CURRENT_USER\Software\Microsoft\Windows\ShellNoRoam\MUICache". As these files aren't important, we can delete it from the list. And there's no other items here, we can continue to HKEY_LOCAL_MACHINE. HKEY_LOCAL_MACHINE In HKEY_LOCAL_MACHINE the first branch is "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\RNG\Seed". Nothing important, delete from the list. The next is "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\State\Machine\Extension-List\{00000000-0000-0000-0000-000000000000}", it can also be deleted. Next is "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\My Notes Keeper_is1". Also can be deleted from the list. Next one is "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Prefetcher\TracesProcessed", delete it from the list. If you have printers installed, you may have "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows © tpr 2007
Chapter II - The Basics
25
NT\CurrentVersion\Print\Printers\YOUR PRINTER'S NAME". Delete it from the list. Now there are no items left in the list. If you have some items left that's because your system is different as mine or some other application generated a system change which TU recorded. Now you can close TU. If it asks you whether you want to save or not, select No. Doing so, you can examine this list later if something goes wrong.
3.7
7. Validating Results Now let's do some test to make sure that the registration info we found is really the data we want. To do this, we'll use Registry Workshop (see "Tools" directory).
Because we have exported registration info to a .reg file (RegInfo.reg, remember?), we should open it with a text editor to see what registry key we want to find. Here's the content of RegInfo.reg: REGEDIT4 [HKEY_CLASSES_ROOT\CLSID\{B0CC8D3F-EF1A-4400-A5C7-1A2230AA0B8C}] "Days"="584592960BAF3BEA" "Name"="Portable" "Code"="35AE664E73E18872"
© tpr 2007
26
How to make portables with NSIS
So the key we need is HKEY_CLASSES_ROOT\CLSID\{B0CC8D3F-EF1A-4400-A5C7-1A2230AA0B8C}
Or simply "HKCR\CLSID\{B0CC8D3F-EF1A-4400-A5C7-1A2230AA0B8C}" Normally you should use the left-side browser in Registry Monitor but because the key is somewhat difficult to find that way, we'll do it in another way. Launch Registry Workshop and paste this line to its address bar (at the top of RW's main window, under the toolbar): HKEY_CLASSES_ROOT\CLSID\{B0CC8D3F-EF1A-4400-A5C7-1A2230AA0B8C}
Now press Enter and RW should jump to this key instantly.
To test if it is the key that stores registration info, we'll delete it. We can do this because we can use the undo function of RW if we want. So select the key name in the left-side browser window and hit Delete button (or select Delete from the context menu). On the confirmation box, select Yes. Now the registration info is not present in the registry, so let's test MNK if it works. Because we deleted the registration data from the registry, MNK should revert back to Trial mode. © tpr 2007
Chapter II - The Basics
27
Go to its install folder ("C:\Program Files\My Notes Keeper") and launch it with "MyNotesKeeper.exe". Yes, the trial warning appears when launching it. Great, the registry key we have deleted was the registration data of MNK.
If you want to play with it a bit more, enter the registration data again in MNK and see if the registry key comes back in the registry (hit F5 in Registry Workshop). As you could see you have to decide what changes are important and what are not. Sometimes it is easy to distinguish important changes but sometimes it is not (especially when examining registry changes). After the third or fifth portable you create you'll be able to decide what are those changes that you should pay attention to. Now we have all the program files and the registry changes in our pocket, we can uninstall My Notes Keeper. Go to Control Panel\Add or Remove Programs and uninstall MNK or use your favorite uninstall software. Make sure that all the program files and its directory is removed from "C:\Program Files" directory (or wherever you installed it) during the uninstall process. If something's left there, delete the directory manually. Note: in some cases registration info is not so easy to find. See "Hidden Registration Data" in Chapter III for more info about it.
3.8
8. Bringing NSIS To The Game Now we have all the files we will need and the registration info, so we can start building up our portable. First, let me introduce the directory structure I use in my portables: [Appdata]
© tpr 2007
28
How to make portables with NSIS
[portable] [Source] Portable Application.exe Appdata directory:
the main program files go here
portable directory:
location of registry data (RegInfo.reg, Settings.reg, RegClean.reg, DirSettings.reg, etc)
Source directory:
the NSIS source file of the launcher (Portable Application.nsi) and the icon of the launcher (Portable Application.ico)
Portable Application.exe the launcher itself We'll make Portable MNK using this directory structure, so do the following changes: 1. Move all files and directories from "C:\Portable My Notes Keeper" to "C:\Portable My Notes Keeper\Appdata" except RegInfo.reg and FullReg.reg 2. Move RegInfo.reg and FullReg.reg to directory "C:\Portable My Notes Keeper\portable" 3. Create a folder in "C:\Portable My Notes Keeper" and name it as "Source". I won't tell you everything about NSIS because that would make this guide very long. However, I'm not an NSIS guru, all I know I know from the NSIS Help and the NSIS forum. I can assure you that NSIS is easy to learn and what we need from NSIS is especially easy, so you don't have to worry about it. Furthermore, I created some nice templates so basically you'll have to replace some items in them and you're ready to go.
3.9
9. Modifying The Template Open "Portable Application.nsi" from directory "Templates" using your text editor. Now save it to "C:\Portable My Notes Keeper\Source" directory and rename it to "Portable My Notes Keeper.nsi". Renaming is very important so do this now. In the third line you'll find this: !define SNAME "Portable Application"
Select the word "Application" and open up replace dialog (in Scite: hit Ctrl+H). In the "Replace with:" field enter "My Notes Keeper", then click on "Replace All". Now all occurrences of the word "Application" is replaced with "My Notes Keeper" and we don't have to change each one manually, and the possibility to make a mistake is also smaller. There's nothing to change until line 34 (Section "Main"). However, you can personalize your launcher if you wish, changing these lines: VIProductVersion "0.1.0.0" VIAddVersionKey /LANG=${LANG_ENGLISH} "ProductName" "Portable My Notes Keeper Launcher" VIAddVersionKey /LANG=${LANG_ENGLISH} "LegalCopyright" "© tpr 2007" VIAddVersionKey /LANG=${LANG_ENGLISH} "FileDescription" "My Notes Keeper"
© tpr 2007
Chapter II - The Basics
29
VIAddVersionKey /LANG=${LANG_ENGLISH} "FileVersion" "0.1"
I think it is straightforward; change the final parts of each rows if you wish (i.e. "© tpr 2007" to "© I am not dumbass for NSIS! 2007"). But you can also remove these five lines if you wish. In Section "Main" you can see these lines: ;-----Importing Regkeys------
${registry::RestoreKey} "$EXEDIR\portable\Settings.reg" $R0 Sleep 300 ${registry::RestoreKey} "$EXEDIR\portable\RegInfo.reg" $R0 Sleep 200 ${registry::RestoreKey} "$EXEDIR\portable\DirSettings.reg" $R0 Sleep 200
These lines, as you may think when reading Restorekey, restores registry keys, or in other words, imports .reg files. You can see the path of the .reg file and the name of it: "$EXEDIR\portable\Settings.reg" $EXEDIR: when launching the portable launcher, $EXEDIR is replaced with the full path of the launcher. So, if we launch it from "D:\MyPortables", $EXEDIR will be replaced with D:\MyPortables. So the whole path looks like this: $EXEDIR\portable\Settings.reg ---> D:\MyPortables\portable\Settings.reg (if you launch it from "D:\MyPortables" location). This feature of NSIS makes it easy to handle the problem arising from the fact that the path of the portable application may change on every PC, according to what drive letter is assigned to the USB stick. It comes handy when we have to enter absolute paths to the registry also. There are several $EXEDIR-like things in NSIS (search the forum if you don't know what they are meaning - neither do I know each one): $INSTDIR, $OUTDIR, $CMDLINE, $LANGUAGE, $PROGRAMFILES, $COMMONFILES, $DESKTOP, $EXEDIR, ${NSISDIR}, $WINDIR, $SYSDIR, $TEMP, $STARTMENU, $SMPROGRAMS, $SMSTARTUP, $QUICKLAUNCH, $DOCUMENTS, $SENDTO, $RECENT, $FAVORITES, $MUSIC, $PICTURES, $VIDEOS, $NETHOOD, $FONTS, $TEMPLATES, $APPDATA, $LOCALAPPDATA, $PRINTHOOD, $INTERNET_CACHE, $COOKIES, $HISTORY, $PROFILE, $ADMINTOOLS, $RESOURCES, $RESOURCES_LOCALIZED, $CDBURN_AREA, $HWNDPARENT, $PLUGINSDIR
As we have seen, MNK stores its settings in an .ini file in its program directory, so no need to import any Settings.reg into the registry. So we can delete this line. The next line contains "Sleep 300". It tells the launcher to take a deep breath and pause for 300 milliseconds. I usually fill my NSIS scripts with sleeps to ensure that every operation has enough time to complete. 1, 2 or more extra seconds when launching won't hurt anybody. Because we have deleted the line with Settings.reg before, now this "Sleep 300" also can be deleted. The next line is "${registry::RestoreKey} "$EXEDIR\portable\RegInfo.reg" $R0". It import the registration data to the Registry, so it is important. Do not delete it, and neither delete the next line ("Sleep 200"). If you plan to use MNK on a slower computer, you can increase the sleep time (but I think 200 ms is enough).
© tpr 2007
30
How to make portables with NSIS
Next two lines can be deleted ("${registry::RestoreKey} "$EXEDIR\portable\DirSettings.reg" $R0" and "Sleep 200"). We'll use it when we will put absolute paths to the registry but now we don't have to do that. The next part is straightforward: ;-----Launching My Notes Keeper-----ExecWait "$EXEDIR\Appdata\My Notes Keeper.exe"
ExecWait does what its name suggests: executes the given program and waits until it (the executed program) finishes. It is handy because we want to clean up registry after the program is closed. Note that the path uses $EXEDIR again, but after it "Appdata" comes. Now we have to see how is our main executable named. In the Appdata directory the name of the exe is "MyNotesKeeper", so change this line to: ExecWait "$EXEDIR\Appdata\MyNotesKeeper.exe"
The next part is ;-----Saving settings-----${registry::SaveKey} "HKEY_CURRENT_USER\Software\My Notes Keeper\The My Notes Keeper" "$EXEDIR\portable\Settings.reg" "/G=1" $R0 Sleep 500
It exports the given registry key to the given registry file, then waits 500 milliseconds. Because here we don't want to export anything, it can be deleted. (The registry key in the code above is non-existent, it was created when doing search and replace). Now comes the cleaning up: ;-----Cleaning up-----${registry::RestoreKey} "$EXEDIR\portable\RegClean.reg" $R0 DeleteRegKey /ifempty HKEY_CURRENT_USER "Software\My Notes Keeper"
First, the launcher imports RegClean.reg. But there's a problem: we don't have any RegClean.reg yet! So let's fix it. Open RegInfo.reg (from "C:\Portable My Notes Keeper\portable" directory) using your text editor and change from Windows Registry Editor Version 5.00 [HKEY_CLASSES_ROOT\CLSID\{B0CC8D3F-EF1A-4400-A5C7-1A2230AA0B8C}] "Days"="584592960BAF3BEA" "Name"="Portable" "Code"="35AE664E73E18872"
to REGEDIT4
© tpr 2007
Chapter II - The Basics
31
[-HKEY_CLASSES_ROOT\CLSID\{B0CC8D3F-EF1A-4400-A5C7-1A2230AA0B8C}]
Notice the minus (-) sign after the first square bracket. If we import this into the registry, it will delete the whole branch ("HKEY_CLASSES_ROOT\CLSID\{B0CC8D3F-EF1A-4400-A5C7-1A2230AA0B8C}"). Save it as RegClean.reg (do not overwrite RegInfo.reg!). One thing we have to do with these reg files: the first row in both files says "Windows Registry Editor Version 5.00". Although it is fine, but change it to "REGEDIT4" to ensure compatibility with older systems (such as Win9x). If you want to delete only a reg value you should use the minus sign this way: REGEDIT4 [HKEY_CLASSES_ROOT\CLSID\{B0CC8D3F-EF1A-4400-A5C7-1A2230AA0B8C}] "Name"=-
This code delete registry value "HKEY_CLASSES_ROOT\CLSID\{B0CC8D3F-EF1A-4400-A5C7-1A2230AA0B8C}\Name" only, "Days" and "Code" will remain in the registry. But now we want to clean the whole key, so put the minus sign in front of the key name. Now we have our RegClean.reg file, but there are some other registry keys that are present in the registry and we should remove them. Open FullReg.reg in your text editor. Although this file contains the registry changes made by the install process, we have to examine it because when launching MNK, it may write some of these settings back to the registry (especially file association keys). These are the keys we should remove: [-HKEY_CLASSES_ROOT\.mnk] [-HKEY_CLASSES_ROOT\mnkfile] [-HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\My Notes Keeper_is1]
These keys may be present in your registry if you launch MNK (even if you haven't install it). You only have to remove the main branch with the minus sign because all sub-branches are removed also. So, for example, "HKEY_CLASSES_ROOT\.mnk\123456\123456\whatstheheckisnext" is also removed when importing [-HKEY_CLASSES_ROOT\.mnk]. So we have to paste these lines after existing ones in RegClean.reg. The entire RegClean.reg should look like this: REGEDIT4 [-HKEY_CLASSES_ROOT\CLSID\{B0CC8D3F-EF1A-4400-A5C7-1A2230AA0B8C}] [-HKEY_CLASSES_ROOT\.mnk] [-HKEY_CLASSES_ROOT\mnkfile] [-HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\My Notes Keeper_is1]
We have this line left in the script: DeleteRegKey /ifempty HKEY_CURRENT_USER "Software\My Notes Keeper"
It is not required here, so delete it. Make sure you haven't deleted "SectionEnd" from the © tpr 2007
32
How to make portables with NSIS
end of the script. Note: there's an NSIS script in directory "Templates" "Portable Template.nsi". It is a general template that I'm using when I create my portables. It contains a lot of things so you should keep only those lines which you need when you build up your script for a portable. It speeds up the script-writing process and it's more easier to replace some words than beginning with a blank .nsi file.
3.10
10. Compiling The Launcher Now the script is ready, we should compile it and the portable version of MNK is ready. However, we have to extract the icon from the main exe first. To do this, launch "extraico.exe" from "Tools\Icons from File" directory. It is a very simple application, just drag and drop "MyNotesKeeper.exe" from "C:\Portable My Notes Keeper\Appdata" directory to its window. Two icons appears in extraico.exe's window.
The first looks very attractive, select it and click on the second icon on the toolbar, then select "Save selected" (or Ctrl+S). Save it to "C:\Portable My Notes Keeper\Source" with name "Portable My Notes Keeper.ico". It is important that the name of the .ico and the name of the .nsi files should be the exactly the same, or you won't be able to compile the script. So in "Source" directory you should have these two files: Portable My Notes Keeper.nsi © tpr 2007
Chapter II - The Basics
33
Portable My Notes Keeper.ico Also, the third line in the .nsi file should be !define SNAME "Portable My Notes Keeper". If you get error when compiling with NSIS, you should check if these names are the same first. Okay, everything is in its desired location, let's build up the launcher exe. Open "makeNSISw.exe" from directory "Tools\NSIS 2.17". Drag and drop "Portable My Notes Keeper.nsi" file from directory "C:\Portable My Notes Keeper\Source\" into this window. If everything goes fine, the last line in the NSIS window should be (values may differ, of course): Using zlib compression. EXE header size: Install code: Install data:
36864 / 34816 bytes 654 / 2890 bytes 8302 / 30728 bytes
Total size:
45820 / 68434 bytes (67.0%)
If there was an error during compiling, check what NSIS says about the error. There is always a line number when NSIS encounters an error. Go to your script and check that line. Maybe it's just a mistyping or a missing or extra quotes. But if you've followed my instructions properly and I didn't make any mistake, you should find a "Portable My Notes Keeper.exe" in directory "C:\Portable My Notes Keeper".
© tpr 2007
34
How to make portables with NSIS
Now do some testing to see if it works and how it works. If the program MNK won't start, check if everything is okay in line containing ExecWait in the .nsi file. If it starts up, go to the About box and see if it is registered. You have to re-compile the exe if you modified something in the script, of course. One common mistake is that one can think that if a program starts up and says it is registered, it works well also. That's not true. You have to test if every function of the software is working properly. So, in this case, create a new note in MNK (File-New), write something in it, insert a picture, change settings in the options, save it, restart it, so make everything you can to test it thoroughly. Test it on at least 2 or 3 clean PC's to ensure that it works as expected. There's always a possibility that something is left on your PC after the uninstallation of the software, that's why you have to test it on other PC's also. Of course, you cannot test everything but you should try to test your portable as much as you can to ensure that it is working good. If everything is OK, then congratulations! You've just made your first portable! Below is your well-deserved gift. Enjoy!
Now only one thing is left: examining what happens if a local installation is present on the PC. It may seem not so important now that you've just compiled the launcher successfully but if you want to create a really good portable, you should take care of the host computer's health also.
3.11
11. Keeping Local Installation In the previous topics you successfully created the launcher. However, what if a local installation is present in the target machine? If we launch our new portable on a machine where MNK is installed, it will destroy the local installation's registration data and file associations. To fix it, we should modify our script. If you examine our script, the first modification to the registry we do is when we import RegInfo.reg. Doing so, if there's a locally installed MNK, its registration data will be overwritten with our registration data found in RegInfo.reg. To prevent this, we should first save the local installation's registry key into a .reg file, and after the final clean-up we'll import it back. To save a registry key, use this formula: ${registry::SaveKey} "HKEY_CLASSES_ROOT\CLSID\{B0CC8D3F-EF1A-4400-A5C71A2230AA0B8C}" "$EXEDIR\portable\LocalRegInfo.reg" "/G=1" $R0 Sleep 500
This will save the registry key "HKEY_CLASSES_ROOT\CLSID\{B0CC8D3F-EF1A-4400A5C7-1A2230AA0B8C}" to the file LocalRegInfo.reg in "C:\Portable My Notes Keeper \portable" directory. We should add some milliseconds to ensure that the saving of this registry key will be successful (that's why "Sleep 500" is there). © tpr 2007
Chapter II - The Basics
35
Now examine RegClean.reg: REGEDIT4 [-HKEY_CLASSES_ROOT\CLSID\{B0CC8D3F-EF1A-4400-A5C7-1A2230AA0B8C}] [-HKEY_CLASSES_ROOT\.mnk] [-HKEY_CLASSES_ROOT\mnkfile] [-HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\My Notes Keeper_is1]
The first line removes the registration data. Because we will restore local registration data at the and of the script, it is not important here. The two HKCR key is important because these are required for file associations. If we don't save them, clicking on a .mnk file won't open MNK. But let's see if they are really present in the registry! Launch "Portable My Notes Keeper.exe" and while it's running, launch Registry Workshop. Paste this line into its Address bar (below the toolbar) and hit Enter: HKEY_CLASSES_ROOT\.mnk
The "Confirm Create Key" pops up which means there's no such key in the registry. So I was wrong in topic 9 ("Modifying The Template") when I wrote that MNK will create these keys when launching it even if it's not installed. Let's test the next key, "HKEY_CLASSES_ROOT\mnkfile". The same thing happens as before, so there's no such key in the registry. If we test the last key in RegClean.reg, we'll find that it is not in the registry. This means that we shouldn't delete them from the registry when the program finishes because these keys are not in the registry. However, if they are in the registry, this could mean only one thing: these belongs to the local installation of MNK, and if we delete them then we destroy the local installation. The local MNK will run even if these keys are deleted. However, deleting these will destroy file type associations and presumable you will not be able to uninstall the local MNK. We have to change our RegClean.reg file to: REGEDIT4 [-HKEY_CLASSES_ROOT\CLSID\{B0CC8D3F-EF1A-4400-A5C7-1A2230AA0B8C}]
Now it is clear that we should bother with only this key to keep the local installation of MNK intact. The new NSIS script will look like this (I only quote the Section "Main" part here, changes are written in red): Section "Main" ;-----Saving Local Registration Data-----${registry::SaveKey} "HKEY_CLASSES_ROOT\CLSID\{B0CC8D3F-EF1A-4400-A5C7© tpr 2007
36
How to make portables with NSIS
1A2230AA0B8C}" "$EXEDIR\portable\LocalRegInfo.reg" "/G=1" $R0 Sleep 500 ;-----Importing Regkeys-----${registry::RestoreKey} "$EXEDIR\portable\RegInfo.reg" $R0 Sleep 200 ;-----Launching My Notes Keeper-----ExecWait "$EXEDIR\Appdata\MyNotesKeeper.exe" ;-----Cleaning up-----${registry::RestoreKey} "$EXEDIR\portable\RegClean.reg" $R0 Sleep 500 ;-----Restoring Local Registration Data-----${registry::RestoreKey} "$EXEDIR\portable\LocalRegInfo.reg" $R0 SectionEnd
Let's complicate the thing a little bit: what happens if there's no local installation in the target PC but there's a LocalRegInfo.reg file on the USB drive (from previous runs)? If you look at the script part above, you can imagine what would happen: the launcher tries to save the registry key but it founds nothing, so exports nothing. LocalRegInfo.reg remains intact. Then it imports RegInfo.reg, runs the software and then cleans up with RegClean.reg. But after that, it restores LocalRegInfo.reg, so when you leave the computer, a registry key is left on it which wasn't there before running Portable MNK. We do not want that, so we'll modify the script again. To my mind, the easiest way to prevent this is to delete LocalRegInfo.reg at the end of the script. If we do this, on next run there'll be no LocalRegInfo.reg on the USB drive, so nothing will be restored (presuming there's no local installation of MNK). To delete a file with NSIS, use the following code: Delete "$EXEDIR\portable\LocalRegInfo.reg"
We'll have to add some milliseconds before this line to ensure that there's enough time to restore LocalRegInfo.reg (if it exists). Here is the complete and final script: ;---Definitions---!define SNAME "Portable My Notes Keeper" ;----Includes---!include "Registry.nsh" ;-----Runtime switches---CRCCheck off AutoCloseWindow True SilentInstall silent WindowIcon off XPSTYLE on
© tpr 2007
Chapter II - The Basics
37
;-----Set basic information----Name "${SNAME}" Icon "${SNAME}.ico" Caption "${SNAME} Launcher" OutFile "..\${SNAME}.exe" ;-----Version Information-----LoadLanguageFile "${NSISDIR}\Contrib\Language files\English.nlf" VIProductVersion "0.1.0.0" VIAddVersionKey /LANG=${LANG_ENGLISH} Launcher" VIAddVersionKey /LANG=${LANG_ENGLISH} VIAddVersionKey /LANG=${LANG_ENGLISH} VIAddVersionKey /LANG=${LANG_ENGLISH}
"ProductName" "Portable My Notes Keeper "LegalCopyright" "© tpr 2007" "FileDescription" "My Notes Keeper" "FileVersion" "0.1"
Section "Main" ;-----Saving Local Registration Data-----${registry::SaveKey} "HKEY_CLASSES_ROOT\CLSID\{B0CC8D3F-EF1A-4400-A5C71A2230AA0B8C}" "$EXEDIR\portable\LocalRegInfo.reg" "/G=1" $R0 Sleep 500 ;-----Importing Regkeys-----${registry::RestoreKey} "$EXEDIR\portable\RegInfo.reg" $R0 Sleep 200 ;-----Launching My Notes Keeper-----ExecWait "$EXEDIR\Appdata\MyNotesKeeper.exe" ;-----Cleaning up-----${registry::RestoreKey} "$EXEDIR\portable\RegClean.reg" $R0 Sleep 500 ;-----RestoringLocal Registration Data-----${registry::RestoreKey} "$EXEDIR\portable\LocalRegInfo.reg" $R0 Sleep 800 Delete "$EXEDIR\portable\LocalRegInfo.reg" SectionEnd
Compile the launcher and the Portable MNK is ready. Note: if you launch the new Portable MNK, you'll see that no LocalReginfo.reg file is created. That is because NSIS will not save a non-existing registry key. To test if this part of the script is working, select the key ("HKEY_CLASSES_ROOT\CLSID\{B0CC8D3F-EF1A4400-A5C7-1A2230AA0B8C}") in Registry Workshop while Portable MNK is running and simply delete it. Now close Portable MNK. Go back to Registry Workshop and click on the Undo button on the toolbar (or hit Ctrl+Z). Now the registration info is again in the registry but MNK is not running. If you run Portable MNK again, it should save the registration data into the file LocalRegInfo.reg and when you close it, it will put this key back to the registry. If you want, you may delete some files from the "Appdata" directory to make the size of your © tpr 2007
38
How to make portables with NSIS
portable smaller. For example, deleting "unins000.exe", "unins000.dat" and some other nonimportant txt files (licence.txt, Readme.txt, Tips.txt, Whatsnew.txt) won't do any harm.
3.12
12. Testing, Testing, Testing... You should always thoroughly test your portables. I know that it is a very boring activity but if you create something that other people may also use, then make it as perfect as possible or even fool-proof, to ensure that it will work exactly the same way as expected. It isn't pleasant when people complain that your portable won't run or even it did some harm to their computers. For testing Portable MNK, go to another PC's and see if it runs well. You should try it on other operation systems also (Win9x, Win2000, Windows XP, Vista, etc). If it won't run on either of them, notify would-be users that your portable cannot be run on that OS. Use RegMon or FileMon to monitor every activity of the portable. You can also use Total Uninstall to do this, using the Portable MNK exe instead of the setup file. If you find that everything is OK, then you can say: I've made it! Note: no gifts for you now. I was more than generous at the end of topic 10.
3.13
13. Conclusion As you could seen in the previous topics, there's a lot of things you have to pay attention when creating a portable launcher. You have to ask as many "What if?" questions to yourself as you can and try to find the best possible solutions for them. I'm sure that the script we made could be made more better and nicer but I think that will do now. For example, you may use if clauses to test if there's a local install of the software on the host PC or if there's a need to restore registry settings and so on. In this chapter you've learned how to capture changes that were made during the install process, to what changes you should pay attention and how to find registration data. You've also learned how to build up the NSIS script, how to save and restore registry keys from and to .reg files, how to launch an application and how to delete files. That's the basics of creating a portable launcher. In the next chapter you'll find how to create a launcher for a software which will do the following: saves and restores settings in the registry, creates directory, copies and deletes files, renames files to the logged in user's name, registers and unregisters .dll or .ocx files, silently installs .msi files, etc.
© tpr 2007
Chapter II - The Basics
39
Despite the list above you won't learn so much new things in this chapter because you know almost everything you have to know to create your own portable launchers.
4
Chapter III - Advanced Topics 1. Relative Paths 2. Reg2NSIS 3. Universal Extractor 4. Settings In Registry 5. Hidden Registration Data 6. File Management 7. More File Management 8. Registering Libraries 9. Installing MSI Files 10. Time and Date 11. .NET and Java 12. Reducing Size 13. Safe Portable 14. Failures
4.1
1. Relative Paths When creating a portable application you will often find that using relative paths instead of absolute ones spares a lot of time and hard work. The problem is that not every software supports relative paths, so you have to check it first. Definition of absolute and relative paths (from Wiki): A full path or absolute path is a path that points to the same location on one file system regardless of the working directory or combined paths. A relative path is a path relative to the current working directory, so the full absolute path may not need to be given. For example, an absolute path looks like this: "C:\Windows\System32". It must contain a drive letter. A relative path does not contain the drive letter: "Windows\System32". It is relative to the current working directory, so in this example you "must be" in drive C. If you "are" in "D: \Music" and use the relative path above, it will be interpreted as "D:\Music\Windows \System32". So, relative path is dependent from the current working directory. In most cases, paths in the registry must be absolute paths otherwise the software will not run correctly or won't run at all.
© tpr 2007
40
How to make portables with NSIS
You can define relative paths in several ways. The two you will find useful when creating portables are these: .\ = refers to the current directory ..\ = refers to the parent directory
In some cases you shouldn't create a launcher to make a software portable. I'll demonstrate it on a software called Wings 3D, which is a great subdivision modeler software (freeware). I will not begin the install process with Total Uninstall now, because I want only show you how to turn a software portable with changing absolute paths to relative ones in the program's settings. So install Wings 3D ("Install\Wings 3D\wings-0.98.32a.exe"), then go to the directory where you've installed it (you'll find it probably in "C:\Program Files\wings3d_0.98.32a" directory. The directory settings of the program is in the "bin" directory, in "erl.ini" file. Open it with a text editor. Its contents should look like this: [erlang] Bindir=C:\\Program Files\\wings3d_0.98.32a\\bin Progname=erl Rootdir=C:\\Program Files\\wings3d_0.98.32a
The paths of Bindir and Rootdir is given with absolute paths. Note that these paths are not ordinary paths because two backslashes are in it instead of only one. It is important to notice because we should modify it taking this fact into account. First, we have to find the .exe file, because the directory where it is located will be the root directory, and relative paths need a root directory. The .exe file now is Wings3D.exe. The Bindir is the directory "bin" and the Rootdir is the root directory (where the .exe is located). So normally the modified erl.ini should look like this: [erlang] Bindir=.\bin Progname=erl Rootdir=.\
But if we save it this way, Wings3D will not run. Now remember that there was two backslashes in the original erl.ini instead of one, so change erl.ini this way: [erlang] Bindir=.\\bin Progname=erl Rootdir=.\\
Save it and see if it works (it should). Note: you can refer to the current directory with a single point (.). So changing Rootdir to "Rootdir=." will work also. In some cases, when referring to a child directory, you can simply refer it with the directory's name, no need to use points and backslashes. It works here also; change "Bindir=.\\bin" to "Bindir=bin" and it will work also.
© tpr 2007
Chapter III - Advanced Topics
41
In the previous chapter you saw that with NSIS it is really easy to create paths relative to the launcher. For example, "$EXEDIR" refers to the current directory, "$EXEDIR\..\" refers to the parent directory of the launcher. But you can use other ones also, for example: "$WINDIR"=Windows directory, "$PROGRAMFILES"=Program files directory, and so on (see "Templates\NSIS directories.txt"). The beauty of these is that you shouldn't bother with drive letters. For example, if you have to copy a file into the Windows directory but on the target computer it is not on drive C but, for example, on "Y:\wheretoinstallthis\Windows", it will be copied there using "$WINDIR". You can imagine that it is really handy if you want to refer to the user's application data folder, because the name of the user vary on every computer. But using "$APPDATA" in NSIS eliminates this problem. This example is only for showing you how to use relative paths. If you wish to make Wings3D (or any other software) portable, you should check with Total Uninstall that what changes were made during the install process, and create a launcher (wrapper) if it is necessary. In fact, Wings3D creates a directory in the Application Data "C:\Documents and Settings \YOURNAME\Application Data\Wings3D" and a text file in it called "Preferences.txt". If you wish to make it portable, you should handle this text file somehow (see topic "File Management" in this chapter).
4.2
2. Reg2Nsis I mentioned Reg2Nsis in Chapter I when I introduced NSIS. It can convert .reg files to NSIS scripts, so it will convert the code REGEDIT4 [HKEY_CURRENT_USER\Software\MySoftware] "ArchiveSupport"="C:\\Program Files\\Datadir" "LanguageFile"="English.lng" "RootDir"="J:\\" [HKEY_CURRENT_USER\Software\NotMySoftware] "Rev"="3" "Visible"="0" "DockedTo"="ListViewDock" "LastDock"="ListViewDock"
to WriteRegStr HKEY_CURRENT_USER "Software\MySoftware" "ArchiveSupport" "$PROGRAMFILES\Datadir" WriteRegStr HKEY_CURRENT_USER "Software\MySoftware" "LanguageFile" "English.lng" WriteRegStr HKEY_CURRENT_USER "Software\MySoftware" "RootDir" "J:\" WriteRegStr WriteRegStr WriteRegStr WriteRegStr
HKEY_CURRENT_USER HKEY_CURRENT_USER HKEY_CURRENT_USER HKEY_CURRENT_USER
"Software\NotMySoftware" "Software\NotMySoftware" "Software\NotMySoftware" "Software\NotMySoftware"
"Rev" "3" "Visible" "0" "DockedTo" "ListViewDock" "LastDock" "ListViewDock"
As you can see, the first is a normal .reg file, and the resulting code is an NSIS code. This means that you can put this code in your script and it will be equal as if you imported a © tpr 2007
42
How to make portables with NSIS
registry file. So if you want, you can get rid of RegInfo.reg if you build its contents into the launcher. How to use Reg2Nsis? Go to "Tools\Reg2NSIS" and execute "InstallContextMenu.exe". This will put a line into the context menu of .reg files. So if you right-click on a .reg file (i.e. on RegInfo.reg), you'll find an entry saying "Convert to NSIS script". If you select this, it will create a RegInfo.nsh file in the same directory. Open this .nsh file with a text editor. The first eight lines (which are commented out) is about the auther of Reg2NSIS and such things. After them come the lines we want, and the last line of the .nsh file (commented out) tells us that it is the end of the file. When does Reg2Nsis come handy? If you wish, you may convert RegInfo.reg to RegInfo.nsh, and then copy its contents to your .nsi script. Although this method is absolutely correct, I use it only occasionally. You're asking why? Because you may want to update your software (in the "Appdata" directory") and if it is serial-protected, the serial for the new version may not be the same as it was in the earlier version. In these cases you should only update RegInfo.reg and your portable will still working. Otherwise, if you have no RegInfo.reg, you have to modify the script, which is a bit more difficult. As for Settings.reg you shouldn't use Reg2NSIS to convert it to NSIS code, because Settings.reg changes when you set an option in the main program, or if it contains paths. So hard-coding it to the launcher makes no sense. RegClean.reg can be converted to NSIS code because it is fairly constant. However, the path or paths in RegClean.reg may change if you update the main program, so take care of it when updating. But when Reg2NSIS come really handy is when you have to put absolute paths to the registry. As I mentioned that earlier, you can use "$EXEDIR" (which is the launcher's current location) to put the current path of the launcher into the registry, no matter in what drive it is located and in which directory/subdirectory. So, for example, modifying the Reg2NSIS-generated code from WriteRegStr HKEY_CURRENT_USER "Software\MySoftware" "ArchiveSupport" "$PROGRAMFILES\Datadir" WriteRegStr HKEY_CURRENT_USER "Software\MySoftware" "LanguageFile" "English.lng" WriteRegStr HKEY_CURRENT_USER "Software\MySoftware" "RootDir" "J:\"
to WriteRegStr HKEY_CURRENT_USER "Software\MySoftware" "ArchiveSupport" " $EXEDIR\Appdata\Datadir" WriteRegStr HKEY_CURRENT_USER "Software\MySoftware" "LanguageFile" "English.lng" WriteRegStr HKEY_CURRENT_USER "Software\MySoftware" "RootDir" "$EXEDIR"
will change paths in "ArchiveSupport" and "Rootdir" entries dynamically, according to the launcher's current location. If a program requires its paths to be absolute ones in the registry then this is the only way to do this. Of course, you can do this without Reg2NSIS but I think it is much more convenient © tpr 2007
Chapter III - Advanced Topics
43
then writing all the code by hand. You may face a problem when you have to convert hundreds of paths, now imagine how much easier is to do it with Reg2NSIS... However, if your .reg file contains hex values, then NSIS cannot import it to the registry (at least the current version). So, as a general rule, if your .reg file contains hex values, use the registry plugin's restorekey method to put it in the registry: ${registry::RestoreKey} "$EXEDIR\portable\RegInfo.reg" $R0
Otherwise you can use the code converted with Reg2Nsis. You should always check if the generated code is right. In some cases you have to modify it manually but Reg2Nsis works well in general.
4.3
3. Universal Extractor Universal Extractor allows you to extract setup files. This may come handy when you would like to see what files are in it and if you know that the software is portable, you shouldn't install it to get it work. However, UE cannot extract every kind of setup file. We'll see how to use UE with a software called Hotkeyz. HotKeyz is a keyboard utility with hotkey control for executing other files, folders or RUN commands. And it is portable, so if we can extract it with UE, we can use it immediately. To use Universal Extractor, launch "UniExtract.exe" from "Tools\Universal Extractor" directory. Drag and drop the installer of Hotkeyz ("Install\Hotkeyz\htkz2600.exe") to Universal Extractor's window and click on OK. Universal Extractor will extract files from the installer (which was created with Inno Setup as you can see while unpacking). A new directory is created by Universal Extractor, called "htkz2600". In this directory, there's a directory called {app} and the install script, install_script.iss. Because we want program files only, install_script.iss file can be deleted. However, you may open this file with a text editor and see what changes would make the installer if we run it. In the {app} directory you can find the main program files. Because Hotkeyz is portable, you may launch it with the executable "Hotkeyz.exe". In other cases you'll find more than one directories after extracting the setup file. You should examine the files in them. If you're not sure whether the program is originally portable or not, use Total Uninstall to capture changes when running it for the first time. Maybe it copies files or creates directories, creates registry keys and entries, and so on. If you find a directory named "sys" then it contents would be copied to "Windows" or "Windows\System32" directory. Try to copy these files to the main directory, where the main exe is located, because many software will use them from there. If the program is serial-protected, you should also use Total Uninstall to monitor changes when entering registration info. So Universal Extractor may come handy in many cases. It can reduce the time you spend on creating your portable, but use it with care. If UE can extract a setup file and if you can launch the software right after the extraction it does not mean that it is also portable. You
© tpr 2007
44
How to make portables with NSIS
should always investigate what changes does it make to your system before you can say that it's portable.
4.4
4. Settings In Registry Actually, this topic will teach you nothing new. In the previous chapter we used the formula ${registry::SaveKey} "HKEY_CURRENT_USER\Software\My Notes Keeper\The My Notes Keeper" "$EXEDIR\portable\Settings.reg" "/G=1" $R0
which saves the registry key "HKEY_CURRENT_USER\Software\My Notes Keeper\The My Notes Keeper" to file "$EXEDIR\portable\Settings.reg" file. We'll use this formula to save the program's settings stored in the registry to a file, and on next launch, we'll write it back to the registry (importing it). If you examine one of my templates, you should see the following code: ;-----Importing Regkeys-----${registry::RestoreKey} "$EXEDIR\portable\Settings.reg" $R0 Sleep 300 ${registry::RestoreKey} "$EXEDIR\portable\RegInfo.reg" $R0 Sleep 200 ${registry::RestoreKey} "$EXEDIR\portable\DirSettings.reg" $R0 Sleep 200
Here three registry file is imported: Settings.reg, RegInfo.reg and DirSettings.reg. Settings.reg this file contains settings that is stored in the registry RegInfo.reg this is only the registration info (user name and serial in most cases) DirSettings.reg this file is used to clear paths in registry The order of these .reg files are important, you shouldn't change it. If you change some settings in the application, this change is stored in the registry (provided that the application stores its settings in the registry, of course). Because we save settings to Settings.reg from the registry, this file is always changing. So it shouldn't contain registration data because it is constant. That's why we store registration info in RegInfo.reg. It is imported after Settings.reg to ensure that the data it writes to the reigstry is not overwritten by the data in Settings.reg. Otherwise you may loose your registration data which we really don't want to. The third one is DirSettings.reg. I use it to clear paths in the registry which must be overwritten with absolute paths. For example, we want to import these path to the registry: "H:\Data". "H" is the drive letter of the usb drive, which changes every time you plug in your USB drive at another computer. Because the previous time we used our portable, in Settings.reg there's "Y:\Data". "Y" was the USB drive's letter on the previous computer. Now, if we import Settings.reg, it writes "Y:\Data" into the registry. But we want "H:\Data" to be present in the registry when the main program starts. So, we'll clear it DirSettings.reg first: © tpr 2007
Chapter III - Advanced Topics
45
REGEDIT 4 [HKEY_CURRENT_USER\Software\My Software\Settings] "Datadir"=-
Notice that red minus (-) sign after "Datadir" - that will clear the data of "Datadir" value. So before importing DirSettings.reg, "Datadir" looked like this: "Datadir"="H:\Data"
It contains "H:\Data" because our Settings.reg contains that from the previous run. After importing DirSettings.reg, it should look like: "Datadir"=
So totally empty. Now we can write the absolute path to it with NSIS: WriteRegStr HKEY_CURRENT_USER "Software\My Software\Settings" "Datadir" "$EXEDIR \Appdata\"
Theoretically if you the launcher executes the code above, it overwrites the previous value. In some cases I found that although it should overwrite it, it didn't, so I'm using this DirSettings.reg method instead. Ok, now the settings, the registration info and the required absolute paths are in the registry, we can execute the main program with ExecWait. ExecWait executes the main program and waits until it finishes. Then we should save settings and clean up. To save settings, use this code: ${registry::SaveKey} "HKEY_CURRENT_USER\Software\My Software\Settings" "$EXEDIR\portable\Settings.reg" "/G=1" $R0
You can see that if something was changed in this registry key (for example, you changed some settings of the software), the new Settings.reg will be different as it was before the portable software run. The old Settings.reg is overwritten with the new Settings.reg. For deleting a registry key we'll import RegClean.reg into the registry: ${registry::RestoreKey} "$EXEDIR\portable\RegClean.reg" $R0
Because RegClean.reg contains minus (-) signs in front of the registry key's name, it will delete it: REGEDIT 4 [-HKEY_CURRENT_USER\Software\My Software\Settings]
Notice that not the whole branch was deleted, only its "Settings" sub-branch. Why don't we delete the entire "HKEY_CURRENT_USER\Software\My Software" branch? It is for security reasons. The branch "My Software" may store other programs' settings also, and we don't want to delete them. For example, Corel's registry key looks like this:
© tpr 2007
46
How to make portables with NSIS
HKEY_CURRENT_USER\Software\Corel HKEY_CURRENT_USER\Software\Corel\CorelDRAW\11.0 HKEY_CURRENT_USER\Software\Corel\CorelDRAW\9
If we delete "HKEY_CURRENT_USER\Software\Corel" registry key, the settings of version 9 and version 11 will be gone. We'll need NSIS to check if the registry key we want to delete is empty or not: DeleteRegKey /ifempty HKEY_CURRENT_USER "Software\Corel"
Notice that "/ifempty" switch after DeleteRegKey (written in red). That tells the launcher that the given registry key can be deleted only if it is empty. And that's all about saving and restoring registry settings. Of course, these all are only general things and you should modify your code that suits best to the application you're trying to portablize. Because each software is different, you have to examine them thoroughly. You must be aware of how it works, should understand every settings of it and so on. If you're not knowing the software very well, your portable might be unusable. I stated it earlier but I have to emphasize again that if a software runs without installation on every PC it is not sure that it is also portable. If you cannot use them or if it makes a dustbin from your PC, it is not really something that you should call as portable.
4.5
5. Hidden Registration Data Softwares always store registration data somewhere, whether in the registry or in a file. The file that stores registration info may be found in one of these locations: 1. 2. 3. 4. 5. 6. 7.
The program's directory (best situation) Document folder of the logged in user or of All Users: "C:\Documents and Settings\YOURNAME\Documents\" "C:\Documents and Settings\All Users\Documents\" Application Data of the logged in user or of All Users: "C:\Documents and Settings\YOURNAME\Application Data\" "C:\Documents and Settings\All Users\Application Data\" Application Data in Local Settings: "C:\Documents and Settings\YOURNAME\Local Settings\Application Data\" Windows directory Windows\System32 directory etc.
To find registration info which is stored in a file, you should examine the directories listed above. Here are some tips for searching:
Make sure you've set you file manager to show hidden files during this process. Sort files by date because it is likely that this file is the newest in these directories. Examine all files that can store info (.ini, .txt, .key, .reg and such). Files with small size are more suspicious as the registration data is usually not so big. © tpr 2007
Chapter III - Advanced Topics
47
In some cases, mainly in windows or system32 directory, you should view dll, ocx and other files that are small and new - view them with your text editor, sometimes registration data is hidden in these files. This kind of searching can be very cumbersome, but also challenging in the same time. If it is stored in the registry, it can be almost everywhere. Mostly they are in HKEY_CURRENT_USER (HKCU) or in HKEY_LOCAL_MACHINE (HKLM) but sometimes you may find it in HKEY_CLASSES_ROOT (HKCR) (as we did it when creating My Notes Keeper in Chapter II). The best is when it is located in HKCU, because users without admin rights can access it. If it is in HKLM or HKCR, users without admin rights won't be able to import registration info and thus the portable they try to launch won't be licensed. In most cases the registration data cannot be found in the registry in the form it was entered in the registration box, because it is encrypted. If we couldn't find anything with Registry Workshop, then we should use Regmon (see "Tools" directory). Before introducing RegMon, here's an easier way to find registration info. Monitor the software with Total Uninstall, but instead of a setup fiile, use the software's main exe. If it captures nothing, then you should turn to RegMon. This process is a bit more complicated. You have to monitor the registry with Regmon when entering the registration data into the registration fields in My Notes Keeper (especially when you hit OK button, because that is the time when registration info is written into the registry). Because RegMon captures all registry activity, the list it generates is very long. You should be as quick as you can to avoid capturing registry activity that is not related with the software's registration data you are searching for. Although you can apply several filters to reduce the length of RM's log file, there will be a lot of entries that you have to examine to find the registration info that you're searching for. If it is in encrypted form, you won't find it in a form that you can recognize (i.e. if you're searching for "Conan the portable creator" as a user name, you maybe find it in a registry key "HKLM\Software\1431461fsd15613151313\duuislsdfjl" with a value "010111101011" which is not so easy to notice). So you'll have to investigate suspicious ones by deleting them from the registry (using Registry Workshop) and then see if the program reverts to trial mode. If not, undo the deletion in RW and go to the next suspicious key. If it reverts to trial mode, then undo deletion and save that key as RegInfo.reg. Similarly, you can use FileMon to capture changes made to your file system in real time (see Tools directory).
4.6
6. File Management Sometimes you have to copy files before you launch the main program exe. Let's see an easy example where we should copy an .ini file to the Windows directory. The chosen software is Kleptomania, which allows you to capture and process images and text from any (even clipboard-unaware) application. You can copy text onto the clipboard, launch your internet browser or email program for further editing, sum numbers, count a number of words/characters and more.
© tpr 2007
48
How to make portables with NSIS
Capturing Changes So start up Total Uninstall and click on Install. Drag and drop "Install\Kleptomania 2.5 \kleptomania_setup.exe" file to TU's window. After the system scan, install Kleptomania using Total Uninstall. I won't write down every little steps like I did in the previous chapter. If you get stuck somewhere, go to Chapter II and look for help there. Install with default settings, so basically the only thing you have to do is clicking on Next every time. When the install finishes, let the install program launch Kleptomania. Kleptomania will now build up a font database. When it's done, close Kleptomania and go back to TU and examine what changes were made. In the File System section there's only one entry important: k-mania.Ini in the Windows directory (apart from the main program files in "C:\Program Files\Kleptomania"). We should copy these files (program files and k-mania.Ini to a directory, so copy them i.e. to "C:\Portable Kleptomania\Appdata". First you have to create the directory structure we used in Chapter II, "Bringing NSIS To The Game". Registry changes The registry changes captured by Total Uninstall show nothing important, except from "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall \Kleptomania 2.5" This is required when you want to uninstall Kleptomania, but as you've seen in Chapter II it is not written to the registry when you launch the portable version of a program. Because there are no other changes we should pay attention to, so uninstall Kleptomania. Make sure you have copied all program files and k-mania.Ini to "C:\Portable Kleptomania" directory. So we have the program files and the settings file (k-mania.Ini). Let's examine the latter one. First, search for any path in this .ini file (the easiest way is to search for paths is searching for ":\"). There are two of them: Install Path=C:\PROGRA~1\KLEPTO~1\ Database Path=C:\PROGRA~1\KLEPTO~1\k-mania.Pat
Change it to relative paths, like so: Install Path=.\Appdata\ Database Path=.\Appdata\k-mania.Pat
Unfortunately there's no entry which defines the location of k-mania.Ini (its location is hardcoded). That's why we should copy it prior to the main program's launch. Some program, if they find their .ini files in their own directory, will use it instead of the .ini file in its installed location. To test this, delete k-mania.ini from the Windows directory and make sure in the program's directory there's the copy of it. Now launch Kleptomania with k© tpr 2007
Chapter III - Advanced Topics
49
mania.exe. An error message appears, telling that k-mania.Ini not found. So there's nothing left, we have to copy this ini file to Windows directory. It is not so good because if you have no admin rights on the target PC, you won't be able to run Kleptomania. To copy a file with NSIS, use this code: CopyFiles /SILENT "$EXEDIR\Appdata\k-mania.Ini" "$WINDIR"
/SILENT tells NSIS to copy files in the background. "$WINDIR" is the destination directory ("C:\Windows" if Windows is located there). Because we want our settings to be saved, we'll copy this file back to the "Appdata" directory after k-mania.exe is terminated: CopyFiles /SILENT "$WINDIR\k-mania.Ini" "$EXEDIR\Appdata\"
This is the same code but with inverted directions. We also want to keep Windows directory clean, so at the end of the scrip we'll delete kmania.Ini file: Delete "$WINDIR\k-mania.Ini"
Because there's no registry settings to bother with, the NSIS script is very simple (you have to pay attention to the words written in red): ;---Definitions---!define SNAME "Portable Kleptomania" ;----Includes---!include "Registry.nsh" ;-----Runtime switches---CRCCheck off AutoCloseWindow True SilentInstall silent WindowIcon off XPSTYLE on ;-----Set basic information----Name "${SNAME}" Icon "${SNAME}.ico" Caption "${SNAME} Launcher" OutFile "..\${SNAME}.exe" ;-----Version Information-----LoadLanguageFile "${NSISDIR}\Contrib\Language files\English.nlf" VIProductVersion "0.1.0.0" VIAddVersionKey /LANG=${LANG_ENGLISH} VIAddVersionKey /LANG=${LANG_ENGLISH} VIAddVersionKey /LANG=${LANG_ENGLISH} VIAddVersionKey /LANG=${LANG_ENGLISH}
© tpr 2007
"ProductName" "Portable Kleptomania Launcher" "LegalCopyright" "© tpr 2007" "FileDescription" "Portable Kleptomania" "FileVersion" "0.1"
50
How to make portables with NSIS
Section "Main" CopyFiles /SILENT "$EXEDIR\Appdata\k-mania.Ini" "$WINDIR" Sleep 300 ExecWait "$EXEDIR\Appdata\k-mania.exe" CopyFiles /SILENT "$WINDIR\k-mania.Ini" "$EXEDIR\Appdata\" Sleep 500 Delete "$WINDIR\k-mania.Ini" SectionEnd
Note that there's a "Sleep 500" before deleting k-mania.Ini. Save this script with name "Portable Kleptomania.nsi" in directory "C:\Portable Kleptomania \Source". Now only the icon is missing, so extract it from k-mania.exe with Icons From File, and save it with name "Portable Kleptomania.ico" in directory "C:\Portable Kleptomania\Source". Remember that the name of the .nsi file and the .ico file must be the same. Now open makeNSISw.exe, drag and drop the script file "Portable Kleptomania.nsi" and theoretically the launcher exe is created in the parent directory ("C:\Portable Kleptomania \Portable Kleptomania.exe"). Do some testing to see if everything works as expected. You can use some of the tools if you wish: First of all, copy the whole "Portable Kleptomania" directory to a USB drive and try it on another PC (or copy it over a lan if available). Try it on as many computers as you can. Total Uninstall: instead of a setup file, use the program's main exe file. Let TU do a system scan and then let it launch the exe. Do some things in the program and close it. Now see what changes were made to your system. RegMon, FileMon: monitor the portable's activity and see if everything works as expected. Launch the portable, then rename k-mania.Ini file in the Appdata folder. Now close Kleptomania and see if the k-mania.Ini file is copied back or not to the Appdata folder. If not, check your script (and, of course, rename the .ini file back). Launch Portable Kleptomania and change some settings in it (in the Properties page). Now close it and see if it is reflected in the .ini file. Now launch it again and see if your settings came back or not. Note: you can use wildcards to copy files if you wish. For example, CopyFiles /SILENT "$EXEDIR\Appdata\*.*" "$WINDIR"
will copy all files (and directories) from the Appdata directory to the Windows directory. Use it with care, especially when deleting files in this way. Another note: if you copy files this way, you may overwrite the local installation's settings file (if any). To prevent this, you should rename the local installation's k-mania.Ini file before
© tpr 2007
Chapter III - Advanced Topics
51
launching portable Kleptomania, and at the end you should restore its original name. For example, if you rename the local "k-mania".Ini to "k-mania_.Ini" will keep it from overwriting. In the next topic you'll see how to rename files with NSIS.
4.7
7. More File Management In this topic I'll show you how to create and delete a directory and how to rename files. Creating Directories Knowing how to create a directory with NSIS is necessary because if you have to copy files, NSIS will not copy anything if the destination directory doesn't exists. It is a bit annoying but fortunately it is very easy to create a directory (the example is from the NSIS Help): 4.9.3.3 CreateDirectory path_to_create Creates (recursively if necessary) the specified directory. The error flag is set if the directory couldn't be created. You should always specify an absolute path. CreateDirectory $INSTDIR\some\directory
What is important to note from it: - creates directories recursively: so, if you would create a subdirectory structure, you should only create the last directory in it, like so: CreateDirectory "C:\RootDir\Subdir1\Subdir2\Subdir3"
In this case, if there was no "Rootdir" earlier, 4 directories will be created. - absolute path: you shouldn't specifiy a directory with relative path, like 'CreateDirectory "MyFolder" ' or 'CreateDirectory "..\" ' because it won't work. In fact, specifying directories which are relative to the launcher's path is very easy with NSIS as you've seen earlier (think of "$EXEDIR" or "$APPDATA"). You should also use the double quotes (") when specifying a path, to ensure that NSIS will recognize them properly. For example, if you specify the path "C:\My very new directory\hey this is newer\even newer directory\help how to get out of here" without quotes, NSIS will give you an error because it thinks that the spaces in in are delimiters. However, this is acceptable (with no quotes): CreateDirectory C:\RootDir\Subdir1\Subdir2\Subdir3
because it has no spaces in names of the directories. You should also pay attention to this when working with registry keys. When will you need to create a directory? For example, when an application stores its settings in the application data folder. Then you should copy all files to this directory from you USB drive prior to launching the main exe. When you close the program, the launcher should copy all files from application data folder back to the USB drive. Doing so, on next © tpr 2007
52
How to make portables with NSIS
run your settings will be the same on every PC, no need to reconfigure the application. To create a directory in the user's application data directory, use this code: CreateDirectory "$APPDATA\MySoftware\Settings\"
Note that this "$APPDATA" is not the same as "Appdata". "$APPDATA" is substituted by NSIS to "C:\Documents and Settings\YOURUSERNAME\Application Data"
where YOURUSERNAME is the logged in user's name (which is probably different on another computer). Appdata is, on the other hand, the directory where we keep the main program files. Deleting Directories In some cases you may want to delete a directory. It is very simple with NSIS: RMDir "$APPDATA\MySoftware\Settings"
This will remove the "Settings" directory from "Application Data\MySoftware" directory. If you add an extra "/r" switch after RMDir, it will delete all files from the specified directory and from its subdirectories. So, if you got "Settings" directory with a "Data" subdirectory, using the "/r" switch will remove all files in the "Settings" directory and also removes its "Data" subdirectory. RMDir /r "$APPDATA\MySoftware\Settings"
Renaming Files You may find yourself in a situation when you have to rename some files. You can do it for example if you would like to keep local installation files intact or when a software stores its settings in a file or folder that must contain the logged in user's name. In the first situation, you should rename the local installation's file (or files) before launching the main exe, and after closing it, you should restore its original name. It is somewhat better than overwriting the original one (as we would do with k-mania.Ini in the previous topic, if a local Kleptomania is present on the host computer) because if our portable accidentally crashes, the original file would be in its original location, we only need to restore its original name. To rename a file, use this code: Rename "$EXEDIR\Backup\settings.ini" "$EXEDIR\Backup\settings_new.ini"
It will rename "settings.ini" to "settings_new.ini". The first parameter is the file's path with the old name and the second one is its path and its new name. It works with directories also; so if you want to rename a directory, just give the source path and the destination path.
© tpr 2007
Chapter III - Advanced Topics
53
The second situation needs a more complicated code: System::Call "advapi32::GetUserName(t .r0, *i ${NSIS_MAX_STRLEN} r1) i.r2" Rename "$EXEDIR\Backup\settings.ini" "$EXEDIR\Backup\settings-$0.ini"
The first line of the code gets the logged in user's name and stores it in $0. The second line renames "settings.ini" file to "settings.ini-USERNAME.ini". You'll probably not see applications that requires this kind of renaming too often but if you come across one, you'll know how to handle it. If not, go to NSIS forum and search for a solution.
4.8
8. Registering Libraries You may want to create a portable launcher (wrapper) for a software that needs a .dll or other (i.e. .ocx) library files to be registered. With NSIS it is not a big deal registering them. You may see some .dll files copied to the Windows or Windows\System32 (or other) directories during the installation (in Total Uninstall's changes log). First you should try to copy this file or files to the program's directory, next to the main exe file (in the "Appdata" directory if you use the same directory structure as I). If solves the problem in most cases because softwares can use those dll files from their directories if they find it there (provided if the software is programmed so). If you test your portable and you get an error message that some dll or other files are missing, you have to copy these files to their original installed location before the main executive starts (see topic "File Management" in this chapter on how to copy files). You shouldn't overwrite any files in the Windows or other directory because you may overwrite newer files with older ones. To eliminate this problem, make a backup of original files by renaming it before copying and restoring their names on closing the portable, or copying it to the USB drive and at the and copying it back. If you modify your portable in this way, the error message(s) should disappear and your portable should work. But in some cases, you should see another error message: "downloadthewholeinternet.dll is not registered" That's because you have to register that dll file before launching the main exe. To do this, use the following code: RegDLL "$EXEDIR\Appdata\downloadthewholeinternet.dll"
As you can see it is very straightforward. And it is safe because it uses the dll file that is located on your USB drive. When the the main exe is closed, the launcher should unregister that dll to keep the host PC clean: UnREGDLL "$EXEDIR\Appdata\downloadthewholeinternet.dll"
Alternatively, you can use this method: ExecWait 'regsvr32.exe /s "$EXEDIR\Appdata\downloadthewholeinternet.dll"'
© tpr 2007
54
How to make portables with NSIS
This method uses the "regsvr32.exe" file located in the "Windows\System32" directory. The "/s" switch stands for silent mode, so you'll see nothing when regsvr32.exe register that dll. To unregister, use ExecWait 'regsvr32.exe /u /s "$EXEDIR\Appdata\downloadthewholeinternet.dll"'
code, where "/u" switch stands for "ungregister". To see what switches are available, double-click on "Windows\System32\regsvr32.exe". Note that I used ExecWait here but you can use Exec action also. But because ExecWait waits until the executed process is closed, it is better to use it here. Also note the quotes used here. The whole command is wrapped around with single quote (') to ensure the whole expression is evaluated together.
4.9
9. Installing MSI Files There are some special cases when you will have to silently install and .msi file to make your portable work. This .msi file is not the main setup file of the software, it only installs an additional feature that must be present on the local computer for the portable to run. You should use it with care because it may install older files on the host computer, overwriting newer version of them. To install an .msi file silently, use this code: ExecWait 'MSIEXEC.EXE /i "$EXEDIR\Appdata\msi\Microsoft_VC80_MFC_x86.msi" /qn / norestart' $0
Because this it may take some to time to finish, it is better to use ExecWait instead of Exec. Of course, you can add some extra waiting with the sleep command (i.e. Sleep 500) but it should work without it also. To see what switches are available, double-click on "Windows\System32\msiexec.exe". ExecWait 'MSIEXEC.EXE /x "$EXEDIR\Appdata\msi\Microsoft_VC80_MFC_x86.msi" /qn / norestart' $0
Because you don't know whether the msi package is installed on the host computer or not, use it only in cases if you're 100% sure it can be removed without any harm. However, I had to install an .msi file only one time so far (out of some hundred portables). If you're unsure, I recommend you not to uninstall it. It's still better if an earlier version remains on the host PC than no version at all. Note: in this guide I used "Exec" or "ExecWait" every time I wanted to launch an application. But in some cases you have to use "ExecShell" to launch a file. The NSIS Help says about ExecShell: 4.9.1.3 ExecShell action command [parameters] [SW_SHOWNORMAL | SW_SHOWMAXIMIZED | SW_SHOWMINIMIZED | SW_HIDE]
Execute the specified program using ShellExecute. Note that action is usually "open", "print", etc, but can be an empty string to use the default action. Parameters and the show type are © tpr 2007
Chapter III - Advanced Topics
55
optional. $OUTDIR is used for the working directory. The error flag is set if the process could not be launched. Note: If you want to launch an exe file, Exec or ExecWait will do. But if you want to open (or whatever the default action is associated with that file type) other files such as bitmaps, text documents, etc, you should use ExecShell (Exec or ExecWait won't work in these cases).
4.10
10. Time and Date In some cases you may want to set the system time or date back before starting your portable and restoring the current time and date a few seconds later. In the example below we'll set the date back 5 years and restore the actual date after 3 seconds. Thus it won't do any harm to your system (hopefully). This is not a common thing that you would use in your portables but I'll show you how to do that, maybe it will come handy to you. To be able to do this, you'll have to modify the NSIS script to include the Time plugin. Although the plugin is in the right place ("Tools\NSIS 2.17\Plugins" and "Tools\NSIS 2.17 \Include" directories, you have to put this line in your script under the other Includes: ;----Includes---!include "Registry.nsh" !include "Time.nsh"
Now comes the fun part. First you have to understand the main steps: 1. Store the current local date to $0 variable 2. Set any number in $1 variable (in the example below it is 5, which means 5 years now) 3. Compute the new date and store it in $2 4. Set the new local date based on $2 5. Sleep 1 seconds 6. Start main exe, than Sleep 2 seconds 7. Set the number you've set in Step 2 in $3 (you can use $1 again if you wish instead of $3) 8. Compute new date ($2 date + 3 seconds which is the result of the two sleeps) and store it in $4 9. Set the new local date (which is in fact the current date) 10.Unload the Time plugin And here's the code (change the "Application.exe" to your application's name): Section "Main" ${time::GetLocalTime} $0 StrCpy $1 5 ${time::MathTime} "date($0) - date(0.0.$1 0:0:0) = date" $2 ${time::SetLocalTime} "$2" $R0 Sleep 1000 Exec "$EXEDIR\Application.exe" Sleep 2000 StrCpy $3 5 ${time::MathTime} "date($2) + date(0.0.$3 0:0:03) = date" $4 ${time::SetLocalTime} "$4" $R0 Sleep 200 © tpr 2007
56
How to make portables with NSIS
${time::Unload} SectionEnd
Of course, the new time may differ from the current time in some milliseconds but I think it is not a big deal. This script may come handy if the software checks the current time and it doesn't start if the date exceeds a specific date (for example when the trial period is over). You can alter the script the way you want, of course. As I said, you will probably not use this script when creating your portables. But it shows that NSIS can cope with some other things also beside what I showed you earlier. Actually this is another script I get from the NSIS forum, but of course I had to modify it a bit. So if you have a problem that needs to be solved with NSIS, just go to the forum and perform a search there. If you've found nothing, you may ask the gurus there about it, I'm sure they'll come up with an answer or recommend you another way to solve the problem.
4.11
11. .NET and Java Some softwares require .NET Framework or Java to be installed on the host computer to run. You cannot even install them if they are not present in the system. You'll see these messages if you try to install them:
However, you can make these software portable but they won't work at all if the host computer hasn't got .NET or Java installed. Of course, you have to make it on a computer with .NET or Java is installed. Personally I prefer stand-alone applications which don't rely on other softwares to run. If you really want to bring a .NET or Java software with you wherever you go, you may be interested in virtual applications. However, this guide is about portable softwares so I won't discuss virtual ones here. See the last chapter "Final Words" for some info about them.
© tpr 2007
Chapter III - Advanced Topics
4.12
57
12. Reducing Size When you create a portable you should pay attention to its size. If you want to put it on your USB stick, it should be as small as possible but also should be fully functional. The most obvious way to reduce size is to delete some irrelevant files. Usually there are some files in a program's directory which are not needed to run the program. You may delete them but make sure that you delete only those files which the program doesn't need. These files may be: log files (.log, .txt) if you don't want any log files. You may also need to disable logging in the program's settings to ensure the log file won't come back again on next run. .gid, .cnt files: these are help file's accessories as I know. Although it is re-generated when you launch the help file but you can delete them to reduce size temporarily. help files (.hlp, .chm, .pdf, etc.). Delete these files only in cases when you are 100% sure you don't want to use it later. If you plan to share your portable with other people you shouldn't delete these files as others may need them. some smaller text files, info files, html files, files without extension, etc. These files may contain licence details, ordering info, general info about the software, and so on. language files: these can be in various formats. If you don't want any other languages beside you own language, you can delete other ones. But again, if you want to share it with others you shouldn't get rid of them. some image files, but make sure the program runs well even if these images are missing skin files: some program come with an enormous number of skins and they may take up very much disk space. If you want to reduce size you may delete them. If the program needs at least one skin file to run, select one that suits best to your likings and delete the others. source files: I almost always include the source file of my portable launcher and I encourage you to do the same. Doing so, people may look at the code and can see what's going on when they launch the launcher and they can also learn from it. But if you are not so generous you may delete these files. Another way to reduce size is using UPX. UPX is a free, portable, extendable, high-performance executable packer for several different executable formats. It achieves an excellent compression ratio and offers very fast decompression. Your executables suffer no memory overhead or other drawbacks because of in-place decompression. The beauty of upx is that it compresses .exe, .ocx, .dll and .com files with an excellent ratio and these files can be launched directly after compression. So, you may reduce a size of an executable that was originally 2 MB to 1 MB and it remains usable. Although upx is a very nice tool to reduce file size you must use it with care. Some programs won't accept upx-ed files so always backup them before compressing them. If the programs starts up as expected you should thoroughly test to make sure every function of the program is working properly. My experience is that compressing .exe files is safe, if they run after compressing they'll probably run without any problems. But compressing .dll, .ocx and .com files is not so obvious so you should test them.
© tpr 2007
58
How to make portables with NSIS
The NSIS script has a line that says: ;-----Runtime switches---CRCCheck off
This disables CRC check so the launcher will not check if its size is the same as it was when creating it. If you change it to "CRCCheck on" and compress it with upx, you'll get an error when you try to launch the resulting .exe file: NSIS Error The installer you are trying to use is corrupted or incomplete. This could be the result of a damaged disk, a failed download or a virus. You may want to contact the author of this installer to obtain a new copy. It may be possible to skip this check using the /NCRC command line switch (NOT RECOMMENDED).
If you want to protect your portable launcher, use "CRCCheck on". If a virus modifies the size of the launcher it simply will not run and thus protects your computer from being infected. And because your portable may travel from one computer to another it is greatly exposed to virus attacks. Until now I did compress my launchers with upx because I was a brave man. But as I reread my last few lines I thought I shouldn't be so brave... You can find upx in directory "Tools\UPX 2.03" so you do not need to download it. But I recommend to check if there's a newer version available before using it. You can see in its website how to use UPX from command line. Here's an example for compressing "toobigfile.dll" (with maximum compression): "D:\Tools\UPX\upx.exe" -9 "H:\Data\toobigfile.dll"
And another one for decompressing: "D:\Tools\UPX\upx.exe" -d "H:\Data\toobigfile.dll"
To compress files with upx I use it from command line but I created a context menu with PowerPro so I only have to select files and select "Compress with UPX" or "Uncompress with UPX" from the context menu. It is not a built-in feature but you should add it manually. I won't discuss PowerPro here; see the website or its forum for more info about it. Using it from command line is somewhat cumbersome if you have a large number of files to compress so I recommend you to use a GUI for that like UPX Mass Compressor, UPX Shell, UPX-it or other tools. Unfortunately from this list only UPX Mass Compressor has the ability to compress several files at once but maybe you'll find another great GUI for it on the net.
4.13
13. Failures From all that I've written so far in this guide you could think that every attempt to create a portable version of a software would be crowned with success. But unfortunately it's not true. Even if you're an experienced portable creator, there will be many cases when you simply © tpr 2007
Chapter III - Advanced Topics
59
can't get the portable version to work. However, there are signs of possible future failures when you start creating the portable: setup installs a service setup installs a driver software protection is based on hardware ID (so the portable you create won't work on other computers because the hardware ID is not the same as on your computer) the software is heavily tied to the registry (hundreds or even thousands of registry keys although in these cases it is possible to create a working portable version but it can be a really hard work) the launcher should copy too many files to the host computer. For example, copying some 100 MB of data before launching the main exe would take a lot of time. Again, it is possible to get it work but the portable will be hell slow. .NET or Java is required to run the software (see topic 11 ".NET and Java" in this chapter) etc. As I wrote before, if the user has no admin rights he or she may not be able to run the portable. So if you have a chance to decide how to make the portable, make it that way that users without admin rights could also use it.
5
Final Words By this time you should have enough knowledge about how to create a portable launcher. You've seen that there's no simple method that works for every software. Sometimes it may take a lot of time to create one but in other cases it'll take only a few minutes. When you become more and more experienced, the time you spent on creating a portable app will be only the fraction of that you spent on it now. You'll see that all I wrote here is only the basics, it's up to you and your creativity to make better portables. Sometimes you'll come across softwares that cannot be made portable, or at least not with this method. But NSIS can do a lot more than I discussed here. In fact, this is only the tip of the iceberg, just go to the NSIS Forum and see what topics are there. And NSIS is only an install maker software, imagine what could a hardcore programmer do if he begin producing portables... Sky's the limit, I think. I cannot finish this guide without mentioning Thinstall Virtualization Suite. It brings a brand new approach to creating (or modifying) applications that run without installation. Info about it from their website: Thinstall is an Application Virtualization Platform that enables complex software to be delivered as self-contained EXE files which can run instantly with zero installation from any data source. Furthermore, thinstalled applications can run even if the user has no admin rights on the computer and they do not use the Windows registry. They run in a portable manner but it's an entirely new technology, that's why we call them virtual or thinstalled applications. Maybe that's the way this whole portable-thing will go, but right now hand-made portable (or
© tpr 2007
60
How to make portables with NSIS
portablized) applications are more reliable than their thinstalled counterparts, I think. There are so many question marks about thinstalled applications. Some programs cannot be thinstalled but portable versions of them are working good, and vice versa. So which one is better? The one that works, I think, no matter if it is portable or thinstalled. I think we'll see a lot of happenings in the portable field in the following months and years, so stay tuned.
© tpr 2007