Notwendigkeit von Manifesten für DLL’s mit VC-2005

Durch eine Anfrage in meiner Lieblingsgruppe microsoft.public.de.vc bin ich auf folgende interessante Frage gestoßen: Benötigt eine DLL die mit VC-2005 erzeugt wurde ein Manifest?

Nun wie viele Antworten im Leben lässt sich dies nicht eindeutig mit Ja oder Nein beantworten.

Nein! Es wird kein Manifest benötigt, wenn die CRT statisch gelinkt wird. In diesem Fall wird auch kein Manifest benötigt zumindest nicht für die CRT, was nicht heißt, dass nicht auch andere Assemblies per Manifest angebunden werden müssen.

Nein! Wenn die EXE-Datei bereits über ein Manifest verfügt und eine CRT-DLL mit gleichem Namen lädt, hier also z.B. die MSVCR80.DLL. In diesem Fall kann man sich ein Manifest sparen. Es kann aber hier spannend werden, weil die entsprechende DLL natürlich so nicht beeinflussen kann dir 8.0 CRT als SP1 oder RTM zu nutzen. Aber vermutlich ist das sowieso egal.

Ja! Die DLL benötigt ein Manifest, wenn ein beliebiges Programm die DLL nutzt. Zum Beispiel eines, das die CRT statisch linkt, oder das mit einer älteren VC Version erzeugt wurde. In diesem Fall muss die DLL zwingend ein Manifest haben. Und jetzt wird es noch strenger. Wird die DLL per LoadLibrary geladen, dann muss dieses Manifest sogar embedded sein! 🙄
Externe Manifeste bei DLLs werden nur beim impliziten Laden berücksichtigt. Wird eine DLL mit LoadLibrary geladen, dann werden nur eingebette Manifeste berücksichtigt.

❗ Falle: Hat die DLL kein Manifest wird immer garantiert, dass die CRT Version von EXE und DLL passen. Man kann also gefahrlos Speicher in der DLL allozieren und in der EXE freigeben und umgekehrt. Oder eben auch CRT Objekte austauschen. Nutzt die DLL ein eigenes Manifest besteht die Möglichekit, dass EXE und DLL eine unterschiedliche CRT verwenden! Und noch spannender wird es wenn eine EXE mit CRTx eine DLL1 benutzt die per Manifest CRTy verwendet und diese nun eine DLL ohne Manifest lädt… Ja es wird die CRT der EXE verwendet…

Ja ja. Wir haben dank der Manifeste nun keine DLL Hölle mehr. Wir haben eine Manifest Hölle 😀

Meine Empfehlung daher:

  1. Wenn es eigenständige kleine Module sind, dann statisch gegen die CRT linken.
  2. Ansonsten immer ein Manifest einbetten, wenn die DLL eigenständig genutzt wird!
  3. Wird die DLL im Kontext einer bestimmten EXE(s) Datei verwendet, sollte nur die EXE(s) ein  Manifest haben.
  4. In jedem Fall darauf achten, dass gleiche CRT Versionen verwendet werden. RTM, SP1 und irgendwann wahrscheinlich SP2 werden hier Konflikte möglich machen.
  5. MFC Extension DLLs müssen zwingend mit der selben MFC Version (RTM oder SP1) verwendet werden!

Stoff zum weiterlesen:
Isolated Applications and Side-by-side Assemblies

Besonders lesenswert hier der Beitrag von Nicola Dudar:
How to Debug ‚The System cannot Execute the specified program‘ message

Der VirtualStore und seine Schattenseiten

Es ist ja bekannt, dass Programme, die nicht mit einem entsprechenden Trustinfo Manifest ausgestattet sind, unter Vista besonders behandelt werden. Werden diese Programme nicht im administrativen Rechten ausgeführt werden alle Zugriffe auf das Verzeichne C:\Program Files und auf HKEY_LOCAL_MACHINE\Software in der Registry umgeleitet.

Ein Registry Zugriff landet dann in HKEY_CURRENT_USER auf HKEY_CURRENT_USER\Software\Classes\VirtualStore\MACHINE\SOFTWARE. Ein Dateizugriff auf C:\Program Files wird umgeleitet nach C:\Users\Username\AppData\Local\VirtualStore\Program Files.

