Kalender
<<  November 2014  >>
MoDiMiDoFrSaSo
272829303112
3456789
10111213141516
17181920212223
24252627282930
1234567
blettner , eingetragen am 27. Januar 2009, 16:28

Prelude:

Schon seit längerem hatte ich geplant, den Teamfoundation Server bei mir in der Firma auf die aktuelle Version zu upzudaten. Da ich mich noch an die letzte Installation recht gut erinnern konnte, habe ich mich bis jetzt eigentlich gestreubt das zu machen. Aber nachdem ich gerade Zeit hatte, das SP1 auch schon längere Zeit veröffentlich ist, wollte ich das jetzt machen. In Summe hat mich dieses Vorhaben ca. 5 Arbeitstage gekostet. Warum? Na fangen wir mal an…

P.S: Das wird keine Installationsanleitung, von denen gibt es viele (siehe auch am Ende des Posts) und wenn man sich an den “Installation Guide” hält, sollte es ohne Probleme funktionieren… Ok, wenn es so wäre, würde es nicht so viele Posts dazu geben!

Intro:

Ich möchte hier noch schnell auf meine vohandene Konfiguration eingehen:

Data Tier:

SQL2005 mit eingespielten SP3

Client Tier:

Windows Server 2003
Reporting Services 2005 ink. SP3
Teamfoundation Server 2005 SP1

Der Client in ein Image welches am Virtual Server 2005 läuft, Datenbank läuft auf einem anderen Server.

Akt 1: Upgrade der vorhandenen Installation

Bevor man überhaupt daran denkt das Upgrade zu starten, sollte man seine vorhandene Installation mittels des Best Practize Analyzers auf vorhandene Fehler überprüfen. Erst wenn hier keine Fehler angezeigt werden, kann man daran denken das Upgrade durchzuführen.

In meinem Fall wurden keine Fehler angezeigt und ich war guter Hoffnung, dass das ein Vorhaben in der Dauer von 1 – 2 Stunden wird. Ich hab noch ein Backup sämtlicher Datenbanken durchgeführt und auch das Image auf dem der TFS läuft gesichert. Ohne einer DB und Client Sicherung sollte man ebenfalls nicht anfangen!!

Nachdem nun alle Vorbereitungen durchgeführt wurden (ja, ich habe im TFS Installation Guide nachgelesen was zu tun ist),  habe ich die CD eingelegt und das Setup gestartet. Es wurde auch alles brav erkannt, der Server auf dem sich die Datenbank befindet, Reporting Services usw. Also habe ich das Update gestartet, lief die ersten 10 Minuten ohne weiteres…

doch dann: “TF30059: Fatal error while initializing web service”. Was ist denn da jetzt los!? Hab dann nach kurzer Suche gefunden, dass das ein Problem mit einem Login sein könnte. Alle Logins überprüft, Best Practize Analyzer nochmal laufen lassen, wieder keine Fehler gefunden. Setup nochmal gestartet – wieder der selbe Fehler in Kombination mit einem anderen der die Reporting Services betraf.

Wieder in Google gesucht – wobei ich bei einer Lösung etwas schmunzeln musste: Man sollte doch das TFS 2008 SP1 installieren, dann würde alles funktionieren. Da frag ich mich halt, auf was soll ich das installieren, wenn noch nicht mal die normale Installation durchgelaufen ist!?

Also zurück an den Start, sämtliche Datenbanken rückgesichert und auch das Image am Virtual Server wiederhergestellt (um das nicht immer schreiben zu müssen, wird das mit Start abgekürzt).

Bei meinem zweiten Upgrade Versuch, bin ich einen Schritt weitergekommen. Da ist zumindest das Setup durchgelaufen und ich habe mir schon gedacht, dass ich es geschafft habe. Hehe, denkste. Gscheit wie ich bin, wollte ich auch gleich das SP1 installieren, hab das Setup gestartet und was war? Natürlich hat es während der Installation abgebrochen und das System in einen inkonsistenten Zustand hinterlassen. DB war auf Stand von SP1, Client war gar nichts mehr…

