Thomas Woelfers Baustatik Blog

Baustatik-Software und was sonst des Weges kommt

Kundenmakro: Export von AS-Werten nach ZEIG

Vom Ingenieurbüro Balster gibt es ein neues Makro für die Baustatik – um genau zu sein: Es gibt ein Paket das aus einem Baustatik-Makro und Prozeduren für unser CAD-System Zeig besteht.

Exportiert werden die berechneten AS-Werte aus der Baustatik, und importiert werden die dann nach ZEIG, und dort “halb” automatisch zu Bewehrungsplänen weiterverarbeitet.

Folgendes passiert (Beschreibung von Herrn Hobbensiefken, von dem das Makro stammt. Er ist auch bereit darüber hinaus im gewissen Umfang Fragen dazu zu beantworten):

1. Es werden nur die Bewehrungsdaten der ersten Bemessungsgruppe übergeben.
2. Automatisch erzeugte Bemesungsergebnisse werden nicht erfasst.
3. Das Export-Makro ist nicht fehlertolerant, soll heißen: o.g. Bedingungen werden nicht überprüft.
4. Die VEC-Datei mit den Bewehrungsdaten wird im Ordner der Xfalt-Berechnungen abgelegt (keine Auswahlmöglichkeit)
5. Die Bewehrungsrichtungen werden in der VEC-Datei als Layer abgelegt (asxu - 11, asxo -12, asyu -13, asyo -14, asw -15)
6. Für die automatische Erstellung der VEC-Datei wird der Zeig-Bildschirm-Maßstab auf 1:100 und der Zeig-Plot-Maßstab aus 1:50 festgelegt.


Zur Bearbeitung der Daten unter Zeig dient die Prozedur ASXYAB.PRC unter folgenden Bedingungen:

1. Die Datei mit den Bewehrungsdaten wird in eine VEC-Datei (z.B. zu bewehrender Grundriss) in die Detail-Ebene geladen.
2. Der Grundriss enthält vor dem Zuladen noch keine Detail-Ebene.
3. Die Funktionsweise unter Zeig auf Basis PicturesByPC Version 3.2 ist noch nicht getestet.


Die Arbeit mit den eingelesenen Bewehrungsdaten erfolgt momentan händisch über die Kommandoeingabe.

Nach dem Zuladen der Bewehrungsdaten in die Detailebene eines Grundrisses sind normalerweise alle Layer (11 - 15) der Bewehrungsdaten aktiv und die Texte stehen übereinander. Die Größe der Bewehrung wird als Text angezeigt. Der Startpunkt des Textes (ma ....  - Zeichenbefehl im Edit der VEC-Datei) ist die Lage des gerechneten Bewehrungspunktes. Die Farbe der Texte (6 - magenta) darf nicht verändert werden, da die Zeig-Prozedur in ihrer Funktion darauf abgestellt ist.

Mit den Befehl 'ly' können die gewünschten Layer ein- und ausgeschaltet werden. "ly -d 11..15" schaltet alle Bewehrungslayer aus. Mit "ly -e 11" kann Layer 11 (asux) wieder sichtbar geschaltet werden.
Der einfache Aufruf von "ly" öffnet den Layer-Dialog und die gewünschten Layer können im Dialog an/aus geschaltet werden.

Die Prozedur 'asxyab.prc' erstellt bei der ersten Benutzung der Bewehrungsdaten eine Sicherung der Bewehrungsdaten, sodass mit 'asxyab -u' der Anfangszustand wieder hergestellt werden kann, egal wieviel Operationen bis dahin ausgeführt worden sind. Mit 'asxyab -f (Skalierung) kann die Textgröße der Bewehrungsdaten prozentual geändert werden, dabei bedeutet z.B. 'asxyab -f 1.2', dass die Texte um 20% vergrößert werden.
Wird z.B. eine Grundbewehrung mit einer Matte Q-335A gelegt und es sollen die noch abzudenkenden Spitzen angezeigt werden ist 'asxyab 3.35' der benötigte Befehl. Es können beliebig oft Werte abgezogen werden, da mit dem Parameter '-u' der Grundzustand wieder herzustellen ist. Alle Befehle der Prozedur 'asxyab' wirken auf alle Bewehrungslayer gleichzeitig. Änderungen der Textgröße werden mit dem Parameter '-u' nicht zurückgenommen.


