2017-03-21 3 views
1

Microsoft.SqlServer.Smoアセンブリを参照する.NETアプリケーションがあります。 アセンブリはアプリケーションとともに配布されません。代わりにsql sdkがシステムにインストールされ、dllがGACに登録され、アプリケーションがロードできるようになります。 一部のターゲットマシンではSDKのv12があるのに対し、他のプラットフォームではSDKのv13(通常はSSMSにインストールされています)がある点を除いては問題ありません。 私はシステム上で利用可能なものの最新バージョンを読み込むようにしたいので、v13か、利用できない場合はv12をロードしてください。 これをコードで実行することも、アプリケーションの設定で実行することも可能ですか?.netアセンブリの最新バージョンをロードします。

+0

だけターゲット・マシンのようにGACにMicrosoft.SqlServer.Smoアセンブリで構成された開発マシン/ビルドマシンですか? – sevzas

+0

はい私の開発マシンは、GACのv11、v12、v13を持っています – gigi

+1

あなたの.csprojファイルでSmoアセンブリへの参照のSpecificVersionプロパティをfalseに設定するのがいいようです。この回答が役立つかどうかを確認するhttp://stackoverflow.com/questions/1063459/net-reference-specificversion-true-or-false – sevzas

答えて

0

質問に対する簡単な答えは、@sevzasが正しく示唆しているように、SpecificVersionをfalseに設定することです。

とにかく、システムにSSMS 2016アップデート13.0.16000.28がインストールされている場合、DLLの13.100.0.0がGACに登録され、上記の変更でロードされるバージョンです。残念ながら、このバージョンはサードパーティの開発者がMicrosoft製品だけで使用するためのものではないため、ロードしようとすると例外(see here)が生成されます。この時点で、なぜ人々がGACにそれを使用したくないのであれば、それをGACに登録するのか、誰かが不思議に思います。

とにかく、アセンブリ解決イベントを使用して、以下のコードでv13.0(またはそれ以前、または将来の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; 
    } 

`` `

関連する問題