Zertifikat verlängert

Gestern lief mein CodeSigning-Zertifikat ab. Schon letzte Woche hatte ich den Verlängerungsantrag per gelber Post an die deutsche GlobalSign-Vertretung Wiesinger & Schenk geschickt, am Mittwoch erhielt ich dann einen Tag vor Ablauf den neuen öffentlichen Schlüssel per eMail zugeschickt.

Die Aktualisierung des öffentlichen Schlüssels im Zertifikat gestaltete sich dank der zur Verfügung gestellten Batchdatei sehr einfach. Das alte Zertifikat muss vorher samt dem privaten Schlüssel aus der Zertifikatsverwaltung exportiert und als old.pfx gespeichert werden. Dazu gesellt sich dann noch der neue öffentliche Schlüssel als new.pem. Nach dem Aufruf der Batchdatei samt dreimaliger Eingabe des privaten Schlüssels wird das neue Zertifikat wieder in die Zertifikatsverwaltung importiert.

Das war’s auch schon. In drei Jahren gibt es dann den nächsten Bericht.

Symboldateien einzeln laden

Beim Debuggen von Memory-Dumps hat man meistens das Problem, dass die entsprechenden Windows-Symboldateien zum Snapshot des Anwenders nicht vorhanden sind. Letztlich muss eine Symboldatei immer genau zur jeweiligen Dll passen, damit der Debugger den Aufrufstack vernünftig anzeigen kann. Dank dem Microsoft-Symbolserver ist das aber kein großes Problem, der Debugger kann sich die passenden Symboldateien automatisch herunterladen.

Nachteilig ist, dass man keine Möglichkeit hat, die gewünschten Symboldateien auszuwählen. Startet man einen Dump mit aktiviertem Symbolserver, dann werden automatisch alle Symboldateien heruntergeladen, die zum jeweiligen Snapshot passen. Zudem lädt der Debugger auch noch die entsprechenden System-Dlls herunter, was natürlich entsprechend dauert.

Mit VS 2008 SP1 scheint Microsoft das Laden von Symboldateien erheblich vereinfacht zu haben. Gestern habe ich ein Kontextmenü entdeckt, das ich bisher noch nie gesehen hatte. Ich bin mir sicher, dass dieses Menü in der RTM-Version noch nicht enthalten war:

Symboldateien herunterladen

Nach Auswahl des Befehls wurde die passende Symboldatei für “kernel32.dll” heruntergeladen und der Aufrufliste aktualisiert. Genial!

TFS: Warehouse-Aktualisierung

Die TfsWarehouse-Datenbank enthält alle wichtigen Daten, die für die Generierung und Anzeige von Berichten nötig sind. Die Informationen stammen aus den operationalen Datenbanken (z.B. Arbeitsaufgaben, Versionskontrolle), sie werden durch den Warehouse-Webservice in die TfsWarehouse-Datenbank übertragen. Der TFSServerScheduler-Dienst sorgt dafür, dass dies stündlich geschieht. Allerdings läuft der Dienst wie berichtet nur auf einem an eine Domäne angeschlossenen Server.

Als Abhilfe habe ich mir ein kleines Programm geschrieben, welches die Aktualisierung der TfsWarehouse-Datenbank durch den Webservice anstößt. In Verbindung mit der Windows-Aufgabenplanung kann dies je nach Bedarf stündlich, täglich oder in anderen gewünschten Abständen geschehen. Optimaler wäre natürlich ein eigener Dienst, aber so schwer wollte ich es mir dann auch nicht machen.

// ****************************************************************************
// ******                     Implementation zu wWinMain                 ******
// ****************************************************************************
int APIENTRY wWinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, LPWSTR /*lpCmdLine*/, int /*nCmdShow*/)
{
    // Internet-Session oeffnen
    HINTERNET hSession = WinHttpOpen(NULL, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0);
    if (NULL != hSession)
    {
        // Verbindung herstellen
        HINTERNET hConnect = WinHttpConnect(hSession, L"localhost", 8080, 0);
        if (NULL != hConnect)
        {
            // Anforderung erstellen
            HINTERNET hRequest = WinHttpOpenRequest(hConnect, L"POST", L"/Warehouse/v1.0/warehousecontroller.asmx/Run", NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, 0);
            if (NULL != hRequest)
            {
                // Anforderung senden
                BOOL fResult = WinHttpSendRequest(hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0);

                // Anforderung wurde gesendet
                if (fResult && WinHttpReceiveResponse(hRequest, NULL))
                {
                    // Antwort abfragen
                    char szResponse[2048] = { 0 }; DWORD dwBytesRead = 0;
                    WinHttpReadData(hRequest, szResponse, 2048, &dwBytesRead);
                }

                // Anforderung schliessen
                WinHttpCloseHandle(hRequest);
            }

            // Verbindung schliessen
            WinHttpCloseHandle(hConnect);
        }

        // Session freigeben
        WinHttpCloseHandle(hSession);
    }

    // Ans kloar
    return 0;
}

