Naracea 1.1.2: Installing .NET Framework as part of installation process
There is new version of Naracea available: version 1.1.2. What is new in this version? I replaced installer. For versions prior to 1.1.2, Naracea was distributed as MSI file, which is Microsoft Installer package, for 1.1.2 and further I’m using NSIS, which generates EXE file which installs the application.
Why did I change the installer? Well, because with NSIS I can easily bootstrap .NET Framework for computers which do not have it installed. With MSI file, you either need to have .NET 4.0 installed on your computer already, or you need to go to Microsoft download page and install it manually. It is somehow annoying, to try to install the application, then being interrupted by some messagebox which tells you that you need to do something else, before you can continue.
Therefore I decide it is time to get over this, and change the installer.
Don’t get me wrong: MSI is not that bad if you have right tools to author it. By “right tools” I mean WixSharp, which allows you to write installers in C#, which is much more convenient that using original Wix, which requires writing cryptic XML files. The problem with MSI is, that you cannot write single file installer (as far as I know), which would check whether you have .NET 4.0 installed and download it and install in case you don’t.
Thus I was looking for something to overcome this limitation, and from available options, NSIS looks the best.
Now I’ll describe shortly what I do to build this new installer.
First of all, I have file “VERSION” in my project folder, which contains current version of the application without build version. The build version (that last number which is attached to the end of the installer’s file name) is generated by the rake script when I start build process, and it consists of last two digits of the year (so for builds done in year 2012 it is 12), and from number of the day in current year (so build 121 was build on the January 1st of 2012).
Now, for NSIS install file I need this exact release version, so it can be attached to installer’s file name and to be set in Windows registry entry, which shows Naracea in “Install Programs and Features” control panel.
Following rake tasks generates “VERSION.nsh” from VERSION file with full version number and runs makensis.exe program which processes installer script and generates installer EXE file:
task :pack_release do | task| puts 'packing release files...' ver = "0" File.open("VERSION", "rb") do |file| ver = file.read end ver = ver + "." + get_build_version() File.open("VERSION.nsh", "w") do |file| file.write("!define VERSION \"") file.write(ver) file.write("\"") end system '_tools\nsis\makensis.exe naracea.nsi' end def get_build_version() return Date.today.year.to_s[2..4] + Date.today.yday.to_s end
To run this task you need to have NSIS in folder “_tools\nsis\” (relative path from where you run the rake). When getting NSIS, download and install plugin Inetc, which is needed by installer for file download (in this case .NET Framework 4.0 installer).
Now we are ready to write the NSIS installer script, which will check whether .NET 4.0 is installed, and if it isn’t, it will download it and install (I removed mentions of Naracea from it, because some people tend to copy and paste stuff from internet without thing about it):
;-------------------------------- ;Include Modern UI !include "MUI2.nsh" !include "FileFunc.nsh" !include "VERSION.nsh" !include WordFunc.nsh !insertmacro VersionCompare !include LogicLib.nsh ;-------------------------------- ;General ;Name and file Name "<product>" ; "_build" is folder into which your application installer will be build into OutFile "_build\<product>-${VERSION}.exe" ;Request application privileges for Windows Vista/7 RequestExecutionLevel admin ;Additional settings CRCCheck on !define UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\<product>" ;Icon ;"_icons" is folder where you have your application icon stored !define MUI_ICON "_icons\icon.ico" ;Default installation folder InstallDir "$PROGRAMFILES\<product>" ;Get installation folder from registry if available InstallDirRegKey HKCU "Software\<product>" "" ;Remove "Nullsoft Install System" text BrandingText " " ;-------------------------------- ;Interface Settings !define MUI_ABORTWARNING ;-------------------------------- ;Pages ; "_texts" is folder where you license file is stored !insertmacro MUI_PAGE_LICENSE "_texts\License.rtf" !insertmacro MUI_PAGE_DIRECTORY !insertmacro MUI_PAGE_INSTFILES !insertmacro MUI_UNPAGE_CONFIRM !insertmacro MUI_UNPAGE_INSTFILES ;-------------------------------- ;Languages !insertmacro MUI_LANGUAGE "English" ;-------------------------------- ;Functions checking for .NET presence Var InstallDotNET Function .onInit ;Here we check for Client .NET 4.0 profile. To check for Full .NET 4.0, replace "Client" with "Full" ReadRegDWORD $0 HKLM 'SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Client' Install ${If} $0 == '' StrCpy $InstallDotNET "Yes" MessageBox MB_OK|MB_ICONINFORMATION "<product> requires that the Microsoft .NET Framework 4.0 is installed. The Microsoft .NET Framework will be downloaded and installed automatically during installation of <product>." Return ${EndIf} FunctionEnd ;-------------------------------- ;Installer Sections Section "<product>" SecDummy SetOutPath "$INSTDIR" ; Get .NET if required ${If} $InstallDotNET == "Yes" inetc::get /caption "Downloading Microsoft .NET Framework 4.0" /canceltext "Cancel" "<http://URL.to.NET4.0.installer.exe>" "$TEMP\dotnetfx40.exe" /end Pop $1 ${If} $1 != "OK" Delete "$TEMP\dotnetfx40.exe" Abort "Installation cancelled." ${EndIf} ExecWait "$TEMP\dotnetfx40.exe" Delete "$TEMP\dotnetfx40.exe" ${EndIf} ;Files to be installed ; "_build" is folder into which your application files are being built into File "_build\<product>\<product>.exe" ;Create shortcuts SetShellVarContext all CreateDirectory "$SMPROGRAMS\<product>" CreateShortCut "$SMPROGRAMS\<product>\<product>.lnk" "$INSTDIR\<product>.exe" CreateShortCut "$SMPROGRAMS\<product>\Uninstall <product>.lnk" "$INSTDIR\Uninstall.exe" ;Store installation folder WriteRegStr HKCU "Software\<product>" "" $INSTDIR WriteRegStr SHCTX "${UNINST_KEY}" "DisplayName" "<product>" WriteRegStr SHCTX "${UNINST_KEY}" "Publisher" "<author>" WriteRegStr SHCTX "${UNINST_KEY}" "DisplayVersion" "${VERSION}" WriteRegStr SHCTX "${UNINST_KEY}" "DisplayIcon" "$\"$INSTDIR\<product>.exe$\",0" ${GetSize} "$INSTDIR" "/S=0K" $0 $1 $2 IntFmt $0 "0x%08X" $0 WriteRegDWORD SHCTX "${UNINST_KEY}" "EstimatedSize" "$0" WriteRegStr SHCTX "${UNINST_KEY}" "UninstallString" "$\"$INSTDIR\Uninstall.exe$\"" WriteRegStr SHCTX "${UNINST_KEY}" "QuietUninstallString" "$\"$INSTDIR\Uninstall.exe$\" /S" ;Create uninstaller WriteUninstaller "$INSTDIR\Uninstall.exe" SectionEnd ;-------------------------------- ;Uninstaller Section Section "Uninstall" ;Remove files from installation folder ;List all installed files here Delete "$INSTDIR\<product>.exe" Delete "$INSTDIR\Uninstall.exe" ;Remove installation folder RMDir /r "$INSTDIR" ;Remove links from startmenu SetShellVarContext all Delete "$SMPROGRAMS\<product>\Uninstall <product>.lnk" Delete "$SMPROGRAMS\<product>\<product>.lnk" RMDir /r "$SMPROGRAMS\<product>" DeleteRegKey /ifempty HKCU "Software\<product>" DeleteRegKey SHCTX "${UNINST_KEY}" SectionEnd
Of course, you need to replace all occurrences of product with name of your application, and http://URL.to.NET4.0.installer.exe with URL to where the .NET 4.0 can be downloaded from.
And now you have your NSIS install script ready to build installer for your .NET application.
And don’t forget to give new Naracea a try!
Naracea 1.1
Well, it is obvious, that I’m better in developing Naracea than writing about it. Yes. There is version 1.1 available for download for some time. I was even able to release an update, and I have another one in the testing. However, I’m back now, and I’d like to go through what’s new in 1.1.
There are still three main things I’m using Naracea for, and I kind of improved things which are needed for these areas. I’m using Naracea for writing, for editing of couple of scripts, and I rely on it heavily with my note taking. Let’s go though improvements for each of these areas.
Writing with infinite undo
Since the very beginning I knew editing capabilities of the 1.0 were not sufficient. Problem was that adapting some other editing component would take some time (significant amount of time, as I found out when working on 1.1), and didn’t want to delay release. So 1.0 had to live with limited editing capabilities, and immediately after release I started to work on integration of more powerful text editing component. Finally I decided to use AvalonEdit (which is powering SharpDevelop) for 1.1.
AvalonEdit is beautiful piece of software, it is nicely designed, it has lots of features and it has permissive LGPL license. And of course: it is text editor developed for IDE. That means that while it is really great for editing code, there were some limitations when I tried to use it as a base for text editor which is meant for writing of text. So I did some adaptations and now, I believe it works really nice as the main part of the Naracea’s UI. (Naracea’s version of AvalonEdit can be downloaded from forum.)
Next feature I was really missing was simple overview of text changes. While timeline is nice, and it gives overview of the development of the text, it is not easy to explain how Naracea works and how changes are recorded when they are not visible on the first sight. Also finding the point I want to get to in document history was somehow complicated, because while the history can be searched, sometimes I do not remember what I’m exactly searching for. Therefore now there is change stream. It shows changes as they were entered, it distinguishes inserts and deletions, shows how changes are grouped and allows quick rewinding to any point in document’s history.
Minor function related to writing is possibility to show whitespaces, convert tabs to spaces automatically, and set size of tabs (if you are using indentation instead of empty lines between paragraphs).
Simple to-do lists and note taking
For note taking, there are two new important features for me. It might surprise you, but first one is the way indentation is kept when you hit enter. I build my to-do lists hierarchically, so having indentation kept when I hit enter is pretty important for me. Second feature is support for regular expressions. Searching history is hard when you do not know what are you looking for, and being able to search with regular expressions make this way easier. I know regular expressions aren’t something majority of people will use, but still — it is great to have it there.
Persistent history/undo for scripts
Honestly — Naracea is far from being best editor for writing code, and it is not my intention to turn it into one. There are lots of better tools for full time code editing. However there is this kind of exploratory coding I do from time to time, where I really appreciate I have whole history of the code available. As I already mentioned, I keep my build scripts as Naracea document. Because I’m not so proficient in Ruby and rake scripts, having the whole history and being able to develop by trial and error without fear of losing previously working code is something I really like.
That’s why I added syntax highlighting. It was cheap and easy (because AvalonEdit supports syntax highlighting out of the box — well, it is text editor for IDE), and I like to have it there for those occasions I need it.
OK, so that’s what’s new in Naracea 1.1. If you like it, please, go to the download page, and try Naracea by yourselves.