Benutzer mit den meisten Antworten
Framework 4.0 ByteViewer

Frage
-
Antworten
-
Hallo u
Meinst du diese Klasse:
http://msdn.microsoft.com/en-us/library/system.componentmodel.design.byteviewer.aspx
Namespace: System.ComponentModel.Design
Assembly: System.Design (in System.Design.dll)
hast du Verweis auf System.Design und using-Namespace?
(oder wo findest du den ByteViewer nicht mehr?)
Wenn du ein Assembly/Projekt für Zielframework 2.0 (bis 3.5) kompilierst, dann kann dieses keine Assemblies aus dem neueren Framework 4 nutzen (direkt referenzieren).
(umgekehrt meist schon)
- Als Antwort markiert Robert BreitenhoferModerator Samstag, 15. Januar 2011 18:25
-
Hallo U.,
- > gibt es den ByteViewer im 4.0 nicht mehr?
doch, den "System.ComponentModel.Design.ByteViewer" gibt es in .NET 2.0 und .NET 4.0.
- > Ist es grundsätzlich ein Problem, wenn eine Anwendung in 2.0 erstellt, auf Assemblys mit höheren Framework zugreifen will,
ja, nach oben geht ein direkter Verweis normal nicht, nach unten ~oft schon. Wenn Du auf ein höheres Framework verweisen willst, ist entweder die Kompilierung Deines alten Projektes für .NET 4.0 nötig, oder Du kompilierst immernoch in 2.0 und benutzt dann Brücken-DLLs (etwa über COM), die dann auf 4.0 Funktionalität zugreifen. Dennoch würde ich unbedingt die Variante der Kompilierung für 4.0 empfehlen.
ciao Frank- Als Antwort markiert Robert BreitenhoferModerator Samstag, 15. Januar 2011 18:25
-
Hallo U.,
> Ist es grundsätzlich ein Problem, wenn eine Anwendung in 2.0 erstellt, auf Assemblys mit höheren Framework zugreifen will, aber die Klasse nichts nach aussen gibt, was nicht höher als 2.0 ist?
Eine Möglichkeit gäbe es noch: Du benutzt in Deiner für das FX 2.0 kompilierte Anwendung in der Konfiguration: <supportedRuntime version="v4.0"/>. Damit wird beim Starten der Anwendung die CLR 4.0 gehostet und Du kannst über Reflection bzw. Assembly.LoadFile die gewünschte 4.0-Assembly laden und die benötigte Typen instanzieren ohne BadImageFormatException ("Die Assembly wird von einer Laufzeit erstellt, die aktueller als die derzeit geladene Laufzeit ist, und kann nicht geladen werden") zu erhalten. Du solltest diesen Weg aber nur dann gehen, wenn Du - warum auch immer - nicht für das .NET 4.0 Framework direkt kompilieren kannst.
Gruß
Marcel- Als Antwort markiert Robert BreitenhoferModerator Samstag, 15. Januar 2011 18:25
Alle Antworten
-
Hallo u
Meinst du diese Klasse:
http://msdn.microsoft.com/en-us/library/system.componentmodel.design.byteviewer.aspx
Namespace: System.ComponentModel.Design
Assembly: System.Design (in System.Design.dll)
hast du Verweis auf System.Design und using-Namespace?
(oder wo findest du den ByteViewer nicht mehr?)
Wenn du ein Assembly/Projekt für Zielframework 2.0 (bis 3.5) kompilierst, dann kann dieses keine Assemblies aus dem neueren Framework 4 nutzen (direkt referenzieren).
(umgekehrt meist schon)
- Als Antwort markiert Robert BreitenhoferModerator Samstag, 15. Januar 2011 18:25
-
Hallo U.,
- > gibt es den ByteViewer im 4.0 nicht mehr?
doch, den "System.ComponentModel.Design.ByteViewer" gibt es in .NET 2.0 und .NET 4.0.
- > Ist es grundsätzlich ein Problem, wenn eine Anwendung in 2.0 erstellt, auf Assemblys mit höheren Framework zugreifen will,
ja, nach oben geht ein direkter Verweis normal nicht, nach unten ~oft schon. Wenn Du auf ein höheres Framework verweisen willst, ist entweder die Kompilierung Deines alten Projektes für .NET 4.0 nötig, oder Du kompilierst immernoch in 2.0 und benutzt dann Brücken-DLLs (etwa über COM), die dann auf 4.0 Funktionalität zugreifen. Dennoch würde ich unbedingt die Variante der Kompilierung für 4.0 empfehlen.
ciao Frank- Als Antwort markiert Robert BreitenhoferModerator Samstag, 15. Januar 2011 18:25
-
Hallo U.,
> Ist es grundsätzlich ein Problem, wenn eine Anwendung in 2.0 erstellt, auf Assemblys mit höheren Framework zugreifen will, aber die Klasse nichts nach aussen gibt, was nicht höher als 2.0 ist?
Eine Möglichkeit gäbe es noch: Du benutzt in Deiner für das FX 2.0 kompilierte Anwendung in der Konfiguration: <supportedRuntime version="v4.0"/>. Damit wird beim Starten der Anwendung die CLR 4.0 gehostet und Du kannst über Reflection bzw. Assembly.LoadFile die gewünschte 4.0-Assembly laden und die benötigte Typen instanzieren ohne BadImageFormatException ("Die Assembly wird von einer Laufzeit erstellt, die aktueller als die derzeit geladene Laufzeit ist, und kann nicht geladen werden") zu erhalten. Du solltest diesen Weg aber nur dann gehen, wenn Du - warum auch immer - nicht für das .NET 4.0 Framework direkt kompilieren kannst.
Gruß
Marcel- Als Antwort markiert Robert BreitenhoferModerator Samstag, 15. Januar 2011 18:25
-
Hallo Marcel und U.,
dazu eine kleine Ergänzung: Wenn man über eine Anwendung oder eine Komponente verfügt, die mit .NET 1.1 oder .NET 2.0 erstellt wurde, und man sie mit .NET 4.0 ausführen möchte, ist es nicht ausreichend, .NET 4.0 in der Liste der unterstützten Laufzeiten (<supportedRuntime version="v4.0"/>) anzugeben. Man muss außerdem in der Konfigurationsdatei im <startup>-Element das useLegacyV2RuntimeActivationPolicy-Attribut auf true festlegen. Andernfalls sucht die Laufzeit in der Liste der unterstützten Laufzeiten nach der aktuellsten Version von .NET Framework, die kleiner als .NET 4.0 ist. Falls .NET 4.0 die einzige Runtime in der Liste ist, tritt ein Fehler beim Laden auf.
Gut - aber wie wir dann ja alle empfehlen - sollte das ganze eher für .NET 4.0 neu kompiliert werden.
ciao Frank -
Hallo Frank,
dazu eine kleine Ergänzung: Wenn man über eine Anwendung oder eine Komponente verfügt, die mit .NET 1.1 oder .NET 2.0 erstellt wurde, und man sie mit .NET 4.0 ausführen möchte, ist es nicht ausreichend, .NET 4.0 in der Liste der unterstützten Laufzeiten (<supportedRuntime version="v4.0"/>) anzugeben. Man muss außerdem in der Konfigurationsdatei im <startup>-Element das useLegacyV2RuntimeActivationPolicy-Attribut auf true festlegen.
Das hast Du wahrscheinlich in Bezug auf meinen Beitrag mißverstanden. MSDN dazu: "Diese Standardrichtlinie lädt die meisten Assemblys mit der CLR-Version, mit der sie kompiliert wurden und bieten so größere Kompatibilität." Wenn man aber die mit 2.0 kompilierte Anwendung über die 2.0er CLR lädt, kann man nicht mehr über Assembly.LoadFile eine .NET 4.0 Assembly laden. Die erforderliche Konfigurationsdatei ist also lediglich:
<?xml version="1.0"?> <configuration> <startup> <supportedRuntime version="v4.0"/> </startup> </configuration>
So geht das Laden der .NET 4.0-Assembly wieder. Nachfolgend eine als .NET 2.0 kompilierte Konsolenanwendung, die über Reflection eine .NET 4.0-Anwendung lädt (Voraussetzung ist die Konfigurationsdatei v. oben):
using System; using System.Reflection; namespace ConsoleApp20 { class Program { static void Main(string[] args) { Console.WriteLine(Environment.Version); string result = String.Empty; try { Assembly assembly40 = Assembly.LoadFile(@"C:\Temp\ClassLib40.dll"); Type type = assembly40.GetType("ClassLib40.Class40", true); MethodInfo mi = type.GetMethod("Foo", BindingFlags.Public | BindingFlags.Instance); object o = assembly40.CreateInstance("ClassLib40.Class40"); result = (string)mi.Invoke(o, new object[] { }); } catch (Exception ex) { Console.WriteLine(ex.Message); } Console.WriteLine(result); Console.ReadKey(true); } } }
Gruß
Marcel- Bearbeitet Marcel RomaModerator Sonntag, 12. Dezember 2010 17:36 Beispiel-Code
-
Hallo Marcel,
Nein, Du hast eventuell meinen Beitrag missverstanden, Marcel.
Ich beziehe mich nicht auf Invoke, sondern auf den Standard - als "Ergänzung":
[<supportedRuntime>-Element]
http://msdn.microsoft.com/de-de/library/w4atty68.aspx
siehe dort bitte den Hinweis "Wichtig":- Wichtig
Wenn Sie über eine Anwendung oder eine Komponente verfügen, die mit .NET Framework, Version 1.1 oder dem .NET Framework, Version 2.0 erstellt wurde, und Sie sie mit .NET Framework, Version 4 ausführen möchten, ist es nicht ausreichend, .NET Framework 4 in der Liste der unterstützten Laufzeiten anzugeben. Außerdem müssen Sie in der Konfigurationsdatei im <startup>-Element das useLegacyV2RuntimeActivationPolicy-Attribut auf true festlegen. Andernfalls sucht die Laufzeit in der Liste der unterstützten Laufzeiten nach der aktuellsten Version von .NET Framework, das kleiner als .NET Framework 4 ist.Falls .NET Framework 4 die einzige Runtime in der Liste ist, tritt ein Fehler beim Laden auf.
ähnliche Hinweise auch [hier] und [hier].
ciao Frank - Wichtig
-
Hallo Frank,
He-he, da ist ja wohl bei der Übersetzung des englischen Originals ins Deutsche ein klein bischen was verloren gegangen ;-)
"If your application uses legacy activation paths, such as the CorBindToRuntimeEx function, and you want those paths to activate version 4 of the CLR instead of an earlier version, or if your application is built with the .NET Framework 4 but has a dependency on a mixed-mode assembly built with an earlier version of the .NET Framework, it is not sufficient to specify the .NET Framework 4 in the list of supported runtimes [...]"http://msdn.microsoft.com/en-us/library/w4atty68.aspx
Nevermind: Du mußt mir nicht glauben, führ einfach den Code von oben aus auf einem System mit .NET 2.0/3.0/3.5 und 4.0. Sage mir bitte Bescheid, wenn's nicht funktioniert.
Gruß
Marcel -
Marcel,
> Übersetzung
die deutsche Version ist da ja deutlich ausführlicher als die US-Englische (das ist in anderen Versionen zu diesem Thema tatsächlich genauso, siehe unten).
Eine Möglichkeit ist sicher, dass die Englische geändert wurde und die Deutsche nicht nachgeführt wurde (etwas unwahrscheinlich, da in der Deutschen ja 4.0 beschrieben ist, es gibt aber mehre Deutungen). Zumindest aus meinen anderen Links sieht man ja, dass es so richtig ist, wie in deutschen und englischen Artikeln aufgeführt. Das sieht man auch an folgender US-Englischen Doku:
http://msdn.microsoft.com/en-us/library/bbx34a2h.aspx
siehe dort: "The useLegacyV2RuntimeActivationPolicy Attribute"
im Vergleich zu folgender:
<->http://msdn.microsoft.com/de-de/library/bbx34a2h.aspx
vergleiche dort: "Das useLegacyV2RuntimeActivationPolicy-Attribut"
"Aber", schalte einmal auf mehrere Sprachen und dann sieht man,
dass das Englische dort dem ausführlichen Deutschen entspricht.
wie gesagt, von mir ist kein Invoke ist gemeint, es sind Standards gemeint (ohne Invoke). Du meinst eben den spät gebundenen Zugriff auf .NET 4.0 Assemblies - ich meine und ergänze da nur das Szenario, wo man ganz normal auf die ByteViewer Klasse von .NET 4.0 ohne Invoke zugreift.Also zum Beispiel so [.NET 2.0 Assembly] (funktioniert mit config-Einstellungen auch in 4.0) :
static void Main(string[] args) { Console.WriteLine("Hallo " + Environment.UserName + "!"); Console.WriteLine("Genutzte CLR-Version: " + Environment.Version.ToString()); ByteViewer bv = new ByteViewer(); Console.WriteLine("Genutzte CLR-Version des ByteViewers: " + typeof(ByteViewer).Assembly.ImageRuntimeVersion.ToString()); Console.ReadLine(); }
Man braucht ja eben kein Invoke - den der OP eh nicht erwähnt hat (und für meine Begriffe hier eher irrelevant ist, aber sicher für Dein geschildertes Szenario richtig und wichtig ist und das ziehe ich hier nicht in Zweifel!).
In meinen Links ist ja aber gut beschrieben, wann und warum useLegacyV2RuntimeActivationPolicy wichtig ist - es ist sicher nicht immer notwendig. Ich greife nicht Deine Schilderung an, sondern ergänze hier nur das Standard-Szenario, wo man ohne Invoke zur Lösung kommen kann!
_____________________
The useLegacyV2RuntimeActivationPolicy Attribute
The .NET Framework version 2.0 activation policy is to load all assemblies by using the latest supported version of the CLR.Starting with the .NET Framework 4 Beta 1, the default activation policy is to cap this "roll-forward" behavior at the latest CLR version before version 4.In most cases, the latest CLR version before version 4 is CLR version 2.0, which is used in all .NET Framework versions from 2.0 through 3.5 SP1.This default policy loads most assemblies by using the CLR version they were compiled with, providing greater compatibility.
Thus, if the list of supported runtimes includes CLR version 1.1, CLR version 2.0, and CLR version 4, an assembly that was compiled with CLR version 1.1 or CLR version 2.0 is loaded by using CLR version 2.0 by default.An assembly that is compiled with CLR version 4 is loaded by using CLR version 4.
Note
In-process side-by-side execution of managed COM components enables CLR version 4 to run in-process with either CLR version 1.1 or CLR version 2.0.See Side-by-Side Execution for COM Interop.
If you want to use CLR version 4 to load an assembly that was created with CLR version 1.1 or 2.0, include version 4 in the list of supported runtimes and set the useLegacyV2RuntimeActivationPolicy attribute to true.This enables the .NET Framework version 2.0 activation policy, which loads the assembly using the highest supported CLR version.
ciao Frank -
Frank,
Die Dokumentation ist unvollständig und wahrscheinlich nicht aktuell. Das Attribut useLegacyV2RuntimeActivationPolicy hat Relevanz nur wenn die Anwendung:
- globale statischen Hosting-Funktionen verwendet
- globale statistische Funktionen für Signierung mit starkem Namen verwendet
- die Funktion CoCreateInstance aus nativem Code aufruft
- verwalteten Code verwendet, der COM-Interop erledigt
Eine vollständigere Liste kann im unten verlinkten Artikel des CLR Teams nachgelesen werden. Wenn die o.g. Bedingungen nicht zutreffen, hat die Verwendung von useLegacyV2RuntimeActivationPolicy keine Auswirkung ("the highlighted portion [useLegacyV2RuntimeActivationPolicy] is required only if the application depends on functionality from Figure 1 [s. Liste oben]").CLR-Team Blog: In-Proc SxS and Migration Quick Start
http://blogs.msdn.com/b/clrteam/archive/2010/06/23/in-proc-sxs-and-migration-quick-start.aspx
Marcel -
Hallo Marcel,
betrifft: ... Relevanz von useLegacyV2RuntimeActivationPolicy nur in bestimmten Situationen ...
ja, genau, deswegen auch meine Ergänzung - ich erwähnte ja, das das Attribut nicht "immer" notwendig ist. Und dass die Doku da nur die Essenzen widergibt, ist schon in vielen meiner Links thematisiert, ist aber IMHO ok, da das den Rahmen einer Doku sprengen würde und in Blogs richtig ausführlich beschrieben werden kann. Ein paar Zitate aus Deinem Link u.a. ja auch:Thus, if you were migrating a .NET 3.5 application to .NET 4, your configuration file might look like this:
<configuration>
<startup useLegacyV2RuntimeActivationPolicy="true">
<supportedRuntime version="v4.0"/>
</startup>
</configuration>oder:
Migration Decision Tree
Use the following decision tree to decide the correct migration path for your component in the most common scenarios.
Binary Migration Examples
Application: Target v2 and v4
Create an application configuration file with the following contents, where the highlighted portion is required only if the application depends on functionality from Figure 1:
<configuration>
<startup useLegacyV2RuntimeActivationPolicy="true">
<supportedRuntime version="v4.0"/>
<supportedRuntime version="v2.0.50727"/>
</startup>
</configuration>
ciao Frank -
Hallo Frank,
Der Vollständigkeit halber noch ein Zitat aus dem CLR Team Blog:
In the vast majority of cases it is simple to migrate an application to run on .NET Framework 4: [...] if you are migrating an application without recompiling, create or update the application configuration file to target .NET 4.For example, the following is the recommended <startup> section to use when migrating an application that targets .NET 3.5 to also target .NET 4:<?xml version ="1.0"?> <configuration> <startup> <supportedRuntime version="v4.0"/> <supportedRuntime version="v2.0.50727"/> </startup> </configuration>
Wie Du siehst: Ohne useLegacyV2RuntimeActivationPolicy-Attribut geht es auch.
Gruß
Marcel -
Hallo Marcel,
genau, kurz zusammengefasst ... man braucht nicht immer das Attribut (wie ich ja mehrfach erwähnte) aber in einigen Fällen muss eben useLegacyV2RuntimeActivationPolicy benutzt werden und man braucht dann auch kein Invoke. Dass die Doku hier von "nicht ausreichend" ohne das Attribut spricht, ist IMHO eher so gemeint, dass es eben auch Fälle geben "kann", wo es dann zu einem Ladefehler führt, ergo das Attribut gesetzt werden sollte. Wenn man sich sicher ist, dass diese Fälle nicht vorhanden sind, kann man das Attribut weglassen.
ciao Frank -
Hallo Frank,
Darum liebe ich Forums-Diskussionen: Am Ende stehen alle als Sieger da und wissen mehr. Das ist doch letztlich der wahre Sinn eines Forums.
siehe auch: H .v. Kleist - Über die allmähliche Verfertigung der Gedanken beim RedenGruß
Marcel