Es wird einfach nur eine Url aufgerufen und die Antwort abgefragt, auf eine Fehlerausgabe habe ich verzichtet. Das kompilierte Programm könnt ihr hier herunterladen.

MFC abgespeckt

Letzte Woche Montag ist das Service Pack 1 für Visual Studio 2008 erschienen. Wichtige Neuerungen für den C++-Entwickler sind sicherlich die Unterstützung von TR1 und das UI-Update für die MFC. Nach den Installationsproblemen mit dem im April veröffentlichten Feature Pack wollte ich eigentlich erst einmal die Erfahrungen anderer abwarten.

Daraus wurde dann doch nichts. Zu Testzwecken hatte ich mir ein VS 2008 in einer VM installiert und anschließend das SP1 eingespielt. Probleme gab es keine, die Microsoft-Entwickler haben aus dem Feature Pack-Dilemma gelernt und diesmal wieder ausreichend getestet.

Erfreulicherweise hat Microsoft auch das Konzept beibehalten, die bisherige MFC sowie die neuen UI-Klassen nicht zu verzahnen. Somit kann man die Einbindung der neuen Klassen durch Entfernen der entsprechenden Sektion im Makefile sehr einfach entfernen und die MFC weiter im bisherigen Umfang verwenden. Nach dem Löschen der nicht mehr benötigten Dateien hat man wieder ein schlankes und übersichtliches MFC-Verzeichnis.

Neben den neuen UI-Klassen gab es in der Standard-MFC nur kleinere Korrekturen. Die in afximpl.h definierten Konstanten CX_BORDER und CY_BORDER wurden nach AFX_CX_BORDER und AFX_CY_BORDER umbenannt. Bei einigen Zeigern fehlte bisher die Prüfung gegen NULL, das wurde mit dem SP1 auch behoben.

Nach den positiven Erfahrungen bei der VM-Installation habe ich das SP1 dann auch auf meinem Entwicklungsrechner eingespielt sowie C/C++-Laufzeit und MFC kompiliert. Die Anleitungen für die C/C++-Laufzeit sowie für die MFC sind weiter gültig, zusätzlich müssen für einen manifestlosen Einsatz die Linkerkommentare in appmodul.cpp

#pragma comment(linker, “/include:__forceMFCManifestRTM”)

und crtdll.c

#pragma comment(linker, “/include:__forceCRTManifestRTM”)

auskommentiert werden. Ansonsten beschwert sich der Linker beim Erstellen der CRT sowie beim Erstellen einer MFC-Anwendung über einen fehlenden Import. Bisher habe ich leider noch nicht herausgefunden, was diese beiden Linkerkommentare bewirken sollen. Die RTM-Version kam noch ohne diese aus.

Fehler 1603 bei der Installation von TFS 2008 SP1

Die Aktualisierung auf TFS 2008 SP1 wurde kurz vor Fertigstellung mit dem Fehler 1603 beendet. Beim Durchstöbern der Log-Dateien entdeckte ich folgende Zeilen:

Using workflow file from location exe.
Executing workflow ‘Unquiesce AT’…
Stopping Windows Service ‘W3SVC’…
Starting Windows Service ‘W3SVC’…
Starting Windows Service ‘TFSServerScheduler’…
Der Dienst TFSServerScheduler kann nicht auf dem Computer . gestartet werden.
Retrying…
Starting Windows Service ‘TFSServerScheduler’…
Der Dienst TFSServerScheduler kann nicht auf dem Computer . gestartet werden.
Retrying…
Starting Windows Service ‘TFSServerScheduler’…
Der Dienst TFSServerScheduler kann nicht auf dem Computer . gestartet werden.
Retrying…
Starting Windows Service ‘TFSServerScheduler’…
Der Dienst TFSServerScheduler kann nicht auf dem Computer . gestartet werden.
Retrying…
Starting Windows Service ‘TFSServerScheduler’…
Der Dienst TFSServerScheduler kann nicht auf dem Computer . gestartet werden.
Retrying…
Starting Windows Service ‘TFSServerScheduler’…
System.InvalidOperationException: Der Dienst TFSServerScheduler kann nicht auf dem Computer . gestartet werden. —> System.ComponentModel.Win32Exception: Der angegebene Dienst kann nicht gestartet werden. Er ist deaktiviert oder nicht mit aktivierten Ger„ten verbunden
   — Ende der internen Ausnahmestapelberwachung —

