...someplace, where there isn't any trouble? Do you suppose there is such a place, Toto?

Sinnvolle Beschäftigung während des Weihnachtsurlaubs

Was macht der Softwareentwickler von Welt, wenn ihm langweilig ist? Klaro, er findet Lösungen zu Problemen, die es noch gar nicht gibt. So auch bei mir dieses Jahr: Seit etwa 10. Dezember 2005 und vor allem zwischen den Jahren und in der ersten Januarwoche habe ich mich mit der MMC und Snap-Ins für die MMC beschäftigt. Der Grund dafür lag auf der Hand: Das war wieder mal eine Technologie mit der ich mich noch nicht beschäftigt habe, wohl aber der DEI, und das wurmt. Außerdem wollte ich mal wissen, wie lange sowas dauert, wenn man ein richtig amtliches Snap-In entwickeln will, das dem "Services" und "Event Log" Snap-In von W2K oder XP in punkto Aussehen und Funktionalität in nichts nachsteht.

Die Wahl des Frameworks

Für MMC Snap-Ins gibt es eine Reihe von Frameworks, die aber alle ihre Vor- und Nachteile haben. Man kann zum einen VB nehmen, da gibt es sogar einen Wizard dazu, der einem eine Menge abnimmt. Aber nein, sowas mach' ich nicht, man hat ja schließlich noch einen Funken Selbstachtung im Leib. Dann gibt es ATL und einen Wizard, der einem auch wieder viel abnimmt. Aber einige Postings in der Newsgroup microsoft.public.management.mmc haben mich dann doch aufhorchen lassen, weil einige Sachen dann doch ziemlich Broken sind, wenn man ATL verwendet. Die Samples zur MMC im PlatSDK hingegen verwenden ein selbergestricktes Framework und führen einen in mehreren Schritten von einem bare-bones Snap-In, das wirklich nur die allernötigsten COM-Interfaces implementiert, hin zu etwas aufwendigeren Snap-Ins mit einem richtigen Baum in der Scope-Pane und mit Property Pages für einzelne Knoten in der Result View usw. Und nachdem ich von der MMC bis dato noch überhaupt keinen Blassen hatte, dachte ich mir, es ist vielleicht sinnvoll, erstmals durch die Samples aus dem PlatSDK durchzudebuggen, um die Abläufe zu verstehen und hinterher vielleicht eine "more educated decision" zu treffen, was das Framwework der Wahl sein sollte. Und dabei bin ich dann auch geblieben, denn das Framework aus dem PlatSDK hat einen sehr großen Vorteil: Es versteht sich nicht als in Stein gemeißelte Klassenstruktur, das auf den immergleichen virtuellen Methoden und Klassen besteht, sondern es "erfindet sich quasi für jedes einzelne Sample neu". Die Samples untereinander teilen sich also nicht tonnenweise Framework Code als Common Code, sondern benutzen für jedes Sample gleichnamige Klassen mit denselben Dateinamen und Aufgaben, die aber für jedes Sample leicht unterschiedlich aussehen. Was zählt ist die Idee, die hinter jeder Klasse steckt, nicht aber die codemäßige Wiederverwendung. Sowas gefällt mir, denn es ist superflexibel und man kann sich aus den Samples, wo jedes einen bestimmten Bereich abdeckt, ganz frei bedienen. Wenn man also wissen will, wie man eine Toolbar implementiert, macht man einfach einen Diff zwischen dem nodes Sample und dem Toolbars Sample und weiss dann, wie man sein Snap-In erweitern muss, um die Toolbar zu kriegen.

Und so schaugt's aus

So sieht in etwa mein Snap-In aus, wenn man es frisch startet:

Wie man sieht, gibt's eine Toolbar, über die man die Result View Items steuern kann. Über ein Kontextmenü (Hey dafür muß man wie für die Toolbar extra ein neues COM-Interface implementieren, kein Witz!) kann man natürlich die einzelnen Result View Items auch a bissal bedienen:

Was dann passiert, wenn man das tut, habe ich mir vom "Services" MMC-Snap-in abgeschaut:

Das coolste aber ist dér Aufbau zu einem Remote-Computer. Was noch ausschaut wie beim Eventlog-Snap-In oder dem Services-Snap-In....

Sieht plötzlich voll aus wie Max im Wizard97-Look:

Wenn man dann beim Max weiterklickt, kommt einem wieder alles verdächtig bekannt vor:

...bis man dann auf diese Seite stößt, die einem gestattet, sich als anderer User als dem eingeloggten zu verbinden:

Am Schluß gratuliert Max dann natürlich artig, daß man das so toll hingekriegt hat:

