{"id":759,"date":"2012-09-08T22:51:39","date_gmt":"2012-09-08T21:51:39","guid":{"rendered":"http:\/\/minibrain.wordpress.com\/?p=759"},"modified":"2012-09-08T22:51:39","modified_gmt":"2012-09-08T21:51:39","slug":"system-io-fileloadexception-verwenden-von-net-2-0-assemblies-innerhalb-eines-net-4-0-prozesses","status":"publish","type":"post","link":"https:\/\/abramowitsch.de\/blog\/?p=759","title":{"rendered":"System.IO.FileLoadException: Verwenden von .NET 2.0 Assemblies innerhalb eines .NET 4.0 Prozesses"},"content":{"rendered":"<p>Verwendet eine .NET 4.0 Assembly .NET 2.0 Komponenten, kommt es zu einer System.IO.FileLoadException mit der detaillierten Meldung \u201eDie Assembly im gemischten Modus wurde w\u00e4hrend Version v2.0.50727 der Laufzeit erstellt und kann nicht w\u00e4hrend der 4.0-Laufzeit ohne zus\u00e4tzliche Konfigurationsinformationen geladen werden.\u201c:<\/p>\n<p><a href=\"http:\/\/abramowitsch.de\/blog\/wp-content\/uploads\/2012\/09\/fileloadexception.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-760\" title=\"FileLoadException\" src=\"http:\/\/abramowitsch.de\/blog\/wp-content\/uploads\/2012\/09\/fileloadexception.png\" alt=\"\" width=\"452\" height=\"267\" srcset=\"https:\/\/abramowitsch.de\/blog\/wp-content\/uploads\/2012\/09\/fileloadexception.png 452w, https:\/\/abramowitsch.de\/blog\/wp-content\/uploads\/2012\/09\/fileloadexception-300x177.png 300w\" sizes=\"auto, (max-width: 452px) 100vw, 452px\" \/><\/a><\/p>\n<p>Bei mir lag es einfach daran, dass ich eine UI-Bibliothek verwendete, die f\u00fcr die CLR 2.0 entwickelt wurde, w\u00e4hrend mein Hauptprojekt in .NET 4.0 entwickelt wurde.<\/p>\n<p>Es gibt mehrere M\u00f6glichkeiten, das Problem zu l\u00f6sen:<\/p>\n<p>&#8211;\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00dcber eine Konfigurationsdatei<\/p>\n<p>&#8211;\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00dcber das Konfigurierung der Aktivierung via Code<\/p>\n<p><strong>L\u00f6sungsm\u00f6glichkeit 1: via Konfigurationsdatei<\/strong><\/p>\n<p><em>&lt;startup useLegacyV2RuntimeActivationPolicy=&#8220;true&#8220;&gt;<\/em><br \/>\n<em> &lt;supportedRuntime version=&#8220;v4.0&#8243;\/&gt;<\/em><br \/>\n<em> &lt;\/startup&gt;<\/em><\/p>\n<p>Die app.config muss nat\u00fcrlich neben der ausf\u00fchrbaren Datei stehen.<\/p>\n<p>Beispiel:<\/p>\n<p>Ausf\u00fchrbare Datei: example.exe<br \/>\nKonfigurationsdatei: example.exe.config<\/p>\n<p>Mark Miller hat in einem <a href=\"http:\/\/www.marklio.com\/marklio\/PermaLink,guid,ecc34c3c-be44-4422-86b7-900900e451f9.aspx\">Blog-Beitrag<\/a> (als PDF:\u00a0<a href=\"http:\/\/abramowitsch.de\/blog\/wp-content\/uploads\/2012\/09\/marklio-what-is-uselegacyv2runtimeactivationpolicy-for_.pdf\">marklio &#8211; What is useLegacyV2RuntimeActivationPolicy for_<\/a>) beschrieben, wozu die useLegacyV2RuntimeActivationPolicy nun wirklich gut ist und was sie tut.<\/p>\n<p>Es gibt jedoch Anwendungsf\u00e4lle, f\u00fcr die man nicht einfach eine Konfigurationsdatei neben die ausf\u00fchrbare Datei legen kann. Ein Beispiel daf\u00fcr k\u00f6nnte sein, dass eine C-API oder eine COM-API zur Verf\u00fcgung gestellt wird. Dann kann nicht einfach der ausf\u00fchrbaren Datei, die die C-API verwendet, eine Konfigurationsdatei beigelegt werden.<\/p>\n<p><strong>L\u00f6sungsm\u00f6glichkeit 2: via Code<\/strong><\/p>\n<p>Im Blog von Reed Copsey bin ich auf einen interessanten Artikel gesto\u00dfen, der genau mein Problem l\u00f6st: <a href=\"http:\/\/reedcopsey.com\/2011\/09\/15\/setting-uselegacyv2runtimeactivationpolicy-at-runtime\/\">http:\/\/reedcopsey.com\/2011\/09\/15\/setting-uselegacyv2runtimeactivationpolicy-at-runtime\/<\/a><\/p>\n<p>Nachfolgend der Code, der f\u00fcr meine Belange (C-API) funktionierte. Jedoch ist die L\u00f6sung in Reed Copseys Blog explizit als inoffiziell gekennzeichnet.<\/p>\n<p>public static bool LegacyV2RuntimeEnabledSuccessfully { get; private set; }<\/p>\n<p>staticRuntimePolicyHelper()<\/p>\n<p>{<\/p>\n<p>ICLRRuntimeInfoclrRuntimeInfo = \u00a0\u00a0(ICLRRuntimeInfo)RuntimeEnvironment.GetRuntimeInterfaceAsObject(Guid.Empty, \u00a0typeof(ICLRRuntimeInfo).GUID);<\/p>\n<p>try<\/p>\n<p>{<\/p>\n<p>clrRuntimeInfo.BindAsLegacyV2Runtime();<\/p>\n<p>LegacyV2RuntimeEnabledSuccessfully = true;<\/p>\n<p>}<\/p>\n<p>catch (COMException)<\/p>\n<p>{<\/p>\n<p>\/\/ This occurs with an HRESULT meaning<\/p>\n<p>\/\/ &#8222;A different runtime was already bound to the legacy CLR version 2 activation policy.&#8220;<\/p>\n<p>LegacyV2RuntimeEnabledSuccessfully = false;<\/p>\n<p>}<\/p>\n<p>}<\/p>\n<p>[ComImport]<\/p>\n<p>[InterfaceType(ComInterfaceType.<strong>InterfaceIsIUnknown<\/strong>)]<\/p>\n<p>[Guid(&#8222;BD39D1D2-BA2F-486A-89B0-B4B0CB466891&#8220;)]<\/p>\n<p>private interface ICLRRuntimeInfo<\/p>\n<p>{<\/p>\n<p>void xGetVersionString();<\/p>\n<p>void xGetRuntimeDirectory();<\/p>\n<p>void xIsLoaded();<\/p>\n<p>void xIsLoadable();<\/p>\n<p>void xLoadErrorString();<\/p>\n<p>void xLoadLibrary();<\/p>\n<p>void xGetProcAddress();<\/p>\n<p>void xGetInterface();<\/p>\n<p>void xSetDefaultStartupFlags();<\/p>\n<p>void xGetDefaultStartupFlags();<\/p>\n<p>[MethodImpl(MethodImplOptions.<strong>InternalCall<\/strong>, MethodCodeType = MethodCodeType.<strong>Runtime<\/strong>)]<\/p>\n<p>void BindAsLegacyV2Runtime();<\/p>\n<p>}<\/p>\n<p>Interessanterweise wird ein statischer Konstruktor verwendet, der unmittelbar nach dem Laden der assembly ausgef\u00fchrt wird. Dadurch wird der Code implizit von der Runtime ausgef\u00fchrt und nicht explizit vom Programm selbst. Das sollte ausreichend gut dokumentiert werden, da potentiell nicht jeder im Team den Code sofort versteht und potentiell den Code als \u201eunn\u00fctz\u201c l\u00f6schen k\u00f6nnte \ud83d\ude09<\/p>\n<p>Die Eigenschaft &#8222;LegacyV2RuntimeEnabledSuccessfully&#8220; gibt an, ob das Umschalten der Runtime-Aktivierung funktioniert hatte. In meinem Fall habe ich eine Ausgabe f\u00fcr die API erstellt, die dem Benutzer angibt, wie er das Problem mithilfe der Konfigurationsdatei l\u00f6sen kann.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Verwendet eine .NET 4.0 Assembly .NET 2.0 Komponenten, kommt es zu einer System.IO.FileLoadException mit der detaillierten Meldung \u201eDie Assembly im gemischten Modus wurde w\u00e4hrend Version v2.0.50727 der Laufzeit erstellt und kann nicht w\u00e4hrend der 4.0-Laufzeit ohne zus\u00e4tzliche Konfigurationsinformationen geladen werden.\u201c: Bei mir lag es einfach daran, dass ich eine UI-Bibliothek verwendete, die f\u00fcr die CLR [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"jetpack_post_was_ever_published":false},"categories":[3],"tags":[126,55,91],"class_list":["post-759","post","type-post","status-publish","format-standard","hentry","category-net","tag-net","tag-interop","tag-uselegacyv2runtimeactivationpolicy"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p3Ug90-cf","_links":{"self":[{"href":"https:\/\/abramowitsch.de\/blog\/index.php?rest_route=\/wp\/v2\/posts\/759","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/abramowitsch.de\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/abramowitsch.de\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/abramowitsch.de\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/abramowitsch.de\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=759"}],"version-history":[{"count":0,"href":"https:\/\/abramowitsch.de\/blog\/index.php?rest_route=\/wp\/v2\/posts\/759\/revisions"}],"wp:attachment":[{"href":"https:\/\/abramowitsch.de\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=759"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/abramowitsch.de\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=759"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/abramowitsch.de\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=759"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}