Donnerstag, 17. Juli 2008

HowTo: Erstellen eines Windows Service unter .NET

Da ich gerade zum ersten mal in die Verlegenheit komme, einen Windows Service unter .NET zu entwickeln, habe ich mich mal ein wenig im WWW umgeschaut, um ein brauchbares Tutorial zu finden. Fündig wurde ich hierbei bei CodeGuru.

Im Tutorial wird nicht nur sehr schön erklärt, wie ein Windows Service aufgebaut ist, sondern es wird ebenfalls darauf eingegangen, wie er zu installieren ist und wie man den laufenden Service dann debuggen kann. Gerade für Anfänger auf dem Gebiet sicherlich sehr nützliche Informationen. Das Tutorial ist hier zu finden: http://www.codeguru.com/columns/dotnet/article.php/c6027/

Noch ein Zusatz von meiner Seite: Bei der Installation des Windows Service via InstallUtil.exe über die Visual Studio Eingabeaufforderung ist unbedingt die Version des Frameworks zu beachten, mit der der Service erstellt wurde. Wird nämlich die Eingabeaufforderung einer anderen Framework-Version verwendet als jene, mit der der Service erstellt wurde, erhält man beim Aufruf von InstallUtil.exe nur einen Fehler, der einem mitteilt, dass der Service nicht installiert werden konnte.

Alternativ kann man die normale Windows-Eingabeaufforderung verwenden und InstallUtil.exe aus dem Ordner "C:\WINDOWS\Microsoft.NET\Framework\FRAMEWORKVERSION" heraus starten.

Biztalk SAP Adapter Error 8007007e

Vielleicht "schon wieder" ein 64Bit Enviroment Issue... (?) der Auslöser ist mir nicht ganz klar, aber bei meinem aktuellen Projekt tritt nach der Konfiguration im Biztalk Server 2006 von SAP Ports alle paar Minuten im Eventlog den folgenden Fehler:

Nach etwas Rumforschen und Abgleichen der SAP Adapter Installationsverzeichnisse ergab sich das sowohl die ATL71.dll als auch die MSVCR71.dll fehlten. Offensichtlich hat der Adapter Installer Probleme diese Komponenten unter Windows 2003R2/x64 zu installieren. Ich musste diese von Hand nachträglich reinkopieren nach "C:\Program Files (x86)\Microsoft BizTalk Adapter v2.0 for mySAP Business Suite" Der Fehler stoppte sofort, ohne irgendetwas neu zustarten, von alleine.

Mittwoch, 16. Juli 2008

Verzögerung beim .NET BlogBook

Wie ich gerade eben via Norbert Eders Blog erfahren habe, verzögert sich das Erscheinen der nunmehr siebten Ausgabe des .NET BlogBook. Der eigentliche Erscheinungstermin wäre der 15. Juli gewesen.

Wie im entsprechenden Post nachzulesen ist, hängt die Verspätung damit zusammen, dass zur Zeit ein "großer Umbau" vorgenommen wird. Dieser scheint so groß zu sein, dass die nächste Ausgabe wohl erst am 15. Oktober erscheinen wird.

Da bin ich doch jetzt wirklich mal gespannt, wie die Änderungen am BlogBook aussehen werden.

Dienstag, 15. Juli 2008

Webcast: Neuerungen im SP1 für .NET3.5 & VS2008

Am heutigen Dienstag ist ein Webcast erschienen, der sich mit den Neuerungen und Änderungen  in .NET 3.5 und Visual Studio 2008 beschäftigt, die durch das Service Pack 1 Einzug halten werden. Als Vorbereitung auf den Release ist dies mit Sicherheit eine sehr interessante Sache und für jeden Entwickler, der mit der Technologie bzw. dem Tool arbeitet, ein Muss, um vorbereitet zu sein.

Über die Qualität kann ich bisher leider noch nichts sagen, da ich mir den Webcast noch nicht angeschaut habe. Da er aber von Dariusz Parys abgehalten wird, kann er eigentlich nur sehr gut und informativ sein. Unbedingt anschauen!

Zu beziehen ist der Webcast (mit gültigem Live-Account) hier: https://www.microsoft.com/germany/msdn/webcasts/library.aspx?id=1032382740

Skype-AddIn für Visual Studio 2005 / 2008

Ein weiterer Schritt in Richtung "Ich geh nie wieder aus meinem VS raus" ist gemacht: Der thailändische Entwickler Keng Pongsathon hat ein AddIn für Visual Studio geschrieben, welches Skype in unser aller Lieblingsspielzeug einbindet. Dieses ist auf Codeplex verfügbar: http://www.codeplex.com/SkypeStudio/

Über Sinn und Unsinn dieses AddIns kann man jetzt diskutieren. Meine Reaktion war eher in Richtung "Wozu", die eines anderen Teilnehmers an diesem Blog ein schlichtes "Goil". Da sollte sich wohl jeder selbst seine Meinung bilden.

Gefunden habe ich das AddIn im Übrigen über den deutschen MSDN Blog.

Donnerstag, 3. Juli 2008

64Bit / 32Bit und universelles Postbuildevent mit gacutil

Nur als kleine Notiz für mich selbst, da die Pfade für die Programmordner unterschiedlich sind unter 64 und 32 Bit. Hab ich mir aus den Makros die Pfade zusammengeklickert und da ich allein schon mit dem setzen von " und \ herumeiere leg ich das hier mal lieber ab ;)

