diff --git a/ILSpy.AddIn/Commands/OpenCodeItemCommand.cs b/ILSpy.AddIn/Commands/OpenCodeItemCommand.cs index 958b0e00a..0f26fa2d6 100644 --- a/ILSpy.AddIn/Commands/OpenCodeItemCommand.cs +++ b/ILSpy.AddIn/Commands/OpenCodeItemCommand.cs @@ -18,6 +18,7 @@ namespace ICSharpCode.ILSpy.AddIn.Commands public OpenCodeItemCommand(ILSpyAddInPackage owner) : base(owner, PkgCmdIDList.cmdidOpenCodeItemInILSpy) { + ThreadHelper.ThrowIfNotOnUIThread(); } protected override void OnBeforeQueryStatus(object sender, EventArgs e) @@ -185,6 +186,8 @@ namespace ICSharpCode.ILSpy.AddIn.Commands internal static void Register(ILSpyAddInPackage owner) { + ThreadHelper.ThrowIfNotOnUIThread(); + instance = new OpenCodeItemCommand(owner); } } diff --git a/ILSpy.AddIn/Commands/OpenILSpyCommand.cs b/ILSpy.AddIn/Commands/OpenILSpyCommand.cs index 6f1261d3c..317004f50 100644 --- a/ILSpy.AddIn/Commands/OpenILSpyCommand.cs +++ b/ILSpy.AddIn/Commands/OpenILSpyCommand.cs @@ -32,6 +32,8 @@ namespace ICSharpCode.ILSpy.AddIn.Commands protected ILSpyCommand(ILSpyAddInPackage owner, uint id) { + ThreadHelper.ThrowIfNotOnUIThread(); + this.owner = owner; CommandID menuCommandID = new CommandID(GuidList.guidILSpyAddInCmdSet, (int)id); OleMenuCommand menuItem = new OleMenuCommand(OnExecute, menuCommandID); @@ -120,6 +122,7 @@ namespace ICSharpCode.ILSpy.AddIn.Commands public OpenILSpyCommand(ILSpyAddInPackage owner) : base(owner, PkgCmdIDList.cmdidOpenILSpy) { + ThreadHelper.ThrowIfNotOnUIThread(); } protected override void OnExecute(object sender, EventArgs e) @@ -129,6 +132,8 @@ namespace ICSharpCode.ILSpy.AddIn.Commands internal static void Register(ILSpyAddInPackage owner) { + ThreadHelper.ThrowIfNotOnUIThread(); + instance = new OpenILSpyCommand(owner); } } diff --git a/ILSpy.AddIn/Commands/OpenProjectOutputCommand.cs b/ILSpy.AddIn/Commands/OpenProjectOutputCommand.cs index 924f8deaa..8fd06a50c 100644 --- a/ILSpy.AddIn/Commands/OpenProjectOutputCommand.cs +++ b/ILSpy.AddIn/Commands/OpenProjectOutputCommand.cs @@ -12,6 +12,7 @@ namespace ICSharpCode.ILSpy.AddIn.Commands public OpenProjectOutputCommand(ILSpyAddInPackage owner) : base(owner, PkgCmdIDList.cmdidOpenProjectOutputInILSpy) { + ThreadHelper.ThrowIfNotOnUIThread(); } protected override void OnBeforeQueryStatus(object sender, EventArgs e) @@ -36,6 +37,8 @@ namespace ICSharpCode.ILSpy.AddIn.Commands internal static void Register(ILSpyAddInPackage owner) { + ThreadHelper.ThrowIfNotOnUIThread(); + instance = new OpenProjectOutputCommand(owner); } } diff --git a/ILSpy.AddIn/Commands/OpenReferenceCommand.cs b/ILSpy.AddIn/Commands/OpenReferenceCommand.cs index 682f5659d..5c2b61fa8 100644 --- a/ILSpy.AddIn/Commands/OpenReferenceCommand.cs +++ b/ILSpy.AddIn/Commands/OpenReferenceCommand.cs @@ -17,6 +17,7 @@ namespace ICSharpCode.ILSpy.AddIn.Commands public OpenReferenceCommand(ILSpyAddInPackage owner) : base(owner, PkgCmdIDList.cmdidOpenReferenceInILSpy) { + ThreadHelper.ThrowIfNotOnUIThread(); } protected override void OnBeforeQueryStatus(object sender, EventArgs e) @@ -87,6 +88,8 @@ namespace ICSharpCode.ILSpy.AddIn.Commands internal static void Register(ILSpyAddInPackage owner) { + ThreadHelper.ThrowIfNotOnUIThread(); + instance = new OpenReferenceCommand(owner); } } diff --git a/ILSpy.AddIn/ILSpyAddInPackage.cs b/ILSpy.AddIn/ILSpyAddInPackage.cs index fe1d19bdc..aedbda510 100644 --- a/ILSpy.AddIn/ILSpyAddInPackage.cs +++ b/ILSpy.AddIn/ILSpyAddInPackage.cs @@ -3,6 +3,8 @@ using System.Diagnostics; using System.Globalization; using System.Runtime.InteropServices; using System.ComponentModel.Design; +using System.Threading; +using Microsoft; using Microsoft.VisualStudio; using Microsoft.VisualStudio.Shell.Interop; using Microsoft.VisualStudio.Shell; @@ -11,6 +13,7 @@ using Microsoft.VisualStudio.ComponentModelHost; using Microsoft.VisualStudio.LanguageServices; using EnvDTE; using System.Collections.Generic; +using Task = System.Threading.Tasks.Task; namespace ICSharpCode.ILSpy.AddIn { @@ -26,15 +29,15 @@ namespace ICSharpCode.ILSpy.AddIn /// // This attribute tells the PkgDef creation utility (CreatePkgDef.exe) that this class is // a package. - [PackageRegistration(UseManagedResourcesOnly = true)] + [PackageRegistration(UseManagedResourcesOnly = true, AllowsBackgroundLoading = true)] // This attribute is used to register the information needed to show this package // in the Help/About dialog of Visual Studio. [InstalledProductRegistration("#110", "#112", "1.0", IconResourceID = 400)] // This attribute is needed to let the shell know that this package exposes some menus. [ProvideMenuResource("Menus.ctmenu", 1)] [Guid(GuidList.guidILSpyAddInPkgString)] - [ProvideAutoLoad(VSConstants.UICONTEXT.SolutionExistsAndFullyLoaded_string)] - public sealed class ILSpyAddInPackage : Package + [ProvideAutoLoad(VSConstants.UICONTEXT.SolutionExistsAndFullyLoaded_string, PackageAutoLoadFlags.BackgroundLoad)] + public sealed class ILSpyAddInPackage : AsyncPackage { /// /// Default constructor of the package. @@ -65,19 +68,24 @@ namespace ICSharpCode.ILSpy.AddIn /// Initialization of the package; this method is called right after the package is sited, so this is the place /// where you can put all the initialization code that rely on services provided by VisualStudio. /// - protected override void Initialize() + protected override async Task InitializeAsync(CancellationToken cancellationToken, IProgress progress) { - Debug.WriteLine(string.Format(CultureInfo.CurrentCulture, "Entering Initialize() of: {0}", this.ToString())); - base.Initialize(); + Debug.WriteLine($"Entering {nameof(InitializeAsync)}() of: {this}"); + + await base.InitializeAsync(cancellationToken, progress); + + await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken); + cancellationToken.ThrowIfCancellationRequested(); + + var componentModel = (IComponentModel)await GetServiceAsync(typeof(SComponentModel)); + Assumes.Present(componentModel); // Add our command handlers for menu (commands must exist in the .vsct file) - this.menuService = GetService(typeof(IMenuCommandService)) as OleMenuCommandService; + this.menuService = (OleMenuCommandService)await GetServiceAsync(typeof(IMenuCommandService)); + Assumes.Present(menuService); - var componentModel = (IComponentModel)this.GetService(typeof(SComponentModel)); this.workspace = componentModel.GetService(); - - if (menuService == null || workspace == null) - return; + Assumes.Present(workspace); OpenILSpyCommand.Register(this); OpenProjectOutputCommand.Register(this); @@ -88,16 +96,22 @@ namespace ICSharpCode.ILSpy.AddIn public void ShowMessage(string format, params object[] items) { + ThreadHelper.ThrowIfNotOnUIThread(); + ShowMessage(OLEMSGBUTTON.OLEMSGBUTTON_OK, OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST, OLEMSGICON.OLEMSGICON_INFO, format, items); } public void ShowMessage(OLEMSGICON icon, string format, params object[] items) { + ThreadHelper.ThrowIfNotOnUIThread(); + ShowMessage(OLEMSGBUTTON.OLEMSGBUTTON_OK, OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST, icon, format, items); } public int ShowMessage(OLEMSGBUTTON buttons, OLEMSGDEFBUTTON defaultButton, OLEMSGICON icon, string format, params object[] items) { + ThreadHelper.ThrowIfNotOnUIThread(); + IVsUIShell uiShell = (IVsUIShell)GetService(typeof(SVsUIShell)); Guid clsid = Guid.Empty; int result;