Soweit zur derzeitigen Verwendungsmöglichkeit des Bewehrungsdaten-Exportes nach Zeig. Wir verwendet diese Routinen in erster Linie bei größeren Decken mit ungleicher Belastung oder bei sehr unterschiedlichen Feldkonfigurationen.

Die mir von Ihnen zur Verfügung gestellten Methoden habe ich mit den entsprechenden Änderungen in das Makro integriert und umbenannt, um die Originale im Programmcode auszusparen. Zur besseren Verifizierung zwischen Ihren ursprünglichen Methoden und meinen Änderungen, bzw. den bis heute im Programm vorliegenden Methoden habe ich Ihnen die alten Dateien noch mit in die Zip-Datei gepackt.

Wer mag, kann alles zusammen hier herunterladen.

Makros in der Baustatik

Die Baustatik ist vollständig vom Anwender programmierbar und damit erweiterbar. Ein gutes Beispiel für eine solche Erweiterung ist die Variantenkonstruktion, also eine Art der Konstruktion, bei der immer ähnliche Konstruktionen mit veränderten Parametern angelegt werden.

So sind zum Beispiel die Regale der Firma Heiss konzipiert. Die sehen ungefähr wie folgt aus und haben auch die ersichtlichen Parameter:

image

Dafür gibt es nun ein Makro – und wer will, kann das auch ausprobieren. Dazu ist folgendes zu tun:

Sie gehen in der Baustatik nach "Optionen -> Makro -> Makro herunterladen".  (Der Rechner muss dazu einer Internetverbindung haben.)

image

Das zeigt das Fenster mit den Makros an. Dort wählen sie "Regalerzeugen.cs" aus, und klicken dann auf "Speichern". Dadurch wird das Makro auf Ihren Rechner herunterladen und dort abgelegt. (Man kann es auch alternativ direkt vom Server aus ausführen, aber dann müssen Sie sich immer wieder verbinden, und können auch nichts ändern.)

Dann legen Sie ein neues leeres Faltwerks oder Rahmendokument an, und gehen dann auf Optionen -> Makro -> Makro ausführen. In der Liste taucht das "Regalerzeugen.cs" Makro dann wieder auf: Da drücken Sie auf "ausführen".

image

Das Makro startet dann, und öffnet zunächst ein Fenster, in dem die Parameter fürs Regal erfagt werden:

image

Die einfach eingeben (alle Abmessungen in [m], und "Kommas" mit ".") und OK drücken -> Das RegaL wird erzeugt. Die Stäbe darin haben dann bereits die "richtig" sortierten Querschnitte - die sind aber noch "leer" und Sie müssen also die Querschnittsdefinitionen über die Dokumenten-Ansicht noch ergänzen.

Wenn man das getan hat, sieht die ganze Sache ungefähr so aus – und alles mit nur 6 eingegebenen Werten:

image

Kleine Statistik zur Baustatik

Weil ich kürzlich mal wieder drauf geschaut und darum die Zahlen zur Hand habe: So sieht die Baustatik aus Entwickler-Sicht aus:

Eigentlicher Quellcode: circa 19.000 Dateien, 3000 Ordner mit insgesamt etwa 1.5 GB
Testumgebung: circa 8600 Dateien in 65 Ordnern mit etwa 3.7 GB
Begleitende Webseite (Doku, Case-Management, etc.): circa 3700 Dateien, 120 Ordner, 500 MB.

… alles zusammen also etwa 30.000 Dateien. Schon eher ein größeres Projekt Smiley

Ein Makro zum auswählen und bearbeiten

Heute kam die Frage auf, ob wir nicht ein Beispiel-Makro fürs auswählen und bearbeiten von Objekten hätten. Haben wir… Smiley

Der einfachste Weg ist natürlich der, einfach ein Objekt auszuwählen und dann den Eigenschaften-Dialog anzuzeigen. Fürs auswählen selbst braucht man kein Makro: Das geht ja “einfach so”. Ein Beispiel für das anzeigen des Eigenschaften-Dialoges gibt es im Makro “AuswahlBearbeiten”.

image