Start

Dritter Versuch, Installation durchgelaufen… diesmal hab ich das Service Pack nicht mehr eingespielt um nicht wieder alles kaputt zu machen. Starte mein Visual Studio, Verbinde mich zum TFS und was kommt!?  Eine Fehlermeldung, dass die Liste der Projekte nicht abgefragt werden kann und ich mich mit meinem Administrator in Verbindung setzen soll. *Kopfschüttel*

Start 

Hab mir jetzt die aktuellste Version der Installationsanleitung von der MS Seite runtergeladen und nochmal alles überprüft… das Setup gestartet: “TF30059: Fatal error while….”

Start

Weil ich nicht gleich aufgebe, folgten hier noch einige Versuche mit mehr oder weniger der selben Fehlermeldung (manchmal auch in Kombination mit anderen…).

Irgendwann hat es mir gereicht und ich habe beschlossen, dass es wohl kein Upgrade geben wird.

Akt 2: Neue installation des TFS 2008

Nachdem meine Upgrade Versuche letztendlich erfolglos blieben, habe ich beschlossen den TFS neu aufzusetzen. DB Server war ja vorhanden, daher mußte nur der Client Teil neu gemacht werden. Bei einem Virtual PC Image ist das schnell erledigt (da hatte ich schon was vorbereitet). Nachdem alle aktuellen Updates eingespielt ware habe ich begonnen die Prerequisits einzurichten und zu Installieren.

Nachdem meine Datenbank ein SQL Server 2005 war, habe ich die Reporting Services von SQL 2005 installiert (so wie es in der Anleitung steht). Als die Installation beendet war und die Services liefen, startete ich wieder mal die Installation.

Habe den Datenbank Server angegeben, auf “Weiter” geklickt und gewartet, gewartet… noch immer gewartet (schon etwas skeptisch geworden)…

Fehler, es konnte keine Verbindung zu den Reporting Servces hergestellt werden. Man solle überprüfen, ob sie laufen und ob der User berechtigt ist darauf zuzugreifen. In der Installationsanleitung steht nichts davon, dass man einen User zuweisen muß!? Komisch dachte ich mir und hab den beiden Reporting Services Accounts den Installationsuser zugewiesen und das Setup wieder gestartet. Siehe da, sie wurden erkannt und ich konnte mit der Installation fortfahren. Lief auch soweit alles gut (bei den PreChecks gab es keinen Fehler), bis naja… dieses blöde Popup am Bildschirm auftauchte, bevor der Fortschrittsbalken sein Ende erreicht. Anscheinend wurden die Reporting Services nicht gefunden.

donkey

Ungefähr so fühlte ich mich gerade und ich glaub mein Gesichtsausdruck war dem sehr ähnlich.

Hab noch im Google gesucht was die Ursache hätte sein können aber letzendlich zurück an den…

Start

Bei den nächsten drei bis vier Installationen trat immer wieder der selbe Fehler auf… einmal noch eine kleine Abwandlung, dass nämlich Reporting Services und die DB von der Version unterschiedlich seien und Reporting Services deshalb nicht Initialisiert werden könne. Wieder Eselsblick, hab doch beides von der selben DVD installiert!?!?

Um es in den Worten unseres Ex-Kanzlers zu sagen (für alle die es nicht wissen, Willi Molterer war gemeint): ES REICHT!

Akt 3: Neue installation ganz anders 

