views:

38

answers:

3

I have an ASP.NET server that provides its client as an MSI download (similar to CCNet/CCTray). There can be more than a single server (for example, for dev/testing/production, but there may be different production instances).

So client has to know server URL. I can not ask users for URL because it does not really make much sense for them, they do not know of any other servers anyway. So the MSI should have the server URL included.

Now, I can pre-build different versions of MSI for different environments (since there are already distinct build steps for these dev/test anyway), but this does not solve a question of several productions where the product is already built.

So I think server should modify the MSI and add the correct URL before serving it. Is it possible without rebuilding the msi? What is the easiest way to achieve this?

A: 

I don't know of a way to modify the MSI itself, but you can have the server write the url to a known file on the client and have the MSI project read in that file (and delete it). That way you can have one MSI build for all servers.

Tamar
Well, but how this file gets to the client machine? Assume the client machine is a workstation of some user who wants to do absolute minimum of clicks to get his things set up.
Andrey Shchekin
+2  A: 

Basically an MSI file is just a database, using the Windows Installer API you can run arbitrary SQL on this database... for example:

Dim installer, database, view, result
Set installer = CreateObject("WindowsInstaller.Installer")
Set database = installer.OpenDatabase ("setup.msi", 1)
Set view = database.OpenView ("INSERT INTO Property (Property, Value) VALUES ('URLPROPERTY', 'http://some.server/blah/service')")
view.Execute
database.Commit
Set database = nothing

Just use this script in a post-build or pre-download process and you'll be sorted :)

For more information and additional (better) sample scripts, refer to the Windows SDK

sascha
Thanks, that is it. One question, should I call Close on the view as well?
Andrey Shchekin
I'd check the documentation, it appears view.Close is called internally when the view is destroyed... http://msdn.microsoft.com/en-us/library/aa372501(VS.85).aspx
sascha
A: 

Modifying MSI file on web server before serving it is not a good idea. What if someone requests the file while you are still updating it?

You are better off modifying your build process to produce a set of MSI files corresponding to production websites. Each website would have its own custom MSI file.

Pavel Chuchuva
Well, I can modify it in application_start, for example, so this is not a problem.
Andrey Shchekin
Of course, never modify a live downloadable file.. you'd serve it from another page - request received, make a copy, update copy, serve it, destroy it.
sascha