Was aber tun, wenn man in einer Schleife nacheinander mehrere Objekte auswählen und dann bearbeiten will. Also: Objekt auswähle, Objekt bearbeiten –> und dann wieder von vorne anfangen? Das ist etwas komplizierter (das vorige Makro ist ein Einzeiler), und darum gibts hier eine kurze Erklärung dazu, was das Ding tut. Der Quellcode dazu findet sich in “ObjektAuswählenUndBearbeiten”.

Neben dem normalen immer für Makros benötigten Kram gibt es im wesentlichen 3 Methoden:

1.) DoIt()

Das ist die Funktion, die die eigentliche Arbeit tut: Sie wird auch ganz am Anfang im Execute() des Makros aufgerufen. Das Ding tut folgendes:

  • Ein neues MouseTool vom Typ “ObjectSelectionMouseTool” erzeugen. MouseTools sind die Dinger, mit denen man in der Graphik interaktiv arbeiten kann. Wenn man z.B. in der Graphik mit der Maus irgendwo draufklickt und das angeklickte Objekt wird rot, dann war da das normale “SelectionMouseTool”. Wenn man mit der Maus einen Zoom durchführt, dann passiert das mit dem ZoomMouseTool etc.. Das ObjectSelectionMouseTool ist dafür da, ein (oder mehrere) Objekt(e) beliebigen Typs in der Graphik auszuwählen.
  • Das MouseTool hat mehrere Ereignisse, die man mitbekommen kann. Die beiden die man hier braucht sind “SelectCanceled” und “SelectFinished”. Das erste Ereignis tritt ein, wenn die Auswahl abgebrochen wurde (Rechte Maustaste gedrückt), das zweite tritt ein, wenn eine Auswahl durchgeführt und ein Objekt ausgewählt wurde.
  • Das Makro hängt sich nun an beide Ereignisse dran: Im Cancel-Fall wird dann die Methode Cancel() aufgerufen (die zeigt einfach nur eine Meldung an, damit man mitbekommt, das die Sache nun ein Ende hat), im anderen Fall wird Finished() aufgerufen.
  • Das MouseTool ist nun fertig und kann aktiviert werden. Das passiert mit FormBase.ActivateMouseTool().

2.) Cancel()

  • Tut wie gesagt nicht viel: Auf die Meldung darin kann man eigentlich verzichten, aber damit man hier im Beispiel mitbekommt, das irgendwas passiert, wird sie eben angezeigt.

3.) Finished()

  • Hier wird zunächst das erste der ausgewählten Objekte aus den Argumenten der Funktion extrahiert. Das Objekt ist garantiert vom Typ IDocObject (weil das MouseTool nichts anderes auswählen kann.). Das ganze sieht darum etwas kompliziert aus, weil das MouseTool eigentlich darauf ausgelegt ist, mehrere Objekte auszuwählen. In unserem Fall gibt es aber immer nur ein Objekt, und darum kann das aus dem Array-Parameter mit “[0]” rausgeholt werden.
  • Dann wird eine neue “DocObjectCollection” angelegt, und das eine ausgewählte Objekt wird in diese Sammlung reingesteckt. Die Sammlung braucht man – obwohl es nur um eine Element geht – weil auch der ganze restliche Code immer darauf ausgelegt ist, mehrere Objekte gleichzeitig zu bearbeiten.
  • Dann wird mit Hilfe des FactoryManagers ein Eigenschafts-Dialog erzeugt. Der Eigenschafts-Dialog ist dabei einer, der für den Typ Objekt zuständig ist, das ausgewählt wurde. Darum muss der Typ des Objektes übergeben werden. (Dieser Typ ist also der konkrete Typ “Beam”, “Node”, etc. – und nicht der “allgemeine” Fall “IDocObject”)
  • Als nächstes wird die zuvor vorbereitete Sammlung in den Dialog gesteckt.
  • Dann hängt sich der Code noch an das “Closed” Ereignis des Dialogs. Dieses Ereignis tritt ein, wenn das Fenster geschlossen wird. Ist das der Fall, wird wieder “DoIt” aufgerufen – die ganze Sache geht also wieder von vorne los.
  • Und schließlich wird die Dialogbox angezeigt.

