tags:

views:

860

answers:

6

I have an application with complex setup requirements. I'm well familiar with some of the tools out there for creating setup programs such as Wix, Visual Studio Setup project, Inno-setup and 3rd party tools. For this particular app however, I've determined that I need to write the setup program from scratch in C#, not using any of those tools. Some of the reasoning expressed by Joel applies here, except I want to do this in C# instead of MFC.

Anyway, my question is: how would I go about creating a .NET executable that can contain a set of files which are extracted at run time? In this case the exe is the setup program and the files are the program files that it needs to install. Also, how do I make the program executable completely standalone, i.e. even though I am using some external assemblies (my own as well as 3rd party) I want them to be packed together into a single EXE (in C/C++ native world this was accomplished via static linking).

UPDATE

This is the approach I have gotten working so far, which I will stick with unless someone suggests something better:

  • Created a manifest file in XML containing the list of all the files and the folder structure comprising the application that my setup program is installing. I added this file to the VS project for the setup program.
  • Wrote a tool in C# (zipfiles.exe) which takes the manifest XML and creates a zip file containing all the files. This tool uses the awesome DotNetZip library to create the zip.
  • Added a Pre-Build action to my setup program project that launches the zipfiles tool with the manifest XML and outputs the zip file (Files.zip) in the project folder.
  • Added Files.zip as an embedded resource in my setup program project.
  • My setup program at runtime extracts the embedded zip and unzips it to the target install folder for the application (again using DotNetZip)
  • Added a Post-Build action to my setup program project which uses the ILMerge tool to bundle all the external assemblies that it uses into the exe.

I now have a VS project for my setup program which builds a self-contained exe with all the files it needs to install embedded in it. When the list of files for the application being installed changes, I simply update the manifest XML and rebuild.

Now I can focus on the rest of my setup logic!

A: 

Installing may not be too hard (assuming the .NET framework is already installed) but you also need to consider rollback during an installation failure and uninstallation. These are the reason why MSI installs are so complicated. You would need to handle this yourself...

GraemeF
Yes i understand this. Its not hard writing a simple commit/rollback mechanism. Also I'm doing this in .NET 2.0 which will be a minimum pre-requisite to run the setup. My first problem is figuring out how to bundle everything (set program files, application program files and resources) into one exe, and handling registering in Add/Remove programs properly to point to the exe.
DSO
A: 

WIX is the standard for making MSIs. It is somewhat complicated and frustrating to learn IMO but it is worth it. Plan on spending a day to get a basic installer going. This is the tool that Microsoft and many other firms use.

RichAmberale
TS has already mentioned that he used WIX
Jan Jongboom
+2  A: 

You could use Inno-Setup as the main container for your installer. Within Inno-Setup you can run-and-wait for your own applications, that install or configure specific parts of the application.

Mark Redman
This may work as a more flexible alternative to iexpress... using inno setup as just the packaging to unpack and launch the setup program. I'll investigate further, thanks
DSO
+1  A: 

We did just that for an application that we update weekly with new data.

We created two applications. The first was used to wrap the installation up. This consisted of gathering the files to distribute and then zipping them up into a zip archive. We used ChilkatZip to create an archive that would self extract and then execute the second application which handled the installation process on the client machine.

Our needs were fairly simply however, but it allowed us to remove a dependency on Installshield that was causing some support issues internally.

Martin
+1  A: 

Just create a standard Visual Studio install project containing just a single custom install action.

This is actually a standard .NET dll assembly where you can run any code you require to install and un-install your application.

It exists for exactly the reasons you mention, ie when your app. requires more complex installation and uninstallation steps then the standard installer provides.

Ash
This just allows you to write MSI custom actions in .NET. It doesn't give you control over the entire setup process (UI dialogs, workflow logic, etc).
DSO
Actually it gives you *complete* control over the setup process. ie create your own setup UI dialogs, setup SQL databases, write to registry, install/start services. I have used this myself for complex setups. The entire setup is just the one custom action. You are in fact doing it from scratch, but within the Windows installation guidelines, ie you get Add/Remove programs etc for free.
Ash
Hmm.. didn't know you could throw up UI dialogs in a custom action. But it is still a custom action which is invoked at a particular time in the setup by the MSI engine. You have no control over what happens before or after.
DSO
That's correct, but because the installer only contains the custom action there is nothing else to control anyway. Your custom action is normal .NET code. You can reference System.Windows.Forms for example and display whatever you need.
Ash
+3  A: 

Well, there's a reason why installer systems like InnoSetup have been in in active development for years - writing an installer is not an easy task. You say you want total control over the process, which you say you can achieve by writing the installer from scratch.

This is true of course, but it is not a good reason for writing it all yourself - you can also achieve this by not writing it all from scratch, but by using for example the scripting capabilities of Inno Setup to create your own UI and setup flow, while still relying on the well-tested features of Inno Setup.

I think that the time you'd have to spend on creating an installer from scratch would be better invested in checking out the various existing systems, evaluating them as to which one provides best support for all the setup tasks required and then customizing it, so that the setup flow fits your needs.

Thorsten Dittmar
I don't want to write all my setup logic in a scripting language that hardly anyone knows and even if I learned it, I will forget. My goal is to do this in C#, which anyone can pick up and maintain, and which I won't forget.
DSO
Also by writing your setup logic in C# you get better tooling (VS) better testability.
DSO