Ist es möglich, eine .NET 4.5-App unter XP auszuführen?


85

Zuerst habe ich folgendes gelesen:

Nach dem letzten Punkt denke ich wirklich, dass es keinen Weg daran vorbei gibt, aber ich musste sehen, ob ich eine endgültige Antwort bekommen konnte, da mein Team ein Upgrade von .NET 4.0 auf .NET 4.5 durchführen möchte. Wir müssen jedoch XP unterstützen.

Gibt es keine Möglichkeit, zu .NET 4.5 zu wechseln, wenn wir XP unterstützen möchten?

Ich könnte mir nur vorstellen, zwei separate Lösungen zu erstellen, aber dann müssten die Codebasen auseinander gehen, wenn wir .NET 4.5-Funktionen verwenden würden.

Also suche ich nach einer erstaunlichen Problemumgehung, die ich nicht finden konnte, und andere wissen es vielleicht schon.


9
Nein, das kannst du nicht. Bleib bei 4.0, bis XP definitiv stirbt.
Federico Berasategui

Antworten:


186

Ich zögere, diese Antwort zu posten, es ist eigentlich technisch möglich, aber in der Praxis funktioniert es nicht so gut. Die Versionsnummern der CLR und der Core Framework-Assemblys wurden in 4.5 nicht geändert. Sie zielen weiterhin auf v4.0.30319 der CLR, und die Versionsnummern der Framework-Assembly lauten weiterhin 4.0.0.0. Das einzige, was das Assembly-Manifest auszeichnet, wenn Sie es mit einem Disassembler wie ildasm.exe betrachten, ist das Vorhandensein eines [TargetFramework] -Attributs, das besagt, dass 4.5 benötigt wird und geändert werden müsste. Eigentlich nicht so einfach, es wird vom Compiler ausgegeben.

Der größte Unterschied ist nicht so sichtbar, Microsoft hat eine längst überfällige Änderung im ausführbaren Header der Assemblys vorgenommen. Welche gibt an, mit welcher Windows-Version die ausführbare Datei kompatibel ist. XP gehört zu einer früheren Windows-Generation, die mit Windows 2000 gestartet wurde. Ihre Hauptversionsnummer ist 5. Vista war der Start der aktuellen Generation, Hauptversionsnummer 6.

.NET-Compiler haben immer eine Mindestversionsnummer von 4,00 angegeben, die Version von Windows NT und Windows 9x. Sie können dies sehen, indem Sie dumpbin.exe / headers in der Assembly ausführen. Die Beispielausgabe sieht folgendermaßen aus:

OPTIONAL HEADER VALUES
             10B magic # (PE32)
            ...
            4.00 operating system version
            0.00 image version
            4.00 subsystem version              // <=== here!!
               0 Win32 version
            ...

Neu in .NET 4.5 ist, dass die Compiler diese Subsystemversion auf 6.00 ändern. Eine Änderung, die zum großen Teil überfällig war, weil Windows auf diese Zahl achtet und nicht nur prüft, ob sie klein genug ist. Außerdem werden Appcompat-Funktionen aktiviert, da davon ausgegangen wird, dass das Programm für alte Windows-Versionen geschrieben wurde. Diese Funktionen verursachen Probleme, insbesondere die Art und Weise, wie Windows über die Größe eines Fensters in Aero liegt, ist problematisch. Es hört auf, über den fetten Rändern eines Aero-Fensters zu lügen, wenn es sieht, dass das Programm für die Ausführung auf einer Windows-Version mit Aero entwickelt wurde.

Sie können diese Versionsnummer ändern und auf 4.00 zurücksetzen, indem Sie Editbin.exe auf Ihren Assemblys mit der Option / subsystem ausführen. Diese Antwort zeigt ein Beispiel für ein Postbuild-Ereignis.

Hier endet jedoch die gute Nachricht. Ein erhebliches Problem ist, dass .NET 4.5 nicht sehr kompatibel mit .NET 4.0 ist. Das mit Abstand größte Problem ist, dass die Klassen von einer Versammlung in eine andere verlegt wurden. Dies geschah vor allem für das Attribut [Erweiterung]. Zuvor wurde es in System.Core.dll in .NET 4.5 in Mscorlib.dll verschoben. Dies ist ein Kaboom unter XP, wenn Sie Ihre eigenen Erweiterungsmethoden deklarieren. Ihr Programm fordert Sie auf, in Mscorlib nach dem Attribut zu suchen, das durch ein Attribut [TypeForwardedTo] in der .NET 4.5-Version der System.Core-Referenzassembly aktiviert wird. Es ist jedoch nicht vorhanden, wenn Sie Ihr Programm unter .NET 4.0 ausführen