Ich hoffe mal, mit dieser Erklärung wird das alles etwas klarer….

Die nächtlichen Testläufe

Ich habe schon hin und wieder darauf hingewiesen, das wir die jeweils tagesaktuelle Version der Baustatik jede Nacht automatisiert testen. Wie hat man sich das aber vorzustellen?

So:

Am Quellcode der Baustatik wird natürlich von mehreren Personen gleichzeitig gearbeitet – und die befinden sich auch an unterschiedlichen Standorten. Damit das klappt gibt es einen zentralen Server, der für die Verwaltung der richtigen Versionen des Quellcodes zuständig ist. Von diesem Server kann jede Workstation in unseren Standorten eine Kopie des Quellcodes abholen, und man kann dann auf dieser Workstation damit arbeiten. Lokal vorgenommene Änderungen werden dann wieder in den zentralen Server zurückübertragen.

Im Münchner Netzwerk gibt es nun zwei Server die automatisiert laufen. Der eine ist für die 64bit-Version der Baustatik zuständig, der andere für die 32bit Version. Beide holen einmal am Tag ebenfalls den aktuellen Quellcode vom zentralen Server ab. Danach wird auf dem einen Server die tagesaktuelle Version der Baustatik als 64bit Version gebaut, auf dem anderen die 32bit Version.

Wenn das ging, wird auf beiden Rechner die Baustatik mit speziellen Kommandozeilen-Argumenten gestartet: Die führen dazu, das die Baustatik das spezielle Test-Projekt lädt. Dieses Testprojekt enthält mehrere tausend (Tendenz: steigend) Baustatik-Dokumente. Jedes einzelne dieser Dokumente wird dann durchgerechnet, und jedes einzelne Ergebnis mit dem Ergebnis des Rechenganges vom Vortag verglichen.

Gibt es einen Unterschied, dann wird ein entsprechender “Vermerk” angelegt: Sind alle Dokumente durchgerechnet, dann erhalten alle Beteiligten noch eine EMail, an der man sofort ablesen kann, ob der letzte Durchlauf “geklappt” hat oder nicht – wenn nicht, muss die Ursache dafür beseitigt werden.

Nachdem das Programm immer umfangreicher wird – und dadurch auch immer mehr Testcases anfallen – wird ist die Sache inzwischen relativ zeitaufwendig geworden: Ein kompletter Durchlauf dauert mittlerweile etwa 6 Stunden. Nachdem wird das ganze nur einmal pro Tag machen, ist aber noch jede Menge Luft – bis wir den Prozess irgendwann dann mal anders portionieren müssen.

