Wenn die eigene Tochter im Radio zu hören ist…

… dann ist man schon ein wenig stolz :mrgreen:

Katrin war am 25.+26.02.2008  im MDR1 Radio Sachsen mit Beiträgen zu hören.

Hier die Links zum Text:
Wort zum Tag – Sonnabend, 26. Januar 2008
Wort zum Tag – Freitag, 25. Januar 2008

Hier die Liste der Podcasts, einen direkten Link zu den Beiträgen habe ich hier leider nicht gefunden:
MDR1 Radio Sachsen: Wort zum Tag
Anmerkung: Da derMDR hier nur die letzten 14 Tage vorhält wird es nicht mehr lange dauern bis der Beitrag rausfällt.

VS-Tipps & Tricks: Einfaches Navigieren mit Strg+-

Vielleicht ist einigen schon aufgefallen, dass es die Schalter Navigate Backward und Navigate Forward im Standard-Toolbar von Visual Studio gibt. Diese Funktionen werden über die Hotkeys Strg+- (Bindestrich) und Strg+Umschalt+- ausgelöst.

Bei dieser Funktion werden Go-Back-Markierungen in einer Liste vermerkt. Hierbei wird nicht jede Cursorbewegung aufgezeichnet, sondern Bewegungen, die über eine größere Distanz erfolgen.

D.h. man kann mit Strg+- sofort an die Position zurückspringen, die man soeben verlassen hat. Die Umkehrfunktion wird wie gewohnt mit der Umschalt-Taste ausgelöst, Umschalt+Strg+-.

Solche Go-Back-Marken werden in den folgenden Fällen gesetzt.

  • Öffnet man eine neue Datei, dann wird die Position in der aktuellen Datei, als Go-Back-Marke gespeichert. Das Wechseln in eine andere Datei (Strg+Tab) setzt keine Go-Back-Marke (was ich verwunderlich finde).
  • Jede Löschoperation nach einer Cursorbewegung setzt eine Go-Back-Marke.
  • Eine Textsuche (Strg+F) setzt eine Go-Back-Marke an der Fundstelle.
  • Inkrementelle Suche (ob vorwärts oder rückwärts ist egal), trägt eine Go-Back-Marke in die Liste ein und gleichfalls, wenn die inkrementelle Suche beendet wird.
  • Verwendet man GotoLine (Strg+G) oder bewegt den Cursor mehr als 10 Zeilen von der aktuellen Position weg, wird eine Go-Back-Marke an der neuen Position gesetzt. Dies gilt auch wenn dies durch eine Suche ausgelöst wird, die mehr als 10 Zeilen weiterspringt. In diesem Fall wird auch die Startposition als Go-Back-Marke gespeichert.
  • Jeder Klick mit der linken bzw. rechten Maustaste platziert eine Go-Back-Marke an der alten Cursor-Position. Weitere Mausklicks ohne Cursor-Operationen zwischen drin platziert keine neue Go-Back-Marke.
  • Jeder Step-Into beim Debuggen löst auch setzt auch eine Go-Back-Marke.

Sehr nett ist auch die Möglichkeit den gesamten Text von der aktuellen Position bis zurück zur letzten Go-Back-Marke zu selektieren. Dies erfolgt über den Hotkey Strg++ (Pluszeichen).

Ausgesprochen nützlich finde ich diese Funktion auch beim debuggen. Man kann sofort an die Stelle zurückspringen von der man soeben kam, ohne das Call-Stack-Fenster zu verwenden.

BTW: Diese Funktionen habe ich erst durch das versehentliche Auslösen der Kombination Strg++ vor längerer Zeit entdeckt 🙂

Löschen von Verzeichnissen über Laufwerke, die als Verzeichnis bereitgestellt wurden

Ich habe eine zweite SATA Festplatte in meinem Rechner (Windows XP SP2). Festplatten kann man ja auch direkt als neue Verzeichnisse bereitstellen. Schön, da eines meiner Verzeichnisse auf der ersten Festplatte am überquellen ist dachte ich mir:
Stelle einfach dies zweite Festplatte als neues Verzeichnis in meiner Verzeichnisstruktur zur Verfügung.