Und natürlich hilft Ihnen nichts dabei, die Verwendung von Klassen und Methoden zu beenden, die nur in .NET 4.5 verfügbar sind. Wenn Sie dies tun, schlägt Ihr Programm mit einer TypeLoadException oder MissingMethodException fehl, wenn es unter 4.0 ausgeführt wird

Wenn Sie nur auf 4.0 abzielen, verschwinden alle diese Probleme. Oder brechen Sie diesen Stau und beenden Sie die Unterstützung von XP, eine Geschäftsentscheidung, die Programmierer nicht oft treffen können, aber sicherlich fördern können, indem sie auf die Probleme hinweisen, die sie verursachen. Die Unterstützung alter Betriebssysteme ist natürlich mit Kosten ungleich Null verbunden, nur der Testaufwand ist erheblich. Die Windows-Kompatibilität ist legendär, es sei denn, sie wird darauf hingewiesen. Leiten Sie diese Kosten an den Kunden weiter und er trifft die richtige Entscheidung viel schneller :) Aber wir können Ihnen dabei nicht helfen.


2
Danke Hans, ich dachte, es gibt einige bahnbrechende Änderungen. Ich schätze auch die Problemumgehung. Wir können aus den von Ihnen angegebenen Gründen nicht mitmachen, aber es ist gut zu wissen. Vielleicht wird XP eines Tages für immer
verschwinden

3
just the testing effort is substantial- Das war es, was unser Management dazu brachte, "die XP-Unterstützung fallen zu lassen".
Christoph Fink

Ich weiß, dass dies ein alter Beitrag ist - aber - @JustinPihony: Hat Ihr Unternehmen jemals daran gedacht, ein späteres Betriebssystem und dann VMWare oder Virtual Box zu installieren? Für Windows 7 ist es etwas spät - aber Microsoft hat eine virtuelle Windows XP-Installation veröffentlicht, mit der Sie zwischen 7 und XP wechseln können. Nur ein Gedanke. :-)
Mark Manning

@ MarkManning es war nicht in unserer Kontrolle. Es wurde woanders verwendet.
Justin Pihony

1
@ JustinPihony: Ah. Hmmmmm ...... Mein einziger anderer Vorschlag ist ein Kluge. Erfassen Sie die Betriebssystemversion und richten Sie dann einfach alle Funktionen in Ihren Klassen ein, die in Arrays (oder einem Array) abgelegt werden sollen. Lassen Sie ein Array (oder einen Teil eines Arrays) für XP und das andere für neuere Betriebssysteme sein. Dann brauchen Sie nur noch eine Art globale Variable, mit der angegeben wird, welcher Satz verwendet werden soll. Die Aufrufe können alle gleich sein (oder gleich aussehen), aber ein Satz verwendet NET40_ <FUNKTION> und die anderen können NET45_ <FUNKTION> verwenden. Dies wäre ein indirekter Aufruf der Funktion selbst. Ist das sinnvoll?
Mark Manning


7

Versuchen Sie es mit Mono:

http://www.go-mono.com/mono-downloads/download.html

Dieser Download funktioniert unter allen Versionen von Windows XP, 2003, Vista und Windows 7.


2
Mono ist langsamer als .NET und verfügt zwar über die meisten Funktionen von .NET 4.5, es fehlen jedoch bestimmte Hauptkomponenten wie WPF ( mono-project.com/Compatibility ). Sie können also die Unterstützung von Mono für XP verwenden, wenn sie alles bietet, was Sie benötigen, und Sie mit den Auswirkungen auf die Leistung einverstanden sind. Auf der positiven Seite sollte es nicht erforderlich sein, einen speziellen "Mono-Build" zu erstellen. Der normale .NET 4.5-Build funktioniert normalerweise unter Mono, aber Sie müssen speziell gegen Mono testen, um sicherzustellen, dass Sie kompatibel sind.
Qwertie

2
Ich habe mono-3.12.1-gtksharp-2.12.26-win32-0.msi unter Windows XP SP3 ausprobiert und es ist mit "mono.exe ist keine gültige Win32-Anwendung" fehlgeschlagen . Ich habe auch mono-3.0.10-gtksharp-2.12.11-win32-0.exe ausprobiert, was mit "mono.exe - Einstiegspunkt nicht gefunden" fehlgeschlagen ist. Der Prozedureintrittspunkt InterlockedCompareExchange64 konnte nicht in der dynamischen Verbindungsbibliothek KERNEL32 gefunden werden .dll " .
Cristian Ciupitu

7

Das Mono-Projekt hat die Windows XP-Unterstützung eingestellt und "vergessen", dies zu erwähnen. Obwohl sie immer noch behaupten, Windows XP SP2 sei die minimal unterstützte Version, handelt es sich tatsächlich um Windows Vista.

Die letzte Version von Mono, die Windows XP unterstützt, war 3.2.3.


Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.