Was passiert aber nun, wenn der Administrator nun tatsächlich die „richtigen“ Daten in HKLM und C:\Program Files ändert UND es existieren bereits entsprechende Daten im VirtualStore?

Die Antwort ist logisch! Eine Änderung der Daten bleibt ohne Wirkung! Denn die Daten aus dem VirtualStore werden hier mit Vorrang behandelt. Sonst macht das ganze ja keinen Sinn, denn der VirtualStore soll ja scheinbar Schreibzugriffe erlauben.

Im Klartext: Existieren Daten sowohl im VirtualStore als auch in den eigentlichen originalen Positionen, dann werden immer die Daten des VirtualStore verwendet. Nur wenn der entsprechende Registry Key nicht vorhanden/gelöscht wird oder die entsprechende Datei nicht vorhanden/gelöscht ist, dann werden die Daten aus den original Verzeichnissen bzw. Registryästen verwendet.

Nur daraus folgt ein Problem:
Macht der Admin Korrekturen an den realen Daten UND es existieren Daten im VirtualStore, dann bleiben die Änderungen des Admins wirkungslos, bis er die Daten aus dem VirtualStore entfernt. Das kann eine spannende Aufgabe werden.
Vielleicht ist dies eine profane Erkenntnis, aber die Implikationen sind meines Erachtens immens.

PS: Gemein ist einfach, dass Software die bisher mit einer Fehlermeldung gerechnet hat, wenn ein Schreibversuch nach HKLM oder C:\Program Files erfolgte, nun auf einmal erfolgreich schreiben kann. Da kann man sich noch so sehr an alle Empfehlungen halten, hier wird man von Vista reingelegt und man muss schleunigst das entsprechende Trustinfo Manifest nachrüsten.

Button + Accelerator + ShowWindow(SW_HIDE) – EnableWindow(FALSE) = Falle

Da hat man einen Multifunktionalen Dialog. Einer der Schalter in dem Dialog heißt Delete. Und das D ist als Accelerator mit einem & versehen. Gemäß einer internen Rechteverwaltung haben manche Nutzer nicht das Recht diesen Button zu benutzen. Der Programmierer (nicht ich ;-)) hat in diesem Fall einfach den Schalter mit ShowWindow(SW_HIDE) verborgen. Ein weiterer Test ob die Rechte wirklich gegeben sind entfiel im OnBtDelete Handler.

Nun stellte sich aber heraus, dass es manche Nutzer geschafft haben, dennoch Einträge zu löschen.

Nun der Grund ist einfach. Solange der Button nicht mit EnableWindow(FALSE) auch disabled wird, kann man mit ALT+D, also Drücken der ALT-Taste und des Accelerators diesen Schalter auslösen.

Jo. So einfach hat man ein Userinterface gebastelt, mit dem man sich hereinlegen kann.

Was mit Visual Studio 2005 SP1 unter Vista zu beachten ist

Ganz Allgemein hier eine kleine Sammlung wertvoller Links für die Nutzung von Visual Studio 2005 unter Vista. Besonders der zweite Link ist wichtig nach meiner Meinung.

Installationshinweise:
http://support.microsoft.com/kb/929470/en-us

Visual Studio 2005 on Windows Vista Issue List – Running with normal user permissions http://msdn2.microsoft.com/en-us/vstudio/aa972193.aspx

Visual Studio 2005 on Windows Vista Issue List – Running with elevated administrator permissions http://msdn2.microsoft.com/en-us/vstudio/aa964140.aspx

Visual Assist X unter Vista mit VS2005 und SP1

Meine ersten Gehversuche und Test mit VS2005 unter Vista waren gut. Aber da ich mich ohne Visual Assist X gleich fühle als man man mir drei Finger an jeder Hand amputiert hat war ich sehr frustriert als ich merkte, dass VA-X nicht ganz so funktionierte wie es das sonst auf XP tat.

Ein ALT+G, also ein GotoDefinition lies nur einen lästigen Beep hören. Ich befürchtete ohne eine der Hauptfunktionen von VA-X auskommen zu müssen.