Gesagt getan und alles prima.

Bis ich heute auf die Idee kam ein wenig aufzuräumen:
Hier eine Datei gelöscht: OK. Dort eine Datei gelöscht: auch OK. Hier das Verzeichnis löschen: Peng „Zugriff wurde verweigert“! 😮
Was ist denn hier los ❓

Der Explorer hat mit meinem so eingemappten Laufwerk ein Problem. Er möchte die Dateien, die zu löschen sind, in den Papierkorb (Recycler Verzeichnis) verschieben. Das gelingt ihm offensichtlich mit Dateien (und die werden kopiert), allerdings gelingt ihm das nicht mit Verzeichnissen.

Direkt Löschen kann man diese Verzeichnisse indem man die Umschalt-Taste festhält m Explorer.
Das Löschen gelingt auch, wenn man die Festplatte über einen Laufwerksbuchstaben zusätzlich einmappt und dann über diese Verknüpfung die Verzeichnisse löscht.

Irgendwie nicht zu verstehen, dass hier der Explorer so kläglich versagt. 🙁
Aber auch dieses Verhalten ist dokumentiert, was ich nach einer Rückfrage bei meinen Mit-MVP Ralf Breuer auch erfuhr:
http://support.microsoft.com/kb/319368

Anmerkung: ❗ Eine Datei, die über das gemappte Verzeichnis C:\xyz gelöscht wird landet übrigens im Papierkorb auf der Platte C:, obwohl sie physikalisch auf einer anderen Platte liegt. Wirre Explorer Welt!

Installation von Team Foundation Server 2008

Eben erst TFS 2005 installiert und gleich ein neuer Server mit TFS 2008.

Das ganze in folgender Umgebung:
2 Prozessor 2,4 Ghz Xeon, 2GB Speicher, mit 90GB Raid5 SCSI
Windows Server 2003 R2 (deutsch)
SQL Server 2005 (deutsch)
Team Foundation Server 2008 (englisch)

Das ganze lief so glatt, dass ich nicht mal was dazu bloggen kann 😉
Im Ernst: Microsoft hat aus den ganzen anfänglichen Schwierigkeiten mit der Team Foundation Server 200x Installation scheinbar wirklich gelernt.

Und netter Weise arbeitet auch der Team Explorer 2005 problemlos mit TFS 2008.

… und schließlich entdeckte Kolumbus SS_CENTERIMAGE

Wer wollte nicht  schon immer mal einen Text in einem Static-Control zentrieren. Nein nicht horizontal mit SS_CENTER, das weiß ja jeder ;-). Es geht um das vertikale zentrieren.

Und wieder lernt man etwas dazu, was man einfach die letzten Jahre überlesen hat.

SS_CENTERIMAGE Specifies that a bitmap is centered in the static control that contains it. The control is not resized, so that a bitmap too large for the control will be clipped. If the static control contains a single line of text, the text is centered vertically in the client area of the control.

Auch wenn es nicht für mehrzeilige Texte in einem Static-Controls geht, so funktioniert es zumindest für einzeilige Control, was mit Sicherheit die Mehrzahl ist.

Danke CTecS aus dem Deutschen C++ Forum für die Geist-erhellende Anmerkung.

Zusätzliche Befehle im Explorer-Kontextmenü von Vista

Gerade habe ich durch Zufall im Explorer von Windows Vista entdeckt, dass sich das Kontextmenü verändert, wenn man die Umschalttaste festhält. Es ist hierbei egal ob man dies mit der rechten Maustaste oder mit der Kontextmenütaste macht. Es erscheinen 3 zusätzliche Befehle, wenn man eine Datei selektiert hat:

  1. An Startmenü anheften
  2. Zur Schnellstartleiste hinzufügen
  3. Als Pfad kopieren

und 2 neue Befehle wenn man ein Verzeichnis ausgewählt hat:

  1. Eingabeaufforderung hier öffnen
  2. Als Pfad kopieren 