"$(DevEnvDir)..\..\SDK\v2.0\Bin\gacutil.exe" /u "$(TargetPath)"
"$(DevEnvDir)..\..\SDK\v2.0\Bin\gacutil.exe" /i "$(TargetPath)"

log4net, IBaseComponent & 64Bit Windows Server

log4net 1.2.10, IBaseComponent & 64Bit Windows Server funktionieren irgendwie nicht zusammen. Das witzige unter 32Bit funktioniert es!

Für eine Biztalk Pipeline habe ich zwei Komponenten entwickelt die aus einem Flatfile Format eine XML Datei erzeugt. Beim einbinden der Komponten war im Browser von VisualStudio bei einer der korrekte Name aus der IBaseComponent zu sehen, bei der anderen der Assembly Name.
Dumm denn auf meiner 32Bit Entwicklungsmaschine war dem nicht so, aber auf dem 64Bit Zielsystem. Nach einer etwas längeren Remotedebuggingsession stellte sich dann heraus das bei der Komponente mit dem "falschen Namen", nicht einmal der Konstruktor angesprungen wird, geschweige denn die Informationen aus IBaseComponent, wenn man diese in VisualStudio "an"browst.

Erst nach der vollständigen Entfernung der log4net Referenzierung (darauf muss man erstmal kommen), wurde der korrekte Name aus dem Interface angezeigt. Befand sich log4net gar im GAC war die Pipeline Komponente überhaupt nicht mehr auffindbar, beim manuellen Browsen gabs dann nur noch den lapidaren Hinweis das wohl etwas mit der Sicherheitseinstellung der Komponente nicht stimmen würde... sehr merkwürdig....

Eine Sicherheitseinstellung in Windows Server? Ein Problem mit log4net? :-/

Montag, 9. Juni 2008

Fallstrick: DateTime.AddXXX()

Ich stolpere immer wieder darüber und wie ich heute gesehen habe, bin ich tatsächlich nicht der einzige, dem es so geht:

Auf einen vorhandenen DateTime soll eine bestimmte Anzahl von Stunden (oder Minuten, Sekunden, ...) addiert werden. Natürlich, kein Problem, dafür bietet der DateTime ja die Methode AddHours(). Ein Aufruf, um auf das aktuelle Datum mit der aktuellen Uhrzeit fünf Stunden zu addieren, sähe demnach so aus:

   1:  DateTime dt = DateTime.Now;
   2:  dt.AddHours(5.0);

Verwendet man jetzt jedoch den Wert von dt weiter, um ihn beispielsweise anzuzeigen, fällt auf, dass die fünf Stunden nicht wie erwartet auf den aktuellen Wert addiert wurden. Der Grund hierfür ist ein ganz einfacher, der einem sogar von IntelliSense angezeigt wird.
Der Aufruf geht einfach deshalb ins Leere, weil er nicht auf den übergebenen DateTime addiert, sondern das Ergebnis der Addition zurück gibt. Irgendwo logisch, es handelt sich ja nicht um einen ref- oder out-Parameter, andererseits ist es dennoch irgendwie verwirrend, da es einfach logisch erscheint, dass auf den Ursprungswert addiert wird.

Wie auch immer, der korrekte Aufruf muss wie folgt aussehen:

   1:  DateTime dt = DateTime.Now;
   2:  dt = dt.AddHours(5.0);

Auf dass ich in Zukunft nicht mehr hierüber stolpern werde!

Vergleich VB.NET und C#

Ich springe in letzter Zeit öfter mal zwsichen VB.NET und C# hin und her, wobei ich ganz klar aus der C#-Ecke komme und mich daher mit der Syntax von VB.NET nicht wirklich auskenne.
Da kommt mir diese Seite mehr als gelegen. Hier wird ein direkter Vergleich angestellt, wie etwas in C# und VB.NET realisiert wird. Danke dafür an meinen Kollegen Sebastian.

Sollte ein Leser des Öfteren zwischen C# und Java wechseln müssen, für den gibt es hier eine ähnliche Übersicht.

Dienstag, 3. Juni 2008

Hashtable in Key Reihenfolge abarbeiten

Ich hatte in einer Hashtable Strings mit einem Integer Wert als Key abgelegt und wollte die nun in numerischer Folge abarbeiten, mein erster gedankenloser Ansatz war etwas umständlich. Mit etwas nachdenken hatte ich einen eleganteren Weg gefunden.

Dazu hab ich ersteinmal die Hashtable in ein generisches Dictionary umgewandelt, dann die Keys in eine generische Liste geschaufelt und dann einfach den Sort angewendet. Natürlich hätte dies auch mit einer Hashtable und einer Arraylist funktioniert, aber da beide in jeder Hinsicht in der Performance den Generics unterlegen sind hab ich das umgeschrieben nach diesem Beispiel:

   1:  ...
   2:  Dictionary<int, string> ht = new Dictionary<int, string>(10);
   3:  ht.Add(1, "hallo");
   4:  ht.Add(2, "welt");
   5:  ht.Add(3, "!");
   6:  ...
   7:             
   8:  List<int> keys = new List<int>(ht.Keys);
   9:  keys.Sort();
  10:   
  11:  foreach (int k in keys)
  12:  {
  13:     System.Console.WriteLine("key = " + k.ToString() + " value = " + (string)ht[k]);
  14:  }
  15:  ...

Das funktioniert dann auch analog mit anderen Datentypen, ggf. muss dann der Comparer implementiert/überladen werden, je nach Geschmack :)