Code Monkeys auch überall bei uns…

Über den Code Project newsletter habe ich diesen Blog-Eintrag gefunden:
http://geekswithblogs.net/sdorman/archive/2007/06/29/Programming-for-the-masses.aspx

Ich sehe auch in den Deutschen Foren, in denen ich mich tummle genau die gleichen Tendenzen. Die Szene in den Online Foren und in den NNTP Gruppen hat sich ziemlich verändert.
Man trifft überall Massen an Code Monkeys!

  • Netiquette unbekannt
  • F1-Taste drücken und die Basics der MSDN lesen wird nicht gemacht
  • FAQ ansehen ist umständlich
  • Nichtmal die entsprechenden bekannten Suchbegriffe in Google einzugeben gelingt
  • Basiswissen über die entsprechenden Programmiersprachen wird per Try&Error erprobt
  • Es zählt nur der schnelle Erfolg, auch wenn die Art und Weise wie die Lösung gefunden ist zweifelhaft ist
  • Grundsätzlich ist immer der Compiler und die verwendeten Libraries (CRT/MFC) buggy. Nie der eigene Code!

Irgendwie bin ich aus meiner Vergangenheit verwöhnt.
In meiner Anfangszeit als MVP habe ich weniger gepostet. Dafür waren die Antworten länger und ausführlicher, und meistens handelte es sich um wirkliche Probleme, die es zu lösen galt. Heute sind die Antworten weitaus kürzer und bestehen oft nur auf einen Verweis auf die Doku. Schade eigentlich. Man muss sich wirklich fragen warum man das eigentlich macht!

Im Großen und Ganzen hat sich das Niveau in der Newsgroup nntp://microsoft.public.de.vc gehalten. Allerdings ist die Gruppe der Poster und Regulars ziemlich geschrumpft. Es scheinen NNTP Gruppen irgendwie aus der Mode gekommen zu sein.

Foren wie http://www.c-plusplus.de/forum/index-var-.html und http://forums.microsoft.com/MSDN/default.aspx?SiteID=1 scheinen zu boomen, allerdings ist das Niveau hier nach unten offen…

Tja: Scheinbar war früher wirklich alles besser… 😉

VC-2005 Features der CRT für Unicode Unterstützung

Die CRT der VC-2005 hat eine perfekte Unterstützung für Unicode Dateien im UTF-8 und UTF-16 Little Endian Format.

Wollte man bisher Unicode Dateien lesen, so mussten diese mit _wfopen(…,L“rb“) geöffnet werden und entsprechende Leseoperationen mussten folgen. Um Unicode und ANSI Dateien zu unterscheiden schrieb man selbst entsprechenden Code, der nach einer BOM (Byte Order Mark) schaut. Beim Schreiben hatte man auch selbst darauf zu achten die BOM entsprechend zu setzen.

Ziemlich unbemerkt (auch von mir 🙂 ), hat die CRT hier eine entscheidene Erweiterung erfahren. Mit dem folgenden Code lässt sich gezielt jede Datei entsprechend öffnen und lesen, sofern Sie über eine korrekte BOM verfügt, bzw. auch eine Datei zum Schreiben öffnen die mit der entsprechenden BOM versehen wird.

FILE *pFile = _tfopen(_T(„myfile.txt“),_T(„rt, ccs=UNICODE“));

Ist die Datei eine ANSI Datei ohne BOM, wird sie entsprechend geöffnet. Unicode Dateien im Typ UTF-8 und UTF-16 little endian werden an der entsprechenden BOM erkannt und entsprechend gelesen.
Über ccs=UTF-8 bzw. ccs=UTF-16LE lässt sich auch gezielt eine entsprechende Unicode Datei ohne BOM öffnen. Eine vorhandene BOM überschreibt allerdings die beim Öffnen angegebenen Formatierung. Fein!

Leider hinkt die MFC diesen wirklich tollen Funktionen der CRT hinterher. Weder die MFC  8.0 aus VS-2005 noch die neue Orcas Version (Stand Beta1) verfügt über eine neue Version der CStdioFile, die diese Funktionen der CRT abbildet.