Nachdem ich mit der Installation so nicht weiterkam habe ich folgendes gemacht (um das Ganze etwas abzukürzen)

  • Das vohandene Image gelöscht und durch eine Neues ersetzt
  • Das Teamfoundation Server Service Pack 1 mit dem normalen Setup gemerged (steht im Installationsdokument wie man das macht)
  • Auf dem Datenbank Server eine neue SQL2008 Instanz erstellt (daher auch der Merge des Service Pack, da der TFS erst damit mit dem SQL Server 2008 kann)
  • Auf dem Client die SQL 2008 Reporting Services installiert (ohne noch zusätzlich Rechte vergeben zu haben)
  • Das Setup des TFS gestartet

Man wird es kaum glauben, aber das hat funktioniert.

Akt 4: Security, Security und nochmals Security

Nachdem alles fertig installiert war, fügte ich jene Benutzer, die mit dem TFS arbeiten sollten, zu den jeweiligen Gruppen (Licensed User,…) hinzu. Setzte die Berechtigungen bei den Reporting Services und auch in Sharepoint. Danach erstellte ich mein erstes Projekt – bis hierhin funktionierte alles wunderbar.

Dann wollte ich ein zweites Projekt anlegen – Fehler: “TF30224: Failed to retrieve projects from the report server. Please check that the SQL Server Reporting Services Web and Windows services are running and you have sufficient privileges for creating a project.” Ich überprüfte das, und konnte mich mit allen Usern zu den Reporting Services verbinden, konnte alle Berichte aufmachen.

Zu diesem Zeitpunkt versuchte ich mich auch von einem anderen Rechner zum TFS zu verbinden – das scheiterte mit der Fehlermeldung: “TF31004: Could not connect to Team Foundation Server”.

Nochmal alles überprüft, Benutzer im TFS, Benutzer in den Reporting Services und Benutzer in den Sharepoint Services… ware alle angelegt.

Die Lösung dieses Problems hat mich ca. 4h gekostet. Sobald man jenen Benutzern auch Rechte auf dem TFS Rechner gibt (lokal), klappt die Verbindung. Es können Projekte angelegt werden und auch auf alle Ressourcen kann man zugreifen. Verstehen tu ich das Ganze zwar nicht, aber so funktionierts!!

Akt 5: TFS Migration Tool

Das einzige was wirklich von Anfang an funktionierte, war das TFS Migration Tool. Damit konnte ich meine Source Control Items von dem einen auf den anderen Server migrieren. Das Tool wäre an sich noch viel mächtiger (zwei Server synchronisieren usw.), aber für mich hat das gereicht.

Hinweis: mit dem Tool kann man nur Sourcecontrol Items und Work Items migrieren. Alles andere ist nicht möglich.

Downloaden kann man es hier.

Outro

Letztendlich hat mich das (wie schon erwähnt) fünf Arbeitstage gekostet. Bei der Installation des TFS kann einen schon der Frust packen, aber aufgeben wollte ich auch nicht! Auf alle Fälle werde ich es mir beim Nächsten mal genau überlegen, ob ich das mache oder nicht. Wenn alles funktionieren würde, wär es ja kein Problem. Aber wenn man die Menge an Posts liest, die es zu Thema Setup und damit verbundenen Problemen mit dem TFS gibt, bin ich in Zukunft vorsichtiger!

Links & Anleitungen

Während ich nach den verschiedensten Fehlern gesucht habe, habe ich auch einige interessante und an sich ganze gute Anleitungen gefunden. Vielleicht helfen sie jemanden weiter, der mehr Glück mit seiner Installation hat als ich!

Kurze Anleitung:
http://olausson.net/blog/2007/12/03/UpgradeTFS2005To2008.aspx

Eine ausführliche Anleitung mit sämtlichten Links zu den nötigen downloads:
http://blogs.imeta.co.uk/nrees/archive/2008/11/07/upgrading-dual-server-tfs-2005-to-tfs-2008-sp1.aspx

TFS Migration Tool

http://www.codeplex.com/tfstotfsmigration

Auf ein interessantes Theme bin ich vor kurzem gestossen. Wie kann man eine WPF Applikation so steueren, dass Forms auf verschiedenen Physischen Screens dargestellt werden. Nach ein wenig suchen bin ich auf eine einfache Lösung gestossen.