Nach einigen Tests merkte ich auch, dass VisualStudio 2005 auch nicht korrekt beendet wurde. Es war zwar nicht mehr sichtbar auf dem Monitor, aber im Taskmanager blieb die Applikation immer noch aktiv und lies sich nur durch den Taskmanager beenden.

Nun das ganze war kein Problem mehr, wenn man VisualStudio mit erweiterten Rechten (also mit Run as Administrator) startet. Aber genau das wollte ich nicht. Zudem mag ich keine überflüssigen Fragen beim Programmstart.

Nach kurzem Nachdenken war mir klar, dass VA-X seine Daten im Programm-Verzeichnis ablegt. Nun und das ist in Vista nun mal nicht gerne gesehen, denn auch als Administator hat man auf diese Verzeichnisse nur mit angehobenen Rechten Schreibzugriff.

Also habe ich die Rechte für das Verzeichnis C:\Programme\Visual Assist X einfach auch für den normalen Benutzer erweitert und auch Änderungsrechte vergeben. Und siehe da, alles funktioniert jetzt ohne Probleme.

BTW: Wer Visual Assist X nicht kennt, der sollte ganz schnell http://www.wholetomato.com besuchen und sich eine Demo besorgen.
Kein Tool mit dem ich arbeite ist so sehr sein Geld wert wie dieses!

Microsoft SQL Server Management Studio Express auf Vista schlägt fehl. Fehler 29506

Fehlermeldung 29506Ich wollte mir das Microsoft SQL Server Management Studio Express auf Vista installieren. Aber während der Installation erhielt ich die folgende Fehlermeldung:

Bei der Installation dieses Pakets ist ein unerwarteter Fehler aufgetreten. Es liegt eventuell ein das Paket betreffendes Problem vor. Der Fehlercode ist 29506.

Und nun? Man sollte doch annehmen, dass eine MSI-Datei sich installieren lässt und auch im Admin-Modus installiert wird. Pustekuchen.

Es geht doch, mit einem Trick:

Man starte eine Console im Admin-Modus: Rechtsklick auf die Verknüpfung und Als Administrator ausführen wählen. Dann von dort die entsprechende SQLServer2005_SSMSEE.msi aufrufen. Dann läuft das Setup ohne Fehler durch.

Langsam habe ich das Gefühl, dass dieses Verfahren zur Installation unter Vista grundsätzlich zu empfehlen ist. Leider kann man MSI-Pakete nicht direkt über ein Kontextmenü im Admin-Modus installieren.
Das wäre was für Vista SP1 😉

Nachtrag 22.08.2009:
Das Problem betrifft auch die Installation unter Windows Server 2008 als auch Windows 7, sofern UAC eingeschaltet ist. Das MSI Paket muss in jedem Fall als Admin (elevated) gestartet werden.

Der # operator im RC-Compiler arbeitet inkonsistent

Heute ist mir ein übler Fehler des Ressourcen Compilers untergekommen.

Beabsichtigt war es einen #define in einen Text umzuwandeln, der als Ressourcen-String abgelegt wird.

Das ganze wurde so implementiert:

#define _MYSTRING(x)   #x
#define MYSTRING(x)    _MYSTRING(x)
STRINGTABLE
BEGIN
4713 MYSTRING(0409)
4714 MYSTRING(040E)
END

Alles kein Geheimnis, nur macht der Ressource-Compiler was er will. Der erste String wird korrekt angelegt. Beim zweiten wird wie durch Zauberhand noch eine 0 angehängt.

Das ganze Problem konnte ich auf allen VS-Systemen (VS2003, VS2003SP1, VS2005 und VS2005 SP1) nachvollziehen.

Gemeldet für Microsoff-Feedback unter:
https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=252616

Voraussetzungen für Remote debugging mit MSVCMON (unmanaged)

Ich bin ein Fan von Remote Debugging!
Aber was benötigt man minimal für Remote Debugging auf dem Target auf dem man debuggen möchte (unmanaged Code)?
Das gesamte Remote Debugging Paket zu installieren ist aufwendig und verändert das Zielsystem. Wenn man auch noch bei einem Kunden vor Ort ist auch natürlich ein Eingriff, den man einem Admin erst mal erklären muss.
Geht es also auch mit weniger? JA…