Nach diesen Zeilen startete dann das Rollback. 

Die Startprobleme mit TFSServerScheduler kenne ich schon seit der Installation des TFS. Dieser Dienst ist dafür verantwortlich, die Warehouse-Datenbanken zu aktualisieren, auf denen die verschiedenen generierten Reporte aufbauen. TFSServerScheduler ist abhängig vom Windows-Anmeldedienst (Netlogon), der sich nach dem Start auf normalen Servern und Arbeitsplatzrechnern aber gleich wieder beendet. Er ist der Meinung, dass seine Dienste nur beim Arbeiten in einer Domäne nötig sind. Um auf die Berichte nicht verzichten zu müssen, habe ich mir ein kleines Hilfsprogramm geschrieben. Dazu demnächst mehr.

Dummerweise lässt sich der TFS aber nicht direkt auf einem Domänencontroller (DC) installieren. Bis kurz vor der finalen Version von TFS 2005 war das wohl noch möglich, laut Berichten in diversen Foren soll das mit der nächsten Version (Rosario) auch wieder möglich sein. Allerdings habe ich keine Lust, mir bis dahin noch einen zweiten Server als DC einzurichten.

Das halb eingespielte Update hatte den TFS 2008 aber in einen undefinierten Status gebracht, Verbindungsversuche wurden mit folgendem Fehler abgelehnt:

TF31001: Team Foundation kann die Liste von Teamprojekten aus Team Foundation Server nicht abrufen. Team Foundation Server gab folgenden Fehler zurück: Fehler bei der Anforderung mit HTTP-Status 503: TF30059: Schwerwiegender Fehler beim Initialisieren des Webdiensts.

Was tun? Die Lösung bestand darin, auf meinem Entwicklungsrechner in einer VM einen Windows Server 2003 zu installieren und diesen als DC einzurichten. Nach dem Beitritt des Server zu dieser Domäne ließ sich auch der Windows-Anmeldedienst samt TFSServerScheduler starten und das Update lief fehlerfrei durch. Anschließend hat der Server die Domäne wieder verlassen und läuft nun wieder eigenständig.

Bin ich denn etwa der Einzige, der den TFS 2008 ohne Domäne betreibt?

Erste Beta zu SpeedCommander 12.30

Im öffentlichen Betabereich des Anwenderforums könnt ihr euch die erste Beta zu SpeedCommander 12.30 herunterladen. Die Hintergrundfarbe für die Vororteditierfelder kann jetzt angepasst werden, was besonders den Nutzern des NC-Farbschemas gefallen sollte.

Neu ist auch eine Einstellung, mit der das automatische Ausblenden des Registerkartenbereichs deaktiviert werden kann, wenn nur ein Ordnerfenster angezeigt wird. Einige kleine Fehler wurden ebenfalls behoben.

Die nächste Beta ist für Ende August geplant, mit der finalen Version ist dann Ende September zu rechnen.

TFS: Dateidatum beim Verzweigen erhalten

Beim Verzweigen von Projekten im TFS und anschließenden Abruf des neuen Projekts bekommen die Dateien immer das aktuelle Systemdatum als Datum der letzten Änderung verpasst. In SourceSafe war es noch möglich, beim Abruf zwischen dem Systemdatum, dem Datum des Eincheckens und dem Datum der letzten Änderung zu wählen. Im TFS habe ich diese Einstellung leider noch nicht gefunden, ich würde aber das Datum der letzten Änderung bevorzugen.

Als Workaround habe ich mir ein kleines Programm geschrieben, welches das Änderungsdatum eines Verzeichnisbaums auf einen anderen überträgt. Der Aufruf erfolgt über die Kommandozeile mit dem Befehl

SyncModified.exe <SourceDir> <TargetDir>

Das Quellverzeichnis wird inklusive den Unterverzeichnissen durchlaufen und das Datum der letzten Änderung einer jeden Datei in das Zielverzeichnis übernommen (sofern die Datei dort existiert). Ein eventuell gesetztes Schreibschutzattribut bleibt erhalten.

Das kleine Tool (76 KiB) könnt ihr hier herunterladen.

TF80042 beim Öffnen einer Abfrage mit Excel

Beim Versuch, eine Abfrage aus dem Team Explorer heraus mit Excel zu öffnen, erhielt ich anfangs die Fehlermeldung

—————————
Microsoft Visual Studio
—————————
TF80042: Das Dokument kann nicht geöffnet werden, weil Microsoft Excel 2003 oder höher oder eine der zugehörigen Komponenten nicht installiert ist. Weitere Informationen finden Sie im Team Foundation-Installationshandbuch.
—————————
OK  
—————————