Die beiden ersten Befehle für Dateien kann man vergessen.

Ganz anders sieht das jedoch mit dem letzten Befehl Als Pfad kopieren aus.  Der ist überaus nützlich um den Pfad einer Datei, oder gar die Pfade mehrerer Dateien in die Zwischenablage zu kopieren.
Unter XP hatte ich dazu immer noch das uralte Windows 95 Powertoy SendToX verwendet, das es leider für spätere Windows Versionen nicht mehr gab. Eigentlich schade, aber nun verschmerzbar.

Auch der Befehl Eingabeaufforderung hier öffnen ist sehr nützlich. Denn mit diesem Befehl kann man direkt ein DOS-Fenster in einem bestimmten Verzeichnis öffnen. Dafür gibt es zwar auch Registry-Hacks, aber Vista liefert das inklusive.
Leider verwendet Vista hier immer CMD.EXE und nicht den Befehlszeileninterpreter, der in COMSPEC eingetragen ist. Ich verwende seit Jahren 4NT.EXE und deshalb ist bei mir auch 4NT.EXE in COMSPEC eingetragen. Aber das ist verschmerzbar, denn 4NT mach seine eigenen Einträge im Explorer Kontextmenü, wenn man dies wünscht.

PS: Entdeckt habe ich das ganze, weil ich wusste, dass man bei einem Word Dokument zusätzlich den Befehl Schreibgeschützt Öffnen angeboten bekommt, wenn man die Umschalttaste festhält und das Kontextmenü öffnet über die rechte Maustaste oder die Kontextmenütaste. Das funktioniert auch für Excel-Dateien. Vielleicht wusste das ja auch noch nicht jeder ❗

Anmerkung zur Installation des Visual C++ Feature Pack für 2008 Beta (MFCNext)

Die Beta Version des Feature Pack für Visual C++ 2008 ist ja seit einigen Tagen verfügbar.

In der Beschreibung auf dem Download Link steht zu lesen:

This Feature Pack Beta release may fail to install if you do not have a complete installation of Visual Studio 2008 on your system. To workaround this issue, ensure your original Visual Studio 2008 installation source (network path or DVD) is available when installing the Feature Pack.

Diese Anmerkung sollte man wortwörtlich nehmen.
Es sollte wirklich das komplette Visual Studio 2008 installiert sein. Das schließt auch die von mir nie installierten Komponenten Visual Basic und Crystal Reports ein. Diese Teile habe ich noch nie gemocht und auch normalerweise nie installiert. Aber in diesem Fall schlägt die Installation des Feature Packs fehl.

Im Installations Log sind dann folgende Einträge am Ende zu finden:

[1/10/2008, 13:21:13] (HotIron::CMspExternalUiHandler::UiHandler) Returning 0. INSTALLMESSAGE_RESOLVESOURCE [1: 0 2: vs_setup.msi 3: {80C06CCD-7D07-3DB6-86CD-B57B3F0614D8} 4: {80C06CCD-7D07-3DB6-86CD-B57B3F0614D8}; 5: 0 6: 1 7: 1 8: 0 ]
[1/10/2008, 13:21:13] (HotIron::CMspExternalUiHandler::UiHandlerRecord) Returning IDOK. INSTALLMESSAGE_ERROR [Error [1].An installation package for the product [2] cannot be found. Try the installation again using a valid copy of the installation package ‚[3]‘.: 1706Microsoft Visual Studio Team System 2008 Team Suite – ENU]
[1/10/2008, 13:21:13] (HotIron::CMspExternalUiHandler::UiHandler) Returning IDOK. INSTALLMESSAGE_ACTIONSTART [Action 14:21:13: Rollback. Rolling back action:]

Im Eventlog liest man:

 Protokollname: Application