Glücklicherweise gibt es einen entsprechenden CStdioFile(FILE *) Konstruktor. Dadurch ist es möglich, einfach eine Datei mit _tfopen zu öffnen und den Stream einfach an ein CStdioFile Objekt zu koppeln.
Einziger Schönheitsfehler: CStdioFile::Close muss explizit in diesem Fall aufgerufen werden, d. h. Close wird nicht durch den Destruktor aufgerufen.
Für den MFC Kenner: m_bCloseOnDelete ist FALSE und leider protected. Dieses Flag verhindert, dass Close auch durch den Destruktor aufgerufen wird.

MSDN Dokumentation zu _tfopen/fopen/_wfopen

… und schließlich entdeckte Kolumbus SendDlgItemMessage

Wer hat nicht oft genug solchen Code geschrieben:

GetDlgItem(IDC_MYITEM)->SendMessage(WM_MYMSG,wParam,lParam);
// – oder-
HWND hWnd = ::GetDlgItem(hDlg,IDC_MYITEM);
if (hWnd)
    ::SendMessage(hWnd,WM_MYMSG,wParam,lParam);

Da programmiert man Jahrzente unter Windows und hat SendDlgItemMessage noch niemals gesehen und damit geht es so einfach:

SendDlgItemMessage(IDC_MYITEM,WM_MYMSG,wParam,lParam);
// – oder-
::SendDlgItemMessage(hDlg,IDC_MYITEM,WM_MYMSG,wParam,lParam);

Man lernt nie aus. 😉

MSDN Links: SendDlgItemMessage, CWnd::SendDlgItemMessage

BTW: Netter Seiteneffekt. Die direkte Verwendung von GetDlgItem(…)->SendMessage(…); ist natürlich äußerst unsicher. Im Extremfall kracht es. Charmant, dass SendDlgItemMessage sich hier äußerst robust und korrekt verhält.

MFC 8.0 PDB Dateien mit und ohne Source Informationen

Gestern hat es mich überrascht, dass ich beim debuggen auf einmal nicht mehr in eine MFC Funktion mit der F11 Taste steppen konnte. Er sprang immer über diese Zeile. Selbst über die Assembler Ansicht war es nicht möglich die entsprechenden Source-Dateien der MFC im Debugger durch zu steppen.

❓ Eigentümlich. Ein kurzer Blick in die Debug Ausgabe und in die Liste der geladenen Module zeigte, dass die PDB Datei der MFC80UD.DLL aus meinem Symbol-Cache geladen wurden.
In der Modulliste stand als Info: Symbols loaded (source information stripped).
Ich verwende einen zentralen Symbol Cache auf unserem Entwicklungsserver und habe natürlich auch als http://msdl.microsoft.com/download/symbols als Quelle für unbekannte Symbole angegeben.

Scheinbar ist auf irgend einem Weg vom Symbolserver aus dem Netz eine Version in meinen Cache hineingelangt, die nicht alle Debug Informationen enthält. Also gerade die Informationen, die es mir erlauben durch den Sourcecode der MFC zu steppen.

Die entsprechende Version mit den Source Informationen befindet sich durch die Installation von Visual Studio im Verzeichnis C:\Windows\Symbols\dll. Auch in den Optionen für mein Visual Studio war zusätzlich natürlich korrekt auch C:\Windows\Symbols\dll als Pfad angegeben. Die dortigen PDB Dateien wurden jedoch offensichtlich ignoriert. Ein manuelles Nachladen aus diesem Verzeichnis half allerdings sofort.
Bei der nächsten Debug Session wurden jedoch wieder die Informationen aus dem Cache geladen.

Also was machen?

❗ Ich habe einfach die entsprechenden Symbol aus dem C:\Windows\Symbols\dll Verzeichnis in meinen Symbol Cache geladen. Das geht einfach mit dem entsprechenden symstore Befehl:

symstore add /r /f C:\Windows\Symbols\dll\*.* /s <My symbol store>

Und siehe da. Nun werden immer die richtigen PDB-Dateien geladen und Step-Into Befehl F11 verhält sich beim debuggen wieder wie gewohnt.

Die Manifest Pest…

Hier noch mal ein paar wirklich nette Sachen, die zeigen warum ich Manifeste mittlerweile  nicht mehr ganz so mag (um es wirklich vorsichtig auszudrücken):