Ein paar Dinge die ich beim bauen des Index gelernt habe

  • Der in der Theorie einfachste Weg eine gute Suche zusammenzubasteln besteht darin, den Search Server (Express) zu verwenden.  In der Praxis scheitert das aber daran, das das Ding praktisch nicht installiert werden kann.
  • Ein weiterer einfacher Weg ist einfach die Volltextsuche vom SQL Server zu verwenden: Auch die Express-Variante hat einen Katalog für Volltextsuchen. Man braucht dann aber noch einen Spider, der die Webseiten einsammelt – und für ein paar tausend Seiten, so wie bei www.die.de, ist der SQL-Server meiner Ansicht nach ein bisschen übertrieben. Ein .net Dictionary tut es da auch.
  • Für das Spidern der Webseiten kann man – auch wenn eigentlich alle Foren anderer Ansicht sind – prima das WebBrowser Control von .net verwenden: Woran offenbar irgendwie alle scheitern: Man muss an “passender” Stelle Application.DoEvents aufrufen. Damit kann man das Browser-Control auch ein einer Kommandozeilen-Anwendung verwenden. Wenn man das Control verwendet, dann hat man Vor- und Nachteile. Die Vorteile sind klar: Man bekommt Javascript redirects und sonstige Dinge die in der Webseite per Javscript passieren “umsonst”: Die ausgewertete Seite (die man einfach per DOM des Browsers auswerten kann) sieht (von der Struktur her betrachtet) genau so aus, wie sie auch im Browser aussehen würde. Wer sich nicht mit dem eher aufwendigeren auswerten des HTML auseinandersetzen will, der ist mit dem Control gut aufgehoben. Die Nachteile: Das ganze ist recht langsam, und man kann das Control nicht in mehreren parallel Threads verwenden. Ich habe das Control in der ersten Version meines Spiders verwendet, und das hat gut geklappt.
  • Wer das Control nicht verwenden will – zum Beispiel weil man eben mehrere Threads (oder Tasks) braucht, der kann das Html Agility Pack verwenden. Das nehme ich in der aktuellen Version des Spiders: Man hat mehr Arbeit beim auswerten, aber die Sache geht dramatisch viel schneller. (Der erste Spider brauchte für www.die.de ca. 50 Minuten, meine aktuelle Variante braucht unter 2.)
  • Hat man den Spider braucht man noch einen Index: Da kann man wie gesagt den Sql Server hernehmen, oder aber man steckt den Index einfach in ein paar Dictionaries. (Das mache ich.). Dazu ist es ganz gut zu wissen, das es den “Porter Stemmer” Algorithmus gibt. Der führt im Prinzip beliebige Worte in eine “Grundform” über. Das ist dafür gut, damit man zum Beispiel auch das Wort “Preis” findet, wenn “Preise” gesucht wurden. Vom Algorithmus gibt es fertige Implementierungen auch in C#.
  • Im Gegensatz zum Download/Html auswerten geht das indizieren so schnell, das es sich nicht lohnt, selbiges zu parallelisieren.
  • Fürs vernünftige parallelisieren der Downloads braucht man den SerivcePointManager.
  • Nach einer einigermaßen brauchbaren Filterung der Seiten und des Inhalts darauf (inklusive stemming) überrascht einen der geringe Umfang des dann resultierenden Kataloges: Im Fall von www.die.de sieht es so aus, das von ca. 12.000 Seiten “hinterher” gerade noch knapp 4500 Seiten übrigbleiben – und die haben auch noch unter 30.000 unterschiedliche Worte. Eigentlich wirklich nicht besonders viel. Dabei ist die Sache mit den Seiten sicherlich stark von der Webseite abhängig – im Fall von die.de kommen die “vielen unnützen” Seiten durch die diversen Übersichtsseiten der Blogs zustande. Was die Anzahl der Worte angeht: Ich habe das auch mit “anderen” Webseiten ausprobiert, und da sah die Sache ähnlich aus.

Unabhängig davon: Falls jemand Interesse an einem Spider/Indexer in C# für  eine Suche auf der eigenen Asp.Net Webseite hat: Ping me Smiley

Batch-Job: In einen Ordner mit Tages-Nummer kopieren

Musste ich heute machen, und weil man so was immer wieder mal braucht, hier ein kleiner Tipp, wie man in einem Batch-Job an die Nummer des aktuellen Tages im aktuellen Monat (also 1 bis 31) kommt, und diese Nummer dann als Zielordner beim kopieren verwendet.

Einfacher ausgedrückt: Man will jeden Tag ein Backup von irgendwas anlegen, und das Backup soll in einem nummerierten Ordner landen. Die Nummer des Ordners ist dabei die Nummer des Tages.

Geht so (das interessante ist die Zweite Zeile. Da werden 2 Zeichen aus dem Date-String entnommen, und zwar ab dem ‘0’ten Zeichen.):

set DATE=%date%
set DAY=%DATE:~0,2%
copy quelle\*.* ziel\%DAY%

FileNotFoundException beim XmlSerializer

Folgendes passiert: Man versucht Instanzen mit dem XmlSerializer zu serialisieren, bekommt aber im Konstruktor der Serializers eine FileNotFoundException. Was ist zu tun?

Dazu muss man zunächst mal wissen, das es im Wesentlichen zwei Methoden gibt, die Serialisierungs-Assemblies zu erzeugen:

  1. Zur Kompilierzeit, also beim bauen des Projektes
  2. Zur Laufzeit der Anwendung

Der erste Fall ist manchmal ganz gut dafür geeignet, die Ladezeit der Anwendung zu verkürzen: In diesem Fall ist die DLL aber garantiert da, denn wenn das nicht der Fall wäre, wäre bereits beim bauen der Anwendung ein Fehler aufgetreten.