Quelle:        MsiInstaller
Datum:         10.01.2008 14:21:58
Ereignis-ID:   1023
Aufgabenkategorie:Keine
Ebene:         Fehler
Schlüsselwörter:Klassisch
Benutzer:      MyDomain\Martin
Computer:      LAP-DEV.xyz.loc
Beschreibung:
Produkt: Microsoft Visual Studio Team System 2008 Team Suite – ENU – Update „Visual C++ 2008 Beta Feature Pack“ konnte nicht installiert werden. Fehlercode 1603. Weitere Informationen sind in der Protokolldatei C:\Users\Martin\AppData\Local\Temp\Visual C++ 2008 Beta Feature Pack – KB945273_20080110_131516000-Msi0.txt enthalten.

Protokollname: Application
Quelle:        MsiInstaller
Datum:         10.01.2008 14:21:13
Ereignis-ID:   11706
Aufgabenkategorie:Keine
Ebene:         Fehler
Schlüsselwörter:Klassisch
Benutzer:      MyDomain\Martin
Computer:      LAP-DEV.xyz.loc
Beschreibung:
Product: Microsoft Visual Studio Team System 2008 Team Suite – ENU — Error 1706.An installation package for the product Microsoft Visual Studio Team System 2008 Team Suite – ENU cannot be found. Try the installation again using a valid copy of the installation package ‚vs_setup.msi‘.
Ereignis-XML:

Ach ja, ehe ich es vergesse:
Etwas Geduld sollte man auch mitbringen. Die Installation dauerte auf meinem sonst rechte flotten Firmenlaptop über 35 Minuten!

Die Unsitte Objekte direkt in printf und Funktionen mit variabler Anzahl von Argumenten zu nutzen

Immer wieder sieht man Code wie diesen:

CString strText = _T("xyz"); 
_tprintf(_T("Irgendwas ist %s und jetzt kommt eine Zahl %d"), 
                           strText, 4711);

Sieht harmlos aus und funktioniert. Warum eigentlich?

Es funktioniert nur aus einem einzigen Grund:
CString ist 4 Bytes groß, besteht nur aus einem einzigen Element und das ist ein Zeiger auf einen TCHAR Array!

Das ganze funktioniert sofort nicht mehr wenn wir eine eigene CMyString Klasse ableiten, der wir eine virtuelle Funktion zuordnen. Was passiert nun?
Nun ist CString nicht mehr 4 Bytes groß sondern 8 Bytes und besteht aus zwei Zeigern. Einem Zeiger auf eine vtable und einen Zeiger auf einen TCHAR Array.

Nicht nur wird jetzt kein Text mehr ausgegeben, sondern auch die Zahl wird nicht korrekt ausgegeben! Das ganze obwohl CMyString immer noch einen Umwandlungsoperator für LPCTSTR hat.

Das Problem ist aber, dass _tprintf eine Variable Anzahl von Argumenten (Ellipsis) hat und der C/C++ Compiler gar nicht weiß, was _tprintf erwartet. Also wird das ganze Objekt auf den Stack geschoben.

Man macht eine kleine Änderung, und schon geht die Sache in die Hose. Das habe ich ja schon in dem Artikel Die Cx2y Falle beschrieben. Oder sollte also so etwas wie eine Änderung der Implementierung von CString erfolgen würde solch ein Programm auch sofort nicht mehr funktionieren. Man muss jedoch vermuten, dass Microsoft sich das gar nicht erlauben würde, weil zu viele Entwickler solchen nicht portablen und unabhängigen Code verwenden.

Wie macht man es richtig? Man verwendet den entsprechenden cast oder eine Funktion, die den entsprechenden Typ returniert.

CString strText = _T("xyz"); 
_tprintf(_T("Irgendwas ist %s und jetzt kommt eine Zahl %d"), 
                       static_cast<LPCTSTR>(strText), 4711); 
// -- oder -- 
_tprintf(_T("Irgendwas ist %s und jetzt kommt eine Zahl %d"), 
                       strText.GetString(), 4711);

Man sollte grundsätzlich bei der Verwendung von einer variablen Anzahl von Argumenten (Ellipsis) immer auf den Typ casten, der auch letzten Endes erwartet wird.

Das Visual C++ Feature Pack für 2008 ist als Beta-Version jetzt verfügbar (MFCNext)

