29 October 2009

WiX Lessons Learned

The last week I was playing around with the Windows Installer XML to create a simple setup for a very simple product implemented with .NET. All I needed to do was to copy some files, install a service under a custom account, let the user enter the address of some web services.
These features are hot:
  • open source
  • frontend for the built-in windows installer
  • done by people who know windows installer inside out
  • simple declaration of files and actions in xml
  • simple install/deinstall of services with properties like windows account or description
  • custom actions can done with .net very easily, they have read/write access to properties via a session object (see tutorial)
  • you can use managed custom actions for easy validation of custom dialogs
  • can easily integrated into automatic msbuild builds
  • very good logging capabilities which helps you on debugging
  • property based, declarative style
  • property values can be changed by administrators to support customized automatic install on clients
  • support for commit/rollback and repair/maintenance mode
But this is what bites me:
  • Bringing new Custom Dialogs (e.g. query user/password) into the dialog chain is really a pain in the ass. The chaining is done through adding event-actions to the next/back buttons which open new dialogs. Adding some conditional logic if a dialog should be shown or not has to be done by attaching conditions on the adding of event actions of the Next button of the previous dialog and the Back button of the following dialog. An you have to deal with this because on Repair/Maintenance Mode your need probably another dialog sequence.
  • Managed Custom Actions don’t seem to work in elevated mode. The bad thing is, that the installation succeeds without an error, and the custom action is ignored (that is unless you look into the log file).
  • There is no easy way to manipulate files, say app.config on the fly during installation. There is an XmlConfig extension you can use, but using it is rather crude, if you know how to do it in managed code.
  • The GUI support is very limited, you can have edit, password, combobox, listbox, check and radio controls, but layouting is done by entering x and y coordinates by hand. Browsing for a file is impossible, you can browse only for directories.
Other things:
  • You need the WiX tutorial or you are lost
  • You need DTF (Deployment Tools Foundation) for managed custom actions
    • it is included in the WiX package
    • the documentation is hidden in the doc folder of you installation … it is neither linked from the WiX documentation nor to be easily found on the internet

  • If you are a mortal .NET developer you have to do bend your mind to understand it, the windows installer technology sometimes feels like C64 basic with line numbers. Don’t be afraid, after one or two frustrating days you will get it.

20 October 2009

IE8 Kompatibilitätsansicht für Intranetsites

Nachdem ich nun dem Table Layout abgeschworen habe und ins CSS Lager gewechselt bin, habe ich am Wochenende auch mein Hobbyprojekt SvnQuery auf CSS umgestellt. Das hat zwar etwas Mühe gekostet, aber dafür habe ich wieder etwas gelernt, das html hat eine klare Struktur und nebenbei wurden noch einige andere html Fehler beseitigt.

Zurück in der Arbeit aktualisierte ich auch die Suche der Firmenrepositories. Doch gleich bei der ersten Suche der Schock: Fette Scrollbalken schon auf der Startseite, offensichtlich wurde das Layout 200% breit statt wie gewünscht 100%. Und das auf dem IE8 gegen den ich hauptsächlich getestet hatte. Hatte ich schlecht getestet? Warum war mir das daheim nicht aufgefallen?

Also schnell das Projekt heruntergeladen, lokal installiert und ausprobiert. Und siehe da, das Layout war wie erwartet. Aber was war das Problem? Irgendwo musste es einen Unterschied geben. Entwickelt hatte ich gegen den ASP.NET Development Server, in der Firma läuft ein IIS6. Also schnell die Seite auf dem lokalen IIS gehostet. Doch auch hier wurde die Seite einwandfrei dargestellt. Jetzt wurde es mysteriös. Der einzige Unterschied, der noch blieb, war, dass auf meinem Enwicklungsrechner ein deutsches Vista mit IIS7 lief, und der Produktivserver mit einem englischen Windows Server 2003 und IIS6 arbeitete. Vielleicht ein Lokalisierungsproblem im IIS oder IE8? Ein Vergleich der Quelltexte von beiden Quellen zeigte zumindestens, dass der ASP.NET DataPager ein paar Texte lokalisierte (First ~ Erste, Next ~ Nächste, ...). Nachdem dies gefixt war, gab es aber auch hier keine Unterschiede mehr ... bis auf die Adressen der verlinkten CSS Stylesheets und Javscripts. Nun lernte ich, dass ASP.NET Scripts an dynamischen Adressen zum Nachladen generiert :
script src="/search/WebResource.axd?d=UV3-E5OwNGFcSb3I84w2&t=6391349351841...
Diese Scripte sind immerhin ca 20k groß und ihre Adresse ändert sich bei jedem Aufruf der Webseite. Vielleicht lag hier das Problem. Also speicherte ich die funktionierende Seite in ein lokales html file und bog händisch Schritt für Schritt die Links von der funktionierenden Quelle auf die nicht funktionierende um, in der Hoffnung irgendwann eine Seite mit dem zerstörten Layout zu erreichen.
Am Ende hatte ich jedoch eine lokale Seite mit Scripten und Stylesheets vom nicht funktionierenden Server, die immer noch das korrekte Layout anzeigte. Jetzt war ich völlig perplex!

