C# .net加载程序集的最新版本

C# .net加载程序集的最新版本,c#,.net,sql-server,app-config,smo,C#,.net,Sql Server,App Config,Smo,我有一个引用Microsoft.SqlServer.Smo程序集的.net应用程序。 程序集不随应用程序一起分发。相反,sql sdk安装在系统中,dll注册在GAC中,以便应用程序可以加载。 这没有问题,除了在一些目标机器上我有SDK的v12,而在其他机器上我有SDK的v13(通常随SSM一起安装)。 我希望应用程序能够加载系统上可用的最新版本,因此v13或v12(如果不可用)。 是否可以在代码中或通过应用程序配置实现这一点?问题的简短答案是按照@sevzas的正确建议,将SpecificVe

我有一个引用Microsoft.SqlServer.Smo程序集的.net应用程序。 程序集不随应用程序一起分发。相反,sql sdk安装在系统中,dll注册在GAC中,以便应用程序可以加载。 这没有问题,除了在一些目标机器上我有SDK的v12,而在其他机器上我有SDK的v13(通常随SSM一起安装)。 我希望应用程序能够加载系统上可用的最新版本,因此v13或v12(如果不可用)。
是否可以在代码中或通过应用程序配置实现这一点?

问题的简短答案是按照@sevzas的正确建议,将SpecificVersion设置为false

无论如何,如果在系统上安装了SSMS 2016 update 13.0.16000.28,则dll的13.100.0.0将在GAC中注册,并进行上述更改,这是将加载的版本。不幸的是,此版本不适用于第三方开发人员,而仅适用于Microsoft产品,因此尝试加载它将生成异常()。有人可能会在这一点上感到奇怪,如果他们不想让人们使用它,为什么他们会在GAC中注册它

无论如何,我找到了一种使用assembly resolve事件加载v13.0(或更早版本,或future 14)和以下代码的方法

    static int Main(string[] args)
    {
        //we set an event handler at the begging of our program
        AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
        //your stuff
    }

    private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
    {
        //if the dll is a sqlserver dll, we do our trick
        if(args.Name.StartsWith("Microsoft.SqlServer"))
            return LoadSqlAssembly(args.Name);

        return null;
    }

    private static readonly int[] SqlVersions = new int[] {14, 13, 12, 11};

    private static bool _reEntry = false;

    private static Assembly LoadSqlAssembly(string name)
    {
        if (_reEntry)
            return null;

        name = name.Split(',')[0];

        foreach (var version in SqlVersions)
        {
            try
            {
                _reEntry = true;
                var ret = Assembly.Load($"{name}, Version={version}.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=MSIL");
                //Logger.InfoFormat("Loaded {0} version {1}", name, version);
                return ret;
            }
            catch (Exception)
            {
                //ignore exception
            }
            finally
            {
                _reEntry = false;
            }
        }

        return null;
    }

```问题的简短答案是将specific version设置为false,正如@sevzas正确建议的那样

无论如何,如果在系统上安装了SSMS 2016 update 13.0.16000.28,则dll的13.100.0.0将在GAC中注册,并进行上述更改,这是将加载的版本。不幸的是,此版本不适用于第三方开发人员,而仅适用于Microsoft产品,因此尝试加载它将生成异常()。有人可能会在这一点上感到奇怪,如果他们不想让人们使用它,为什么他们会在GAC中注册它

无论如何,我找到了一种使用assembly resolve事件加载v13.0(或更早版本,或future 14)和以下代码的方法

    static int Main(string[] args)
    {
        //we set an event handler at the begging of our program
        AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
        //your stuff
    }

    private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
    {
        //if the dll is a sqlserver dll, we do our trick
        if(args.Name.StartsWith("Microsoft.SqlServer"))
            return LoadSqlAssembly(args.Name);

        return null;
    }

    private static readonly int[] SqlVersions = new int[] {14, 13, 12, 11};

    private static bool _reEntry = false;

    private static Assembly LoadSqlAssembly(string name)
    {
        if (_reEntry)
            return null;

        name = name.Split(',')[0];

        foreach (var version in SqlVersions)
        {
            try
            {
                _reEntry = true;
                var ret = Assembly.Load($"{name}, Version={version}.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=MSIL");
                //Logger.InfoFormat("Loaded {0} version {1}", name, version);
                return ret;
            }
            catch (Exception)
            {
                //ignore exception
            }
            finally
            {
                _reEntry = false;
            }
        }

        return null;
    }

```

您的开发机器/构建机器在GAC中配置了Microsoft.SqlServer.Smo程序集,与目标机器一样吗?是的,我的开发机器在GAC表中配置了v11、v12和v13,方法是在.csproj文件中将Smo程序集引用的SpecificVersion属性设置为false。如果出于某种原因在我的开发计算机上这样做,请查看此答案是否有帮助:{“无法加载文件或程序集”Microsoft.SqlServer.Smo,Version=13.100.0.0,Culture=neutral,PublicKeyToken=89845dcd80cc91“或其依赖项之一。系统找不到指定的文件。”:“Microsoft.SqlServer.Smo,Version=13.100.0.0,Culture=neutral,PublicKeyToken=89845dcd8080cc91”}该错误消息是否在生成时或运行时出现?您能否编辑您的问题并发布.csproj中引用Smo dll的行?您是否确保您的计算机上没有Smo dll的副本(GAC中除外)?您的开发机器/构建机器在GAC中配置了Microsoft.SqlServer.Smo程序集吗?与目标机器一样?是的,我的开发机器在GAC中配置了v11、v12和v13,方法是在.csproj文件中将Smo程序集引用的SpecificVersion属性设置为false。如果我由于某种原因,在我的开发计算机上执行此操作会出现异常:{“无法加载文件或程序集'Microsoft.SqlServer.Smo,Version=13.100.0.0,Culture=neutral,PublicKeyToken=89845dcd8080cc91'或其依赖项之一。系统找不到指定的文件。”:“Microsoft.SqlServer.Smo,Version=13.100.0.0,Culture=neutral,PublicKeyToken=89845dcd8080cc91“}该错误消息是否在生成时或运行时出现?您是否可以编辑您的问题并发布.csproj中引用Smo dll的行?您是否确保您的计算机上没有Smo dll的副本(GAC中除外)?