@@ -192,6 +192,36 @@ Microsoft Analysis Services Projects (by Microsoft) v2.8.11 04a86fc2-dbd5-4222-8
192192 //given the version numbers seem to be changing frequently, try this approach to increment version numbers of references
193193 AppDomain currentDomain = AppDomain . CurrentDomain ;
194194 currentDomain . AssemblyResolve += new ResolveEventHandler ( currentDomain_AssemblyResolve ) ;
195+
196+
197+
198+
199+ try
200+ {
201+ MulticastDelegate handler = ( MulticastDelegate ) AppDomain . CurrentDomain . GetType ( ) . InvokeMember ( "_AssemblyResolve" , System . Reflection . BindingFlags . GetField | System . Reflection . BindingFlags . Instance | System . Reflection . BindingFlags . NonPublic , null , AppDomain . CurrentDomain , null ) ;
202+ System . Collections . Generic . List < object > invocationList = new System . Collections . Generic . List < object > ( handler . GetInvocationList ( ) ) ;
203+ int cnt = invocationList . Count ;
204+ for ( int i = 0 ; i < cnt ; i ++ )
205+ {
206+ System . ResolveEventHandler info = ( System . ResolveEventHandler ) invocationList [ i ] ;
207+ Log . Debug ( info . Method . ToString ( ) + " - " + info . Method . DeclaringType . ToString ( ) ) ;
208+ if ( info . Method . DeclaringType . FullName . StartsWith ( "Microsoft.DataWarehouse." ) ) //remove this event handler. We will call it from our AssemblyResolve code
209+ {
210+ Log . Debug ( "removed this AssemblyResolve event handler from the list and will call in our AssemblyResolve event handler" ) ;
211+ invocationList . RemoveAt ( i ) ;
212+ _microsoftEventHandlersToIgnoreErrors . Add ( info ) ;
213+ cnt -- ;
214+ i -- ;
215+ }
216+ }
217+
218+ typeof ( MulticastDelegate ) . InvokeMember ( "_invocationList" , System . Reflection . BindingFlags . NonPublic | System . Reflection . BindingFlags . FlattenHierarchy | System . Reflection . BindingFlags . Instance | System . Reflection . BindingFlags . SetField , null , handler , new object [ ] { invocationList . ToArray ( ) } ) ;
219+ typeof ( MulticastDelegate ) . InvokeMember ( "_invocationCount" , System . Reflection . BindingFlags . NonPublic | System . Reflection . BindingFlags . FlattenHierarchy | System . Reflection . BindingFlags . Instance | System . Reflection . BindingFlags . SetField , null , handler , new object [ ] { new IntPtr ( invocationList . Count ) } ) ;
220+ }
221+ catch
222+ {
223+
224+ }
195225#endif
196226
197227 StatusBar = new Core . VsIntegration . StatusBar ( this ) ;
@@ -655,6 +685,7 @@ System.Reflection.Assembly currentDomain_AssemblyResolve(object sender, ResolveE
655685#else
656686 string _recursiveAssemblyResolveNameToSkip = null ;
657687 System . Collections . Generic . List < string > _assemblyLoadsFailed = new System . Collections . Generic . List < string > ( ) ;
688+ System . Collections . Generic . List < System . ResolveEventHandler > _microsoftEventHandlersToIgnoreErrors = new System . Collections . Generic . List < ResolveEventHandler > ( ) ;
658689
659690 /// <summary>
660691 /// Only fires if an assembly fails to load. This gives us a chance to redirect to a DLL that does exist.
@@ -666,6 +697,22 @@ System.Reflection.Assembly currentDomain_AssemblyResolve(object sender, ResolveE
666697 {
667698 try
668699 {
700+ //we removed the Microsoft AssemblyResolve event handler from the list and are now calling theirs at the top of ours
701+ //we do this to swallow an error due to a bug in their AssemblyResolve event handler as of May 2020
702+ foreach ( System . ResolveEventHandler handler in _microsoftEventHandlersToIgnoreErrors )
703+ {
704+ try
705+ {
706+ Assembly a = handler . Invoke ( sender , args ) ;
707+ if ( a != null )
708+ return a ;
709+ }
710+ catch ( Exception ex )
711+ {
712+ Log . Debug ( "Caught error in Microsoft AssemblyResolve and skipped: " + ex . Message ) ;
713+ }
714+ }
715+
669716 if ( _recursiveAssemblyResolveNameToSkip == args . Name )
670717 return null ; //skip recursion
671718 Log . Debug ( "AssemblyResolve: " + args . Name ) ;
@@ -679,13 +726,36 @@ System.Reflection.Assembly currentDomain_AssemblyResolve(object sender, ResolveE
679726 )
680727 {
681728 var assemblyname = new AssemblyName ( args . Name ) ;
729+
730+ //first see if this assembly is loaded already... if so, don't scan folders for an assembly... just reuse the previously loaded assembly
731+ foreach ( Assembly loadedAlready in AppDomain . CurrentDomain . GetAssemblies ( ) )
732+ {
733+ if ( loadedAlready . GetName ( ) . Name == assemblyname . Name
734+ && loadedAlready . GetName ( ) . Version . Major == assemblyname . Version . Major )
735+ return loadedAlready ;
736+ }
737+
682738 System . Collections . Generic . List < string > pathsToCheck = new System . Collections . Generic . List < string > ( ) ;
683739 var bidsHelperPath = new System . IO . FileInfo ( typeof ( BIDSHelperPackage ) . Assembly . Location ) ;
684740 pathsToCheck . Add ( bidsHelperPath . DirectoryName + "\\ " ) ;
685741 if ( SSASExtensionInstallPath != null ) pathsToCheck . Add ( SSASExtensionInstallPath ) ;
686742 if ( SSISExtensionInstallPath != null ) pathsToCheck . Add ( SSISExtensionInstallPath ) ;
687743 if ( SSRSExtensionInstallPath != null ) pathsToCheck . Add ( SSRSExtensionInstallPath ) ;
688744 if ( BISharedExtensionInstallPath != null ) pathsToCheck . Add ( BISharedExtensionInstallPath ) ;
745+
746+ //if (SSISExtensionInstallPath != null)
747+ //{
748+ // foreach (string sPath in System.IO.Directory.GetFiles(SSISExtensionInstallPath, assemblyname.Name + ".dll", System.IO.SearchOption.AllDirectories))
749+ // {
750+ // if (!sPath.ToUpper().Contains("\\BISHARED\\")) continue;
751+ // var assembly = Assembly.Load(System.IO.File.ReadAllBytes(sPath));
752+ // if (assembly.GetName().Version.Major == assemblyname.Version.Major) //some SSIS subfolders have multiple versions of the assembly... make sure we match the major version number... it appears there may be an assembly redirect in operation, but this is probably safer
753+ // {
754+ // Log.Debug("AssemblyResolveSuccessSSIS-BIShared: " + args.Name + " to version " + assembly.GetName().Version.ToString() + " at " + sPath + " in " + DateTime.Now.Subtract(dtStart).TotalMilliseconds + "ms");
755+ // return assembly;
756+ // }
757+ // }
758+ //}
689759 foreach ( string extensionfolder in pathsToCheck )
690760 {
691761 string sPath = extensionfolder + assemblyname . Name + ".dll" ;
@@ -700,6 +770,7 @@ System.Reflection.Assembly currentDomain_AssemblyResolve(object sender, ResolveE
700770 {
701771 foreach ( string sPath in System . IO . Directory . GetFiles ( SSISExtensionInstallPath , assemblyname . Name + ".dll" , System . IO . SearchOption . AllDirectories ) )
702772 {
773+ //if (sPath.ToUpper().Contains("\\BISHARED\\")) continue;
703774 var assembly = Assembly . Load ( System . IO . File . ReadAllBytes ( sPath ) ) ;
704775 if ( assembly . GetName ( ) . Version . Major == assemblyname . Version . Major ) //some SSIS subfolders have multiple versions of the assembly... make sure we match the major version number... it appears there may be an assembly redirect in operation, but this is probably safer
705776 {
0 commit comments