Ich lud nun die beiden Seiten, funktionierend und defekt, in zwei Tabs des IE8. Während ich versuchte, mir eine neue Hypothese für dieses seltsame Verhalten auszudenken, schaltete ich immer zwischen beiden Tabs hin und her ... bis mir etwas auffiel. Es gab Unterschiede, aber außerhalb des eigentlichen Darstellungsbereiches. Das Symbol für die Kompatibilitätsansicht im IE8 war im defekten Layout nicht sichtbar! Warum nicht? Der andere Unterschied war in der Statusleiste zu sehen, die funktionierende Seite kam von "Computer" die andere von "Lokales Intranet". Hatte es etwas mit dem berüchtigten Zonenmodell zu tun? Ich konnte im Menüpunkt "Internetoptionen" nichts finden. Aber im Menü "Seite" gibt es den Punkt "'Einstellungen der Kompatibilitätsansicht" und dort gibt es die Option "Intranetsites in Kompatibilitätsansicht darstellen".
D.h. alle Seiten aus dem Intranet (wo sich auch das Firmenrepository befindet) werden in der Kompatibilitätsansicht dargestellt, und in der Kompatibilitätsansicht geht das Layout kaputt! Seiten vom lokalen Computer (localhost, Dateisystem) und aus dem Internet werden im neuen, standardkonformen Modus angezeigt! Offensichtlich ist dies die Standard Einstellung des IE8, wobei mir der Sinn dieser Option wirklich schleierhaft ist. Noch merkwürdiger, dass sie  standardmäßig aktiviert ist.





PS: Der Grund für das defekte Layout in der Kompatibilitätsansicht war übrigens ein absolut positioniertes Element, dessen Style die folgenden Attribute fehlten:
right: 1px;
top: 1px;
width: auto;
overflow: hidden;


11 October 2009

Homepage Redesign mit Expression Web und Subversion

Gestern und heute habe ich mit einem Design für meine Homepage begonnen. Diese hatte ich mal vor Urzeiten (ca 2003) nach einem Provider Wechsel neu angelegt aber dann wegen Hochzeit, Kindern etc. nie wieder angefasst. Um den Lachanfällen von Frau, Kollegen und Nachbarn ein Ende zu setzen musste etwas passieren. Und eine gute Gelegenheit mal wieder meine Html Kenntnisse aufzupolieren. Und am besten gleich mal Expression Web 3 ausprobieren. Gesagt getan, rein ins Vergnügen.

Erste Erkenntnis, Table Layout ist out, CSS funktioniert tatsächlich, und nach einer halben Stunde Template Erforschung hatte ich dann a) ein funktionierendes neues Layout mit Navigation und b) endlich verstanden was das Cascading bedeutet. Und das man das Separation of Concerns Prinzip auch auf Stylesheets anwenden kann. Im Vergleich zu Frontpage oder gar dem Html Editor vom Visual Studio ist Expression Web um Lichtjahre besser. Kaum wartet man ein paar Jahre, schon geht alles viel leichter :-)

Doch dann bekam ich Probleme als ich versuchte mein Homepage Projekt unter Versionskontrolle zu stellen, konkret mit Subversion. Expression Web hat ja erstaunlicherweise keine eingebaute Unterstützung für Versionskontrolle außer für Microsofts TFS, welches außerhalb von großen Unternehmen kaum verbreitet sein dürfte. Mit Subversion bekommt man die größten Probleme, wenn Dateien oder gar Verzeichnisse umbenannt oder verschoben werden. Dies muss man unbedingt mit einem Subversion Client machen. Nun sind jedoch genau diese Operationen beim Aufbau einer neuen Struktur nicht gerade selten. Mit Expression Web läßt sich das alles sehr einfach und bequem erledigen, alle Hyperlinks werden automatisch angepasst, etc. Doch danach ist die Subversion Working Copy erst einmal Schrott. OK, dann verschiebe und benamse ich mittels TortoiseSVN. Hat man dabei jedoch Expression Web offen, hatte ich öfters das Problem, das plötzlich Dateien mit altem Inhalt überschrieben wurden, Links kaputt waren und am Ende das Programm behauptete meine Homepage wäre kein gültiges WebSite Projekt mehr.

Grund waren geheime (versteckte) _vti_* Verzeichnisse, deren Inhalt von TortoiseSvn logischerweise nicht upgedatet werden konnte. Letztendlich habe ich meine Homepage wieder aus der Versionskontrolle entfernt und mache jetzt wieder händische Backups des kompletten Verzeichnisses.

Ich frage mich nun, ob überhaupt jemand dieses Programm zu professionellen Web Design hernehmen kann, bzw. wo es Microsoft positioniert? Ohne funktionierende Versionskontrolle kann man doch nicht guten Gewissens arbeiten? Oder arbeiten Web Site Entwickler etwa noch ohne Versionskontrolle? Ich meine ein Versionkontroll Plugin Konzept wäre im Vergleich zu den vielen tollen anderen Features wirklich trivial gewesen. Es muss doch nur eine Benachrichtung übers Anlegen, Ändern, Löschen, Umbenennen, und Verschieben gesendet werden.

Wirklich schade, ohne dieses "fehlende Feature" ist Expression Web 3 wirklich ein tolles Produkt.

06 October 2009

Don't forget to run aspnet_regiis and ServiceModelReg

Every few month I run into weird installation problems on IIS so that ASP.NET applications (including .svc WCF services and Silverlight applications) don't run with misleading error messages. Today I was running into this problem again. Seems that I hadn't the correct permissions to download a .xap file from the ClientBin silverlight folder. After fiddling around for half an hour or so I eventually remembered to run aspnet_regiis.exe -i to reregister the current .net framework. This solved the problem immediately.
Even if this tool is located in "%windir%\Microsoft.NET\Framework\v2.0.50727" it seems to reregister the newest installed framework (in my case .NET 3.5 and Silverlight).

A similar problem can occur for WCF services with the .svc extension. In this case you need to run ServiceModelReg.exe -i again. This tool is located in "%windir%\Microsoft.NET\Framework\v3.0\Windows Communication Foundation"