Die Beta Version des Feature Packs für VC++ 2008 ist verfügbar.
Sie enthält die nächste MFC Version (MFCNext) und die Erweiterungen gemäß TR1!
Happy testing… 😉

Blog post:
http://blogs.msdn.com/vcblog/archive/2008/01/07/mfc-beta-now-available.aspx

Download link:
http://www.microsoft.com/downloads/details.aspx?FamilyId=D466226B-8DAB-445F-A7B4-448B326C48E7&displaylang=en

Dokumentation:
http://www.microsoft.com/downloads/details.aspx?FamilyId=0D805D4E-2DC2-47C7-8818-A9F59DE4CD9B&displaylang=en

Die Unsitte aus Performancegründen VirtualLock zu verwenden

Immer wieder tauchen in den Foren die Frage auf wie man vermeiden kann, das Seiten durch den Windows Memory Manager ausgelagert werden können.

Ursache für diese Frage ist der vermeintliche Glaube von einigen Entwicklern, dass man durch Vermeiden/Verbieten der Auslagerung von Speicherseiten, die Performance eines Programmes erhöhen könnte.

Das ist natürlich Unfug! 

Grundsätzlich sollte man die Dokumentation von VirtualLock beachten:

Locking pages into memory may degrade the performance of the system by reducing the available RAM and forcing the system to swap out other critical pages to the paging file. Each version of Windows has a limit on the maximum number of pages a process can lock. This limit is intentionally small to avoid severe performance degradation. Applications that need to lock larger numbers of pages must first call the SetProcessWorkingSetSize function to increase their minimum and maximum working set sizes. The maximum number of pages that a process can lock is equal to the number of pages in its minimum working set minus a small overhead.

Der Memory Manager weiß weitaus besser, was auszulagern ist und was nicht. Letzten Endes werden nur Seiten ausgelagert, die in der letzten Zeit nicht benötigt wurden. Ist ein Programm aktiv und nutzt den Speicher auch, besteht keine Gefahr, dass dessen Seiten ausgelagert werden.

Umgekehrt schränkt VirtualLock den Spielraum des Memory Managers ein. Werden Sie sinnlos im Speicher festgenagelt, dann müssen aktive Seiten ausgelagert werden und dass senkt meistens die Performance des gesamten Systems, weil nun unnötigerweise ausgelagert werden muss. Was nützt es, wenn das eigene Programm noch einigermaßen performant ist, aber ein Taskwechsel in den Explorer dann Minuten dauert?
Wie schon gesagt: Oft ist der Effekt genau entgegengesetzt!

Meine Erfahrung, selbst bei sehr speicherhungrigen Programmen ist:
Je weniger man Windows in die Quere kommt um so besser verhält sich das gesamte System.

Und bevor man sich an Funktionen wie VirtualLock versucht, sollteman evtl. eher den Speicherhunger seiner Programme eindämmen, oder den Performancemonitor bemühen, um heraus zu bekommen wo wirklich der Bottleneck ist. Die Perfomancewerte, die am meisten Auskunft über das Auslagern von Seiten geben sind im Abschnitt Memory (Speicher): Pages Input/sec (Seitenlesevorgänge/s) und Pages Output/Sec (Seiten-Schreibvorgänge/s). (Man beachte die inkonsistente Übersetzung 😉 !)
Pages Output/Sec (Seiten-Schreibvorgänge/s) ist mit Abstand der beste Indikator um Speicherkanppheit und Auslagerungsproblemen aufzuspüren!

Als Anmerkung sei noch hinzugefügt, dass VirtualLock Windows nicht hindert die Seiten dennoch auszulagern. Mehr Infos dazu hier, wobei dieser Artikel genauso auf die falsche Anwendung von VirtualLock hinweist:
http://blogs.msdn.com/oldnewthing/archive/2007/11/06/5924058.aspx

Ein guter Artikel über das Windows Speichermanagement findet sich noch hier:
http://members.shaw.ca/bsanders/WindowsGeneralWeb/RAMVirtualMemoryPageFileEtc.htm