none
Framework 4.0 ByteViewer RRS feed

  • Frage

  • Hallo,

    gibt es den  ByteViewer im 4.0 nicht mehr?

    Oder wo kann ich den finden?

    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?

    Danke

    Samstag, 11. Dezember 2010 23:56

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)

    Sonntag, 12. Dezember 2010 00:04
  • 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
    Sonntag, 12. Dezember 2010 07:19
  • 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

    Sonntag, 12. Dezember 2010 16:19
    Moderator

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)

    Sonntag, 12. Dezember 2010 00:04
  • 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
    Sonntag, 12. Dezember 2010 07:19
  • 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

    Sonntag, 12. Dezember 2010 16:19
    Moderator
  • 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
    Sonntag, 12. Dezember 2010 17:06
  • 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

    Sonntag, 12. Dezember 2010 17:25
    Moderator
  • 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 
    Sonntag, 12. Dezember 2010 18:47
  • 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

    Sonntag, 12. Dezember 2010 19:55
    Moderator
  • 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.

    NoteNote

    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
    Sonntag, 12. Dezember 2010 21:28
  • 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

    Montag, 13. Dezember 2010 08:09
    Moderator
  • 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. 

    decision_tree

     

    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

    Montag, 13. Dezember 2010 09:01
  • 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

    Montag, 13. Dezember 2010 09:12
    Moderator
  • 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

    Montag, 13. Dezember 2010 09:22
  • 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 Reden

    Gruß
    Marcel

    Montag, 13. Dezember 2010 10:35
    Moderator