Es geht also um den zweiten Fall. Da passiert folgendes: Der Konstruktor des XmlSerializers versucht zunächst eine passende Assembly zu finden (die hat den Namen der DLL, in der der zu serialisierende Typ steckt, plus die Erweiterung “Xmlserializer.dll”). Findet er die nicht, wird zur Laufzeit Code zum serialisieren erzeugt und übersetzt – und die daraus resultierende Assembly wird dann geladen und zum serialisieren eingesetzt.

Die FileNotFound Exception kommt dann, wenn das erzeugen der Serialisierungs-Assembly nicht geklappt hat. Dafür kann es jede Menge Gründe geben – nicht zuletzt Fehler in der Struktur der zu serialisierenden Klassen oder deren Auszeichnung.

Wie findet man nun das Problem? So:

  1. Einen (Visual Studio) Command-Prompt öffnen
  2. In das Verzeichnis wechseln, in der sich die Anwendung befindet
  3. “sgen NameDerAusgabgsDll.Dll /v” eingben

Sgen gibt dann eine im allgemeinen einfach verständliche Fehlermeldung aus: Korrigiert man den Fehler, ist man auch die FileNotFoundException los.

Wir wir die Performance verbessern

Ich hatte in den letzten Tagen mehrfach darauf hingewiesen, das wir die Performance der Baustatik spürbar verbessert haben. Das ist natürlich schön – aber wie macht man das eigentlich ?

image

Es gibt verschiedene Möglichkeiten, aber im Wesentlichen läuft es darauf hinaus, das man die Zeit misst, die die einzelnen Funktionen des Programms brauchen. Dann sucht man die Funktion die am langsamsten ist und überlegt sich, ob die benötigte Zeit “angemessen” ist, oder nicht. Wenn nicht, hat man einen Kandidaten für die Optimierung. Die kann daraus bestehen, das man einfach nur den Code ein bisschen umstellt (hauptsächlich in Fällen, in denen Funktionen extrem oft aufgerufen werden), oder auch daraus, das man tatsächlich einen völlig neuen Algorithmus verwendet.

Das wichtige ist aber immer das Messen – vor allem auch das erneute Messen nach der Änderung: Die Dinge sollen ja nicht langsamer werden…

Damit man sowas messen kann, wird das Programm nicht direkt, sondern unter der Kontrolle eines anderen Programmes gestartet. Das kontrollierende Programm, das auch die Messungen durchführt, nennt man Profiler. Davon gibt es eine ganz Reihe – in unserem konkreten Fall haben wir das Programm GlowCode verwendet. (Das übrigens wirklich erstaunlich schnell ist, wenn ich dessen Performance mit anderen Profilern vergleiche, die ich ausprobiert habe.)

Letzten Endes ist es also ganz einfach: Messen, ändern, wieder messen: Wenn es dann schneller ist – prima, sonst zurück zum Anfang.

Sauer auf Microsoft

Im Normalfall bin ich Microsoft gegenüber eher positiv eingestellt: Letzthin haben die sich aber etwas geleistet, was ich alles andere als lustig finde. Das Visual Studio hat seit Version 2003 eine Projektart namens “Setup and Deployment Project”.

Wir installieren die Baustatik damit seit der ersten Version, und haben das Projekt auch brav nach VS 2005, nach VS 2008 und nun nach VS 2010 portiert. Und zwar nicht mit wenig Arbeit: Zur Zeit installieren wir damit circa 5000 Files. Wenn ich raten müssten würde ich sagen, das im Laufe der Zeit mindestens 4 Monate Arbeit in dieses Projekt gesteckt wurden.

Und mit VS 2010 geht nicht mehr. Das Projekt erzeugt zwar noch ein MSI – aber das kann man eigentlich nicht mehr richtig nutzen: Installieren kann man nur noch auf einem Rechner, auf dem es keine Vorgängerversion gibt – und der von Microsoft gelieferte Workaround führt zwar zu installierten Dateien, aber auch zu nicht mehr funktionierenden Links im Startmenü.

Das ist auch bei Connect alles prima dokumentiert (und der Fehler ist auch schon bestätigt) – nur interessiert es irgendwie niemand. Die letzten 7 Tage habe ich auf irgendein Feedback irgend einer Art gewartet – jetzt geht’s nicht mehr länger: Ich werde in den sauren Apfel beißen und mich nach einem anderen Werkzeug zur Herstellung des Setups umsehen – und dann den ganzen Spaß von vorne aufbauen.

