Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/321.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何加载.NET程序集的旧版本?_C#_.net - Fatal编程技术网

C# 如何加载.NET程序集的旧版本?

C# 如何加载.NET程序集的旧版本?,c#,.net,C#,.net,我有一个引用.NET4.0程序集的WPF/C应用程序。但是,应用程序中有一个文本编辑器,需要显示与.NET3.5程序集关联的C#intellisense。因此,我希望能够在运行时加载适当的.NET 3.5程序集。但是,当我尝试使用: Assembly.Load() Assembly.LoadFile() Assembly.LoadFrom() 我总是从GAC那里得到最新版本。阅读他们的MSDN页面,似乎这是出于设计 我试着按照这篇文章中提出的解决方案来做。然而,链接网页的解决方案不起作用,远程

我有一个引用.NET4.0程序集的WPF/C应用程序。但是,应用程序中有一个文本编辑器,需要显示与.NET3.5程序集关联的C#intellisense。因此,我希望能够在运行时加载适当的.NET 3.5程序集。但是,当我尝试使用:

Assembly.Load()
Assembly.LoadFile()
Assembly.LoadFrom()
我总是从GAC那里得到最新版本。阅读他们的MSDN页面,似乎这是出于设计


我试着按照这篇文章中提出的解决方案来做。然而,链接网页的解决方案不起作用,远程处理过程似乎有些过火。有人知道在运行时加载较旧的.NET程序集的更好和/或更简单的方法吗?

默认情况下,您不能在.NET framework版本4上加载为.NET framework早期版本制作的程序集

但是,有一个配置属性允许:

在app.config文件中放入以下行:

<configuration>
    <startup useLegacyV2RuntimeActivationPolicy="true|false" > 
    </startup>
</configuration>


这在默认情况下不处于活动状态是有原因的,但我相信它应该适合您的使用。

我以前做过这件事,尽管是从GAC中没有的程序集中做的:我的程序集是从字节数组加载的,但我很容易就可以拥有同一程序集的不同版本

解决方案是处理AppDomain的AssemblyResolve事件,以便确保返回所需的程序集。在您的情况下,这可能相当简单,因为您只关心在执行此特定调用时。剩下的时间,您将使用默认值,而根本不处理该值

一个可能的例子可能是:

public DoSomething()
{
    //Add the handler
    AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve

    //Load your assembly...
}

private System.Reflection.Assembly CurrentDomain_AssemblyResolve(Object sender, ResolveEventArgs e)
{
    foreach (System.Reflection.Assembly a In AppDomain.CurrentDomain.GetAssemblies())
    {
       if (a.FullName == <<The one you need>>) return a
    }
}
public DoSomething()
{
//添加处理程序
AppDomain.CurrentDomain.AssemblyResolve+=CurrentDomain_AssemblyResolve
//加载你的程序集。。。
}
private System.Reflection.Assembly CurrentDomain_AssemblyResolve(对象发送方,ResolveEventArgs e)
{
foreach(AppDomain.CurrentDomain.GetAssembly()中的System.Reflection.Assembly a)
{
如果(a.FullName==)返回
}
}
这是相当粗糙的,但它会给出一个过程的概念-您处理assemblyresolve,并返回所需的内容。处理程序的内容可能会有所不同,因为我不确定您的程序集是否会出现在
CurrentDomain.getAssemblys()列表中

可能还有更微妙的assmeblyresolve示例可以为您处理GAC版本


注意:这是在.NET3.5中使用的,而不是在4中,但在不同的版本中确实有效。您可能需要@Jean的解决方案来在4中加载3.5个程序集。

我发现的一个部分解决方案是使用Assembly.ReflectionOnlyLoadFrom()。此方法正确加载较旧版本的程序集,尽管程序集加载到仅反射的上下文中,这意味着您无法在程序集中执行代码。虽然这不是真正的程序集加载,但它确实支持我正在处理的大多数intellisense场景


