diff --git a/GoogleTestAdapter/Packaging.GTA/source.extension.vsixmanifest b/GoogleTestAdapter/Packaging.GTA/source.extension.vsixmanifest index 16efffb82..e07d7e9df 100644 --- a/GoogleTestAdapter/Packaging.GTA/source.extension.vsixmanifest +++ b/GoogleTestAdapter/Packaging.GTA/source.extension.vsixmanifest @@ -1,34 +1,34 @@  - - - Google Test Adapter - Adds support for the C++ unit testing framework Google Tests. - https://github.com/csoltenborn/GoogleTestAdapter - LICENSE.txt - Resources\Icons\Icon.ico - Resources\Preview.png - Unit Test, C++, Google Test, GoogleTest, GTest, Test Explorer, Testing - - - - - - - - - - - - - - - - - - - - - - + + + Google Test Adapter + Adds support for the C++ unit testing framework Google Tests. + https://github.com/csoltenborn/GoogleTestAdapter + LICENSE.txt + Resources\Icons\Icon.ico + Resources\Preview.png + Unit Test, C++, Google Test, GoogleTest, GTest, Test Explorer, Testing + + + + + + + + + + + + + + + + + + + + + + diff --git a/GoogleTestAdapter/VsPackage.GTA/AsyncPackage/AsyncPackageRegistrationAttribute.cs b/GoogleTestAdapter/VsPackage.GTA/AsyncPackage/AsyncPackageRegistrationAttribute.cs new file mode 100644 index 000000000..f5b0b9a80 --- /dev/null +++ b/GoogleTestAdapter/VsPackage.GTA/AsyncPackage/AsyncPackageRegistrationAttribute.cs @@ -0,0 +1,192 @@ +//------------------------------------------------------------------------------ +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +//------------------------------------------------------------------------------ + +namespace Microsoft.VisualStudio.AsyncPackageHelpers { + + using System; + using System.Globalization; + using System.IO; + using System.ComponentModel; + using System.ComponentModel.Design; + using Microsoft.VisualStudio.Shell; + using Microsoft.VisualStudio.Shell.Interop; + + /// + /// This attribute is defined on a package to get it to be registered. It + /// is internal because packages are meant to be registered, so it is + /// implicit just by having a package in the assembly. + /// + [AttributeUsage(AttributeTargets.Class, Inherited=true, AllowMultiple=false)] + public sealed class AsyncPackageRegistrationAttribute : RegistrationAttribute + { + private RegistrationMethod registrationMethod = RegistrationMethod.Default; + private bool useManagedResources = false; + private bool allowsBackgroundLoad = false; + private string satellitePath = null; + + /// + /// Select between specifying the Codebase entry or the Assembly entry in the registry. + /// This can be overriden during registration + /// + public RegistrationMethod RegisterUsing + { + get + { + return registrationMethod; + } + set + { + registrationMethod = value; + } + } + + /// + /// For managed resources, there should not be a native ui dll registered. + /// + public bool UseManagedResourcesOnly + { + get { return useManagedResources; } + set { useManagedResources = value; } + } + + /// + /// Package is safe to load on a background thread. + /// + public bool AllowsBackgroundLoading + { + get { return allowsBackgroundLoad; } + set { allowsBackgroundLoad = value; } + } + + /// + /// To specify a resource dll located in a different location then the default, + /// set this property. This can be useful if your package is installed in the GAC. + /// If this is not set, the directory where the package is located will be use. + /// + /// Note that the dll should be located at the following path: + /// SatellitePath\lcid\PackageDllNameUI.dll + /// + public string SatellitePath + { + get { return satellitePath; } + set { satellitePath = value; } + } + + private string RegKeyName(RegistrationContext context) + { + return String.Format(CultureInfo.InvariantCulture, "Packages\\{0}", context.ComponentType.GUID.ToString("B")); + } + + /// + /// Called to register this attribute with the given context. The context + /// contains the location where the registration information should be placed. + /// it also contains such as the type being registered, and path information. + /// + /// This method is called both for registration and unregistration. The difference is + /// that unregistering just uses a hive that reverses the changes applied to it. + /// + /// + /// Contains the location where the registration information should be placed. + /// It also contains other information such as the type being registered + /// and path of the assembly. + /// + public override void Register(RegistrationContext context) { + Type t = context.ComponentType; + + Key packageKey = null; + try + { + packageKey = context.CreateKey(RegKeyName(context)); + + //use a friendly description if it exists. + DescriptionAttribute attr = TypeDescriptor.GetAttributes(t)[typeof(DescriptionAttribute)] as DescriptionAttribute; + if (attr != null && !String.IsNullOrEmpty(attr.Description)) { + packageKey.SetValue(string.Empty, attr.Description); + } + else { + packageKey.SetValue(string.Empty, t.Name); + } + + packageKey.SetValue("InprocServer32", context.InprocServerPath); + packageKey.SetValue("Class", t.FullName); + + // If specified on the command line, let the command line option override + if (context.RegistrationMethod != RegistrationMethod.Default) + { + registrationMethod = context.RegistrationMethod; + } + + // Select registration method + switch (registrationMethod) + { + case RegistrationMethod.Assembly: + case RegistrationMethod.Default: + packageKey.SetValue("Assembly", t.Assembly.FullName); + break; + + case RegistrationMethod.CodeBase: + packageKey.SetValue("CodeBase", context.CodeBase); + break; + } + + Key childKey = null; + if (!useManagedResources) + { + try + { + childKey = packageKey.CreateSubkey("SatelliteDll"); + + // Register the satellite dll + string satelliteDllPath; + if (SatellitePath != null) + { + // Use provided path + satelliteDllPath = context.EscapePath(SatellitePath); + } + else + { + // Default to package path + satelliteDllPath = context.ComponentPath; + } + childKey.SetValue("Path", satelliteDllPath); + childKey.SetValue("DllName", String.Format(CultureInfo.InvariantCulture, "{0}UI.dll", Path.GetFileNameWithoutExtension(t.Assembly.ManifestModule.Name))); + } + finally + { + if (childKey != null) + childKey.Close(); + } + } + + if (allowsBackgroundLoad) + { + packageKey.SetValue("AllowsBackgroundLoad", true); + } + + if (typeof(IVsPackageDynamicToolOwner).IsAssignableFrom(context.ComponentType) || + typeof(IVsPackageDynamicToolOwnerEx).IsAssignableFrom(context.ComponentType)) + { + packageKey.SetValue("SupportsDynamicToolOwner", Microsoft.VisualStudio.PlatformUI.Boxes.BooleanTrue); + } + } + finally + { + if (packageKey != null) + packageKey.Close(); + } + } + + /// + /// Unregister this package. + /// + /// + public override void Unregister(RegistrationContext context) + { + context.RemoveKey(RegKeyName(context)); + } + + } +} diff --git a/GoogleTestAdapter/VsPackage.GTA/AsyncPackage/ExtensionMethods.cs b/GoogleTestAdapter/VsPackage.GTA/AsyncPackage/ExtensionMethods.cs new file mode 100644 index 000000000..1fc1376f8 --- /dev/null +++ b/GoogleTestAdapter/VsPackage.GTA/AsyncPackage/ExtensionMethods.cs @@ -0,0 +1,48 @@ +using System; +using System.Runtime.InteropServices; +using Microsoft.VisualStudio.Shell.Interop; +using System.Threading.Tasks; +using Microsoft.VisualStudio.Shell; + +namespace Microsoft.VisualStudio.AsyncPackageHelpers +{ + public static class ExtensionMethods + { + /// + /// Helper method to use async/await with IAsyncServiceProvider implementation + /// + /// IAsyncServciceProvider instance + /// Type of the Visual Studio service requested + /// Service object as type of T + public static async Task GetServiceAsync(this IAsyncServiceProvider asyncServiceProvider, Type serviceType) where T : class + { + T returnValue = null; + + await ThreadHelper.JoinableTaskFactory.RunAsync(async () => + { + object serviceInstance = null; + Guid serviceTypeGuid = serviceType.GUID; + serviceInstance = await asyncServiceProvider.QueryServiceAsync(ref serviceTypeGuid); + + // We have to make sure we are on main UI thread before trying to cast as underlying implementation + // can be an STA COM object and doing a cast would require calling QueryInterface/AddRef marshaling + // to main thread via COM. + await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); + returnValue = serviceInstance as T; + }); + + return returnValue; + } + + /// + /// Gets if async package is supported in the current instance of Visual Studio + /// + /// an IServiceProvider instance, usually a Package instance + /// true if async packages are supported + public static bool IsAsyncPackageSupported(this IServiceProvider serviceProvider) + { + IAsyncServiceProvider asyncServiceProvider = serviceProvider.GetService(typeof(SAsyncServiceProvider)) as IAsyncServiceProvider; + return asyncServiceProvider != null; + } + } +} \ No newline at end of file diff --git a/GoogleTestAdapter/VsPackage.GTA/AsyncPackage/ProvideAutoLoadAttribute.cs b/GoogleTestAdapter/VsPackage.GTA/AsyncPackage/ProvideAutoLoadAttribute.cs new file mode 100644 index 000000000..cf0f3103a --- /dev/null +++ b/GoogleTestAdapter/VsPackage.GTA/AsyncPackage/ProvideAutoLoadAttribute.cs @@ -0,0 +1,118 @@ +//------------------------------------------------------------------------------ +// +// Copyright (c) Microsoft Corporation, All rights reserved. +// This code sample is provided "AS IS" without warranty of any kind, +// it is not recommended for use in a production environment. +// +//------------------------------------------------------------------------------ + +namespace Microsoft.VisualStudio.AsyncPackageHelpers +{ + + using System; + using System.Globalization; + using Microsoft.VisualStudio.Shell; + + [Flags] + public enum PackageAutoLoadFlags + { + /// + /// Indicates no special auto-load behavior. This is the default flag value if not specified. + /// + None = 0x0, + + /// + /// When set package will not auto load in newer Visual Studio versions with rule based UI contexts + /// + SkipWhenUIContextRulesActive = 0x1, + + /// + /// When set, if the associated package is marked as allowing background loads (via the ), + /// then the package will be loaded asynchronously, in the background, when the associated UI context is triggered. + /// + BackgroundLoad = 0x2 + } + + /// + /// This attribute registers the package as an extender. The GUID passed in determines + /// what is being extended. The attributes on a package do not control the behavior of + /// the package, but they can be used by registration tools to register the proper + /// information with Visual Studio. + /// + [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)] + public sealed class ProvideAutoLoadAttribute : RegistrationAttribute + { + + private Guid loadGuid = Guid.Empty; + + /// + /// Specify that the package should get loaded when this context is active. + /// + /// Context which should trigger the loading of your package. + public ProvideAutoLoadAttribute(string cmdUiContextGuid) : this(cmdUiContextGuid, PackageAutoLoadFlags.None) + { + } + + /// + /// Specify that the package should get loaded when this context is active. + /// + /// Context which should trigger the loading of your package. + public ProvideAutoLoadAttribute(string cmdUiContextGuid, PackageAutoLoadFlags flags = PackageAutoLoadFlags.None) + { + loadGuid = new Guid(cmdUiContextGuid); + Flags = flags; + } + + /// + /// Context Guid which triggers the loading of the package. + /// + public Guid LoadGuid + { + get + { + return loadGuid; + } + } + + /// + /// Specifies the options for package auto load entry + /// + public PackageAutoLoadFlags Flags + { + get; + private set; + } + + /// + /// The reg key name of this AutoLoad. + /// + private string RegKeyName + { + get + { + return string.Format(CultureInfo.InvariantCulture, "AutoLoadPackages\\{0}", loadGuid.ToString("B")); + } + } + + /// + /// Called to register this attribute with the given context. The context + /// contains the location where the registration information should be placed. + /// it also contains such as the type being registered, and path information. + /// + public override void Register(RegistrationContext context) + { + using (Key childKey = context.CreateKey(RegKeyName)) + { + childKey.SetValue(context.ComponentType.GUID.ToString("B"), (int)Flags); + } + } + + /// + /// Unregister this AutoLoad specification. + /// + public override void Unregister(RegistrationContext context) + { + context.RemoveValue(RegKeyName, context.ComponentType.GUID.ToString("B")); + } + } +} diff --git a/GoogleTestAdapter/VsPackage.GTA/GoogleTestExtensionOptionsPage.cs b/GoogleTestAdapter/VsPackage.GTA/GoogleTestExtensionOptionsPage.cs index e49755ce4..faeff3bbc 100644 --- a/GoogleTestAdapter/VsPackage.GTA/GoogleTestExtensionOptionsPage.cs +++ b/GoogleTestAdapter/VsPackage.GTA/GoogleTestExtensionOptionsPage.cs @@ -1,6 +1,10 @@ -// This file has been modified by Microsoft on 9/2017. +// This file has been modified by Microsoft on 3/2019. +using GoogleTestAdapter.TestAdapter.Settings; using GoogleTestAdapter.VsPackage.ReleaseNotes; +using Microsoft.VisualStudio; +using Microsoft.VisualStudio.AsyncPackageHelpers; +using Microsoft.VisualStudio.ComponentModelHost; using Microsoft.VisualStudio.Shell; using Microsoft.VisualStudio.Shell.Interop; using System; @@ -9,15 +13,52 @@ namespace GoogleTestAdapter.VsPackage { - [ProvideAutoLoad(UIContextGuids.SolutionExists)] - public partial class GoogleTestExtensionOptionsPage + [AsyncPackageRegistration(UseManagedResourcesOnly = true, AllowsBackgroundLoading = true)] + [Microsoft.VisualStudio.AsyncPackageHelpers.ProvideAutoLoad(VSConstants.UICONTEXT.NoSolution_string, PackageAutoLoadFlags.BackgroundLoad)] + [Microsoft.VisualStudio.Shell.ProvideAutoLoad(UIContextGuids.SolutionExists)] + public partial class GoogleTestExtensionOptionsPage : Package, IAsyncLoadablePackageInitialize { private const string PackageGuidString = "e7c90fcb-0943-4908-9ae8-3b6a9d22ec9e"; private const string OptionsCategoryName = "Google Test Adapter"; + private bool _isAsyncLoadSupported; + + protected override void Initialize() + { + base.Initialize(); + + _isAsyncLoadSupported = this.IsAsyncPackageSupported(); + if (!_isAsyncLoadSupported) + { + var componentModel = (IComponentModel)GetGlobalService(typeof(SComponentModel)); + _globalRunSettings = componentModel.GetService(); + DoInitialize(); + } + } + + IVsTask IAsyncLoadablePackageInitialize.Initialize(IAsyncServiceProvider serviceProvider, IProfferAsyncService profferService, + IAsyncProgressCallback progressCallback) + { + if (!_isAsyncLoadSupported) + { + throw new InvalidOperationException("Async Initialize method should not be called when async load is not supported."); + } + + return ThreadHelper.JoinableTaskFactory.RunAsync(async () => + { + var componentModel = await serviceProvider.GetServiceAsync(typeof(SComponentModel)); + _globalRunSettings = componentModel.GetService(); + + await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); + + DoInitialize(); + + return null; + }).AsVsTask(); + } private void DisplayReleaseNotesIfNecessary() { - var thread = new Thread(DisplayReleaseNotesIfNecessaryProc); + var thread = new System.Threading.Thread(DisplayReleaseNotesIfNecessaryProc); thread.SetApartmentState(ApartmentState.STA); thread.Start(); } diff --git a/GoogleTestAdapter/VsPackage.GTA/VsPackage.GTA.csproj b/GoogleTestAdapter/VsPackage.GTA/VsPackage.GTA.csproj index 649bdab33..f9b9c0288 100644 --- a/GoogleTestAdapter/VsPackage.GTA/VsPackage.GTA.csproj +++ b/GoogleTestAdapter/VsPackage.GTA/VsPackage.GTA.csproj @@ -44,6 +44,7 @@ $(FlavoredTargetFrameworkVersion) true false + False true @@ -69,6 +70,9 @@ False + + + Component @@ -136,82 +140,92 @@ + + $(NuGetPackages)CommonMark.NET.0.15.1\lib\net45\CommonMark.dll + + ..\..\NuGetPackages\VSSDK.DTE.7.0.4\lib\net20\envdte.dll False - $(NuGetPackages)VSSDK.DTE.7.0.4\lib\net20\envdte.dll - True + False + ..\..\NuGetPackages\VSSDK.DTE.10.10.0.4\lib\net20\envdte100.dll False - $(NuGetPackages)VSSDK.DTE.10.10.0.4\lib\net20\envdte100.dll - True + False + ..\..\NuGetPackages\VSSDK.DTE.8.8.0.4\lib\net20\envdte80.dll False - $(NuGetPackages)VSSDK.DTE.8.8.0.4\lib\net20\envdte80.dll - True + False + ..\..\NuGetPackages\VSSDK.DTE.9.9.0.4\lib\net20\envdte90.dll False - $(NuGetPackages)VSSDK.DTE.9.9.0.4\lib\net20\envdte90.dll - True + False + ..\..\NuGetPackages\VSSDK.DTE.9.9.0.4\lib\net20\envdte90a.dll False - $(NuGetPackages)VSSDK.DTE.9.9.0.4\lib\net20\envdte90a.dll - True - - - $(NuGetPackages)CommonMark.NET.0.15.1\lib\net45\CommonMark.dll + False - - $(NuGetPackages)VSSDK.ComponentModelHost.11.0.4\lib\net45\Microsoft.VisualStudio.ComponentModelHost.dll + + ..\..\NuGetPackages\VSSDK.ComponentModelHost.12.0.4\lib\net45\Microsoft.VisualStudio.ComponentModelHost.dll False - $(NuGetPackages)VSSDK.GraphModel.11.0.4\lib\net45\Microsoft.VisualStudio.GraphModel.dll + ..\..\NuGetPackages\VSSDK.GraphModel.11.0.4\lib\net45\Microsoft.VisualStudio.GraphModel.dll False - $(NuGetPackages)VSSDK.OLE.Interop.7.0.4\lib\net20\Microsoft.VisualStudio.OLE.Interop.dll - True + ..\..\NuGetPackages\VSSDK.OLE.Interop.7.0.4\lib\net20\Microsoft.VisualStudio.OLE.Interop.dll False - - $(NuGetPackages)VSSDK.Shell.11.11.0.0\lib\net45\Microsoft.VisualStudio.Shell.11.0.dll - True + + ..\..\NuGetPackages\VSSDK.Shell.12.12.0.4\lib\net45\Microsoft.VisualStudio.Shell.12.0.dll + False - $(NuGetPackages)VSSDK.Shell.Immutable.10.10.0.4\lib\net40\Microsoft.VisualStudio.Shell.Immutable.10.0.dll - True + ..\..\NuGetPackages\VSSDK.Shell.Immutable.10.10.0.4\lib\net40\Microsoft.VisualStudio.Shell.Immutable.10.0.dll False - $(NuGetPackages)VSSDK.Shell.Immutable.11.11.0.4\lib\net45\Microsoft.VisualStudio.Shell.Immutable.11.0.dll - True + ..\..\NuGetPackages\VSSDK.Shell.Immutable.11.11.0.4\lib\net45\Microsoft.VisualStudio.Shell.Immutable.11.0.dll + False + + + ..\..\NuGetPackages\VSSDK.Shell.Immutable.12.12.0.4\lib\net45\Microsoft.VisualStudio.Shell.Immutable.12.0.dll False - $(NuGetPackages)VSSDK.Shell.Interop.7.0.4\lib\net20\Microsoft.VisualStudio.Shell.Interop.dll - True + ..\..\NuGetPackages\VSSDK.Shell.Interop.7.0.4\lib\net20\Microsoft.VisualStudio.Shell.Interop.dll False - $(NuGetPackages)VSSDK.Shell.Interop.10.10.0.0\lib\net20\Microsoft.VisualStudio.Shell.Interop.10.0.dll + ..\..\NuGetPackages\VSSDK.Shell.Interop.10.10.0.4\lib\net20\Microsoft.VisualStudio.Shell.Interop.10.0.dll + False False - $(NuGetPackages)VSSDK.Shell.Interop.11.11.0.0\lib\net20\Microsoft.VisualStudio.Shell.Interop.11.0.dll + ..\..\NuGetPackages\VSSDK.Shell.Interop.11.11.0.4\lib\net20\Microsoft.VisualStudio.Shell.Interop.11.0.dll + False False + + ..\..\NuGetPackages\VSSDK.Shell.Interop.12.12.0.4\lib\net20\Microsoft.VisualStudio.Shell.Interop.12.0.dll + False + False + + + True + - $(NuGetPackages)VSSDK.Shell.Interop.10.10.0.0\lib\net20\Microsoft.VisualStudio.Shell.Interop.8.0.dll + ..\..\NuGetPackages\VSSDK.Shell.Interop.8.8.0.4\lib\net20\Microsoft.VisualStudio.Shell.Interop.8.0.dll False - $(NuGetPackages)VSSDK.Shell.Interop.10.10.0.0\lib\net20\Microsoft.VisualStudio.Shell.Interop.9.0.dll + ..\..\NuGetPackages\VSSDK.Shell.Interop.9.9.0.4\lib\net20\Microsoft.VisualStudio.Shell.Interop.9.0.dll False @@ -223,29 +237,33 @@ True - $(NuGetPackages)VSSDK.TextManager.Interop.7.0.4\lib\net20\Microsoft.VisualStudio.TextManager.Interop.dll - True + ..\..\NuGetPackages\VSSDK.TextManager.Interop.7.0.4\lib\net20\Microsoft.VisualStudio.TextManager.Interop.dll False + ..\..\NuGetPackages\VSSDK.TextManager.Interop.10.10.0.4\lib\net20\Microsoft.VisualStudio.TextManager.Interop.10.0.dll False - $(NuGetPackages)VSSDK.TextManager.Interop.10.10.0.4\lib\net20\Microsoft.VisualStudio.TextManager.Interop.10.0.dll - True + False - $(NuGetPackages)VSSDK.TextManager.Interop.8.8.0.4\lib\net20\Microsoft.VisualStudio.TextManager.Interop.8.0.dll - True + ..\..\NuGetPackages\VSSDK.TextManager.Interop.8.8.0.4\lib\net20\Microsoft.VisualStudio.TextManager.Interop.8.0.dll + False False - $(NuGetPackages)VSSDK.TextManager.Interop.9.9.0.4\lib\net20\Microsoft.VisualStudio.TextManager.Interop.9.0.dll - True + ..\..\NuGetPackages\VSSDK.TextManager.Interop.9.9.0.4\lib\net20\Microsoft.VisualStudio.TextManager.Interop.9.0.dll + False + + + ..\..\NuGetPackages\VSSDK.Threading.12.0.4\lib\net45\Microsoft.VisualStudio.Threading.dll False + + + ..\..\NuGetPackages\VSSDK.DTE.7.0.4\lib\net20\stdole.dll False - $(NuGetPackages)VSSDK.DTE.7.0.4\lib\net20\stdole.dll - True + False @@ -253,8 +271,12 @@ + + + + diff --git a/GoogleTestAdapter/VsPackage.GTA/packages.config b/GoogleTestAdapter/VsPackage.GTA/packages.config index 5e0560398..cb463d7a3 100644 --- a/GoogleTestAdapter/VsPackage.GTA/packages.config +++ b/GoogleTestAdapter/VsPackage.GTA/packages.config @@ -5,29 +5,34 @@ - - + + - + - - + + - - + + + + + + + \ No newline at end of file diff --git a/GoogleTestAdapter/VsPackage.Shared/GoogleTestExtensionOptionsPage.cs b/GoogleTestAdapter/VsPackage.Shared/GoogleTestExtensionOptionsPage.cs index 0d819e02b..0b48ed17d 100644 --- a/GoogleTestAdapter/VsPackage.Shared/GoogleTestExtensionOptionsPage.cs +++ b/GoogleTestAdapter/VsPackage.Shared/GoogleTestExtensionOptionsPage.cs @@ -1,4 +1,4 @@ -// This file has been modified by Microsoft on 5/2018. +// This file has been modified by Microsoft on 3/2019. using GoogleTestAdapter.Settings; using GoogleTestAdapter.TestAdapter.Settings; @@ -7,7 +7,6 @@ using GoogleTestAdapter.VsPackage.Helpers; using GoogleTestAdapter.VsPackage.OptionsPages; using Microsoft.VisualStudio; -using Microsoft.VisualStudio.ComponentModelHost; using Microsoft.VisualStudio.Shell; using Microsoft.VisualStudio.Shell.Interop; using System; @@ -15,13 +14,10 @@ using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; using System.ServiceModel; -using System.Threading; -using Task = System.Threading.Tasks.Task; namespace GoogleTestAdapter.VsPackage { - [PackageRegistration(AllowsBackgroundLoading = true, UseManagedResourcesOnly = true)] [InstalledProductRegistration("#110", "#112", "1.0", IconResourceID = 400)] // Info on this package for Help/About [Guid(PackageGuidString)] [SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1650:ElementDocumentationMustBeSpelledCorrectly", Justification = "pkgdef, VS and vsixmanifest are valid VS terms")] @@ -29,7 +25,7 @@ namespace GoogleTestAdapter.VsPackage [ProvideOptionPage(typeof(ParallelizationOptionsDialogPage), OptionsCategoryName, "Parallelization", 110, 502, true)] [ProvideOptionPage(typeof(GoogleTestOptionsDialogPage), OptionsCategoryName, "Google Test", 110, 503, true)] [ProvideMenuResource("Menus.ctmenu", 1)] - public sealed partial class GoogleTestExtensionOptionsPage : AsyncPackage, IGoogleTestExtensionOptionsPage, IDisposable + public sealed partial class GoogleTestExtensionOptionsPage : IGoogleTestExtensionOptionsPage, IDisposable { private readonly string _debuggingNamedPipeId = Guid.NewGuid().ToString(); @@ -42,32 +38,38 @@ public sealed partial class GoogleTestExtensionOptionsPage : AsyncPackage, IGoog // ReSharper disable once NotAccessedField.Local private DebuggerAttacherServiceHost _debuggerAttacherServiceHost; - protected override async Task InitializeAsync(CancellationToken cancellationToken, IProgress progress) + private void DoInitialize() { - await base.InitializeAsync(cancellationToken, progress); - - var componentModel = await GetServiceAsync(typeof(SComponentModel)) as IComponentModel; - _globalRunSettings = componentModel.GetService(); - - await this.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken); + InitializeOptions(); + InitializeCommands(); + InitializeDebuggerAttacherService(); + DisplayReleaseNotesIfNecessary(); + } - _generalOptions = (GeneralOptionsDialogPage)GetDialogPage(typeof(GeneralOptionsDialogPage)); - _parallelizationOptions = (ParallelizationOptionsDialogPage)GetDialogPage(typeof(ParallelizationOptionsDialogPage)); - _googleTestOptions = (GoogleTestOptionsDialogPage)GetDialogPage(typeof(GoogleTestOptionsDialogPage)); + private void InitializeOptions() + { + _generalOptions = (GeneralOptionsDialogPage) GetDialogPage(typeof(GeneralOptionsDialogPage)); + _parallelizationOptions = + (ParallelizationOptionsDialogPage) GetDialogPage(typeof(ParallelizationOptionsDialogPage)); + _googleTestOptions = (GoogleTestOptionsDialogPage) GetDialogPage(typeof(GoogleTestOptionsDialogPage)); _globalRunSettings.RunSettings = GetRunSettingsFromOptionPages(); _generalOptions.PropertyChanged += OptionsChanged; _parallelizationOptions.PropertyChanged += OptionsChanged; _googleTestOptions.PropertyChanged += OptionsChanged; + } + private void InitializeCommands() + { SwitchCatchExceptionsOptionCommand.Initialize(this); SwitchBreakOnFailureOptionCommand.Initialize(this); SwitchParallelExecutionOptionCommand.Initialize(this); SwitchPrintTestOutputOptionCommand.Initialize(this); + } - DisplayReleaseNotesIfNecessary(); - + private void InitializeDebuggerAttacherService() + { var logger = new ActivityLogLogger(this, () => _generalOptions.DebugMode); var debuggerAttacher = new VsDebuggerAttacher(this); _debuggerAttacherServiceHost = new DebuggerAttacherServiceHost(_debuggingNamedPipeId, debuggerAttacher, logger); @@ -103,15 +105,11 @@ protected override void Dispose(bool disposing) try { - // Cannot simply do ".?" because Code Analysis does not understand that. - if (_debuggerAttacherServiceHost != null) - { - _debuggerAttacherServiceHost.Close(); - } + _debuggerAttacherServiceHost?.Close(); } catch (CommunicationException) { - _debuggerAttacherServiceHost.Abort(); + _debuggerAttacherServiceHost?.Abort(); } } base.Dispose(disposing); diff --git a/GoogleTestAdapter/VsPackage.TAfGT/GoogleTestExtensionOptionsPage.cs b/GoogleTestAdapter/VsPackage.TAfGT/GoogleTestExtensionOptionsPage.cs index 82fc793cf..4dccad96f 100644 --- a/GoogleTestAdapter/VsPackage.TAfGT/GoogleTestExtensionOptionsPage.cs +++ b/GoogleTestAdapter/VsPackage.TAfGT/GoogleTestExtensionOptionsPage.cs @@ -1,22 +1,39 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using GoogleTestAdapter.TestAdapter.Settings; using Microsoft.VisualStudio; +using Microsoft.VisualStudio.ComponentModelHost; using Microsoft.VisualStudio.Shell; +using System; +using System.Threading; namespace GoogleTestAdapter.VsPackage { + [PackageRegistration(AllowsBackgroundLoading = true, UseManagedResourcesOnly = true)] [ProvideAutoLoad(UIContextGuid, PackageAutoLoadFlags.BackgroundLoad)] [ProvideUIContextRule(UIContextGuid, OptionsCategoryName, "VCProject & TestExplorer", new string[] { "VCProject", "TestExplorer" }, new string[] { VSConstants.UICONTEXT.VCProject_string, TestExplorerContextGuid })] - public partial class GoogleTestExtensionOptionsPage + public partial class GoogleTestExtensionOptionsPage : AsyncPackage { private const string PackageGuidString = "6fac3232-df1d-400a-95ac-7daeaaee74ac"; private const string UIContextGuid = "7517f9ae-397f-48e1-8e1b-dac609d9f52d"; private const string TestExplorerContextGuid = "ec25b527-d893-4ec0-a814-d2c9f1782997"; private const string OptionsCategoryName = "Test Adapter for Google Test"; + protected override async System.Threading.Tasks.Task InitializeAsync(CancellationToken cancellationToken, IProgress progress) + { + await base.InitializeAsync(cancellationToken, progress); + + var componentModel = await GetServiceAsync(typeof(SComponentModel)) as IComponentModel; + _globalRunSettings = componentModel.GetService(); + + await this.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken); + + DoInitialize(); + } + private void DisplayReleaseNotesIfNecessary() { // TAfGT does not display release notes.