Was passiert eigentlich wenn man ein internes UND ein externes Manifest zu einer DLL oder EXE hinzufügt?

  1. Auf einem XP Rechner wird der Lader das externe Manifest bevorzugen, das interne Manifest wird ignoriert.
  2. Auf einem Windows 2003 oder Vista Rechner wird das interne Manifest bevorzugt und das externe Manifest wird ignoriert.
  3. Handelt es sich um eine DLL die mit LoadLibrary geladen wird, dann wird niemals ein externes Manifest berücksichtigt, selbst wenn kein internes Manifest vorliegt. Hier verhalten sich XP, 2003 und Vista gleich.

Ein Grund mehr zu meiner Empfehlung: Verwende immer nur interne Manifeste!

Was man beim Umstieg von VSS auf TFS bedenken muss!

Ich plane in der nächsten Zeit Visual Source Safe (VSS) abzulösen. Da wir alle Hauptprojekte (bis auf einigen legacy Kram) auf VC++ 2005 bearbeiten und die entsprechenden Visual Studio Team System Lizenzen haben beabsichtigen wir auch den Team Foundation Server (TFS) einzusetzen.
Einen Team Foundation Server kaufen müssen wir auch nicht, denn wir haben nicht mehr als 5 Clients.

Vorteile:

  • Integration auch in ältere Systeme ist kein Problem! Für VC6, VB6, VS.NET 2003 gibt es entsprechende Plug-Ins! Das ist schon mal genial. Also können wir theoretisch sogar alle legacy Projekte konvertieren und mit den alten Tools weiterarbeiten.
  • Alles wird in einem SQL-Server gehalten. Endlich!
  • Die Projekt Dokumente sind gleich in dem entsprechenden Share Point mit gehalten (leider noch WSS 2.0)
  • Einchecken mehrere Dateien werden direkt zu einem Vorgang zusammengefasst.
  • Direktes Bug-Tracking und einfache Projektierung ist möglich ohne externe Hilfsmittel.

Beim evaluieren der Features habe ich mir schon die Hände gerieben. Allerdings gibt es da eine wirkliche fette Kröte die ich schlucken muss. Mein geliebtes „Sharing“ unter VSS gibt es unter dem Source Control System von TFS nicht ❗

Wir haben einiges an gemeinsamen Code, den wir nicht in Libraries oder DLLs zusammengefasst haben. Da sind einige nette Template Klassen etc., spezielle Header und andere nette Code-Snipplets. Alle diese Code Teile waren in einem kleinen Projekt zusammengefasst und jeder Entwickler konnte diese wahlfrei in sein Projekt sharen. Das ist und war extrem bequem. Mit dem Drawback, dass eine zentrale Code Änderung alle Projekte beeinflusst und evtl. bricht kann man leben.
Man muss einfach regelmäßig Ohrfeigen verteilen für Entwickler die nicht testen und Kerker bei Brot und Wasser androhen… 😉

Unter TFS ist es damit vorbei. Einziger Ausweg wie ich ihn aktuell sehe ist es, die entsprechenden Codeteile einzubranchen in die anderen Projkete. D.h. aber das man die aktuelle Version (und den evtl. gewünschten Fix) nur mit einem Merge bekommt, was wieder nicht unbedingt automatisch geht, man muss also Hand anlegen was man evtl. eben auch vergisst.

Mal sehen vielleicht fällt mir da noch was anderes ein. Anonsten sieht das ganze sehr vielversprechend aus.

Mein erster Codeproject Artikel…

Nun habe ich es endlich mal geschafft und meinen ersten kleinen Artikel auf Codeproject geschrieben:

http://www.codeproject.com/cpp/PrivateAssemblyProjects.asp

 Er schließt sich nahtlos an über alles das was ich hier achon über die Manifest-Hölle geschrieben haben…

EXCHANGE: Jeder hat Rechte auf jedes Postfach…

Upps. Wie das? Keiner hat es bemerkt aber seit ein paar „Monaten“ scheint jeder bei uns volle Rechte auf jedes Postfach zu haben! 😮

Das ist nicht im Sinne des Erfinders, ganz und gar nicht!

Also suchen… aber wo. Mit der Hife von Frank Carius (MVP für Exchange und Herr über die Seite MSXFAQ.DE – Franks MSExchangeFAQ) bin ich dem übel auf die Spur gekommen.

