SHA1 und SHA256 Codesigning mit SIGNTOOL und einem Timestamp

Ihr seid vielleicht auch betroffen und nutzt bisher Code Signing für Eure Software oder MSI Pakete.
Ich zumindest habe von Symantec (ehemals Verisign) für unsere Zertifikate zum Jahresende eine Email bekommen, die mir empfiehlt zukünftig sowohl SHA1 als auch SHA256 zu nutzen. Entsprechende Links wurden mitgeliefert. (1) (2)(3)(4)

Ich habe also erstmal das bisherige Codesigning SHA1 Zertifikat als SHA256 Zertifikat neu ausgeben lassen. Das ganze war kostenlos über die Symantec Seite möglich und dauerte letzten Endes höchstens 30 Minuten.

Dann habe ich das neue Zertifikat im Produktionsserver installiert.
In unserem Produktionsprozess ist das Codesigning integriert. Die entsprechenden Dateien liegen in einem Quellordner und werden von unserem Produktionserver verwendet um daraus unsere Installationspakete oder Hotfixes zu generieren. Dabei werden alle Dateien entsprechend automatisch signiert.

Die entsprechende Code Passage in unserem Batch sah bisher so aus:

>signtool sign -sha1 FingerPint-SHA1-Zertifikat -fd sha1 -t http://timestamp.verisign.com/scripts/timstamp.dll myexe.exe

Da dachte ich: OK Ganz einfach, also nur eine zweite Zeile mit dem Parameter -as hinzufügen und das neue Zertifikat angeben.
Aber Pustekuchen:

>signtool sign -as -sha1 FingerPint-SHA256-Zertifikat -fd 256 -t http://timestamp.verisign.com/scripts/timstamp.dll myexe.exe
Done Adding Additional Store
SignTool Error: SignedCode::Sign returned error: 0x80070057
        Falscher Parameter.
SignTool Error: An error occurred while attempting to sign: AGVIP.exe

🙁 Nach einigem hin und her probieren und Lesen einiger Artikel, musste ich feststellen, dass die Ursache einzig und alleine in dem angegebenen Timestamp Server liegt. Der Verisign Timestamp Server mag einfach keine SHA256 Zertifikate für das Gegenzeichnen.

Die Lösung war also einfach. Ich habe einen anderen Timestamp Server benutzt und nun sehen die Befehlszeilen einfach so aus.

>signtool sign     -sha1 FingerPint-SHA1-Zertifikat   -fd sha1   -tr http://timestamp.geotrust.com -td sha1   myexe.exe
>signtool sign -as -sha1 FingerPint-SHA256-Zertifikat -fd sha256 -tr http://timestamp.geotrust.com -td sha256 myexe.exe

Und siehe da 🙂 alles funktioniert bestens und meine Programme haben nun 2 Zertifikate.

Platz 1 bei Google ;)

Heute habe ich meine Zugriff auf mein Blog mal wieder seit langem kontrolliert und ich war über die hohe Anzahl an Zugriffen erstaunt, die über die Suchbegriffe „VS2010 SP1“ und „VS 2010 SP1“ auf meiner Seite landeten.

Eine Suche über Google ergab, dass mein Blog für diese Suchbegriffe auf Platz 1 steht, und das ganz ohne Werbung und Optimierung 😉

Mein 12. Award als deutscher MVP für Visual C++

Pünktlich am 01. Oktober 2010 bekam ich eine Email die wie folgt beginnt:

Sehr geehrte(r) Martin Richter,
herzlichen Glückwunsch! Wir freuen uns, Ihnen den Microsoft® MVP Award 2010 verleihen zu können!
Diese Auszeichnung wird an herausragende, führende Mitglieder der technischen Communities verliehen, die ihre wertvollen praktischen Erfahrungen mit anderen Menschen teilen. Wir schätzen Ihren außerordentlich bedeutenden Beitrag in den technischen Communities zum Thema Visual C++ im vergangenen Jahr hoch ein.

