I’m not sure if any of you are using Luke’s Setup Assistant tool, but it has been slowly growing and expanding. I stopped posting about it here after every update, because I didn’t want Terminally Incoherent turning to an update log on my projects. This is sort of a place where I come to joke, entertain and rant. Besides, this is one of these things that annoy me as a reader. Seeing funny and/or insightful blog posts interspersed with frequent, content-free blurts of “hey, I just updated that thing you don’t use and/or care about” is not something I enjoy.
But, if you are interested I post that kind of stuff here. At the time I’m writing this, I just released version 0.9.7. You won’t read this until a week or weak and a half from now though. I’m queuing up bunch of posts in advance because there is a bachelor party that is going to blow my weekend productivity away. But that’s neither here nor there. The point is that there is a new version, and you can grab it from the usual place.
But that’s not necessarily what I wanted to talk about. You see, one of the things I just added to Setup Assistant is ability to handle zip files. It does not seem like a big thing, but it allows me to do two new types of actions:
- Download zipped file, unzip it, and run the executable in one button click
- Root through the file system, grab bunch of files and then zip them up for you
The first item is an obvious benefit. A lot of people ship their tools inside of zip files – I’m one of these people. Though I mostly do it because Google Pages won’t host executables. But it is something that people do, and now I can make it easy to download and run these tools.
Second item is less obvious, at least until you realize I’m talking about log files. Here is a potential scenario: a user complains of a recurring, but intermittent BSOD. They never write down the STOP message. How do you troubleshoot? Have them send you the minidump crash logs of course. But getting the user into right place might be difficult. So I made a button that does it in one click. And another one that does the same thing for Event Viewer logs. It grabs all that stuff, and creates zip files on the desktop.
Now, I did not actually write the zip support myself. I figured, why reinvent the wheel if I could use code that someone has already written. So I settled on DotNetZip library. It’s really easy to use (makes for a very clean code), it has lots of good features (for example, it supports AES encryption – and I might want to take advantage of that in the future) and it is free and distributed under MS-PL license. It is also very tiny, and ships as a single DLL file that you can redistribute with your project.
So I happily snagged it, wrote bunch of code around it and only after I was testing it for release did I realize that I needed the DLL file in the same directory as my executable. I mean, duh – that was to be expected, but for some reason I did not internalize this fact until after I had a slew of code, hanging off of it. So I was in a pickle. I really like this library and I did not want to scrap it. On the other hand, Setup Assistant has always been a self contained executable. I did not want to change that. I did not want to make an installer for it. And before you suggest the Click-Once installer built into .NET let me mention that it won’t work because of permissions. Because SA needs admin rights for… Well, for just about every single button my application manifest specifies that it always has to run as admin. For some reason this is a deal breaker for the Click-Once wizard in Visual Studio. There are apparently some ways around it, but I never really cared because I never actually wanted an installer.
Now however I had two files. My executable, and a dll that had to be with it. This was not optimal.
Fortunately, since this is a common pickle to be in, the internet provided me with a ready made solution named ILMERGE. It is a tiny command line tool from Microsoft that lets you merge several .NET assemblies into a single file. The syntax is very simple:
ilmerge /out:foobarbaz.exe foo.exe bar.dll baz.dll
The first file on the list, tells ilmerge what kind of assembly to create. If it is an executable, it will spit out an exe file, if it’s a dll, it will produce library and so on. The example above will merge foo.exe with the two library files. The resulting output file will include all of them, and work just as if these files were simply sitting in the same directory.
The neat thing about this method is that it does not require any changes in your code. For all intents and purposes the DLL files are still external files. They are not embedded in the project, and you don’t have to change the way you reference them. And since this is something you do after compiling you code, you can easily have both – a version of your program merged with all the external libraries, and one that is not. You don’t need to commit to one way or the other.
Finally, since it is a command line app, you can easily add a line to the post-build command box in Visual studio and have it called after every successful build.
Anyways, this is what I wanted to share. It’s a nice little tool, and I did not know about it until I had to figure out how to keep Setup Assistant as a self contained, single file application. Perhaps you will find it useful as well.