Bestandsaufnahme:
Bei den Rechten auf dem Server in meiner Administrativen Gruppe sehe ich das Jeder die Rechte Send As und Receive As hat. Das soll aber nicht sein. Und noch schlimmer: Die Rechte werden geerbt…
Also klicke ich mich immer höher in der Hierarchie und hoffe bald den entsprechenden Eintrag zu finden. Aber da ist kein Eintrag. Und auf der Ebene der Organisationseinheit finde ich keine Eigenschafts Seite mit Sicherheit.

Oh Mann! Wer weiß denn schon, dass man diese Seite in den Eigenschaften auf der Ebene der Organisations Einheit nur sieht wenn man in der HKCU einen bestimmten Eintrag macht? Wohl nur ein Exchange Guru und das bin ich wirklich nicht…
Also unter HKEY_CURRENT_USER\Software\Microsoft\Exchange\EXAdmin den DWORD Eintrag ShowSecurityPage anlegt und dort 1 eingetragen.

Siehe da. Nun habe ich auch auf der Ebene der Organisation unter den Eigenschaften eine Sicherheits Seite! Und was finden wir hier? Die entsprechenden gesetzten Rechte, die irgendein </zensiert>*$%§5!%2%“!</zensiert> dort gesetzt hat. Also aus dem Recht für Jeder zwei Häkchen entfernt.

Nun sollte man nicht ungeduldig werden. Erst nach 30 Minuten hatte Active Directory die Änderung durch und der Exchange verhielt sich jetzt wieder „Privatsphäre schützend“. 🙂

Automatsiches Update des Thunderbird unter Vista

Ich benutze bereits seit Jahren den Thunderbird als Newsreader, weil ich die Macken des Outlook Express einfach satt war. Zudem ist das Quoteverhalten des Thunderbird einfach und vorbildlich.

Jetzt wunderte ich mich in den letzten Tage, dass ich immer wieder gesagt bekommen habe, dass das neue Update 1.5.0.12 verfügabr ist, auf meinem XP SP2 Rechner war das Update im ersten Anlauf installiert. Aber immer, wenn ich das automatische Update gestartet habe auf meinem Vista Laptop, meinte er nur es würde installiert, wenn ich den Thunderbird neu starten würde. Aber Pustekuchen.

Nach dem dritten Fehlversuch habe ich mir gedacht:
Na Vista wird dem Thunderbird ja nicht einfach Zugriff geben und gefragt nach einem elevated Programmstart wurde ich auch nicht. Und die ACL für die Thunderbird Verzeichnisse sind auch nicht verändert.

  • Also einfach den Thunderbird mal als Admin gestartet.
  • Update ausgewählt.
  • Aufforderung zum Neustart abgewartet.
  • Thunderbird neu gestartet.
  • Bingo!

Hier sollten die Programmierer des Thunderbirds einfach mal den ShellExecute(Ex) mit einem RunAs Verb verwenden. Dann würde das Update auch wirklich automatisch durchgeführt, nach dem Elevate-Prompt.

Siehe dazu auch meinen Eintrag hier: http://blog.m-ri.de/index.php/2007/05/09/wie-einen-prozess-unter-vista-mit-gehobenen-rechten-starten/

Was UAC besser verdaulich gemacht hätte!

In den Einstellungen für einen Programm-Link fehlt die Einstellung Mit normalen Benutzerrechten starten. Von mir aus könnte diese Option auch in den Kompatibilitätseinstellungen drin sein.

Wie es die Option „Als Administrator ausführen“ gibt, fehlt eben das Gegenteil:
Führe das Programm als normaler Benutzer aus.

Was soll diese Option bewirken? Diese Option soll das Programm so starten, wie es unter Windows 2000 oder XP unter normalen Benutzerrechten (ohne Adminrechte) auch laufen würde.

D.h. es würde auch das Admin-Token nicht zugewisen bekommen und bei einem Zugriff schreibend auf HKLM oder C:\Program Files, würde das Programm einfach „Kein Zugriff“ gemeldet bekommen. UAC würde für diesen Fall einfach außen vor bleiben.

Alle Programme, die ich geschrieben habe, kommen damit klar. Eigentlich ärgerlich ist ja nur, dass diese Programme unter Vista nun auf einemal schreiben könne, auch wenn es eben dann nur im Virtualstore landet.

Tausende von Kompatibiltätsproblemen durch das stille Virtualisieren könnte man so umgehen.