Das ist nun mein 12. Award für meine Aktivitäten in den C++ Communities ❗

Mittlerweile gibt es, nach meinem Kenntnisstand, nur noch in Kai Schätzl und Karl Donaubauer MVPs, die mit 13 Awards „dienstälter“ sind (ich beziehe mich hier auf den deutschsprechenden Raum).

Siehe auch http://mvp.support.microsoft.com/

VeriSign ‚Microsoft Authenticode‘ Class 3 Code Signing Digital Certificate für $99,–

Ich war mal wieder auf meiner WinQual Seite um festzustellen ob es im aktuellen Release auffällige Crashes gibt.
Dabei viel mir ein Link ins Auge, der ein VeriSign ‚Microsoft Authenticode‘ Class 3 Code Signing Digital Certificate für nur $99,– anbietet. Bei einem Normalpreis von $499,– ist das kein schlechter Preis!

Hier der Link auf die WinQual Seite:
http://winqual.microsoft.com/help/default.htm#obtaining_a_verisign_class_3_digital_id.htm

und hier der entsprechende Link direkt zu VeriSign:
https://securitycenter.verisign.com/celp/enroll/upsell?promo_code=THEDEAL99&application_locale=VRSN_US&originator=VeriSign:CELP&bundle_id=MSIECS002&enable_options=validity_1

Meine Lieblingstools

Hier mal eine Liste meiner Lieblingstools (nicht nur für die Software-Entwicklung).
Sowohl Freeware als auch Tools für die ich gerne Geld ausgegeben habe.

Und wie immer ist das natürlich auch eine Geschmacksache und über den Geschmack lässt sich bekannter Maßen auch streiten.