Im System.Windows.Forms Namespace (die Referenz muß in einer WPF Applikation per Hand hinzugefügt werden) gibt es die Klasse Screen. Diese liefert alle nötigen Informationen wie z.b: welcher Screen der Hauptschirm ist, eine Collection aller zur Verfügung stehenden Screens sowie deren Auflösung und Namen.

Folgendes Codestück zeigt, wie man eine Form auf den jeweiligen Screen anzeigen kann.

List<Screen> objScreenList = Screen.AllScreens.ToList();
 
foreach (Screen objActualScreen in objScreenList) {
   Window1 objForm = new Window1();
 
   objForm.WindowStartupLocation = WindowStartupLocation.Manual;
   objForm.Left = Convert.ToDouble(objActualScreen.Bounds.Location.X + 20);
   objForm.Top = Convert.ToDouble(objActualScreen.Bounds.Location.Y + 20);
   objForm.label1.Content = "Screen: " + objActualScreen.DeviceName;
   objForm.Show();
}

 

Mittels AllScreens erhält man eine Liste sämtlicher Screens die zu diesem Zeitpunkt zur Verfügung stehen. In diesem Beispiel wird eine Testform für jeden Screen erstellt und mittels der Screenproperties auf diesen positioniert. In einem Label wird der jeweilige Devicename angezeigt.

 

image

Letztendlich sollte auf jedem Screen das obige Fenster angezeigt werden.

blettner , eingetragen am 16. Dezember 2008, 12:48

Gestern wurde still und heimlich das Service Pack 3 vom SQL Server 2005 veröffentlicht.

Downloaden kann man das Packet hier. Welche Änderungen vorgenommen wurden, kann man hier nachlesen.

Der Linq2SQL Designer im Visual Studio bietet einem einfach und schnell Datebankanbindugen zu generieren. Leider hat dieser eine Schwachstelle, die zwar während der Entwicklung nicht stört, einem jedoch das Leben erschweren kann wenn man zwischen Entwicklungs- und Produktiv- Betrieb wechselt. Im Grunde geht es dabei um etwas so einfaches wie den Connectionstring zur Datenbank. Dieser wird in einem Resource File abgelegt und kann dadurch zur Laufzeit nicht mehr verändert werden. Die Konfiguration mittels dem App.config Files ist somit nicht möglich und der Entwickler muß diesen vor jedem Deployment anpassen.

Eine Möglichkeit, den Connectionstring zur Laufzeit anzupassen, möchte ich hier zeigen.

app_settings

Als Beispiel nehme ich zwei Tabellen aus der Northwind Datenbank. Diese werden mittels des Linq2SQL Designers vom Server Explorer in das Fenster gezogen. Die erste Änderung die vorzunehmen ist, ist dass man in den Connection Einstellungen die Applikation Settings auf “false” setzt. Erst jetzt kann der Connectionstring angepasst werden (zuvor wären Systemeinstellungen die im settings File gespeichert wurden verwendet).

Wenn man nun das Design File der dbml Datei öffnet (in diesem Fall DataClasses.designer.cs) sieht man folgendes:

code_comment

Es wird ein eigener Konstruktor angelegt, der es einem ermöglicht einen eigenen Connectionstring anzugeben. Problem hier ist aber, jedes mal wenn im Designer etwas geändert wird, wird diese Klasse angepasst und sämtliche Änderungen gehen verloren. Um dem Vorzubeugen und nicht immer alles neu machen zu müssen, ist es ratsam eine eigene Klasse anzulegen die diesen Konstruktor enthält. Jener im .design.cs File kann indessen auskommentiert werden (das ist der einzige Schritt der auch nach eine Änderung im Designer wieder durchzuführen ist).

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;
 