Uuuunnd wen man JJJEEEEETTTTZZZZTTT den "Finish"-Button drückt, dann kommt es einem...

Oooochh, wie? Auf SAAVIK läuft das RPC-Interface nicht? Macht nichts, dann zeigen wir eben kein List Control im Report Mode an sondern das MMC OCX für Messages, so wie im obigen Bild.

Au weia. Das hat mich Tage gekostet, daß das in allen Use Cases lief. Und als mich dann der Wahnsinn gepackt hat und ich dachte, jetzt ist das Biest "Ready for Prime Time", da wollte ich wissen ob das Ganze auch unter NT4 funktioniert. Also, NT4SP6 VMWare genommen, das NT4 Redistributable für die MMC 1.1 installiert. Setup verweigert die Ausführung: "Hey ohne IE 4.01 geht hier nix!". Also im CD-Gruschtelregal nach alten IE4-CDs gesucht, gefunden und installiert. Und dann geht erstmal gar nix in meinem Snap-In: Der schöne Wizard sieht total komisch aus (weil IE4 die Wizard97-Spezifikation nur so halbe eingeführt hat), er kommt nie zum Abschluß (weil ich lauter Makros für Comctl32 Version 5.80 verwendet habe, wo doch IE4 nur comctl32 Version 4.72 mitbringt) und die schöne Message View wie im letzten Bild gibt's schon mal gar nicht, weil es dieses COM-Interface erst mit MMC Version 1.2 gibt (die für NT4 ist 1.1).
Also folgendes getan

  • Code geschrieben für die Erkennung der unterschiedlichen MMC-Versionen (uuh, ist das convoluted! - das IComponent und das IComponentData-Interface müssen da Hand in Hand arbeiten um das rauszukriegen...)
  • Extra Templates für Old-Style Wizards mit MMC1.1 erzeugt
  • Alle 5.80er Common Control Makros ersetzt und höllenviel Code geschreiben, der auch unter comctl32 Version 4.7x funktioniert
  • Die MessageView ersetzt durch ein Pseudo-Result-View-Item, das halt denselben Text in einer Report View anzeigt.

Aber es gibt auch echt was für's Auge, z.B. die Property Pages für die einzelnen Result View Items:

Herzig, sieht doch aus wie bei Muttern, dem Services MMC Snap-in, oder? Die zweite Seite macht bei ihrem großen Vorbild natürlich auch phatte Anleihen:

Nicht zu vergessen Seite 3, die sehr geschwätzig das Service Control Manager API bemüht:

Und wie lange braucht man dafür?
Wollte man so vermessen, sein, mich als "erfahrenen Entwickler" zu bezeichnen, dann könnte man sagen, daß ein erfahrener Entwickler dafür 3 Wochen braucht, und beim zweiten Mal dann zwei Wochen. Davon sind etwa 3 Tage allein anzusetzen für ausschließliches Debuggen der Samples und das Nachvollziehen der Abläufe, unterstützt von den UML-Sequenzdiagrammen (!) aus der PlatSDK Doku. Für den NT4-Backport habe ich einen ganzen Tag gebraucht. Für die korrekte und flickerfreie Implementation eines Refresh (also "F5 Drücken"), etwa 3 Tage. Für die Property Sheets auch etwa 2 Tage (Hey, da steckt Logik dahinter!).

Alles in allem hat's Spaß gemacht und es gibt wieder eine Technologie mehr, wo ich dem DEI wieder hoffentlich auf mehr als Augenhöhe ;-) entgegentrete. Und nein, auch wenn DEI behauptet, das PlatSDK-Framework für MMC-Snap-Ins sei uncool: Ich finde es ganz brauchbar. Wer's verwendet, und wissen will, wo da die Speicherlecks drin sind, darf sich dann vertrauensvoll an den Mission Control Supreme Commander wenden.

Aber das allerbeste ist der Umstand, daß da keine einzelne Zeile MFC-Code drin ist, weil das ganze Mal wieder 'mal eine Technologie ist, wo MFC mehr behindert als nützt. Und wenn ein Projektleiter mich dereinst vielleicht fragt, wieviel davon denn wiederverwendbar sei, dann lautet die freudige Antwort: "Null!" und ich habe nicht ein bißchen ein schlechtes Gewissen dabei.

Halt, halt, ... , nein, das Allerallerbeste ist: Es gibt in dem ganzen Projekt keine einzige globale Variable. Braucht man da einfach nicht, sorry. Naja, es geht auch mit, aber wir wissen ja, wozu sowas führt...

Trackback address for this post

This is a captcha-picture. It is used to prevent mass-access by robots.
Please enter the characters from the image above. (case insensitive)

No feedback yet

Comments are closed for this post.