Für VS.NET 2003 braucht man nicht viel, genau genommen 4 Dateien mit einem Datenvolumen von nicht mal 600kb (passt auf jede Diskette, sofern die noch einer benutzt ;-)) :

  • msvcmon.exe
  • msvcr71.dll
  • NatDbgDM.dll
  • NatDbgTLNet.dll

Wenn man nun auf Firewall Probleme verzichtet und Named Pipes als Transportschicht verwendet dann war es das schon. Dann muss man nur noch MSVCMON auf dem Target starten und es kann losgehen. Seit VS.NET 2003 startet MSVCMON ohne Angabe von Parametern mit named Pipes als Transportschicht. Unter Vista muss man nach meinen Erfahrungen immer den -u Parameter mit angeben wenn man Named Pipes verwendet (siehe hier).

Das einfachste ist es nun sich mit VS.NET 2003 remote auf einen laufenden Prozess zu attachen, den man debuggen möchte. Man öffnet dazu aus dem Menü Debug den Punkt Processes, wählt als Transportschicht Named Pipes und den Target PC. Die Liste der Prozesse füllt sich automatisch.
Nun nur noch den Prozess auswählen und auf Attach klicken. Sofern die PDB-Dateien übereinstimmen kann man sofort seine Breakpoints setzen und loslegen.
Das geht teilweise sogar noch, wenn eine UAE Meldung auf dem Monitor sichtbar ist.

Wer unbedingt TCP/IP als Transportschicht wählen will, der muss seit XP-SP2 einiges an der Firewall einstellen. Die zwei nachfolgenden Links geben entsprechende Hinweise:
http://support.microsoft.com/kb/833977/de
http://support.microsoft.com/kb/841177/en-us

Remote debugging mit MSVCMON im Pipe-Mode auf Vista

Man sollte meinen, dass MSVCMON (aus VS.NET 2003) im Pipe Modus unter dem selben User Account sofort funktionieren sollte. Aber dem ist nicht so.

Normalerweise melde ich mich an der Entwicklungsmaschine und dem Remote-PC auf dem gedebuggt werden soll mit dem selben Benutzernamen an. Wird MSVCMON nun ohne Parameter auf dem Remote Computer gestartet kann man normalerweise sofort eine Verbindung herstellen.
Nicht so unter Vista. Dort bekommt man beim Versuch eine Verbindung herzustellen sofort die Meldung: „Unable to connect to ‚DEV-VISTA‘. Zugriff verweigert“, oder auf einem englischen OS „access denied“.

Nach vielem hin und herspielen und dem Versuch MSVCMON im Administrator-Modus zu starten bin ich auf die Lösung gekommen.

Gibt man direkt noch einmal mit dem -u Parameter den gewünschten Usernamen an, dann erlaubt Vista auch den entsprechenden Zugriff.
Also so gestartet MSVCMON -u MeineDomain\MeinUserName hat man keine Probleme und man kann in gewohnter Weise eine Remote Debug-Session starten und auch unter Vista elementar einfach die Programme debuggen.

PS: Es geht in diesem Artikel natürlich um das Debuggen von nativen Programme, sprich unmanaged Code.

SIGNCODE -i setzt leider nicht den Email-Eintrag

Man könnte meinen, dass SIGNCODE mit dem -i „url“ Parameter , die Email-Adresse in dem Dialog für die digitale Signatur setzt. Zertifikatsanzeige Jeder kennt wahrscheinlich den entsprechenden Dialog:

Nun leider ist dem nicht so. Es wird hier nur eine Zusatzinfo eingetragen.

Die Email- oder URL-Adresse hier müsste im Zertifikat selbst verewigt werden. Nur wird dieses Feld bei Verisign-Zertifikaten nicht mehr ausgefüllt bzw. man kann es nicht mehr bekommen. Angeblich weil es zu viel Spam auf diese entsprechenden Adressen gab. Eine etwas fadenscheinige Ausrede.

Die Info landet in der Struktur SIGNER_ATTR_AUTHCODE in dem Feld pwszInfo und dort ist sie leider nicht sonderlich gut für einen normalen Anwender zu finden.

Schade! Nett wäre es gewesen. Aber nun ist es mal nicht so…