namespace LINQ2SQL_DataSource_Configuration {
    public partial class DataClassesDataContext {
        public DataClassesDataContext() :
            base(MyConnectionStringProperty) {
            OnCreated();
        }
    }
}

Der Rest ist relativ simpel. Es wird eine weitere partielle Klasse der DataContext Klasse angelegt, in dessen Konstruktor die eigene Methode zum auslesen des Connectionstrings aufgerufen wird (kann aus einem eigenen Settings File kommen, aus dem App.config, aus der Registry usw.).

Wie man sieht kann man sich relativ einfach helfen um auch dieses Problem alltagstauglich zu lösen.

blettner , eingetragen am 26. November 2008, 11:35

Queries dynamisch zu erstellen wird einem immer wieder unter kommen. Solange es sich um reine SQL Statements handelt, kann man sich mit dem Zusammenbau eines Strings helfen, der dann letztendlich an das Command Objekt übergeben wird.

objCommand.CommandText = "SELECT server_id, " +
"server_name, " +
"server_version, " +
"FROM tbl_servers " +
  if (blSql2005Up)
      objCommand.CommandText += 
"WHERE server_version >= 2005";
 

Als Beispiel eine Query, welche aus einer Tabelle entweder alle dort gespeicherten SQL Server ausliest oder jene, bei denen die Server Version größer/gleich 2005 ist.

Wie kann man das nun mit LINQ bewerkstelligen? Wenn man folgende Query betrachtet an sich sehr ähnlich!

var ServerList = from p in tbl_Servers
orderby p.Name ascending
select p;
  if (blSql2005Up)
             ServerList = ServerList.Where(
server => server.server_version >= 2005
);

Sämtliche LINQ Query Ergebnisse (solange sie vom Type IEnumerable sind) können nachträglich mittels Lambda Expressions weiter bearbeitet werden. Sei es um die Sortierung zu ändern oder das Ergebnis weiter einzuschränken.

blettner , eingetragen am 18. November 2008, 14:15

Kürzlich stand ich vor dem Problem aus eine Applikation einen SQL Syntax Check durchführen zu wollen, so wie man ihn aus dem SQL Server Management Studio kennt.

Wie funktionierts?
Am Einfachsten mit den SQL Server Managemet Objekten. Wenn keine lokale SQL Server Installation vorhanden ist, kann man diese auch als Teil des SQL Server Feature Packs downloaden (SQL Server Feature Pack Oktober 2008 download).

Sind diese installiert, muß man zunächst folgende Referenzen zum Projekt hinzufügen (die hier aufgelisteten Referenzen beziehen sich auf die SMO Objekte vom SQL Server 2008):

  • Microsoft.SqlServer.ConnectionInfo
  • Microsoft.SqlServer.Management.Sdk.Sfc
  • Microsoft.SqlServer.Smo

Jetzt stehen die nötigen Objekte zur Verfügung um eine Verbindung zum SQL Server herstellen zu können.

Server server = new Server(@".\SQLEXPRESS");
server.ConnectionContext.DatabaseName = "DataBaseForCheck";
server.ConnectionContext.Connect();
	

Zuerst wird ein Serverobjekt angelegt, das die Verbindung zu einer SQL Instanz herstellt.

try {
     intRS = objSQLServer.ConnectionContext.ExecuteNonQuery(
	         strScriptToCheck, ExecutionTypes.ParseOnly
             );
} catch (Exception ex) {
	//Fehlerbehandlung durchführen
} 

Der wirkliche Check passiert nun beim ausführen des Scripts mittels ExecuteNonQuery, wobei man hier noch die Option “ParseOnly” als Execution Typ angibt. Im Falle eines Syntaktischen Fehlers, wird eine Exception geworfen.

Wichtig hierbei ist, dass nur ein Syntaktischer Check durchgeführt wird. Es wird nicht überprüft ob Spalten oder Tabellen die in diesem Script angegeben sind wirklich vorhanden sind!