一个挥之不去的问题是mscorlib。尝试使用从ReflectionOnlyLoadFrom返回的程序集时,对于旧版本的mscorlib,会引发异常:“System.TypeLoadException:无法从程序集'mscorlib'加载类型'System.Object',版本=4.0.0.0,区域性=中性,PublicKeyToken=b77a5c561934e089',因为父级不存在。”

您可以在app.config或web.config中使用AssemblyBinding属性,以适当的为准

例如,我正在与Matlab接口,所以我需要这个

<loadFromRemoteSources enabled="true" />
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
        <dependentAssembly>
            <assemblyIdentity name="MWArray" publicKeyToken="E1D84A0DA19DB86F" culture="neutral" />
            <bindingRedirect oldVersion="0.0.0.0-2.10.0.0" newVersion="2.10.0.0" />
        </dependentAssembly>
    </assemblyBinding>

因为我使用的Matlab引擎是在机器上使用运行时的不同副本编译的(有些疯狂的方式)


您应该能够修改此代码以满足您的需要。

我使用ReflectionOnlyLoadFrom()解决了此问题,以只读模式加载所需版本的程序集,以便仅与reflection一起使用。当您无法为mscorlib执行此操作时(您可以要求2.0,但您将从调用中获得4.0),我通过根据需要的版本过滤返回的类型来处理此问题。毕竟,在这种模式下,您只能使用反射检查DLL中的类型,而不能对它们执行任何其他操作,因此您可以根据需要轻松筛选返回的类型列表

以下是我从mscorlib 4.0中筛选出来的类型,以便在需要旧版本的mscorlib时一切正常:

    /// <summary>
    /// Types to be hidden from .NET mscorlib 4.0 for older versions.
    /// </summary>
    protected static readonly HashSet<Type> HideMscorlib4Types = new HashSet<Type>
        {
            // The Action delegates with 0, 2, 3, 4 type parameters were moved from System.Core 3.5 to mscorlib for 4.0
            typeof(Action), typeof(Action<,>), typeof(Action<,,>), typeof(Action<,,,>),

            // The Func delegates with 1 to 5 type parameters were moved from System.Core 3.5 to mscorlib for 4.0
            typeof(Func<>), typeof(Func<,>), typeof(Func<,,>), typeof(Func<,,,>), typeof(Func<,,,,>),

            // Other types moved from System.Core 3.5 to mscorlib 4.0
            typeof(TimeZoneInfo),

            // Hide various types that were new in mscorlib 4.0
            typeof(Tuple)
        };
//
///对于较旧版本,要对.NET mscorlib 4.0隐藏的类型。
/// 
受保护的静态只读哈希集HIDEMSCRIB4TYPES=新哈希集
{
//具有0、2、3、4类型参数的动作代理已从System.Core 3.5移动到4.0的mscorlib
类型(动作),类型(动作),类型(动作),类型(动作),类型(动作),
//具有1到5个类型参数的Func委托已从System.Core 3.5移动到4.0的mscorlib
typeof(Func)、typeof(Func)、typeof(Func)、typeof(Func)、typeof(Func),
//其他类型从System.Core 3.5迁移到mscorlib 4.0
类型(时区信息),
//隐藏mscorlib 4.0中新增的各种类型
类型(元组)
};

这将允许加载较旧的框架组件;但如果GAC中有一个更新的版本,那就没用了。.NET Framework将始终希望加载它可以加载的最新版本。该启动属性仅与包含本机代码的程序集相关,C++/CLI将创建这些程序集。版本4 CLR加载针对早期.NET版本的纯MSIL程序集没有问题。我实际上尝试过这种方法,但事件处理程序从未启动。顺便说一句,这在configHi Mel的部分中,我尝试将MatLab与Web.API一起使用(作为单独的项目附加)但经常会出现同样的错误:无法初始化MATLAB运行时实例\n SGV-严重错误只有在将API部署到IIS时才会发生(在va上尝试了7.5和8.5)