Bin regelrecht stinkig.

Setup and Deployment Project: Probleme mit VS 2010

Nachdem mich das nun fast 3 Tage gekostet hat, hilft es vielleicht jemand anderem in einer ähnlichen Situation. Ich hatte eine Setup and Deployment Project, das für die Installation unserer Software zuständig war, und das ursprünglich mit VS 2005 erstellt worden war. Das gleiche Projekt funktionierte auch prima mit VS 2008.

In der Version mit VS 2010 klappt es nicht mehr: Wenn man die Software auf einem “leeren” System installiert, geht alles gut. Befindet sich aber bereits eine Vorgängerversion der gleichen Software auf dem Zielsystem, dann werden im Laufe des Installationsvorganges (fast) alle Dateien der Software entfernt: Der Installer sagt das alle in Ordnung wäre – schaut man dann aber auf die Festplatte, so ist keine einzige Datei der Installation vorhanden.

Grund ist ein bekannter Fehler in VS 2010. (Connect-Eintrag dazu.). Im Wesentlichen läuft es darauf hinaus: Wenn man die Option “RemovePreviousVersions” auf “true” stellt, dann werden die Dateien der Vorgängerversion im Zuge der Installation entfernt. Der Fehler macht sich dadurch bemerkbar, das der Schritt mit dem entfernen der alten Version nicht vor der Installation der neuen stattfindet, sondern danach: Alle Dateien die sowohl in der alten als auch in der neuen Version drin sind, landen dann eben nicht auf dem Zielsystem. :-(

Angesichts der Tatsache das sich bei den Setup-Projekten in den letzten 6 Jahren praktisch nichts getan hat, finde ich es schon ein bisschen schwach, das die Softies es trotzdem geschafft haben, eine wichtige Funktion hops gehen zu lassen.

Ein (teilweise brauchbarer) Workaround ist im Connect-Eintrag beschrieben. (Im Wesentlichen baut man einen Post-Build Step, der die Reihenfolge der Arbeitsschritte korrigiert.)

Ein einfaches Web Stress Tool

Ich wollte kürzlich die Performance-Unterschiede vom IIS mit und ohne Output-File-Caching untersuchen: Mit dem Caching sollte der IIS dramatisch mehr Seiten ausliefern können, als ohne. Was mir nicht klar war, war, wie man dieses Caching nun genau einschaltet: Von Haus aus steht im Konfigurations-Manager des IIS, das das Caching “eingeschaltet” ist: Auf den Beispielvideos auf IIS.net werden aber immer noch zusätzliche Maßnahmen getroffen.

Mir war nicht klar, ob das tatsächlich notwendig ist, oder nicht. Die Idee das zu überprüfen war aber ganz einfach: Man nimmt das Web Stress Tool von Microsoft und schaut einfach nach, wie viele Seiten pro Sekunde geliefert werden können.

Leider ist das nur in der Theorie so, denn das an vielen Stellen verlinkte Web Stress Tool gibt es einfach nicht mehr: Man muss entweder WCAT verwenden, oder die Visual Studio-Ausgabe für Tester. Was blöd ist, denn die Tester-Ausgabe habe ich nicht, und WCAT ist mir eindeutig zu umfangreich für meine Zwecke.

Also habe ich selbst ein kleines Web-Stress Tool gebaut.

web_stress_tool

Es handelt sich um eine einfache Windows-Forms Anwendung. Oben gibt man die URL ein, die man testen will. Darunter kann man die Anzahl an Threads einstellen, die parallel die angegebene URL aufrufen sollen. Drückt man dann auf “Start”, fängt das Programm eben mit der eingestellten Anzahl an Threads an, Seiten abzurufen.

Darunter gibt es eine Statistik, die die Anzahl Seiten pro Sekunde und die gesamte Anzahl an Aufrufen auflistet. Das reicht für einen Test vom Caching völlig aus. (Die “optimale” Anzahl an Threads muss man ausprobieren.)

Wer mag kann sich die Sache hier herunterladen: Ausführbare Datei (.Net 4), Quellcode (VS 2010).