Kostenlose Tools in alphabetischer Folge

  • 7-Zip (http://www.7-zip.org/)
    Das rundum sorglos Paket, wenn es um Packen und Entpacken von Dateien geht.
  • Axialis IconWorkshop Lite (http://www.axialis.com/download/iwlite.html)
    Für mich der Beste Icon- und Bitmap Editor. Hier in der Lite Version wer kein Geld ausgeben will.
  • BugTracker.Net (http://sourceforge.net/projects/btnet/)
    Der TFS istprima für die aktuelle Projekt- und Entwicklungsarbeit. Aber als externes Portal und als Ideensamlung, oder auch als Vorstufe zum Filtern zwischen Second-Level-Suppport und der Entwicklung habe ich dieses Tool liebgewonnen. Flexibel, simpel, schnell, kein Wartungsaufwand.
  • Comment Reflower
    VS-2005: http://commentreflower.sourceforge.net/
    VS-2008 und VS-2010: http://www.kynosarges.de/CommentReflower.html
    Das Addin der Wahl um einfach Kommentare im Sourcecode zu formatieren.
  • Radio fx / ClipInc fx (http://www.tobit.de)
    Wer seine Musiksammlung einfach und legal erweitern will, kann dies mit diesem Tool machen.
  • Dependency Walker / Depends.exe (http://dependencywalker.com/)
    Unverzichtbar für die Analyse von ausführbaren Dateien. Besonders eben auch die Trace Funktionen, die auch das Aufspüren von Ladeproblemen bei COM Modulen unterstützt.
  • FileZilla (http://www.filezilla.de)
    Nicht unbedingt die tollste Öberfläche aber nützlich, schnell und effektiv.
  • Frhed (http://frhed.sourceforge.net)
    Der beste Hex-Editor, mit wichtigen Funktionen wie Ersetzen tauschen etc.
  • iTunes (http://www.apple.com/de/itunes)
    OK! Ich habe auch einen 20GB iPod. Aber dennoch ist iTunes für mich das beste Tool meine Musik zu verwalten. Ich habe mich mit dem Mediaplayer nie wirklich anfreunden können.
  • KeePass (http://keepass.info)
    Der Password-Safe! Wer viele Kennworte verwalten muss, ist froh komplexe Kennworte  verwenden zu können, aber sich nur eines merken zu müssen.
  • Notepad++ (http://notepad-plus.sourceforge.net)
    Ein Editor der mir vor allem wegen seiner erweiterten Funktionen für Lesezeichen (Zeilen mit Lesezeichen kopieren, löschen) wichtig ist. Früher habe ich Textpad verwendet nur wurde der einfach nicht vernünftig weiter entwickelt.
  • Sysinternal Suite (http://technet.microsoft.com/en-us/sysinternals)
    Die unentbehrlichen kleinen Helferleins um in den tiefen des Windows OS zu forschen. DbgView, Process Explorer und Monitor müssten geschrieben werden, wenn es sie nicht schon gäbe.
  • TCC LE (http://www.jpsoft.com/downloads/v11/tccle.exe)
    Wer das Geld für TCC nicht ausgeben will, bekommt einen guten CMD.EXE Ersatz, dem nur wenig zum großen Bruder TCC 11.0 fehlt.
  • TeamViewer (http://teamviewer.com/)
    Wer mal seinem älteren Vater/Mutter, Oma/Opa, oder dem Freund/Freundin schon mal am Telefon helfen musste, der freut sich über den TeamViewer! Mit dem Tool kann man das Problem, das man am Telefon in Worten kaum klären kann, schnell online lösen. Für den Privatgebrauch kostenlos! (Ansonsten sein Geld auch für eine Firma wert!)
  • TFS Power Tools (http://msdn.microsoft.com/en-us/vstudio/bb980963.aspx)
    Eigentlich muss man sich fragen warum diese Power Tools  nicht direkter Bestandteil des TFS sind. Aber es gibt sie ja zum Glück. (Besonders einen Blick wert ist die Windows Shell Extension)
  • WinMerge (http://winmerge.org)
    Wenn man öfters mal Reviews macht ist dies das Hilfsmittel der Wahl um Merges und Kontrollen von Änderungen von Sourcecode durchzuführen. 
  • WiX (http://wix.sourceforge.net)
    Wenn man auch etwas komplexere MSI Setup Projekte relativ einfach erzeugen will.

Tools, die (IMHO) ihr Geld Wert sind in alphabetischer Folge:

  • Acronis Home (http://www.acronis.de)
    Datensicherung der gesamten Festplatte, made easy. Dazu noch andere gute Tools (Clonen und Löschen von Festplatten). Für mich
  • Axialis IconWorkshop (http://www.axialis.com)
    Für mich der Beste Icon und Bitmap Editor. Wer kein Geld ausgeben will findet auch eine Lite-Version hier http://www.axialis.com/download/iwlite.html
  • CppDepend (http://www.cppdepend.com)
    Code Analyse mal ganz anders aber sehr effektiv (nicht ganz billig).
  • NOD32 von ESet (http://www.eset.de)
    Seit NOD32 der erste wirklich funktionierende Virenscanner unter Vista war bin ich bei ihm geblieben. Schnell, Effektiv. Macht das System nicht langsam. Klein und nicht mit überbordenden unnötigen Funktionen überfrachtet.
  • SpeedCommander (http://www.speedcommander.de)
    Da ich ein alter XTREE Fan war, habe ich mich nie an den Norton-Commander gewöhnen können. Aber mittlerweile habe ich die vielen integrierten Funktionen des SpeedCommanders schätzen gelernt. Ein zuverlässiges Tool für alles was man so mit Dateien machen muss. Tool einfach auch die FTP Integration, der Quickview, Synchronisation, einen kleinen pasablen Editor und manch anderes mehr.
  • TCC 11.0 (http://www.jpsoft.com)
    Das Beste CMD.EXE Substitut. Ich verwende das Ding seit alten 4DOS Zeiten. Ich kann genauso wenig ohne dieses Ding auskomen wie auch nicht ohne VA-X noch Programme schreiben kann. Auch als LE Version für den, der kein Geld ausgeben will http://www.jpsoft.com/downloads/v11/tccle.exe
  • TextPad (http://www.textpad.com)
    Über Editoren kann man sich bekannter Maßen streiten. Aber ich habe vor Jahren mir mal eine Lizenz gekauft und war eigentlich immer sehr glücklich mit dem Editor, obwohl in der letzten Zeit kaum noch etwas hier in der Entwicklung passiert. Vista wurde auch etwas verschlafen. Dennoch mag ich diesen aufgeräumten guten Editor.
  • Visual Assist (http://www.wholetomato.com)
    Das non plus ultra Addin für jeden Entwickler. Alt+M, ALT+G, ALT+O… all die netten Hotkeys, die man nicht mehr missen will, mit tollen Refaktoring Funktionen.
  • VMWare Workstation (http://www.vmware.com)
    Das Tool um viele Umgebungen auf einer Entwicklungsmaschine testen zu können. Mal kurz eine Beta zu installieren und und und… Virtual PC ist nett. VMWare Workstation ist besser.

Wer Lust hat kann ja seine Tools gerne als Kommentar ergänzen ❗
Vieles Gute kann man in dem unendlichen Angebot an Tools und Software leicht übersehen…

PS: Ich bin dann erstmal weg, ohne Internet und Laptop in der Sonne… also nicht wundern wenn ich mal nicht auf einen Kommentar antworte… 😉

SELECT … FROM … WHERE … NOT IN (…) Mystik

Wieder mal ein ganz normaler Wahnsinn, der einen Stunden gekostet hat…

Wenn wir uns die nachfolgenden SQL Statements ansehen, dann würde ich davon ausgehen, dass die ersten 6 eine Ausgabe erzeugen.

SELECT 'Test 1' WHERE 1 IN (NULL, 1, 2, 3, 4)
SELECT 'Test 2' WHERE 1 IN (1, 2, 3, 4)
SELECT 'Test 3' WHERE 1 NOT IN (NULL, 2, 3, 4) -- !!!
SELECT 'Test 4' WHERE 1 NOT IN (2, 3, 4)
SELECT 'Test 5' WHERE NOT (1 IN (NULL, 2, 3, 4)) -- !!!
SELECT 'Test 6' WHERE NOT (1 IN (2, 3, 4))
-- Empty as expected
SELECT 'Test 5' WHERE 1 IN (NULL, 2, 3, 4)
SELECT 'Test 6' WHERE 1 IN (2, 3, 4)

Aber ❗ Pustekuchen ❗
Die Zeilen 3 und 5 erzeugen keine Ausgabe ❗Dadurch, dass in dem Ausdruck in der Klammer NULL enthalten ist funktioniert der NOT IN Test nicht mehr korrekt.

Ich bin darauf gestoßen, weil ich ein Subquery durchgeführthabe und mit NOT IN prüfen wollte, dass ein bestimmter Wert eben nicht in diesem Subquery enthalten ist. Einziges Problem war, dass in einigen Fällen dieser Subquery eben auch NULL als Ergebnis geliefert hat. 
Und genau in diesem Fall funktionierte die Abfrage nicht korrekt (s.o.). Das sah vereinfacht in etwas so aus:

SELECT [ID] FROM [Table1]
    WHERE [SomeData] NOT IN
        (SELECT [OtherIDWithNULL] FROM [Table2])

Ich habe den Subquery dann entsprechende um ein WHERE … IS NOT NULL erweitert und siehe da es ging:

SELECT [ID] FROM [Table1]
    WHERE [SomeData] NOT IN
        (SELECT [OtherIDWithNULL] FROM [Table2]
            WHERE [OtherIDWithNULL] IS NOT NULL)

Rein gefühlt ist das für mich ein Bug, aber es ist keiner ❗
Hier kommt eine Einstellung zum tragen, die sich ANSI_NULL schimpft. (siehe SET ANSI_NULL { ON | OFF })

ANSI_NULL ist im Allgemeinen ON, und das bedeutet, dass ein Vergleich eines Wertes mit NULL immer undefiniert ist. Das ein IN-Statement aber nichts anderes ist als ein Vergleich der einzelnen Werte in der Klammer mit dem Zielwert, führt dies hier zu einem irritierenden Ergebnis. NULL=NULL und 1=NULL ist eben undefiniert und nicht False wenn ANSI_NULL ON ist! Also können die Zeilen 3+5 kein korrektes Ergebnis liefern.
Man beachte: Dies hat keinen Einfluß solange man IN verwendet und nicht NOT IN!

Meine rein persönliche Meinung:
Ich habe selten solch einen Unsinn in einem ANSI-Standard gesehen. Einfach Unlogisch ❗
Für mich ist NULL=NULL und NULL<>AnyThingElse eben True… Just my 2 cents…

Jetzt könnte man meinen, dass es also auch eine Lösung wäre SET_ANSI_NULL OFF zu verwenden ❗ (BTW: Eine Einstellung die auch als Attribut direkt auf der Datenbank selbst gesetzt werden kann). Aber der folgende Hinweis in der Doku sollte einen zum Umdenken bewegen:

Wichtig:
In einer späteren Version von SQL Server wird ANSI_NULLS immer auf ON festgelegt, und jede Anwendung, die für die Option explizit OFF festlegt, löst einen Fehler aus. Verwenden Sie dieses Feature beim Entwickeln neuer Anwendungen nicht, und planen Sie eine Änderung von Anwendungen, in denen es zurzeit verwendet wird.

Da dies also evtl. Einfluss auf andere Codebereiche haben könnte und zukünftig nicht mehr unterstützt wird habe ich auf diese Nutzung verzichtet und lieber das Subquery abgeändert.

PS: Bitte jetzt nicht darauf hinweisen, dass es auch JOIN gibt. Aufgrund der Komplexität der Abfrage und weil diese auch noch nach bestimmten Bedingungen gebaut wurde, war ein IN mit einem Subquery, der einfachere Weg.

Mein „Baby“ ist nun „Kompatibel mit Windows 7“

Das meine Software auf allem läuft was Windows XP und später heißt war mir schon lange klar 😉 aber ein offizielles „Kompatibel für…“ ist ja schon noch was anderes.
Jetzt habe ich die kostenlose Zertifizierung für die Windows 7 Kompatibilität hinter mich gebracht.
In Klartext ganz offiziell: AG-VIP SQL in der Version 1.20.008 ist kompatibel mit Windows 7

Verglichen mit der Vista Zertifizierung, die wir bei einem 3rd Party Unternehmen (VeriTest) durchgeführt haben, muss ich sagen: Windows 7 kompatibel zu werden ist nicht schwer
Es war wirklich kein großer Aufwand!

Wer sich die Spezifikationen durchgelesen hat wird sehen, dass sich gegenüber der Vista Zertifizierung kaum was geändert hat. Wer also seine Software bereits Vista kompatibel hat, kann gleich einen Durchstart machen und es für Windows 7 auch probieren. Und das schöne: Es kostet nichts!
Ich habe es nicht versucht, aber ich vermute mal, dass genau die Version die ich für Vista eingereicht habe auch durch die Windows 7 Zertifizierung gekommen wäre.

Noch ein paar Anmerkungen:

  • Ich kann jeden ermutigen, den Test zu machen, wenn man sowieso schon ein Code Signing Zertifikat und einen 64bit Rechner zur Verfügung hat. Wenn man auf dem man 64bit Windows 7 virtualisieren kann ist die Zertifizierung wirklich einfach. Ich habe VMWare benutzt und das ist einfach ein super Werkzeug für so etwas.
  • Wie bei vielen Zertifizierungen wird viel zu viel Gewicht auf Installation und Deinstallation gelegt. Das war bei der Vista Zertifizierung auch schon so.
  • Bei der Vista Zertifizierung war noch klar, wie und wo man Waiver (Freistellungen) bekommt, z.B. für Komponenten von Drittherstellern, die Ihre DLLs nicht signieren. Dazu gehört ja auch Microsoft mit den DLLs der MFC 😉
    In diesem Zertifizierungsprozess, erfährt man, dass man sie evtl. benötigt, aber nicht wo man sie bekommt…
  • Manche in meinen Augen wertvolle Tests in der Vista Zertifizierung, wie zum Beispiel, die korrekte Behandlung von Crashes, scheinen vollkommen entfallenzu sein.
  • Der Test bei dem 3rd Party Unternehmen war weitaus tiefer als das was man bei dem Selbsttest macht. Jetzt genügt ja die Software zu starten und wieder zu beenden. Bei den Tests zu Vista sind wir beim ersten mal durchgefallen, weil hier ein Bug in der MFC mit dem Application Verifier gefunden wurde, der uns beim Testen nicht aufgefallen war  (Siehe 1, 2, 3
    Ich empfinde den Selbsttest als zu schwach um dann ein Windows 7 kompatibel Logo zu bekommen.
  • Man muss versichern, dass man keine Spyware zertifiziert oder andere böse Software erzeugt… gelinde gesagt ein Scherz. Bei einem 3rd Party Tester würde solche Spyware (hoffentlich) nicht durchkommen. Das hoffe ich doch wirklich mal! Jetzt muss man nur einen Haken setzen, und sich selbst bestätigen, dass man es nicht tut, obwohl man es evtl. doch tut… 😉
    Das mindert den Wert dieses Logos ungemein.
  • Wenn man früher Geld investierte für eine Zertifizierung, hieß das nicht, dass man deshalb bessere Software produziert. Aber 1000$ waren dennoch eine Schwelle über die nicht jeder Hanswurst mit seiner Mickey-Maus-Software gegangen ist.
    Jetzt bleibt als Schwelle nur noch der Kauf eines Code-Signing Zertifikates bei VeriSign und so was kostet ca. 500$ im Jahr.
  • Ich vermisse schon lange das Verbot anderer Techniken, zum Beispiel ein Verbot von Systemweiten Hooks, wenn man Windows X kompatibel sein will. Wenn dann sollte so etwas auch nur mit einem Waiver und klarer Begründung erlaubt werden.
    Nicht wenige dieser mies programmierten Hooks sorgen für Instabilität, unnützes Aufblähen von Prozessen und manchmal auch miese Performance.

Als Fazit bleibt für mich die Frage:
Was nützt ein Logo, dass man zu leicht bekommen kann?

Es bleibt eine Marketing-Aktion und genauso wurde die Vista und jetzt auch die Windows 7 Zertifizierung auch bei uns in der Firma eingestuft. Technischen Nutzen hat das ganze nicht wirklich.

Was denn nun SwitchToThread(), Sleep(0), Sleep(1)?

Was macht man, wenn man keine Wait-Funktionen verwenden will, aber dennoch möchte, dass ein anderer Thread weiterarbeiten kann. Zum Beispiel, weil man einen Spinlock implementieren will.

Nun es gibt insgesamt vier Methoden die durch das Netz geistern.
Ich gehe mal der Häufigkeit nach, die so in manchen Code-Samples finde:

1. __noop;

Wenn der Lock kurz ist, scheint es das beste zu sein, einfach die Schleife weiterlaufen zu lassen und zu hoffen, dass der ein Thread auf einem anderen Prozessor, die Ressource freigibt. Das eignet sich wirklich nur, wenn die Zeitdauer der Sperre als extrem kurz anzusehen ist und eine hohe Anzahl von Prozessoren zur Verfügung steht.
Nach allen Test, die ich gemacht habe, sollte man aber von dieser Art des Wartens bei einem Spinlock absehen. Es schiebt die Leistung des Kerns auf 100% und bringt nichts.

2.  Sleep(0);

Lies sich gut. Schlafe aber eben nicht lange. Man hat auch schon irgendwo gelesen, dass durch diese Methode der Rest der Zeitscheibe dieses Threads aufgegeben wird und ein anderer Thread an die Reihe kommt.
Leider stimmt das nicht ganz ❗
Liest man die Doku genau steht da aber:

A value of zero causes the thread to relinquish the remainder of its time slice to any other thread of equal priority that is ready to run. If there are no other threads of equal priority ready to run, the function returns immediately, and the thread continues execution.

😮 Threads mit höherer oder niedriger Prio haben also nichts davon.

Besonders eklig wird das ganze gerade wenn man Threads unterschiedlicher Prio hat, die hier gegeneinander laufen. Sleep(0); führt in diesem Fall zu einerunnötigen Prozessorlast und eben nicht dazu, dass die Zeitscheibe abgegeben wird. Der Prozess kommt sofort wieder an die Reihe und spin-t weiter.

3. SwitchToThread();

OK. Seit Windows 2000 gibt es diese nette neue Funktion. Damit wird ein anderer Thread aktiv. Egal was für eine Prio er hat. Aber auch diese Funktion tut evtl. nicht genau das was man will.
Auch hier stecken die Tücken im Detail der Doku:

The yield of execution is limited to the processor of the calling thread. The operating system will not switch execution to another processor, even if that processor is idle or is running a thread of lower priority.

Sollte also der Thread, auf den man wartet auf dem anderen Prozessor laufen, so profitiert der nicht von dem Aufruf von SwitchToThread.

4. Sleep(1):

Hiermit erreicht man wirklich was man möchte. Man gibt seine Timeslice auf und erstmal sind die anderen dran.

Mein persönliches Fazit:

Nach meinen Recherchen ist Sleep(1); der vernünftigste Weg seine Zeitscheibe abzugeben. Und nach meinem Dafürhalten ist ein __noop; strickt zu vermeiden. Die Performance ist grottenschlecht.
Das ganze Verhalten hängt extrem auch von den Umständen ab: Zahl der Theads, Häufigkeit der Kollision, Anzahl verfügbare Prozessoren, Verteilung der Prioritäten, Allgemeine Belastung des Systems, Zeitdauer der Sperre etc.

Ich habe mit einigen Parametern gespielt und auch ein kleines Sample gebaut, dass alle 4 oben genannten Funktionen durchprobiert und in dem man auch mit anderen Faktoren (Priorität etc.) spielen kann.
Es zeigte sich, dass Sleep(1); am effektivsten war. Aber dicht auf gefolgt von Sleep(0);, was mich doch etwas überraschte.

Allerdings führen schon kleinste Änderungen (Lockdauer, Zahl der Prozessoren, Spielen mit der Priorität) zu anderen Ergebnissen.
Interessant ist vor allem das Spielen mit den Prioritäten. Man soll nicht glauben, das ein Thread selbst mit niedrigster Prio noch relativ häufig Arbeit bekommt.

Viel Spaß beim Spielen mit dem Code SleepTest

CDialog::SetDefID und DM_SETDEFID, des Tastaturfreunds Liebling

Die Frage um die Eingabe-Taste in Dialogen und wie man diese „missbraucht“ (sage ich mal provokant) ist eine regelmäßige Frage in allen Foren.

Die Intention ist oft klar. Man möchte mit der Eingabetaste eine bestimmte Aktion verbinden, die evtl. sehr oft ausgeführt werden soll und nicht den Dialog schließen.
Die üblichen Wege sind schon mehrfach diskutiert worden und auch in meinem Blog finden sich dazu ein Artikel .

Zu kurz kommt bei dieser Diskussion die Funktion CDialog::SetDefID bzw. DM_SETDEFID Nachricht.
Was macht diese Funktion/Nachricht?
Sie definieren die Button-ID, die als Default-Aktion in einem Dialog ausgelöst werden soll und das ist nichts anderes als die Aktion die geschehen, soll wenn die Eingabe-Taste gedrückt wird.
Viele Entwickler definieren einfach OnOK um. Aber das eigentlich tolle ist mit SetDefID den Button in Abhängigkeit der Daten umzusetzen und das hat auch einen visuellen Effekt für den Nutzer.

Mal ein Beispiel:
Wir haben einen Dialog mit zwei List Views. Links Elemente die zur Auswahl stehen, rechts die Elemente in der Reihenfolge, die der Benutzer ausgewählt hat.
Der Mausschubser wird einfach die Einträge auf der linken oder rechten Seite doppelklicken und damit auswählen oder entfernen. Entsprechende Buttons für Hinzufügen und Entfernen wird es auch geben. Man kann also auch links oder rechts markieren und dann den Hinzufügen oder Entfernen Schalter nutzen.

Dem Tastaturnutzer können wir helfen indem wir intelligent CDialog::SetDefID / DM_SETDEFID verwenden. Die Vorgehensweise ist einfach.

  • Wir richten uns nur danach in welchem List View wir uns befinden, d.h. befinden wir uns im linken List View steuern wir den Hinzufügen Schalter, und im rechten List View steuern wir den Entfernen Schalter.
  • Wird also im linken List View ein Item ausgewählt, setzen wir mit CDialog::SetDefID / DM_SETDEFID die ID des Hinzufügen Schalters.
  • In dem Moment wird der Hinzufügen Schalter zum Default-Button. Der Nutzer kann nun die Eingabe-Taste drücken und die Items werden in die rechte Box verschoben.
  • Links liegt jetzt nun noch der Fokus, aber es sind keine Items mehr markiert. D.h. wir setzen nun den Default Button zurück auf IDOK.
  • Jetzt kann der Nutzer erneut ein Item markieren. Der Default-Button wird wieder der Hinzufügen/Entfernen Schalter und die Eingabetaste macht was der Nutzer gerne hätte.
  • Ist kein Item mehr markiert schließt die Eingabetaste wieder über IDOK den Dialog.

Ohne Maus kann man also mit den Pfeiltasten, der Leertaste (evtl. Strg-Taste) und der Eingabetaste diesen Dialog bedienen. Und das sogar intuitiv, denn der entsprechende Default Button wird ja in der UI schön umrandet und hervorgehoben.
Das freut jeden Tastaturfreund. Und man muss gar nichts groß machen mit der Behandlung Eingabetaste.

Damit das Ganze nicht so abstrakt ist, habe ich ein kleines Sample gebaut, dass diese Anwendung zeigt. Es hat keine Implementierung für Drag&Drop aber es macht deutlich, wie man dem Tastaturnutzer entgegen kommen kann indem man die Controls geschickt aktiviert.

ACHTUNG! MSDN Bookmarks werden zum 1. Oktober 2009 eingestellt

Ich nutze gerne die MSDN-Bookmarks, allerdings hat dies scheinbar nun ein Ende:

MSDN Bookmarks werden zum 1. Oktober 2009 eingestellt. Weitere Details erfahren Sie hier.

Durch Zufall habe ich dies am Kopf der Tool Seite gelesen:
http://social.msdn.microsoft.com/de-DE/Tools/

Das ganze hat erst im September 2008 seinen Anfang genommen. Ich habe darüber in meinem Blog berichtet http://blog.m-ri.de/index.php/2008/09/18/bookmark-on-msdn-auch-auf-meiner-seite/ . Das Ganze hat genau ein Jahr gehalten. 😐
Eigentümlich, dass dieses Feature jetzt schon wieder abgebrochen wird.

Mehr Infos gibt es angeblich hier http://social.msdn.microsoft.com/de-DE/faq, allerdings steht da auch nicht mehr, als das es eben eine Entscheidung gibt dieses Tool einzustellen.

Ich kann also jedem nur raten, der hier wertvolle Bookmarks gespeichert hat, diese zu exportieren. Auch das geht über die Tool-Seite.