diff --git a/nuget.config b/nuget.config index 70eba72d..c9a29acf 100644 --- a/nuget.config +++ b/nuget.config @@ -11,8 +11,9 @@ - Microsoft;xunit;aarnott;jkeech;sharwell;jamesnk + Microsoft;xunit;aarnott;jkeech;sharwell;jamesnk;Nerdbank;neuecc + @@ -20,5 +21,11 @@ + + + + + + diff --git a/src/.editorconfig b/src/.editorconfig new file mode 100644 index 00000000..3148851d --- /dev/null +++ b/src/.editorconfig @@ -0,0 +1,3 @@ +[*.{cs,csproj}] +indent_style = space +indent_size = 4 \ No newline at end of file diff --git a/src/Microsoft.VisualStudio.SlowCheetah.Tests/Microsoft.VisualStudio.SlowCheetah.Tests.csproj b/src/Microsoft.VisualStudio.SlowCheetah.Tests/Microsoft.VisualStudio.SlowCheetah.Tests.csproj index 58434a52..28bcf53e 100644 --- a/src/Microsoft.VisualStudio.SlowCheetah.Tests/Microsoft.VisualStudio.SlowCheetah.Tests.csproj +++ b/src/Microsoft.VisualStudio.SlowCheetah.Tests/Microsoft.VisualStudio.SlowCheetah.Tests.csproj @@ -13,11 +13,20 @@ - - - - - + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/src/Microsoft.VisualStudio.SlowCheetah.VS.Tests/Microsoft.VisualStudio.SlowCheetah.VS.Tests.csproj b/src/Microsoft.VisualStudio.SlowCheetah.VS.Tests/Microsoft.VisualStudio.SlowCheetah.VS.Tests.csproj index 4ff953df..26d79e73 100644 --- a/src/Microsoft.VisualStudio.SlowCheetah.VS.Tests/Microsoft.VisualStudio.SlowCheetah.VS.Tests.csproj +++ b/src/Microsoft.VisualStudio.SlowCheetah.VS.Tests/Microsoft.VisualStudio.SlowCheetah.VS.Tests.csproj @@ -6,12 +6,23 @@ + - - - - - + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/src/Microsoft.VisualStudio.SlowCheetah.VS/Microsoft.VisualStudio.SlowCheetah.VS.csproj b/src/Microsoft.VisualStudio.SlowCheetah.VS/Microsoft.VisualStudio.SlowCheetah.VS.csproj index 3e26cf83..6befbbf6 100644 --- a/src/Microsoft.VisualStudio.SlowCheetah.VS/Microsoft.VisualStudio.SlowCheetah.VS.csproj +++ b/src/Microsoft.VisualStudio.SlowCheetah.VS/Microsoft.VisualStudio.SlowCheetah.VS.csproj @@ -9,16 +9,24 @@ - + + - - + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + - - - - + + + + + + diff --git a/src/Microsoft.VisualStudio.SlowCheetah.VS/NugetHandler/PackageHandlers/BackgroundInstallationHandler.cs b/src/Microsoft.VisualStudio.SlowCheetah.VS/NugetHandler/PackageHandlers/BackgroundInstallationHandler.cs index a3c7dde5..23cada83 100644 --- a/src/Microsoft.VisualStudio.SlowCheetah.VS/NugetHandler/PackageHandlers/BackgroundInstallationHandler.cs +++ b/src/Microsoft.VisualStudio.SlowCheetah.VS/NugetHandler/PackageHandlers/BackgroundInstallationHandler.cs @@ -35,8 +35,9 @@ public BackgroundInstallationHandler(IPackageHandler successor) public bool IsUpdate { get; set; } = false; /// - public override async TPL.Task Execute(Project project) + public override async TPL.Task ExecuteAsync(Project project) { + await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); string projName = project.UniqueName; bool needInstall = true; lock (SyncObject) @@ -48,7 +49,7 @@ public override async TPL.Task Execute(Project project) { string warningTitle = this.IsUpdate ? Resources.Resources.NugetUpdate_Title : Resources.Resources.NugetInstall_Title; string warningMessage = this.IsUpdate ? Resources.Resources.NugetUpdate_Text : Resources.Resources.NugetInstall_Text; - if (await this.HasUserAcceptedWarningMessage(warningTitle, warningMessage)) + if (await this.HasUserAcceptedWarningMessageAsync(warningTitle, warningMessage)) { // Gets the general output pane to inform user of installation IVsOutputWindowPane outputWindow = (IVsOutputWindowPane)await this.Package.GetServiceAsync(typeof(SVsGeneralOutputWindowPane)); @@ -61,7 +62,7 @@ public override async TPL.Task Execute(Project project) string outputMessage = Resources.Resources.NugetInstall_FinishedOutput; try { - await this.Successor.Execute(project); + await this.Successor.ExecuteAsync(project); } catch { diff --git a/src/Microsoft.VisualStudio.SlowCheetah.VS/NugetHandler/PackageHandlers/BasePackageHandler.cs b/src/Microsoft.VisualStudio.SlowCheetah.VS/NugetHandler/PackageHandlers/BasePackageHandler.cs index 26baa465..650f0a7f 100644 --- a/src/Microsoft.VisualStudio.SlowCheetah.VS/NugetHandler/PackageHandlers/BasePackageHandler.cs +++ b/src/Microsoft.VisualStudio.SlowCheetah.VS/NugetHandler/PackageHandlers/BasePackageHandler.cs @@ -39,6 +39,6 @@ protected BasePackageHandler(IPackageHandler successor) protected IPackageHandler Successor { get; } /// - public abstract TPL.Task Execute(Project project); + public abstract TPL.Task ExecuteAsync(Project project); } } diff --git a/src/Microsoft.VisualStudio.SlowCheetah.VS/NugetHandler/PackageHandlers/DialogInstallationHandler.cs b/src/Microsoft.VisualStudio.SlowCheetah.VS/NugetHandler/PackageHandlers/DialogInstallationHandler.cs index f24b3156..6a6a1b89 100644 --- a/src/Microsoft.VisualStudio.SlowCheetah.VS/NugetHandler/PackageHandlers/DialogInstallationHandler.cs +++ b/src/Microsoft.VisualStudio.SlowCheetah.VS/NugetHandler/PackageHandlers/DialogInstallationHandler.cs @@ -4,6 +4,7 @@ namespace Microsoft.VisualStudio.SlowCheetah.VS { using EnvDTE; + using Microsoft.VisualStudio.Shell; using Microsoft.VisualStudio.Shell.Interop; using TPL = System.Threading.Tasks; @@ -22,9 +23,10 @@ public DialogInstallationHandler(IPackageHandler successor) } /// - public override async TPL.Task Execute(Project project) + public override async TPL.Task ExecuteAsync(Project project) { - if (await this.HasUserAcceptedWarningMessage(Resources.Resources.NugetUpdate_Title, Resources.Resources.NugetUpdate_Text)) + await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); + if (await this.HasUserAcceptedWarningMessageAsync(Resources.Resources.NugetUpdate_Title, Resources.Resources.NugetUpdate_Text)) { // Creates dialog informing the user to wait for the installation to finish IVsThreadedWaitDialogFactory twdFactory = await this.Package.GetServiceAsync(typeof(SVsThreadedWaitDialogFactory)) as IVsThreadedWaitDialogFactory; @@ -37,7 +39,7 @@ public override async TPL.Task Execute(Project project) try { - await this.Successor.Execute(project); + await this.Successor.ExecuteAsync(project); } finally { diff --git a/src/Microsoft.VisualStudio.SlowCheetah.VS/NugetHandler/PackageHandlers/EmptyHandler.cs b/src/Microsoft.VisualStudio.SlowCheetah.VS/NugetHandler/PackageHandlers/EmptyHandler.cs index 0b942b4c..287992bb 100644 --- a/src/Microsoft.VisualStudio.SlowCheetah.VS/NugetHandler/PackageHandlers/EmptyHandler.cs +++ b/src/Microsoft.VisualStudio.SlowCheetah.VS/NugetHandler/PackageHandlers/EmptyHandler.cs @@ -26,7 +26,7 @@ public EmptyHandler(AsyncPackage package) public AsyncPackage Package { get; } /// - public TPL.Task Execute(Project project) + public TPL.Task ExecuteAsync(Project project) { // Do nothing return TPL.Task.CompletedTask; diff --git a/src/Microsoft.VisualStudio.SlowCheetah.VS/NugetHandler/PackageHandlers/IPackageHandler.cs b/src/Microsoft.VisualStudio.SlowCheetah.VS/NugetHandler/PackageHandlers/IPackageHandler.cs index 8da05892..8c1a89ad 100644 --- a/src/Microsoft.VisualStudio.SlowCheetah.VS/NugetHandler/PackageHandlers/IPackageHandler.cs +++ b/src/Microsoft.VisualStudio.SlowCheetah.VS/NugetHandler/PackageHandlers/IPackageHandler.cs @@ -22,6 +22,6 @@ internal interface IPackageHandler /// /// The project to peform actions on /// A task that executes the function - TPL.Task Execute(Project project); + TPL.Task ExecuteAsync(Project project); } } diff --git a/src/Microsoft.VisualStudio.SlowCheetah.VS/NugetHandler/PackageHandlers/NuGetUninstaller.cs b/src/Microsoft.VisualStudio.SlowCheetah.VS/NugetHandler/PackageHandlers/NuGetUninstaller.cs index abcb26c2..90e3dcb9 100644 --- a/src/Microsoft.VisualStudio.SlowCheetah.VS/NugetHandler/PackageHandlers/NuGetUninstaller.cs +++ b/src/Microsoft.VisualStudio.SlowCheetah.VS/NugetHandler/PackageHandlers/NuGetUninstaller.cs @@ -4,6 +4,7 @@ namespace Microsoft.VisualStudio.SlowCheetah.VS { using EnvDTE; + using Microsoft; using Microsoft.VisualStudio.ComponentModelHost; using Microsoft.VisualStudio.Shell; using NuGet.VisualStudio; @@ -24,13 +25,14 @@ public NuGetUninstaller(IPackageHandler successor) } /// - public override async TPL.Task Execute(Project project) + public override async TPL.Task ExecuteAsync(Project project) { var componentModel = (IComponentModel)await this.Package.GetServiceAsync(typeof(SComponentModel)); + Assumes.Present(componentModel); IVsPackageUninstaller packageUninstaller = componentModel.GetService(); packageUninstaller.UninstallPackage(project, SlowCheetahNuGetManager.OldPackageName, true); - await this.Successor.Execute(project); + await this.Successor.ExecuteAsync(project); } } } diff --git a/src/Microsoft.VisualStudio.SlowCheetah.VS/NugetHandler/PackageHandlers/NugetInstaller.cs b/src/Microsoft.VisualStudio.SlowCheetah.VS/NugetHandler/PackageHandlers/NugetInstaller.cs index 674a00f1..bbcc6c40 100644 --- a/src/Microsoft.VisualStudio.SlowCheetah.VS/NugetHandler/PackageHandlers/NugetInstaller.cs +++ b/src/Microsoft.VisualStudio.SlowCheetah.VS/NugetHandler/PackageHandlers/NugetInstaller.cs @@ -4,6 +4,7 @@ namespace Microsoft.VisualStudio.SlowCheetah.VS { using EnvDTE; + using Microsoft; using Microsoft.VisualStudio.ComponentModelHost; using NuGet.VisualStudio; using TPL = System.Threading.Tasks; @@ -23,9 +24,10 @@ public NugetInstaller(IPackageHandler successor) } /// - public override async TPL.Task Execute(Project project) + public override async TPL.Task ExecuteAsync(Project project) { var componentModel = (IComponentModel)await this.Package.GetServiceAsync(typeof(SComponentModel)); + Assumes.Present(componentModel); IVsPackageInstaller packageInstaller = componentModel.GetService(); packageInstaller.InstallPackage( null, @@ -34,7 +36,7 @@ public override async TPL.Task Execute(Project project) version: (string)null, // install latest stable version ignoreDependencies: false); - await this.Successor.Execute(project); + await this.Successor.ExecuteAsync(project); } } } diff --git a/src/Microsoft.VisualStudio.SlowCheetah.VS/NugetHandler/PackageHandlers/TargetsUninstaller.cs b/src/Microsoft.VisualStudio.SlowCheetah.VS/NugetHandler/PackageHandlers/TargetsUninstaller.cs index e8eec717..02e96148 100644 --- a/src/Microsoft.VisualStudio.SlowCheetah.VS/NugetHandler/PackageHandlers/TargetsUninstaller.cs +++ b/src/Microsoft.VisualStudio.SlowCheetah.VS/NugetHandler/PackageHandlers/TargetsUninstaller.cs @@ -6,6 +6,7 @@ namespace Microsoft.VisualStudio.SlowCheetah.VS using System.Linq; using EnvDTE; using Microsoft.Build.Construction; + using Microsoft.VisualStudio.Shell; using TPL = System.Threading.Tasks; /// @@ -23,10 +24,11 @@ public TargetsUninstaller(IPackageHandler successor) } /// - public override async TPL.Task Execute(Project project) + public override async TPL.Task ExecuteAsync(Project project) { // We handle any NuGet package logic before editing the project file - await this.Successor.Execute(project); + await this.Successor.ExecuteAsync(project); + await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); project.Save(); ProjectRootElement projectRoot = ProjectRootElement.Open(project.FullName); diff --git a/src/Microsoft.VisualStudio.SlowCheetah.VS/NugetHandler/PackageHandlers/UserInstallationHandler.cs b/src/Microsoft.VisualStudio.SlowCheetah.VS/NugetHandler/PackageHandlers/UserInstallationHandler.cs index c9da75d0..c1ac94d1 100644 --- a/src/Microsoft.VisualStudio.SlowCheetah.VS/NugetHandler/PackageHandlers/UserInstallationHandler.cs +++ b/src/Microsoft.VisualStudio.SlowCheetah.VS/NugetHandler/PackageHandlers/UserInstallationHandler.cs @@ -6,6 +6,7 @@ namespace Microsoft.VisualStudio.SlowCheetah.VS using System; using System.Threading.Tasks; using Microsoft.VisualStudio; + using Microsoft.VisualStudio.Shell; using Microsoft.VisualStudio.Shell.Interop; /// @@ -28,8 +29,9 @@ public UserInstallationHandler(IPackageHandler successor) /// The title of the message box /// The message to be shown /// True if the user has accepted the warning message - protected async Task HasUserAcceptedWarningMessage(string title, string message) + protected async Task HasUserAcceptedWarningMessageAsync(string title, string message) { + await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); var shell = (IVsUIShell)await this.Package.GetServiceAsync(typeof(SVsUIShell)); if (shell != null) diff --git a/src/Microsoft.VisualStudio.SlowCheetah.VS/NugetHandler/SlowCheetahNuGetManager.cs b/src/Microsoft.VisualStudio.SlowCheetah.VS/NugetHandler/SlowCheetahNuGetManager.cs index dd534cf9..d014518f 100644 --- a/src/Microsoft.VisualStudio.SlowCheetah.VS/NugetHandler/SlowCheetahNuGetManager.cs +++ b/src/Microsoft.VisualStudio.SlowCheetah.VS/NugetHandler/SlowCheetahNuGetManager.cs @@ -6,11 +6,13 @@ namespace Microsoft.VisualStudio.SlowCheetah.VS using System; using System.Collections.Generic; using EnvDTE; + using Microsoft; using Microsoft.VisualStudio; using Microsoft.VisualStudio.ComponentModelHost; using Microsoft.VisualStudio.Shell; using Microsoft.VisualStudio.Shell.Interop; using NuGet.VisualStudio; + using NuGet.VisualStudio.Contracts; using TPL = System.Threading.Tasks; /// @@ -71,9 +73,10 @@ public SlowCheetahNuGetManager(AsyncPackage package) /// True if the project supports NuGet /// This implementation is derived of the internal NuGet method IsSupported /// https://github.com/NuGet/NuGet.Client/blob/dev/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/Utility/EnvDTEProjectUtility.cs#L441 - /// This should be removed when NuGet adds this to their public API + /// This should be removed when NuGet adds this to their public API. public bool ProjectSupportsNuget(IVsHierarchy hierarchy) { + ThreadHelper.ThrowIfNotOnUIThread(); if (hierarchy == null) { throw new ArgumentNullException(nameof(hierarchy)); @@ -113,8 +116,9 @@ public bool ProjectSupportsNuget(IVsHierarchy hierarchy) /// /// Hierarchy of the project to be verified /// A representing the asynchronous operation. - public async TPL.Task CheckSlowCheetahInstallation(IVsHierarchy hierarchy) + public async TPL.Task CheckSlowCheetahInstallationAsync(IVsHierarchy hierarchy) { + await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); if (hierarchy == null) { throw new ArgumentNullException(nameof(hierarchy)); @@ -160,22 +164,24 @@ public async TPL.Task CheckSlowCheetahInstallation(IVsHierarchy hierarchy) plan = new BackgroundInstallationHandler(plan) { // If the old package is installed, this is an update operation - IsUpdate = isOldScPackageInstalled + IsUpdate = isOldScPackageInstalled, }; } - await plan.Execute(currentProject); + await plan.ExecuteAsync(currentProject); } private static IVsPackageInstallerServices GetInstallerServices(IServiceProvider package) { var componentModel = (IComponentModel)package.GetService(typeof(SComponentModel)); + Assumes.Present(componentModel); IVsPackageInstallerServices installerServices = componentModel.GetService(); return installerServices; } private static bool IsOldSlowCheetahInstalled(IVsBuildPropertyStorage buildPropertyStorage) { + ThreadHelper.ThrowIfNotOnUIThread(); buildPropertyStorage.GetPropertyValue("SlowCheetahImport", null, (uint)_PersistStorageType.PST_PROJECT_FILE, out string propertyValue); if (!string.IsNullOrEmpty(propertyValue)) { @@ -193,6 +199,7 @@ private static bool IsOldSlowCheetahInstalled(IVsBuildPropertyStorage buildPrope private static bool SupportsINugetProjectSystem(IVsHierarchy hierarchy) { + ThreadHelper.ThrowIfNotOnUIThread(); var vsProject = hierarchy as IVsProject; if (vsProject == null) { diff --git a/src/Microsoft.VisualStudio.SlowCheetah.VS/Options/AdvancedOptionsDialogPage.cs b/src/Microsoft.VisualStudio.SlowCheetah.VS/Options/AdvancedOptionsDialogPage.cs index 690604ea..513f4379 100644 --- a/src/Microsoft.VisualStudio.SlowCheetah.VS/Options/AdvancedOptionsDialogPage.cs +++ b/src/Microsoft.VisualStudio.SlowCheetah.VS/Options/AdvancedOptionsDialogPage.cs @@ -51,6 +51,7 @@ protected override IWin32Window Window /// public override void SaveSettingsToXml(IVsSettingsWriter writer) { + Shell.ThreadHelper.ThrowIfNotOnUIThread(); try { base.SaveSettingsToXml(writer); @@ -68,6 +69,7 @@ public override void SaveSettingsToXml(IVsSettingsWriter writer) /// public override void LoadSettingsFromXml(IVsSettingsReader reader) { + Shell.ThreadHelper.ThrowIfNotOnUIThread(); try { this.InitializeDefaults(); diff --git a/src/Microsoft.VisualStudio.SlowCheetah.VS/Options/OptionsDialogPage.cs b/src/Microsoft.VisualStudio.SlowCheetah.VS/Options/OptionsDialogPage.cs index dd5d33db..70b2e079 100644 --- a/src/Microsoft.VisualStudio.SlowCheetah.VS/Options/OptionsDialogPage.cs +++ b/src/Microsoft.VisualStudio.SlowCheetah.VS/Options/OptionsDialogPage.cs @@ -53,6 +53,7 @@ protected override IWin32Window Window /// public override void SaveSettingsToXml(IVsSettingsWriter writer) { + Shell.ThreadHelper.ThrowIfNotOnUIThread(); try { base.SaveSettingsToXml(writer); @@ -70,6 +71,7 @@ public override void SaveSettingsToXml(IVsSettingsWriter writer) /// public override void LoadSettingsFromXml(IVsSettingsReader reader) { + Shell.ThreadHelper.ThrowIfNotOnUIThread(); try { this.InitializeDefaults(); diff --git a/src/Microsoft.VisualStudio.SlowCheetah.VS/Package/AddTransformCommand.cs b/src/Microsoft.VisualStudio.SlowCheetah.VS/Package/AddTransformCommand.cs index b53c3c90..5dfa7876 100644 --- a/src/Microsoft.VisualStudio.SlowCheetah.VS/Package/AddTransformCommand.cs +++ b/src/Microsoft.VisualStudio.SlowCheetah.VS/Package/AddTransformCommand.cs @@ -51,6 +51,8 @@ protected override void OnChange(object sender, EventArgs e) /// protected override void OnBeforeQueryStatus(object sender, EventArgs e) { + ThreadHelper.ThrowIfNotOnUIThread(); + // get the menu that fired the event if (sender is OleMenuCommand menuCommand) { @@ -83,6 +85,7 @@ protected override void OnBeforeQueryStatus(object sender, EventArgs e) /// protected override void OnInvoke(object sender, EventArgs e) { + ThreadHelper.ThrowIfNotOnUIThread(); uint itemid = VSConstants.VSITEMID_NIL; if (!ProjectUtilities.IsSingleProjectItemSelection(out IVsHierarchy hierarchy, out itemid)) @@ -133,7 +136,7 @@ protected override void OnInvoke(object sender, EventArgs e) } // Checks the SlowCheetah NuGet package installation - this.package.JoinableTaskFactory.Run(() => this.nuGetManager.CheckSlowCheetahInstallation(hierarchy)); + this.package.JoinableTaskFactory.Run(() => this.nuGetManager.CheckSlowCheetahInstallationAsync(hierarchy)); // need to enure that this item has metadata TransformOnBuild set to true buildPropertyStorage.SetItemAttribute(itemid, SlowCheetahPackage.TransformOnBuild, "true"); @@ -191,6 +194,7 @@ private void AddTransformFile( string projectPath, bool addDependentUpon) { + ThreadHelper.ThrowIfNotOnUIThread(); try { string transformPath = Path.Combine(projectPath, itemName); @@ -245,6 +249,7 @@ private void AddTransformFile( /// True if the item supports transforms private bool ItemSupportsTransforms(IVsProject project, uint itemid) { + ThreadHelper.ThrowIfNotOnUIThread(); if (ErrorHandler.Failed(project.GetMkDocument(itemid, out string itemFullPath))) { return false; @@ -279,6 +284,7 @@ private bool ItemSupportsTransforms(IVsProject project, uint itemid) /// List of publish profile names private IEnumerable GetPublishProfileTransforms(IVsHierarchy hierarchy, string projectPath) { + ThreadHelper.ThrowIfNotOnUIThread(); if (hierarchy == null) { throw new ArgumentNullException(nameof(hierarchy)); diff --git a/src/Microsoft.VisualStudio.SlowCheetah.VS/Package/PreviewTransformCommand.cs b/src/Microsoft.VisualStudio.SlowCheetah.VS/Package/PreviewTransformCommand.cs index df05e2ee..86746067 100644 --- a/src/Microsoft.VisualStudio.SlowCheetah.VS/Package/PreviewTransformCommand.cs +++ b/src/Microsoft.VisualStudio.SlowCheetah.VS/Package/PreviewTransformCommand.cs @@ -84,6 +84,8 @@ protected override void OnChange(object sender, EventArgs e) /// protected override void OnBeforeQueryStatus(object sender, EventArgs e) { + ThreadHelper.ThrowIfNotOnUIThread(); + // Get the menu that fired the event if (sender is OleMenuCommand menuCommand) { @@ -117,6 +119,7 @@ protected override void OnBeforeQueryStatus(object sender, EventArgs e) /// protected override void OnInvoke(object sender, EventArgs e) { + ThreadHelper.ThrowIfNotOnUIThread(); uint itemId = VSConstants.VSITEMID_NIL; // Verify only one item is selected @@ -139,7 +142,7 @@ protected override void OnInvoke(object sender, EventArgs e) } // Checks the SlowCheetah NuGet package installation - this.ScPackage.JoinableTaskFactory.Run(() => this.NuGetManager.CheckSlowCheetahInstallation(hierarchy)); + this.ScPackage.JoinableTaskFactory.Run(() => this.NuGetManager.CheckSlowCheetahInstallationAsync(hierarchy)); // Get the parent of the file to start searching for the source file ErrorHandler.ThrowOnFailure(hierarchy.GetProperty(itemId, (int)__VSHPROPID.VSHPROPID_Parent, out object parentIdObj)); @@ -177,6 +180,7 @@ protected override void OnInvoke(object sender, EventArgs e) /// Full path to the transformation file private void PreviewTransform(IVsHierarchy hier, string sourceFile, string transformFile) { + ThreadHelper.ThrowIfNotOnUIThread(); if (string.IsNullOrWhiteSpace(sourceFile)) { throw new ArgumentNullException(nameof(sourceFile)); @@ -261,7 +265,7 @@ private void PreviewTransform(IVsHierarchy hier, string sourceFile, string trans ProcessStartInfo psi = new ProcessStartInfo(advancedOptionsPage.PreviewToolExecutablePath, string.Format(CultureInfo.CurrentCulture, advancedOptionsPage.PreviewToolCommandLine, $"\"{sourceFile}\"", $"\"{destFile}\"")) { CreateNoWindow = true, - UseShellExecute = false + UseShellExecute = false, }; System.Diagnostics.Process.Start(psi); } @@ -281,6 +285,7 @@ private void PreviewTransform(IVsHierarchy hier, string sourceFile, string trans /// True if the correct file was found private bool TryGetFileToTransform(IVsHierarchy hierarchy, uint parentId, string transformName, out uint docId, out string documentPath) { + ThreadHelper.ThrowIfNotOnUIThread(); IVsProject project = (IVsProject)hierarchy; // Get the project configurations to use in comparing the name diff --git a/src/Microsoft.VisualStudio.SlowCheetah.VS/Package/SlowCheetahPackageLogger.cs b/src/Microsoft.VisualStudio.SlowCheetah.VS/Package/SlowCheetahPackageLogger.cs index b8e80bc6..0159c99f 100644 --- a/src/Microsoft.VisualStudio.SlowCheetah.VS/Package/SlowCheetahPackageLogger.cs +++ b/src/Microsoft.VisualStudio.SlowCheetah.VS/Package/SlowCheetahPackageLogger.cs @@ -31,6 +31,7 @@ public SlowCheetahPackageLogger(IServiceProvider package) /// The message arguments public void LogMessage(string message, params object[] args) { + Shell.ThreadHelper.ThrowIfNotOnUIThread(); if (string.IsNullOrWhiteSpace(message)) { return; diff --git a/src/Microsoft.VisualStudio.SlowCheetah.VS/SlowCheetahPackage.cs b/src/Microsoft.VisualStudio.SlowCheetah.VS/SlowCheetahPackage.cs index ddc99fea..f93b1e77 100644 --- a/src/Microsoft.VisualStudio.SlowCheetah.VS/SlowCheetahPackage.cs +++ b/src/Microsoft.VisualStudio.SlowCheetah.VS/SlowCheetahPackage.cs @@ -101,6 +101,7 @@ public SlowCheetahPackage() /// True if the project supports transformation public bool ProjectSupportsTransforms(IVsProject project) { + ThreadHelper.ThrowIfNotOnUIThread(); return this.NuGetManager.ProjectSupportsNuget(project as IVsHierarchy); } @@ -112,6 +113,7 @@ public bool ProjectSupportsTransforms(IVsProject project) /// True if the item has a transform public bool IsItemTransformItem(IVsProject vsProject, uint itemid) { + ThreadHelper.ThrowIfNotOnUIThread(); IVsBuildPropertyStorage buildPropertyStorage = vsProject as IVsBuildPropertyStorage; if (buildPropertyStorage == null) { diff --git a/src/Microsoft.VisualStudio.SlowCheetah.VS/TransformationPreviewLogger.cs b/src/Microsoft.VisualStudio.SlowCheetah.VS/TransformationPreviewLogger.cs index 250086a8..8dfc76b4 100644 --- a/src/Microsoft.VisualStudio.SlowCheetah.VS/TransformationPreviewLogger.cs +++ b/src/Microsoft.VisualStudio.SlowCheetah.VS/TransformationPreviewLogger.cs @@ -12,7 +12,7 @@ namespace Microsoft.VisualStudio.SlowCheetah.VS using System.Globalization; using Microsoft.VisualStudio.Shell; using Microsoft.VisualStudio.Shell.Interop; - using SlowCheetah; + using Microsoft.VisualStudio.SlowCheetah; /// /// Logger for XDT transformation on Preview Transform diff --git a/src/Microsoft.VisualStudio.SlowCheetah.VS/Utilities/PackageUtilities.cs b/src/Microsoft.VisualStudio.SlowCheetah.VS/Utilities/PackageUtilities.cs index 6c281516..efd8ce8b 100644 --- a/src/Microsoft.VisualStudio.SlowCheetah.VS/Utilities/PackageUtilities.cs +++ b/src/Microsoft.VisualStudio.SlowCheetah.VS/Utilities/PackageUtilities.cs @@ -177,6 +177,7 @@ public static bool IsPathValid(string path) public static T GetAutomationFromHierarchy(IVsHierarchy pHierarchy, uint itemID) where T : class { + Shell.ThreadHelper.ThrowIfNotOnUIThread(); ErrorHandler.ThrowOnFailure(pHierarchy.GetProperty(itemID, (int)__VSHPROPID.VSHPROPID_ExtObject, out object propertyValue)); T projectItem = propertyValue as T; diff --git a/src/Microsoft.VisualStudio.SlowCheetah.VS/Utilities/ProjectUtilities.cs b/src/Microsoft.VisualStudio.SlowCheetah.VS/Utilities/ProjectUtilities.cs index aa17ce16..c0f1c1e0 100644 --- a/src/Microsoft.VisualStudio.SlowCheetah.VS/Utilities/ProjectUtilities.cs +++ b/src/Microsoft.VisualStudio.SlowCheetah.VS/Utilities/ProjectUtilities.cs @@ -33,6 +33,7 @@ public static class ProjectUtilities /// The Visual Studio DTE object public static DTE GetDTE() { + ThreadHelper.ThrowIfNotOnUIThread(); return (DTE)Package.GetGlobalService(typeof(DTE)); } @@ -44,6 +45,7 @@ public static DTE GetDTE() /// True if a single item is selected public static bool IsSingleProjectItemSelection(out IVsHierarchy hierarchy, out uint itemid) { + ThreadHelper.ThrowIfNotOnUIThread(); hierarchy = null; itemid = VSConstants.VSITEMID_NIL; int hr = VSConstants.S_OK; @@ -118,6 +120,7 @@ public static bool IsSingleProjectItemSelection(out IVsHierarchy hierarchy, out /// List of configuration names for that project public static IEnumerable GetProjectConfigurations(Project project) { + ThreadHelper.ThrowIfNotOnUIThread(); List configurations = new List(); if (project != null && project.ConfigurationManager != null && project.ConfigurationManager.ConfigurationRowNames != null) @@ -184,6 +187,7 @@ public static IEnumerable GetSupportedItemExtensions(IVsSettingsManager /// True if a subtype GUID matches the Web App Guid in Resources public static bool IsProjectWebApp(IVsProject project) { + ThreadHelper.ThrowIfNotOnUIThread(); if (project is IVsAggregatableProject aggregatableProject) { aggregatableProject.GetAggregateProjectTypeGuids(out string projectTypeGuidStrings); @@ -210,6 +214,7 @@ public static bool IsProjectWebApp(IVsProject project) private static IEnumerable GetSupportedExtensions(IVsSettingsManager settingsManager, string rootKey) { + ThreadHelper.ThrowIfNotOnUIThread(); ErrorHandler.ThrowOnFailure(settingsManager.GetReadOnlySettingsStore((uint)__VsSettingsScope.SettingsScope_Configuration, out IVsSettingsStore settings)); ErrorHandler.ThrowOnFailure(settings.GetSubCollectionCount(rootKey, out uint count)); diff --git a/src/Microsoft.VisualStudio.SlowCheetah.Vsix/Microsoft.VisualStudio.SlowCheetah.Vsix.csproj b/src/Microsoft.VisualStudio.SlowCheetah.Vsix/Microsoft.VisualStudio.SlowCheetah.Vsix.csproj index 0578c95d..ab6a6882 100644 --- a/src/Microsoft.VisualStudio.SlowCheetah.Vsix/Microsoft.VisualStudio.SlowCheetah.Vsix.csproj +++ b/src/Microsoft.VisualStudio.SlowCheetah.Vsix/Microsoft.VisualStudio.SlowCheetah.Vsix.csproj @@ -80,8 +80,10 @@ - - + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + @@ -94,16 +96,17 @@ + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + - - + - -