1515using System . Linq ;
1616using Microsoft . VisualStudio ;
1717using BIDSHelper . Core . Logger ;
18+ using Task = System . Threading . Tasks . Task ;
1819
1920namespace BIDSHelper
2021{
@@ -43,17 +44,17 @@ public enum enumIDEMode
4344 /// To get loaded into VS, the package must be referred by <Asset Type="Microsoft.VisualStudio.VsPackage" ...> in .vsixmanifest file.
4445 /// </para>
4546 /// </remarks>
46- [ ProvideAutoLoad ( "f1536ef8-92ec-443c-9ed7-fdadf150da82" ) ]
47+ [ ProvideAutoLoad ( "f1536ef8-92ec-443c-9ed7-fdadf150da82" , PackageAutoLoadFlags . BackgroundLoad ) ]
4748 //[ProvideAutoLoad(UIContextGuids80.SolutionExists)]
48- [ PackageRegistration ( UseManagedResourcesOnly = true ) ]
49+ [ PackageRegistration ( UseManagedResourcesOnly = true , AllowsBackgroundLoading = true ) ]
4950 [ InstalledProductRegistration ( "#110" , "#112" , VersionInfo . Version , IconResourceID = 400 ) ] // Info on this package for Help/About
5051 [ Guid ( BIDSHelperPackage . PackageGuidString ) ]
5152 [ SuppressMessage ( "StyleCop.CSharp.DocumentationRules" , "SA1650:ElementDocumentationMustBeSpelledCorrectly" , Justification = "pkgdef, VS and vsixmanifest are valid VS terms" ) ]
5253 [ ProvideMenuResource ( "Menus.ctmenu" , 1 ) ]
5354 [ ProvideOptionPage ( typeof ( BIDSHelperOptionsFeatures ) , "BIDS Helper" , "Features" , 0 , 0 , true ) ]
5455 [ ProvideOptionPage ( typeof ( BIDSHelperPreferencesDialogPage ) , "BIDS Helper" , "Preferences" , 0 , 0 , true ) ]
5556 [ ProvideOptionPage ( typeof ( BIDSHelperOptionsVersion ) , "BIDS Helper" , "Version" , 0 , 0 , true ) ]
56- public sealed class BIDSHelperPackage : Package , IVsDebuggerEvents
57+ public sealed class BIDSHelperPackage : AsyncPackage , IVsDebuggerEvents
5758 {
5859 /// <summary>
5960 /// BidsHelperPackage GUID string.
@@ -75,15 +76,30 @@ public BIDSHelperPackage()
7576 // not sited yet inside Visual Studio environment. The place to do all the other
7677 // initialization is the Initialize method.
7778 }
78-
79+
7980
8081 #region Package Members
8182
8283 /// <summary>
8384 /// Initialization of the package; this method is called right after the package is sited, so this is the place
8485 /// where you can put all the initialization code that rely on services provided by VisualStudio.
8586 /// </summary>
86- protected override void Initialize ( )
87+ protected override async Task InitializeAsync ( System . Threading . CancellationToken cancellationToken , IProgress < ServiceProgressData > progress )
88+ //protected override void Initialize()
89+ {
90+ // runs in the background thread and doesn't affect the responsiveness of the UI thread.
91+ //await Task.Delay(100);
92+
93+ // Switches to the UI thread in order to consume some services used in command initialization
94+ await JoinableTaskFactory . SwitchToMainThreadAsync ( cancellationToken ) ;
95+
96+
97+
98+ OriginalInitialize ( ) ;
99+
100+ }
101+
102+ private void OriginalInitialize ( )
87103 {
88104 bool bQuitting = false ;
89105 base . Initialize ( ) ;
@@ -96,6 +112,67 @@ protected override void Initialize()
96112 Log . LogLevel = LogLevels . Warning ;
97113#endif
98114 Log . Debug ( "BIDSHelper Package Initialize Starting" ) ;
115+
116+
117+ //var bidsHelperPath = new System.IO.FileInfo(typeof(BIDSHelperPackage).Assembly.Location);
118+
119+ //#pragma warning disable 0618 //ignore the fact this is an obsolete method
120+ // AppDomain.CurrentDomain.AppendPrivatePath(bidsHelperPath.DirectoryName);
121+ // AppDomain.CurrentDomain.SetupInformation.ApplicationBase = bidsHelperPath.DirectoryName;
122+ //#pragma warning restore 0618
123+
124+ //(AppDomain.CurrentDomain.SetupInformation.PrivateBinPath + ";" ?? "") +
125+ /*
126+ * VS2019
127+ * Microsoft Reporting Services Projects (by Microsoft) v2.5.6 717ad572-c4b7-435c-c166-c2969777f718
128+ Microsoft Analysis Services Projects (by Microsoft) v2.8.11 04a86fc2-dbd5-4222-848e-911638e487fe
129+
130+ VS2017
131+ Microsoft Reporting Services Projects (by Microsoft) v2.5.6 717ad572-c4b7-435c-c166-c2969777f718
132+ Microsoft Integration Services Projects (by Microsoft) v2.1 D1B09713-C12E-43CC-9EF4-6562298285AB
133+ Microsoft Analysis Services Projects (by Microsoft) v2.8.11 04a86fc2-dbd5-4222-848e-911638e487fe
134+
135+ */
136+ try
137+ {
138+ System . IServiceProvider serviceProvider = this as System . IServiceProvider ;
139+ Microsoft . VisualStudio . ExtensionManager . IVsExtensionManager em =
140+ ( Microsoft . VisualStudio . ExtensionManager . IVsExtensionManager ) serviceProvider . GetService (
141+ typeof ( Microsoft . VisualStudio . ExtensionManager . SVsExtensionManager ) ) ;
142+
143+ string result = "" ;
144+ foreach ( Microsoft . VisualStudio . ExtensionManager . IInstalledExtension i in em . GetInstalledExtensions ( ) )
145+ {
146+ try
147+ {
148+ Microsoft . VisualStudio . ExtensionManager . IExtensionHeader h = i . Header ;
149+ if ( ! h . SystemComponent )
150+ {
151+ if ( h . Name == "Microsoft Reporting Services Projects" || string . Compare ( h . Identifier , "717ad572-c4b7-435c-c166-c2969777f718" , true ) == 0 )
152+ {
153+ SSRSExtensionVersion = h . Version ;
154+ Log . Debug ( "SSRS extension v" + h . Version + " is installed" ) ;
155+ }
156+ else if ( h . Name == "Microsoft Integration Services Projects" || string . Compare ( h . Identifier , "D1B09713-C12E-43CC-9EF4-6562298285AB" , true ) == 0 )
157+ {
158+ SSISExtensionVersion = h . Version ;
159+ Log . Debug ( "SSIS extension v" + h . Version + " is installed" ) ;
160+ }
161+ else if ( h . Name == "Microsoft Analysis Services Projects" || string . Compare ( h . Identifier , "04a86fc2-dbd5-4222-848e-911638e487fe" , true ) == 0 )
162+ {
163+ SSASExtensionVersion = h . Version ;
164+ Log . Debug ( "SSAS extension v" + h . Version + " is installed" ) ;
165+ }
166+ result += h . Name + " (by " + h . Author + ") v" + h . Version + " " + h . Identifier + " " + h . MoreInfoUrl + System . Environment . NewLine ;
167+ }
168+ }
169+ catch { }
170+ }
171+ Log . Debug ( result ) ;
172+ }
173+ catch { }
174+
175+
99176 string sAddInTypeName = string . Empty ;
100177 try
101178 {
@@ -128,9 +205,20 @@ protected override void Initialize()
128205 catch ( ReflectionTypeLoadException loadEx )
129206 {
130207 types = loadEx . Types ; //if some types can't be loaded (possibly because SSIS SSDT isn't installed, just SSAS?) then proceed with the types that work
131- pluginExceptions . Add ( loadEx ) ;
132- Log . Exception ( "Problem loading BIDS Helper types list" , loadEx ) ;
208+ //pluginExceptions.Add(loadEx); //in testing it appears that this does return the complete list of types so there's no need to display this exception to the user, I don't think since we will individually load plugins below and log exceptions
209+ //Log.Exception("Problem loading BIDS Helper types list", loadEx);
210+ //Log.Error(FormatLoaderException(loadEx));
133211 }
212+ Log . Debug ( $ "Found { types . Length } types") ;
213+
214+ //can be used for debugging which types couldn't be loaded above
215+ //for (int i = 0; i < types.Length; i++)
216+ //{
217+ // if (types[i] == null)
218+ // Log.Error("types[" + i + "] is null");
219+ // else
220+ // Log.Debug("types[" + i + "]\t" + types[i].FullName);
221+ //}
134222
135223 foreach ( Type t in types )
136224 {
@@ -141,6 +229,37 @@ protected override void Initialize()
141229 && ( ! t . IsAbstract ) )
142230 {
143231 sAddInTypeName = t . Name ;
232+
233+ //new... only load SSIS to test this works
234+ //load any not marked
235+ var categoryAttribute = t . GetCustomAttributes ( typeof ( FeatureCategory ) , true ) . FirstOrDefault ( ) as FeatureCategory ;
236+ if ( categoryAttribute != null )
237+ {
238+ if ( SSISExtensionVersion == null && categoryAttribute . Category == BIDSFeatureCategories . SSIS )
239+ {
240+ Log . Verbose ( string . Format ( "Skipping Plugin: {0}" , sAddInTypeName ) ) ;
241+ continue ;
242+ }
243+ else if ( SSASExtensionVersion == null && ( categoryAttribute . Category == BIDSFeatureCategories . SSASMulti || categoryAttribute . Category == BIDSFeatureCategories . SSASTabular ) )
244+ {
245+ Log . Verbose ( string . Format ( "Skipping Plugin: {0}" , sAddInTypeName ) ) ;
246+ continue ;
247+ }
248+ else if ( SSRSExtensionVersion == null && categoryAttribute . Category == BIDSFeatureCategories . SSRS )
249+ {
250+ Log . Verbose ( string . Format ( "Skipping Plugin: {0}" , sAddInTypeName ) ) ;
251+ continue ;
252+ }
253+ }
254+ else
255+ {
256+ Log . Verbose ( string . Format ( "Warning: Plugin FeatureCategory not set: {0}" , sAddInTypeName ) ) ;
257+ }
258+
259+
260+
261+
262+
144263 Log . Verbose ( string . Format ( "Loading Plugin: {0}" , sAddInTypeName ) ) ;
145264
146265 BIDSHelperPluginBase feature ;
@@ -173,41 +292,7 @@ protected override void Initialize()
173292 string sException = "" ;
174293 foreach ( Exception pluginEx in pluginExceptions )
175294 {
176- sException += string . Format ( "BIDS Helper encountered an error when Visual Studio started:\r \n {0}\r \n {1}"
177- , pluginEx . Message
178- , pluginEx . StackTrace ) ;
179-
180- Exception innerEx = pluginEx . InnerException ;
181- while ( innerEx != null )
182- {
183- sException += string . Format ( "\r \n Inner exception:\r \n {0}\r \n {1}"
184- , innerEx . Message
185- , innerEx . StackTrace ) ;
186- innerEx = innerEx . InnerException ;
187- }
188-
189- ReflectionTypeLoadException ex = pluginEx as ReflectionTypeLoadException ;
190- if ( ex == null ) ex = pluginEx . InnerException as ReflectionTypeLoadException ;
191- if ( ex != null )
192- {
193- System . Text . StringBuilder sb = new System . Text . StringBuilder ( ) ;
194- foreach ( Exception exSub in ex . LoaderExceptions )
195- {
196- sb . AppendLine ( ) ;
197- sb . AppendLine ( exSub . Message ) ;
198- System . IO . FileNotFoundException exFileNotFound = exSub as System . IO . FileNotFoundException ;
199- if ( exFileNotFound != null )
200- {
201- if ( ! string . IsNullOrEmpty ( exFileNotFound . FusionLog ) )
202- {
203- sb . AppendLine ( "Fusion Log:" ) ;
204- sb . AppendLine ( exFileNotFound . FusionLog ) ;
205- }
206- }
207- sb . AppendLine ( ) ;
208- }
209- sException += sb . ToString ( ) ;
210- }
295+ sException += FormatLoaderException ( pluginEx ) ;
211296 }
212297 AddInLoadException = new Exception ( sException ) ;
213298 }
@@ -244,6 +329,51 @@ protected override void Initialize()
244329
245330 }
246331
332+ public static string FormatLoaderException ( Exception pluginEx )
333+ {
334+ string sException = "" ;
335+ sException += string . Format ( "BIDS Helper encountered an error when Visual Studio started:\r \n {0}\r \n {1}"
336+ , pluginEx . Message
337+ , pluginEx . StackTrace ) ;
338+
339+ Exception innerEx = pluginEx . InnerException ;
340+ while ( innerEx != null )
341+ {
342+ sException += string . Format ( "\r \n Inner exception:\r \n {0}\r \n {1}"
343+ , innerEx . Message
344+ , innerEx . StackTrace ) ;
345+ innerEx = innerEx . InnerException ;
346+ }
347+
348+ ReflectionTypeLoadException ex = pluginEx as ReflectionTypeLoadException ;
349+ if ( ex == null ) ex = pluginEx . InnerException as ReflectionTypeLoadException ;
350+ if ( ex != null )
351+ {
352+ System . Text . StringBuilder sb = new System . Text . StringBuilder ( ) ;
353+ foreach ( Exception exSub in ex . LoaderExceptions )
354+ {
355+ sb . AppendLine ( ) ;
356+ sb . AppendLine ( exSub . GetType ( ) . FullName ) ;
357+ sb . AppendLine ( exSub . Message ) ;
358+ sb . AppendLine ( exSub . StackTrace ) ;
359+ System . IO . FileNotFoundException exFileNotFound = exSub as System . IO . FileNotFoundException ;
360+ if ( exFileNotFound != null )
361+ {
362+ if ( ! string . IsNullOrEmpty ( exFileNotFound . FusionLog ) )
363+ {
364+ sb . AppendLine ( "Fusion Log:" ) ;
365+ sb . AppendLine ( exFileNotFound . FusionLog ) ;
366+ }
367+ sb . AppendLine ( string . Format ( "Source: {0}" , exFileNotFound . Source ) ) ;
368+ sb . AppendLine ( string . Format ( "TargetSite: {0}" , exFileNotFound . TargetSite ) ) ;
369+ }
370+ sb . AppendLine ( ) ;
371+ }
372+ sException += sb . ToString ( ) ;
373+ }
374+ return sException ;
375+ }
376+
247377// private bool SwitchVsixManifest()
248378// {
249379//#if SQL2019
@@ -604,6 +734,9 @@ public int OnModeChange(DBGMODE mode)
604734
605735 public static Exception AddInLoadException = null ;
606736 private uint debugEventCookie ;
737+ public static Version SSISExtensionVersion = null ;
738+ public static Version SSASExtensionVersion = null ;
739+ public static Version SSRSExtensionVersion = null ;
607740
608741 internal System . IServiceProvider ServiceProvider { get { return ( System . IServiceProvider ) this ; } }
609742
0 commit comments