Google brachte mich dann dazu, mit Hilfe des Office-Setupprogramms die Excel-Funktionalität .NET-Programmierunterstützung nachzuinstallieren. Diese Einstellung ist standardmäßig deaktiviert. Nun lassen sich die Abfragen auch in Excel anzeigen.

TFS: Arbeitsaufgaben löschen

Beim Erstellen eines neuen Teamprojekts in TFS unter Verwendung von ‘MSF for Agile Software Development’ werden automatisch 15 Arbeitsaufgaben (Work Items) erstellt, welche die grundlegenden Schritte auflisten (Zuordnung der Benutzer, Erstellung von Bereichen und Iterationen, …). Leider besteht im Team Explorer keine Möglichkeit, diese Aufgaben nach dem Schließen auch zu löschen. Löschen deshalb, weil sie für das eigentliche Projekt keine Relevanz mehr haben. Bei drei Teamprojekten sind es schon 45 überflüssige Aufgaben.

Abhilfe schaffen hier die Team Foundation Server Power Tools. Nach der Installation startet man die Eingabeaufforderung und wechselt in das Verzeichnis, in welches man die Power Tools installiert hat. Das Löschen von Arbeitsaufgaben geschieht mit dem Befehl

tfpt destroywi /server:SERVERNAME /workitemid:id1[,id2,...]

Beim ersten Projekt erhalten die automatisch erstellten Arbeitsaufgaben die IDs 1 bis 15, so dass der Löschbefehl

tfpt destroywi /server:SERVERNAME /workitemid:1,2,3,4,5,6,7,8,9,10,11,12,13,14,15

lautet. Aber Vorsicht, dass man nicht die falschen Aufgaben erwischt. Das Löschen ist nämlich nicht wieder rückgängig zu machen!

Projektstruktur

Seit der Entwicklung von SpeedCommander 9 und Squeez 4 verwende ich ein gemeinsames Bibliotheksverzeichnis für SpeedCommander und Squeez, da wesentliche Komponenten von beiden Anwendungen verwendet werden. Damit bei der Entwicklung einer neuen Hauptversion keine Kollateralschäden bei den alten Versionen auftauchen, wird für die neue Version auch ein neuer eigenständiger Bibliothekszweig eingerichtet. In Visual SourceSafe sah dies folgendermaßen aus:

Projektstruktur in SourceSafe

Mit dem Umstieg auf Subversion bzw. TFS war hier eine Anpassung nötig, da Verzweigungen mit der vorhandenen Struktur nur schwer möglich waren. Normalerweise legt man ja alles zu einem Projekt dazugehörige unter einem einzelnen Projektnamen ab und kann dann bequem neue Versions- oder Entwicklungszweige einrichten. Durch die von SpeedCommander und Squeez gemeinsam verwendeten Bibliotheken gestaltete sich das bei mir aber etwas schwieriger.

Nach längerem Überlegen habe ich mich dann dafür entschieden, das Bibliotheksverzeichnis auf der gleichen Ebene wie die Anwendungen einzurichten. Das Einrichten neuer Versions- und Entwicklungszweige sowie das Zusammenführen geschieht nun zwar doppelt (jeweils für Bibliotheken und Projekt), man gewöhnt sich aber recht schnell daran. Die neue Projektstruktur sieht nun wie folgt aus:

Projektstruktur in TFS

Alle Bezüge vom Projekt- zum Bibliotheksverzeichnis sind nun relativ, es werden keine festen Pfad- bzw. Versionsangaben mehr verwendet. Damit gestalten sich neue Verzweigungen sehr viel einfacher und sie lassen sich anschließend ohne Änderungen gleich kompilieren.

Die erzeugten Bibliotheks-Dlls werden alle im lib-Verzeichnis abgelegt, die Anwendungen entsprechend ihrer Konfiguration unterhalb ihres Projektordners. Dank den projektspezifischen Umgebungsvariablen laden die Anwendungen automatisch immer die richtigen Dlls. Da sich der Bezug auch nach einer Verzweigung nicht ändert, muss man sich in Zukunft um den richtigen Pfad keine Gedanken mehr machen.

Zusätzlich zum Projekt- und Releasezweig habe ich noch einen Entwicklungszweig eingerichtet. Hier kann ich schon Neuerungen für die nächste SC-Hauptversion einbauen, ohne den aktuellen SC12-Zweig zu beschädigen. Im SC12-Zweig behobene Fehler lassen sich einfach mit drei Mausklicks in den SC13-Zweig übernehmen, sofern es keine Konflikte gibt. Mitte nächsten Jahres wird dann der SC13-Zweig mit dem aktuellen SC12-Zweig zusammengeführt.