diff --git a/src/NuGet.Clients/NuGet.PackageManagement.PowerShellCmdlets/NuGetPowerShellBaseCommand.cs b/src/NuGet.Clients/NuGet.PackageManagement.PowerShellCmdlets/NuGetPowerShellBaseCommand.cs index 73bf87ce4..0b5917d81 100644 --- a/src/NuGet.Clients/NuGet.PackageManagement.PowerShellCmdlets/NuGetPowerShellBaseCommand.cs +++ b/src/NuGet.Clients/NuGet.PackageManagement.PowerShellCmdlets/NuGetPowerShellBaseCommand.cs @@ -793,7 +793,7 @@ namespace NuGet.PackageManagement.PowerShellCmdlets { var notFoundException = new ItemNotFoundException( - String.Format( + string.Format( CultureInfo.CurrentCulture, Resources.Cmdlet_ProjectNotFound, projectName)); @@ -831,7 +831,7 @@ namespace NuGet.PackageManagement.PowerShellCmdlets [SuppressMessage("Microsoft.Usage", "CA2201:DoNotRaiseReservedExceptionTypes", Justification = "This exception is passed to PowerShell. We really don't care about the type of exception here.")] protected void WriteError(string message) { - if (!String.IsNullOrEmpty(message)) + if (!string.IsNullOrEmpty(message)) { WriteError(new Exception(message)); } @@ -1043,7 +1043,7 @@ namespace NuGet.PackageManagement.PowerShellCmdlets if (path != null) { string command = "& " + PathUtility.EscapePSPath(path) + " $__rootPath $__toolsPath $__package $__project"; - LogCore(MessageLevel.Info, String.Format(CultureInfo.CurrentCulture, Resources.Cmdlet_ExecutingScript, path)); + LogCore(MessageLevel.Info, string.Format(CultureInfo.CurrentCulture, Resources.Cmdlet_ExecutingScript, path)); InvokeCommand.InvokeScript(command, false, PipelineResultTypes.Error, null, null); } diff --git a/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/Handlers/ProjectRetargetingHandler.cs b/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/Handlers/ProjectRetargetingHandler.cs index 556caa2f2..465e16168 100644 --- a/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/Handlers/ProjectRetargetingHandler.cs +++ b/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/Handlers/ProjectRetargetingHandler.cs @@ -149,8 +149,8 @@ namespace NuGet.PackageManagement.VisualStudio var packageReferencesToBeReinstalled = ProjectRetargetingUtility.GetPackageReferencesMarkedForReinstallation(nuGetProject); if (packageReferencesToBeReinstalled.Count > 0) { - Debug.Assert(ProjectRetargetingUtility.IsNuGetInUse(project)); - var projectHierarchy = project.ToVsHierarchy(); + Debug.Assert(await ProjectRetargetingUtility.IsNuGetInUseAsync(project)); + var projectHierarchy = await project.ToVsHierarchyAsync(); ShowRetargetingErrorTask(packageReferencesToBeReinstalled.Select(p => p.PackageIdentity.Id), projectHierarchy, TaskErrorCategory.Warning, TaskPriority.Normal); } } @@ -275,9 +275,9 @@ namespace NuGet.PackageManagement.VisualStudio if (packagesToBeReinstalled.Count > 0) { // By asserting that NuGet is in use, we are also asserting that NuGet.VisualStudio.dll is already loaded - // Hence, it is okay to call project.ToVsHierarchy() - Debug.Assert(ProjectRetargetingUtility.IsNuGetInUse(project)); - var projectHierarchy = project.ToVsHierarchy(); + // Hence, it is okay to call project.ToVsHierarchyAsync() + Debug.Assert(await ProjectRetargetingUtility.IsNuGetInUseAsync(project)); + var projectHierarchy = await project.ToVsHierarchyAsync(); ShowRetargetingErrorTask(packagesToBeReinstalled.Select(p => p.Id), projectHierarchy, TaskErrorCategory.Error, TaskPriority.High); } // NuGet/Home#4833 Baseline diff --git a/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/IDE/VSSolutionManager.cs b/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/IDE/VSSolutionManager.cs index bf80343f4..991de3adb 100644 --- a/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/IDE/VSSolutionManager.cs +++ b/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/IDE/VSSolutionManager.cs @@ -366,9 +366,16 @@ namespace NuGet.PackageManagement.VisualStudio // first check with DTE, and if we find any supported project, then return immediately. var dte = await _asyncServiceProvider.GetDTEAsync(); - var isSupported = EnvDTESolutionUtility.GetAllEnvDTEProjects(dte) - .Where(EnvDTEProjectUtility.IsSupported) - .Any(); + var isSupported = false; + + foreach (Project project in await EnvDTESolutionUtility.GetAllEnvDTEProjectsAsync(dte)) + { + if (await EnvDTEProjectUtility.IsSupportedAsync(project)) + { + isSupported = true; + break; + } + } return isSupported; } @@ -540,15 +547,13 @@ namespace NuGet.PackageManagement.VisualStudio private void OnEnvDTEProjectRenamed(Project envDTEProject, string oldName) { - NuGetUIThreadHelper.JoinableTaskFactory.RunAsync(async () => + NuGetUIThreadHelper.JoinableTaskFactory.Run(async () => { - await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); - if (!string.IsNullOrEmpty(oldName) && await IsSolutionOpenAsync() && _solutionOpenedRaised) { await EnsureNuGetAndVsProjectAdapterCacheAsync(); - if (EnvDTEProjectUtility.IsSupported(envDTEProject)) + if (await EnvDTEProjectUtility.IsSupportedAsync(envDTEProject)) { RemoveVsProjectAdapterFromCache(oldName); @@ -565,11 +570,11 @@ namespace NuGet.PackageManagement.VisualStudio AfterNuGetProjectRenamed?.Invoke(this, new NuGetProjectEventArgs(nuGetProject)); } - else if (EnvDTEProjectUtility.IsSolutionFolder(envDTEProject)) + else if (await EnvDTEProjectUtility.IsSolutionFolderAsync(envDTEProject)) { // In the case where a solution directory was changed, project FullNames are unchanged. // We only need to invalidate the projects under the current tree so as to sync the CustomUniqueNames. - foreach (var item in EnvDTEProjectUtility.GetSupportedChildProjects(envDTEProject)) + foreach (var item in await EnvDTEProjectUtility.GetSupportedChildProjectsAsync(envDTEProject)) { RemoveVsProjectAdapterFromCache(item.FullName); @@ -596,12 +601,10 @@ namespace NuGet.PackageManagement.VisualStudio private void OnEnvDTEProjectAdded(Project envDTEProject) { - NuGetUIThreadHelper.JoinableTaskFactory.RunAsync(async () => + NuGetUIThreadHelper.JoinableTaskFactory.Run(async () => { - await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); - if (await IsSolutionOpenAsync() - && EnvDTEProjectUtility.IsSupported(envDTEProject) + && await EnvDTEProjectUtility.IsSupportedAsync(envDTEProject) && !EnvDTEProjectUtility.IsParentProjectExplicitlyUnsupported(envDTEProject) && _solutionOpenedRaised) { @@ -659,9 +662,14 @@ namespace NuGet.PackageManagement.VisualStudio { var dte = await _asyncServiceProvider.GetDTEAsync(); - var supportedProjects = EnvDTESolutionUtility - .GetAllEnvDTEProjects(dte) - .Where(EnvDTEProjectUtility.IsSupported); + var supportedProjects = new List(); + foreach (Project project in await EnvDTESolutionUtility.GetAllEnvDTEProjectsAsync(dte)) + { + if (await EnvDTEProjectUtility.IsSupportedAsync(project)) + { + supportedProjects.Add(project); + } + } foreach (var project in supportedProjects) { @@ -697,7 +705,7 @@ namespace NuGet.PackageManagement.VisualStudio private async Task AddVsProjectAdapterToCacheAsync(IVsProjectAdapter vsProjectAdapter) { - if (!vsProjectAdapter.IsSupported) + if (!await vsProjectAdapter.IsSupportedAsync()) { return; } diff --git a/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/ProjectServices/VsCoreProjectSystemReferenceReader.cs b/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/ProjectServices/VsCoreProjectSystemReferenceReader.cs index 7891c6790..ba2304328 100644 --- a/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/ProjectServices/VsCoreProjectSystemReferenceReader.cs +++ b/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/ProjectServices/VsCoreProjectSystemReferenceReader.cs @@ -74,7 +74,7 @@ namespace NuGet.PackageManagement.VisualStudio continue; } - if (EnvDTEProjectUtility.HasUnsupportedProjectCapability(reference3.SourceProject)) + if (await EnvDTEProjectUtility.HasUnsupportedProjectCapabilityAsync(reference3.SourceProject)) { // Skip this shared project continue; diff --git a/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/ProjectServices/VsManagedLanguagesProjectSystemServices.cs b/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/ProjectServices/VsManagedLanguagesProjectSystemServices.cs index d76bb1a2a..3c8a7be3f 100644 --- a/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/ProjectServices/VsManagedLanguagesProjectSystemServices.cs +++ b/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/ProjectServices/VsManagedLanguagesProjectSystemServices.cs @@ -31,7 +31,7 @@ namespace NuGet.PackageManagement.VisualStudio , IProjectSystemReferencesReader , IProjectSystemReferencesService { - private static readonly Array _referenceMetadata; + private static readonly Array ReferenceMetadata; private readonly IVsProjectAdapter _vsProjectAdapter; private readonly IVsProjectThreadingService _threadingService; @@ -59,13 +59,13 @@ namespace NuGet.PackageManagement.VisualStudio static VsManagedLanguagesProjectSystemServices() { - _referenceMetadata = Array.CreateInstance(typeof(string), 6); - _referenceMetadata.SetValue(ProjectItemProperties.IncludeAssets, 0); - _referenceMetadata.SetValue(ProjectItemProperties.ExcludeAssets, 1); - _referenceMetadata.SetValue(ProjectItemProperties.PrivateAssets, 2); - _referenceMetadata.SetValue(ProjectItemProperties.NoWarn, 3); - _referenceMetadata.SetValue(ProjectItemProperties.GeneratePathProperty, 4); - _referenceMetadata.SetValue(ProjectItemProperties.Aliases, 5); + ReferenceMetadata = Array.CreateInstance(typeof(string), 6); + ReferenceMetadata.SetValue(ProjectItemProperties.IncludeAssets, 0); + ReferenceMetadata.SetValue(ProjectItemProperties.ExcludeAssets, 1); + ReferenceMetadata.SetValue(ProjectItemProperties.PrivateAssets, 2); + ReferenceMetadata.SetValue(ProjectItemProperties.NoWarn, 3); + ReferenceMetadata.SetValue(ProjectItemProperties.GeneratePathProperty, 4); + ReferenceMetadata.SetValue(ProjectItemProperties.Aliases, 5); } public VsManagedLanguagesProjectSystemServices( @@ -108,7 +108,7 @@ namespace NuGet.PackageManagement.VisualStudio { if (AsVSProject4.PackageReferences.TryGetReference( installedPackage, - _referenceMetadata, + ReferenceMetadata, out var version, out var metadataElements, out var metadataValues)) @@ -139,23 +139,23 @@ namespace NuGet.PackageManagement.VisualStudio return new ProjectRestoreReference[] { }; } - var references = AsVSProject4.References - .Cast() - .Where(r => r.SourceProject != null && EnvDTEProjectUtility.IsSupported(r.SourceProject)) - .Select(reference => + var references = new List(); + foreach (Reference6 r in AsVSProject4.References.Cast()) + { + if (r.SourceProject != null && await EnvDTEProjectUtility.IsSupportedAsync(r.SourceProject)) { Array metadataElements; Array metadataValues; - reference.GetMetadata(_referenceMetadata, out metadataElements, out metadataValues); + r.GetMetadata(ReferenceMetadata, out metadataElements, out metadataValues); - return new ProjectReference( - uniqueName: reference.SourceProject.FullName, + references.Add(ToProjectRestoreReference(new ProjectReference( + uniqueName: r.SourceProject.FullName, metadataElements: metadataElements, - metadataValues: metadataValues); - }) - .Select(ToProjectRestoreReference); + metadataValues: metadataValues))); + } + } - return references.ToList(); + return references; } private static ProjectRestoreReference ToProjectRestoreReference(ProjectReference item) diff --git a/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/ProjectSystems/CpsProjectSystem.cs b/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/ProjectSystems/CpsProjectSystem.cs index a39ef70a9..780370169 100644 --- a/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/ProjectSystems/CpsProjectSystem.cs +++ b/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/ProjectSystems/CpsProjectSystem.cs @@ -31,13 +31,11 @@ namespace NuGet.PackageManagement.VisualStudio } NuGetUIThreadHelper.JoinableTaskFactory.Run(async delegate - { - await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); - - var root = VsProjectAdapter.ProjectDirectory; - var relativeTargetPath = PathUtility.GetRelativePath(PathUtility.EnsureTrailingSlash(root), targetFullPath); - await AddImportStatementAsync(location, relativeTargetPath); - }); + { + var root = await VsProjectAdapter.GetProjectDirectoryAsync(); + var relativeTargetPath = PathUtility.GetRelativePath(PathUtility.EnsureTrailingSlash(root), targetFullPath); + await AddImportStatementAsync(location, relativeTargetPath); + }); } [MethodImpl(MethodImplOptions.NoInlining)] @@ -62,14 +60,12 @@ namespace NuGet.PackageManagement.VisualStudio } NuGetUIThreadHelper.JoinableTaskFactory.Run(async delegate - { - await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); - - var root = VsProjectAdapter.ProjectDirectory; - // For VS 2012 or above, the operation has to be done inside the Writer lock - var relativeTargetPath = PathUtility.GetRelativePath(PathUtility.EnsureTrailingSlash(root), targetFullPath); - await RemoveImportStatementAsync(relativeTargetPath); - }); + { + var root = await VsProjectAdapter.GetProjectDirectoryAsync(); + // For VS 2012 or above, the operation has to be done inside the Writer lock + var relativeTargetPath = PathUtility.GetRelativePath(PathUtility.EnsureTrailingSlash(root), targetFullPath); + await RemoveImportStatementAsync(relativeTargetPath); + }); } // IMPORTANT: The NoInlining is required to prevent CLR from loading VisualStudio12.dll assembly while running diff --git a/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/ProjectSystems/VsMSBuildProjectSystem.cs b/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/ProjectSystems/VsMSBuildProjectSystem.cs index 5a204e7e8..c06f0e1b9 100644 --- a/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/ProjectSystems/VsMSBuildProjectSystem.cs +++ b/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/ProjectSystems/VsMSBuildProjectSystem.cs @@ -72,8 +72,7 @@ namespace NuGet.PackageManagement.VisualStudio { NuGetUIThreadHelper.JoinableTaskFactory.Run(async delegate { - await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); - _projectFullPath = VsProjectAdapter.ProjectDirectory; + _projectFullPath = await VsProjectAdapter.GetProjectDirectoryAsync(); }); } @@ -465,7 +464,7 @@ namespace NuGet.PackageManagement.VisualStudio { await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); - var containsFile = await EnvDTEProjectUtility.ContainsFile(VsProjectAdapter.Project, path); + var containsFile = await EnvDTEProjectUtility.ContainsFileAsync(VsProjectAdapter.Project, path); return containsFile; }); } diff --git a/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/Projects/CpsPackageReferenceProject.cs b/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/Projects/CpsPackageReferenceProject.cs index a09de3748..10b437b0e 100644 --- a/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/Projects/CpsPackageReferenceProject.cs +++ b/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/Projects/CpsPackageReferenceProject.cs @@ -207,7 +207,7 @@ namespace NuGet.PackageManagement.VisualStudio foreach (var projectReference in frameworkInfo.ProjectReferences) { - if (SupportedProjectTypes.IsSupportedProjectExtension(projectReference.ProjectPath)) + if (ProjectType.IsSupportedProjectExtension(projectReference.ProjectPath)) { projectReferences.Add(projectReference); } diff --git a/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/Projects/LegacyPackageReferenceProject.cs b/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/Projects/LegacyPackageReferenceProject.cs index 53c3edeee..63a4b9d2b 100644 --- a/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/Projects/LegacyPackageReferenceProject.cs +++ b/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/Projects/LegacyPackageReferenceProject.cs @@ -82,8 +82,7 @@ namespace NuGet.PackageManagement.VisualStudio public override async Task GetCacheFilePathAsync() { - await _threadingService.JoinableTaskFactory.SwitchToMainThreadAsync(); - return NoOpRestoreUtilities.GetProjectCacheFilePath(cacheRoot: GetMSBuildProjectExtensionsPath()); + return NoOpRestoreUtilities.GetProjectCacheFilePath(cacheRoot: await GetMSBuildProjectExtensionsPathAsync()); } public override async Task GetAssetsFilePathOrNullAsync() @@ -93,10 +92,7 @@ namespace NuGet.PackageManagement.VisualStudio private async Task GetAssetsFilePathAsync(bool shouldThrow) { - await _threadingService.JoinableTaskFactory.SwitchToMainThreadAsync(); - - var msbuildProjectExtensionsPath = GetMSBuildProjectExtensionsPath(shouldThrow); - + var msbuildProjectExtensionsPath = await GetMSBuildProjectExtensionsPathAsync(shouldThrow); if (msbuildProjectExtensionsPath == null) { return null; @@ -204,9 +200,9 @@ namespace NuGet.PackageManagement.VisualStudio { await _threadingService.JoinableTaskFactory.SwitchToMainThreadAsync(); - EnvDTEProjectUtility.EnsureCheckedOutIfExists(_vsProjectAdapter.Project, _vsProjectAdapter.ProjectDirectory, filePath); + EnvDTEProjectUtility.EnsureCheckedOutIfExists(_vsProjectAdapter.Project, await _vsProjectAdapter.GetProjectDirectoryAsync(), filePath); - var isFileExistsInProject = await EnvDTEProjectUtility.ContainsFile(_vsProjectAdapter.Project, filePath); + var isFileExistsInProject = await EnvDTEProjectUtility.ContainsFileAsync(_vsProjectAdapter.Project, filePath); if (!isFileExistsInProject) { @@ -221,18 +217,19 @@ namespace NuGet.PackageManagement.VisualStudio var folderPath = Path.GetDirectoryName(filePath); var fullPath = filePath; - if (filePath.Contains(_vsProjectAdapter.ProjectDirectory)) + string projectDirectory = await _vsProjectAdapter.GetProjectDirectoryAsync(); + if (filePath.Contains(projectDirectory)) { // folderPath should always be relative to ProjectDirectory so if filePath already contains // ProjectDirectory then get a relative path and construct folderPath to get the appropriate // ProjectItems from dte where you have to add this file. - var relativeLockFilePath = FileSystemUtility.GetRelativePath(_vsProjectAdapter.ProjectDirectory, filePath); + var relativeLockFilePath = FileSystemUtility.GetRelativePath(projectDirectory, filePath); folderPath = Path.GetDirectoryName(relativeLockFilePath); } else { // get the fullPath wrt ProjectDirectory - fullPath = FileSystemUtility.GetFullPath(_vsProjectAdapter.ProjectDirectory, filePath); + fullPath = FileSystemUtility.GetFullPath(projectDirectory, filePath); } var container = await EnvDTEProjectUtility.GetProjectItemsAsync(_vsProjectAdapter.Project, folderPath, createIfNotExists: true); @@ -250,11 +247,11 @@ namespace NuGet.PackageManagement.VisualStudio #endregion - private string GetMSBuildProjectExtensionsPath(bool shouldThrow = true) + private async Task GetMSBuildProjectExtensionsPathAsync(bool shouldThrow = true) { - ThreadHelper.ThrowIfNotOnUIThread(); + await _threadingService.JoinableTaskFactory.SwitchToMainThreadAsync(); - var msbuildProjectExtensionsPath = _vsProjectAdapter.MSBuildProjectExtensionsPath; + var msbuildProjectExtensionsPath = await _vsProjectAdapter.GetMSBuildProjectExtensionsPathAsync(); if (string.IsNullOrEmpty(msbuildProjectExtensionsPath)) { @@ -263,7 +260,7 @@ namespace NuGet.PackageManagement.VisualStudio throw new InvalidDataException(string.Format( Strings.MSBuildPropertyNotFound, ProjectBuildProperties.MSBuildProjectExtensionsPath, - _vsProjectAdapter.ProjectDirectory)); + await _vsProjectAdapter.GetProjectDirectoryAsync())); } return null; @@ -437,7 +434,7 @@ namespace NuGet.PackageManagement.VisualStudio RestoreMetadata = new ProjectRestoreMetadata { ProjectStyle = ProjectStyle.PackageReference, - OutputPath = GetMSBuildProjectExtensionsPath(), + OutputPath = await GetMSBuildProjectExtensionsPathAsync(), ProjectPath = _projectFullPath, ProjectName = projectName, ProjectUniqueName = _projectFullPath, diff --git a/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/Projects/MSBuildNuGetProjectProvider.cs b/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/Projects/MSBuildNuGetProjectProvider.cs index 293fd4850..9e5f18a01 100644 --- a/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/Projects/MSBuildNuGetProjectProvider.cs +++ b/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/Projects/MSBuildNuGetProjectProvider.cs @@ -69,7 +69,7 @@ namespace NuGet.PackageManagement.VisualStudio var folderNuGetProjectFullPath = context.PackagesPathFactory(); // Project folder path is the packages config folder path - var packagesConfigFolderPath = vsProjectAdapter.ProjectDirectory; + var packagesConfigFolderPath = await vsProjectAdapter.GetProjectDirectoryAsync(); return new VsMSBuildNuGetProject( vsProjectAdapter, diff --git a/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/Projects/VsProjectAdapter.cs b/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/Projects/VsProjectAdapter.cs index bee0a4c38..9e1dab377 100644 --- a/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/Projects/VsProjectAdapter.cs +++ b/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/Projects/VsProjectAdapter.cs @@ -35,19 +35,16 @@ namespace NuGet.PackageManagement.VisualStudio #region Properties - public string MSBuildProjectExtensionsPath + public async Task GetMSBuildProjectExtensionsPathAsync() { - get + var msbuildProjectExtensionsPath = BuildProperties.GetPropertyValue(ProjectBuildProperties.MSBuildProjectExtensionsPath); + + if (string.IsNullOrEmpty(msbuildProjectExtensionsPath)) { - var msbuildProjectExtensionsPath = BuildProperties.GetPropertyValue(ProjectBuildProperties.MSBuildProjectExtensionsPath); - - if (string.IsNullOrEmpty(msbuildProjectExtensionsPath)) - { - return null; - } - - return Path.Combine(ProjectDirectory, msbuildProjectExtensionsPath); + return null; } + + return Path.Combine(await GetProjectDirectoryAsync(), msbuildProjectExtensionsPath); } public string RestorePackagesPath @@ -101,18 +98,15 @@ namespace NuGet.PackageManagement.VisualStudio public string FullName => ProjectNames.FullName; - public string ProjectDirectory + public async Task GetProjectDirectoryAsync() { - get + if (!IsDeferred) { - if (!IsDeferred) - { - return Project.GetFullPath(); - } - else - { - return Path.GetDirectoryName(FullProjectPath); - } + return await Project.GetFullPathAsync(); + } + else + { + return Path.GetDirectoryName(FullProjectPath); } } @@ -126,17 +120,14 @@ namespace NuGet.PackageManagement.VisualStudio } } - public bool IsSupported + public async Task IsSupportedAsync() { - get + if (!IsDeferred) { - if (!IsDeferred) - { - return EnvDTEProjectUtility.IsSupported(Project); - } - - return VsHierarchyUtility.IsSupported(VsHierarchy, _projectTypeGuid); + return await EnvDTEProjectUtility.IsSupportedAsync(Project); } + + return await VsHierarchyUtility.IsSupportedAsync(VsHierarchy, _projectTypeGuid); } public string PackageTargetFallback @@ -246,7 +237,7 @@ namespace NuGet.PackageManagement.VisualStudio { if (!IsDeferred) { - return Project.GetProjectTypeGuids(); + return await Project.GetProjectTypeGuidsAsync(); } else { @@ -284,7 +275,7 @@ namespace NuGet.PackageManagement.VisualStudio if (!IsDeferred) { if (Project.Kind != null - && SupportedProjectTypes.IsSupportedForAddingReferences(Project.Kind)) + && ProjectType.IsSupportedForAddingReferences(Project.Kind)) { return EnvDTEProjectUtility.GetReferencedProjects(Project).Select(p => p.UniqueName); } @@ -294,7 +285,7 @@ namespace NuGet.PackageManagement.VisualStudio else { var projectTypeGuids = await GetProjectTypeGuidsAsync(); - if (projectTypeGuids.All(SupportedProjectTypes.IsSupportedForAddingReferences)) + if (projectTypeGuids.All(ProjectType.IsSupportedForAddingReferences)) { return await _workspaceService.GetProjectReferencesAsync(FullProjectPath); } diff --git a/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/Projects/VsProjectAdapterProvider.cs b/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/Projects/VsProjectAdapterProvider.cs index 6b27a0624..3bfcfd197 100644 --- a/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/Projects/VsProjectAdapterProvider.cs +++ b/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/Projects/VsProjectAdapterProvider.cs @@ -68,7 +68,7 @@ namespace NuGet.PackageManagement.VisualStudio // switch to main thread and use services we know must be done on main thread. await _threadingService.JoinableTaskFactory.SwitchToMainThreadAsync(); - var vsHierarchyItem = VsHierarchyItem.FromDteProject(dteProject); + var vsHierarchyItem = await VsHierarchyItem.FromDteProjectAsync(dteProject); Func loadDteProject = _ => dteProject; var buildStorageProperty = vsHierarchyItem.VsHierarchy as IVsBuildPropertyStorage; diff --git a/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/Utility/EnvDTEProjectUtility.cs b/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/Utility/EnvDTEProjectUtility.cs index 967aafdf6..9ee8f5907 100644 --- a/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/Utility/EnvDTEProjectUtility.cs +++ b/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/Utility/EnvDTEProjectUtility.cs @@ -45,17 +45,14 @@ namespace NuGet.PackageManagement.VisualStudio #region Get Project Information - internal static bool IsSolutionFolder(EnvDTE.Project envDTEProject) + internal static async Task IsSolutionFolderAsync(EnvDTE.Project envDTEProject) { - ThreadHelper.ThrowIfNotOnUIThread(); - + await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); return envDTEProject.Kind != null && envDTEProject.Kind.Equals(VsProjectTypes.VsProjectItemKindSolutionFolder, StringComparison.OrdinalIgnoreCase); } - public static async Task ContainsFile(EnvDTE.Project envDTEProject, string path) + public static async Task ContainsFileAsync(EnvDTE.Project envDTEProject, string path) { - ThreadHelper.ThrowIfNotOnUIThread(); - if (string.Equals(envDTEProject.Kind, VsProjectTypes.WixProjectTypeGuid, StringComparison.OrdinalIgnoreCase) || string.Equals(envDTEProject.Kind, VsProjectTypes.NemerleProjectTypeGuid, StringComparison.OrdinalIgnoreCase) @@ -73,7 +70,10 @@ namespace NuGet.PackageManagement.VisualStudio var item = await GetProjectItemAsync(envDTEProject, path); return item != null; } - var vsProject = (IVsProject)envDTEProject.ToVsHierarchy(); + + await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); + + var vsProject = (IVsProject)(await envDTEProject.ToVsHierarchyAsync()); if (vsProject == null) { return false; @@ -82,7 +82,7 @@ namespace NuGet.PackageManagement.VisualStudio int pFound; uint itemId; - if (IsProjectCapabilityCompliant(envDTEProject)) + if (await IsProjectCapabilityCompliantAsync(envDTEProject)) { // REVIEW: We want to revisit this after RTM - the code in this if statement should be applied to every project type. // We're checking for VSDOCUMENTPRIORITY.DP_Standard here to see if the file is included in the project. @@ -99,7 +99,7 @@ namespace NuGet.PackageManagement.VisualStudio // Get the ProjectItems for a folder path public static async Task GetProjectItemsAsync(EnvDTE.Project envDTEProject, string folderPath, bool createIfNotExists) { - ThreadHelper.ThrowIfNotOnUIThread(); + await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); if (string.IsNullOrEmpty(folderPath)) { @@ -113,7 +113,7 @@ namespace NuGet.PackageManagement.VisualStudio // Both types have the ProjectItems property that we want to access. object cursor = envDTEProject; - var fullPath = envDTEProject.GetFullPath(); + var fullPath = await envDTEProject.GetFullPathAsync(); var folderRelativePath = string.Empty; foreach (var part in pathParts) @@ -204,7 +204,7 @@ namespace NuGet.PackageManagement.VisualStudio // Execute command to include the existing folder into project. Must do this on UI thread. await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); - var projectHierarchy = (IVsUIHierarchy)envDTEProject.ToVsHierarchy(); + var projectHierarchy = (IVsUIHierarchy)(await envDTEProject.ToVsHierarchyAsync()); uint itemId; var hr = projectHierarchy.ParseCanonicalName(folderRelativePath, out itemId); @@ -373,48 +373,45 @@ namespace NuGet.PackageManagement.VisualStudio return references; } - public static bool IsSupported(EnvDTE.Project envDTEProject) + public static async Task IsSupportedAsync(EnvDTE.Project envDTEProject) { Assumes.Present(envDTEProject); - ThreadHelper.ThrowIfNotOnUIThread(); - if (SupportsProjectKPackageManager(envDTEProject)) { return true; } - if (IsProjectCapabilityCompliant(envDTEProject)) + if (await IsProjectCapabilityCompliantAsync(envDTEProject)) { return true; } - return envDTEProject.Kind != null && SupportedProjectTypes.IsSupported(envDTEProject.Kind) && !HasUnsupportedProjectCapability(envDTEProject); + await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); + + return envDTEProject.Kind != null && ProjectType.IsSupported(envDTEProject.Kind) && !await HasUnsupportedProjectCapabilityAsync(envDTEProject); } - private static bool IsProjectCapabilityCompliant(EnvDTE.Project envDTEProject) + private static async Task IsProjectCapabilityCompliantAsync(EnvDTE.Project envDTEProject) { - ThreadHelper.ThrowIfNotOnUIThread(); - Debug.Assert(envDTEProject != null); - - var hierarchy = envDTEProject.ToVsHierarchy(); - - return VsHierarchyUtility.IsProjectCapabilityCompliant(hierarchy); + var hierarchy = await envDTEProject.ToVsHierarchyAsync(); + return await VsHierarchyUtility.IsProjectCapabilityCompliantAsync(hierarchy); } public async static Task GetNuGetProjectAsync(EnvDTE.Project project, ISolutionManager solutionManager) { - ThreadHelper.ThrowIfNotOnUIThread(); - Debug.Assert(project != null); Debug.Assert(solutionManager != null); + await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); + var nuGetProject = await solutionManager.GetNuGetProjectAsync(project.Name); if (nuGetProject == null) { nuGetProject = await solutionManager.GetNuGetProjectAsync(project.UniqueName); } + return nuGetProject; } @@ -432,15 +429,14 @@ namespace NuGet.PackageManagement.VisualStudio /// Recursively retrieves all supported child projects of a virtual folder. /// /// The root container project - internal static IEnumerable GetSupportedChildProjects(EnvDTE.Project envDTEProject) + internal static async Task> GetSupportedChildProjectsAsync(EnvDTE.Project envDTEProject) { - ThreadHelper.ThrowIfNotOnUIThread(); - - if (!IsSolutionFolder(envDTEProject)) + if (!await IsSolutionFolderAsync(envDTEProject)) { - yield break; + return Array.Empty(); } + var supportedChildProjects = new List(); var containerProjects = new Queue(); containerProjects.Enqueue(envDTEProject); @@ -453,21 +449,23 @@ namespace NuGet.PackageManagement.VisualStudio if (nestedProject == null) { } - else if (IsSupported(nestedProject)) + else if (await IsSupportedAsync(nestedProject)) { - yield return nestedProject; + supportedChildProjects.Add(nestedProject); } - else if (IsSolutionFolder(nestedProject)) + else if (await IsSolutionFolderAsync(nestedProject)) { containerProjects.Enqueue(nestedProject); } } } + + return supportedChildProjects; } - internal static HashSet GetAssemblyClosure(EnvDTE.Project envDTEProject, IDictionary> visitedProjects) + internal static async Task> GetAssemblyClosureAsync(EnvDTE.Project envDTEProject, IDictionary> visitedProjects) { - ThreadHelper.ThrowIfNotOnUIThread(); + await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); HashSet assemblies; if (visitedProjects.TryGetValue(envDTEProject.UniqueName, out assemblies)) @@ -478,24 +476,24 @@ namespace NuGet.PackageManagement.VisualStudio assemblies = new HashSet(PathComparer.Default); visitedProjects.Add(envDTEProject.UniqueName, assemblies); - var localProjectAssemblies = GetLocalProjectAssemblies(envDTEProject); + var localProjectAssemblies = await GetLocalProjectAssembliesAsync(envDTEProject); CollectionsUtility.AddRange(assemblies, localProjectAssemblies); var referencedProjects = GetReferencedProjects(envDTEProject); foreach (var project in referencedProjects) { - var assemblyClosure = GetAssemblyClosure(project, visitedProjects); + var assemblyClosure = await GetAssemblyClosureAsync(project, visitedProjects); CollectionsUtility.AddRange(assemblies, assemblyClosure); } return assemblies; } - private static HashSet GetLocalProjectAssemblies(EnvDTE.Project envDTEProject) + private static async Task> GetLocalProjectAssembliesAsync(EnvDTE.Project envDTEProject) { if (envDTEProject.IsWebSite()) { - var websiteLocalAssemblies = GetWebsiteLocalAssemblies(envDTEProject); + var websiteLocalAssemblies = await GetWebsiteLocalAssembliesAsync(envDTEProject); return websiteLocalAssemblies; } @@ -531,7 +529,7 @@ namespace NuGet.PackageManagement.VisualStudio return assemblies; } - private static HashSet GetWebsiteLocalAssemblies(EnvDTE.Project envDTEProject) + private static async Task> GetWebsiteLocalAssembliesAsync(EnvDTE.Project envDTEProject) { var assemblies = new HashSet(PathComparer.Default); var references = GetAssemblyReferences(envDTEProject); @@ -550,7 +548,7 @@ namespace NuGet.PackageManagement.VisualStudio // For website projects, we always add .refresh files that point to the corresponding binaries in packages. In the event of bin deployed assemblies that are also GACed, // the ReferenceKind is not AssemblyReferenceBin. Consequently, we work around this by looking for any additional assembly declarations specified via .refresh files. - var envDTEProjectPath = envDTEProject.GetFullPath(); + var envDTEProjectPath = await envDTEProject.GetFullPathAsync(); CollectionsUtility.AddRange(assemblies, RefreshFileUtility.ResolveRefreshPaths(envDTEProjectPath)); return assemblies; @@ -636,7 +634,7 @@ namespace NuGet.PackageManagement.VisualStudio { ThreadHelper.ThrowIfNotOnUIThread(); - return envDTEProject.Kind == null || SupportedProjectTypes.IsUnsupported(envDTEProject.Kind); + return envDTEProject.Kind == null || ProjectType.IsUnsupported(envDTEProject.Kind); } public static bool IsParentProjectExplicitlyUnsupported(EnvDTE.Project envDTEProject) @@ -710,9 +708,9 @@ namespace NuGet.PackageManagement.VisualStudio { var projectNameConfig = ProjectJsonPathUtilities.GetProjectConfigWithProjectName(project.Name); - var containsProjectJson = await ContainsFile(project, projectNameConfig); + var containsProjectJson = await ContainsFileAsync(project, projectNameConfig); - var containsProjectNameJson = await ContainsFile( + var containsProjectNameJson = await ContainsFileAsync( project, ProjectJsonPathUtilities.ProjectConfigFileName); @@ -722,10 +720,9 @@ namespace NuGet.PackageManagement.VisualStudio /// /// Check if the project has an unsupported project capability, such as, "SharedAssetsProject" /// - public static bool HasUnsupportedProjectCapability(EnvDTE.Project envDTEProject) + public static async Task HasUnsupportedProjectCapabilityAsync(EnvDTE.Project envDTEProject) { - var hier = envDTEProject.ToVsHierarchy(); - + var hier = await envDTEProject.ToVsHierarchyAsync(); return VsHierarchyUtility.HasUnsupportedProjectCapability(hier); } diff --git a/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/Utility/EnvDTESolutionUtility.cs b/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/Utility/EnvDTESolutionUtility.cs index 09f647f45..3335de5ba 100644 --- a/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/Utility/EnvDTESolutionUtility.cs +++ b/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/Utility/EnvDTESolutionUtility.cs @@ -6,25 +6,11 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using NuGet.VisualStudio; -using Task = System.Threading.Tasks.Task; namespace NuGet.PackageManagement.VisualStudio { public static class EnvDTESolutionUtility { - /// - /// Get the list of all supported projects in the current solution. This method - /// recursively iterates through all projects. - /// - public static IEnumerable GetAllEnvDTEProjects(EnvDTE.DTE dte) - { - return NuGetUIThreadHelper.JoinableTaskFactory.Run(async delegate - { - var result = await GetAllEnvDTEProjectsAsync(dte); - return result; - }); - } - public static async Task> GetAllEnvDTEProjectsAsync(EnvDTE.DTE dte) { await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); @@ -50,7 +36,7 @@ namespace NuGet.PackageManagement.VisualStudio { var envDTEProject = envDTEProjects.Pop(); - if (EnvDTEProjectUtility.IsSupported(envDTEProject)) + if (await EnvDTEProjectUtility.IsSupportedAsync(envDTEProject)) { resultantEnvDTEProjects.Add(envDTEProject); } diff --git a/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/Utility/NuGetProjectUpgradeUtility.cs b/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/Utility/NuGetProjectUpgradeUtility.cs index 3f830e448..d86d29db3 100644 --- a/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/Utility/NuGetProjectUpgradeUtility.cs +++ b/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/Utility/NuGetProjectUpgradeUtility.cs @@ -75,12 +75,12 @@ namespace NuGet.PackageManagement.VisualStudio envDTEProject = vsmsBuildNuGetProjectSystem.VsProjectAdapter.Project; } - if (!EnvDTEProjectUtility.IsSupported(envDTEProject)) + if (!await EnvDTEProjectUtility.IsSupportedAsync(envDTEProject)) { return false; } - return IsProjectPackageReferenceCompatible(envDTEProject); + return await IsProjectPackageReferenceCompatibleAsync(envDTEProject); } private static async Task GetNuGetProject(Project envDTEProject) @@ -92,9 +92,9 @@ namespace NuGet.PackageManagement.VisualStudio return nuGetProject; } - private static bool IsProjectPackageReferenceCompatible(Project project) + private static async Task IsProjectPackageReferenceCompatibleAsync(Project project) { - var projectGuids = project.GetProjectTypeGuids(); + var projectGuids = await project.GetProjectTypeGuidsAsync(); if (projectGuids.Any(t => UnupgradeableProjectTypes.Contains(t))) { @@ -103,7 +103,7 @@ namespace NuGet.PackageManagement.VisualStudio // Project is supported language, and not an unsupported type return UpgradeableProjectTypes.Contains(project.Kind) && - projectGuids.All(projectTypeGuid => !SupportedProjectTypes.IsUnsupported(projectTypeGuid)); + projectGuids.All(projectTypeGuid => !ProjectType.IsUnsupported(projectTypeGuid)); } public static bool IsPackagesConfigSelected(IVsMonitorSelection vsMonitorSelection) diff --git a/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/Utility/ProjectRetargetingUtility.cs b/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/Utility/ProjectRetargetingUtility.cs index d18285162..e09cdb6a7 100644 --- a/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/Utility/ProjectRetargetingUtility.cs +++ b/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/Utility/ProjectRetargetingUtility.cs @@ -256,9 +256,9 @@ namespace NuGet.PackageManagement.VisualStudio /// Determines if NuGet is used in the project. Currently, it is determined by checking if packages.config is part of the project /// /// The project which is checked to see if NuGet is used in it - public static bool IsNuGetInUse(Project project) + public static async Task IsNuGetInUseAsync(Project project) { - return EnvDTEProjectUtility.IsSupported(project) && File.Exists(project.GetPackagesConfigFullPath()); + return await EnvDTEProjectUtility.IsSupportedAsync(project) && File.Exists(await project.GetPackagesConfigFullPathAsync()); } } } diff --git a/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/Utility/RuntimeHelpers.cs b/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/Utility/RuntimeHelpers.cs index 63ad27d13..190da2053 100644 --- a/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/Utility/RuntimeHelpers.cs +++ b/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/Utility/RuntimeHelpers.cs @@ -31,7 +31,7 @@ namespace NuGet.PackageManagement.VisualStudio await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); // Keep track of visited projects - if (SupportsBindingRedirects(vsProjectAdapter.Project)) + if (await SupportsBindingRedirectsAsync(vsProjectAdapter.Project)) { // Get the dependentEnvDTEProjectsDictionary once here, so that, it is not called for every single project var dependentProjectsDictionary = await vsSolutionManager.GetDependentProjectsDictionaryAsync(); @@ -45,10 +45,10 @@ namespace NuGet.PackageManagement.VisualStudio } } - private static bool SupportsBindingRedirects(EnvDTE.Project Project) + private static async Task SupportsBindingRedirectsAsync(EnvDTE.Project Project) { - return (Project.Kind != null && SupportedProjectTypes.IsSupportedForBindingRedirects(Project.Kind)) - && !Project.IsWindowsStoreApp(); + return (Project.Kind != null && ProjectType.IsSupportedForBindingRedirects(Project.Kind)) + && !await Project.IsWindowsStoreAppAsync(); } private static Task AddBindingRedirectsAsync( @@ -87,7 +87,7 @@ namespace NuGet.PackageManagement.VisualStudio return; } - if (SupportsBindingRedirects(vsProjectAdapter.Project)) + if (await SupportsBindingRedirectsAsync(vsProjectAdapter.Project)) { await AddBindingRedirectsAsync(vsSolutionManager, vsProjectAdapter, domain, projectAssembliesCache, frameworkMultiTargeting, nuGetProjectContext); } @@ -142,7 +142,7 @@ namespace NuGet.PackageManagement.VisualStudio return redirects; } - IEnumerable assemblies = EnvDTEProjectUtility.GetAssemblyClosure(vsProjectAdapter.Project, projectAssembliesCache); + IEnumerable assemblies = await EnvDTEProjectUtility.GetAssemblyClosureAsync(vsProjectAdapter.Project, projectAssembliesCache); redirects = BindingRedirectResolver.GetBindingRedirects(assemblies, domain); if (frameworkMultiTargeting != null) @@ -152,7 +152,7 @@ namespace NuGet.PackageManagement.VisualStudio } // Create a binding redirect manager over the configuration - var manager = new BindingRedirectManager(vsProjectAdapter.Project.GetConfigurationFile(), msBuildNuGetProjectSystem); + var manager = new BindingRedirectManager(await vsProjectAdapter.Project.GetConfigurationFileAsync(), msBuildNuGetProjectSystem); // Add the redirects manager.AddBindingRedirects(redirects); diff --git a/src/NuGet.Clients/NuGet.SolutionRestoreManager/SolutionRestoreJob.cs b/src/NuGet.Clients/NuGet.SolutionRestoreManager/SolutionRestoreJob.cs index c07ca193e..c97ffa554 100644 --- a/src/NuGet.Clients/NuGet.SolutionRestoreManager/SolutionRestoreJob.cs +++ b/src/NuGet.Clients/NuGet.SolutionRestoreManager/SolutionRestoreJob.cs @@ -722,10 +722,20 @@ namespace NuGet.SolutionRestoreManager var dte = await _asyncServiceProvider.GetDTEAsync(); var projects = dte.Solution.Projects; - return projects - .OfType() - .Select(p => new ProjectInfo(p.GetFullPath(), p.Name)) - .Any(p => p.CheckPackagesConfig()); + + var succeeded = false; + + foreach (var p in projects.OfType()) + { + var pi = new ProjectInfo(await p.GetFullPathAsync(), p.Name); + if (pi.CheckPackagesConfig()) + { + succeeded = true; + break; + } + } + + return succeeded; }); } diff --git a/src/NuGet.Clients/NuGet.Tools/NuGetPackage.cs b/src/NuGet.Clients/NuGet.Tools/NuGetPackage.cs index 213ab598e..a1dc084a0 100644 --- a/src/NuGet.Clients/NuGet.Tools/NuGetPackage.cs +++ b/src/NuGet.Clients/NuGet.Tools/NuGetPackage.cs @@ -427,7 +427,7 @@ namespace NuGetVSExtension { await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); - var vsProject = project.ToVsHierarchy(); + var vsProject = await project.ToVsHierarchyAsync(); var documentName = project.FullName; // Find existing hierarchy and item id of the document window if it's @@ -639,7 +639,7 @@ namespace NuGetVSExtension && !project.IsUnloaded() && - EnvDTEProjectUtility.IsSupported(project)) + await EnvDTEProjectUtility.IsSupportedAsync(project)) { var windowFrame = await FindExistingWindowFrameAsync(project); if (windowFrame == null) @@ -907,7 +907,7 @@ namespace NuGetVSExtension } command.Visible = GetIsSolutionOpen() && await IsPackagesConfigBasedProjectAsync(); - command.Enabled = !isConsoleBusy && IsSolutionExistsAndNotDebuggingAndNotBuilding() && HasActiveLoadedSupportedProject; + command.Enabled = !isConsoleBusy && IsSolutionExistsAndNotDebuggingAndNotBuilding() && await HasActiveLoadedSupportedProjectAsync(); }); } @@ -932,7 +932,7 @@ namespace NuGetVSExtension } command.Visible = GetIsSolutionOpen() && IsPackagesConfigSelected(); - command.Enabled = !isConsoleBusy && IsSolutionExistsAndNotDebuggingAndNotBuilding() && HasActiveLoadedSupportedProject; + command.Enabled = !isConsoleBusy && IsSolutionExistsAndNotDebuggingAndNotBuilding() && await HasActiveLoadedSupportedProjectAsync(); }); } @@ -1003,7 +1003,7 @@ namespace NuGetVSExtension command.Enabled = IsSolutionExistsAndNotDebuggingAndNotBuilding() && !isConsoleBusy && - HasActiveLoadedSupportedProject; + await HasActiveLoadedSupportedProjectAsync(); }); } @@ -1081,14 +1081,11 @@ namespace NuGetVSExtension /// Gets whether the current IDE has an active, supported and non-unloaded project, which is a precondition for /// showing the Add Library Package Reference dialog /// - private bool HasActiveLoadedSupportedProject + private async Task HasActiveLoadedSupportedProjectAsync() { - get - { - var project = VsMonitorSelection.GetActiveProject(); - return project != null && !project.IsUnloaded() - && EnvDTEProjectUtility.IsSupported(project); - } + var project = VsMonitorSelection.GetActiveProject(); + return project != null && !project.IsUnloaded() + && await EnvDTEProjectUtility.IsSupportedAsync(project); } private bool ShouldMEFBeInitialized() diff --git a/src/NuGet.Clients/NuGet.VisualStudio.Common/IDE/EnvDteProjectExtensions.cs b/src/NuGet.Clients/NuGet.VisualStudio.Common/IDE/EnvDteProjectExtensions.cs index 6c54f3e7e..86d4b806b 100644 --- a/src/NuGet.Clients/NuGet.VisualStudio.Common/IDE/EnvDteProjectExtensions.cs +++ b/src/NuGet.Clients/NuGet.VisualStudio.Common/IDE/EnvDteProjectExtensions.cs @@ -23,14 +23,14 @@ namespace NuGet.VisualStudio { public static class EnvDteProjectExtensions { - public static IVsHierarchy ToVsHierarchy(this EnvDTE.Project project) + public static async Task ToVsHierarchyAsync(this EnvDTE.Project project) { - ThreadHelper.ThrowIfNotOnUIThread(); + await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); IVsHierarchy hierarchy; // Get the vs solution - var solution = ServiceLocator.GetInstance(); + var solution = await ServiceLocator.GetInstanceAsync(); int hr = solution.GetProjectOfUniqueName(project.GetUniqueName(), out hierarchy); if (hr != VSConstants.S_OK) @@ -41,14 +41,14 @@ namespace NuGet.VisualStudio return hierarchy; } - public static string[] GetProjectTypeGuids(this EnvDTE.Project project) + public static async Task GetProjectTypeGuidsAsync(this EnvDTE.Project project) { Verify.ArgumentIsNotNull(project, nameof(project)); - ThreadHelper.ThrowIfNotOnUIThread(); + await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); // Get the vs hierarchy as an IVsAggregatableProject to get the project type guids - IVsHierarchy hierarchy = ToVsHierarchy(project); + IVsHierarchy hierarchy = await ToVsHierarchyAsync(project); string[] projectTypeGuids = VsHierarchyUtility.GetProjectTypeGuids(hierarchy, project.Kind); return projectTypeGuids; @@ -105,9 +105,9 @@ namespace NuGet.VisualStudio /// /// The project. /// The full path of the project directory. - public static string GetFullPath(this EnvDTE.Project envDTEProject) + public static async Task GetFullPathAsync(this EnvDTE.Project envDTEProject) { - ThreadHelper.ThrowIfNotOnUIThread(); + await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); Debug.Assert(envDTEProject != null); if (IsUnloaded(envDTEProject)) @@ -125,7 +125,7 @@ namespace NuGet.VisualStudio // until we can find one containing the full path. // For website projects, always read FullPath from properties list - if (IsWebProject(envDTEProject)) + if (await IsWebProjectAsync(envDTEProject)) { // FullPath var fullProjectPath = GetPropertyValue(envDTEProject, FullPath); @@ -203,12 +203,12 @@ namespace NuGet.VisualStudio /// Returns the full path of the packages config file associated with the project. /// /// The project. - public static string GetPackagesConfigFullPath(this EnvDTE.Project envDTEProject) + public static async Task GetPackagesConfigFullPathAsync(this EnvDTE.Project envDTEProject) { - ThreadHelper.ThrowIfNotOnUIThread(); + await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); Debug.Assert(envDTEProject != null); - var projectDirectory = GetFullPath(envDTEProject); + var projectDirectory = await GetFullPathAsync(envDTEProject); var packagesConfigFullPath = Path.Combine( projectDirectory ?? string.Empty, @@ -324,11 +324,11 @@ namespace NuGet.VisualStudio } // TODO: Return null for library projects - public static string GetConfigurationFile(this EnvDTE.Project envDTEProject) + public static async Task GetConfigurationFileAsync(this EnvDTE.Project envDTEProject) { - ThreadHelper.ThrowIfNotOnUIThread(); + await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); - return IsWebProject(envDTEProject) ? WebConfig : AppConfig; + return await IsWebProjectAsync(envDTEProject) ? WebConfig : AppConfig; } private class PathComparer : IEqualityComparer @@ -412,10 +412,10 @@ namespace NuGet.VisualStudio "Windows Phone OS 7.1".Equals(GetPropertyValue(envDTEProject, xnaPropertyValue), StringComparison.OrdinalIgnoreCase); } - private static bool IsWebProject(this EnvDTE.Project envDTEProject) + private static async Task IsWebProjectAsync(this EnvDTE.Project envDTEProject) { - ThreadHelper.ThrowIfNotOnUIThread(); - string[] types = envDTEProject.GetProjectTypeGuids(); + await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); + string[] types = await envDTEProject.GetProjectTypeGuidsAsync(); return types.Contains(VsProjectTypes.WebSiteProjectTypeGuid, StringComparer.OrdinalIgnoreCase) || types.Contains(VsProjectTypes.WebApplicationProjectTypeGuid, StringComparer.OrdinalIgnoreCase); } @@ -427,10 +427,10 @@ namespace NuGet.VisualStudio return envDTEProject.Kind != null && envDTEProject.Kind.Equals(VsProjectTypes.WebSiteProjectTypeGuid, StringComparison.OrdinalIgnoreCase); } - public static bool IsWindowsStoreApp(this EnvDTE.Project envDTEProject) + public static async Task IsWindowsStoreAppAsync(this EnvDTE.Project envDTEProject) { - ThreadHelper.ThrowIfNotOnUIThread(); - string[] types = envDTEProject.GetProjectTypeGuids(); + await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); + string[] types = await envDTEProject.GetProjectTypeGuidsAsync(); return types.Contains(VsProjectTypes.WindowsStoreProjectTypeGuid, StringComparer.OrdinalIgnoreCase); } diff --git a/src/NuGet.Clients/NuGet.VisualStudio.Common/IDE/VsHierarchyItem.cs b/src/NuGet.Clients/NuGet.VisualStudio.Common/IDE/VsHierarchyItem.cs index ab07f9f81..9928a3e3f 100644 --- a/src/NuGet.Clients/NuGet.VisualStudio.Common/IDE/VsHierarchyItem.cs +++ b/src/NuGet.Clients/NuGet.VisualStudio.Common/IDE/VsHierarchyItem.cs @@ -2,8 +2,10 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using System.Threading.Tasks; using Microsoft; using Microsoft.VisualStudio; +using Microsoft.VisualStudio.PlatformUI; using Microsoft.VisualStudio.Shell; using Microsoft.VisualStudio.Shell.Interop; @@ -17,7 +19,7 @@ namespace NuGet.VisualStudio private readonly uint _vsitemid; private readonly IVsHierarchy _hierarchy; - internal delegate int ProcessItemDelegate(VsHierarchyItem item, object callerObject, out object newCallerObject); + internal delegate Task<(int processReturn, object newCallerObject)> ProcessItemDelegateAsync(VsHierarchyItem item, object callerObject); public IVsHierarchy VsHierarchy => _hierarchy; @@ -32,11 +34,10 @@ namespace NuGet.VisualStudio { } - public static VsHierarchyItem FromDteProject(EnvDTE.Project project) + public static async Task FromDteProjectAsync(EnvDTE.Project project) { - ThreadHelper.ThrowIfNotOnUIThread(); Assumes.Present(project); - return new VsHierarchyItem(project.ToVsHierarchy()); + return new VsHierarchyItem(await project.ToVsHierarchyAsync()); } public static VsHierarchyItem FromVsHierarchy(IVsHierarchy project) @@ -59,51 +60,49 @@ namespace NuGet.VisualStudio internal uint VsItemID => _vsitemid; - internal bool IsExpandable() + internal async Task IsExpandableAsync() { - ThreadHelper.ThrowIfNotOnUIThread(); - var o = GetProperty(__VSHPROPID.VSHPROPID_Expandable); + var o = await GetPropertyAsync(__VSHPROPID.VSHPROPID_Expandable); if (o is bool) { return (bool)o; } + return (o is int) && (int)o != 0; } - private object GetProperty(__VSHPROPID propid) + private async Task GetPropertyAsync(__VSHPROPID propid) { - ThreadHelper.ThrowIfNotOnUIThread(); - if (TryGetProperty((int)propid, out var value)) - { - return value; - } - - return null; + (bool _, object value) = await TryGetPropertyAsync((int)propid); + return value; } - private bool TryGetProperty(int propid, out object value) + private async Task<(bool found, object value)> TryGetPropertyAsync(int propid) { - ThreadHelper.ThrowIfNotOnUIThread(); - - value = null; try { if (_hierarchy != null) { - _hierarchy.GetProperty(_vsitemid, propid, out value); + await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); + _hierarchy.GetProperty(_vsitemid, propid, out object value); + return (true, value); + } + } + catch (Exception e) + { + if (e.IsCritical()) + { + throw; } - return true; - } - catch - { - return false; + // Ignore. } + + return (false, null); } - internal int WalkDepthFirst(bool fVisible, ProcessItemDelegate processCallback, object callerObject) + internal async Task WalkDepthFirstAsync(bool fVisible, ProcessItemDelegateAsync processCallbackAsync, object callerObject) { - ThreadHelper.ThrowIfNotOnUIThread(); // // TODO Need to see what to do if this is a sub project // @@ -111,13 +110,12 @@ namespace NuGet.VisualStudio // Guid nodeGuid; // if (hier.GetGuidProperty(_vsitemid, (int)__VSHPROPID.VSHPROPID_TypeGuid, out nodeGuid) != 0) - if (processCallback == null) + if (processCallbackAsync == null) { return 0; } - object newCallerObject; - int processReturn = processCallback(this, callerObject, out newCallerObject); + (int processReturn, object newCallerObject) = await processCallbackAsync(this, callerObject); if (processReturn != 0) { // Callback says to skip (1) or stop (-1) @@ -132,44 +130,43 @@ namespace NuGet.VisualStudio } // Walk children if there are any - if (IsExpandable()) + if (await IsExpandableAsync()) { - VsHierarchyItem child = GetFirstChild(fVisible); + VsHierarchyItem child = await GetFirstChildAsync(fVisible); while (child != null) { - object isNonMemberItemValue = child.GetProperty(__VSHPROPID.VSHPROPID_IsNonMemberItem); + object isNonMemberItemValue = await child.GetPropertyAsync(__VSHPROPID.VSHPROPID_IsNonMemberItem); // Some project systems (e.g. F#) don't support querying for the VSHPROPID_IsNonMemberItem property. // In that case, we treat this child as belonging to the project bool isMemberOfProject = isNonMemberItemValue == null || (bool)isNonMemberItemValue == false; if (isMemberOfProject) { - int returnVal = child.WalkDepthFirst(fVisible, processCallback, newCallerObject); + int returnVal = await child.WalkDepthFirstAsync(fVisible, processCallbackAsync, newCallerObject); if (returnVal == -1) { return returnVal; } } - child = child.GetNextSibling(fVisible); + child = await child.GetNextSiblingAsync(fVisible); } } return 0; } - internal VsHierarchyItem GetNextSibling(bool fVisible) + internal async Task GetNextSiblingAsync(bool fVisible) { - ThreadHelper.ThrowIfNotOnUIThread(); - uint childId = GetNextSiblingId(fVisible); + uint childId = await GetNextSiblingIdAsync(fVisible); if (childId != VSConstants.VSITEMID_NIL) { return new VsHierarchyItem(_hierarchy, childId); } + return null; } - internal uint GetNextSiblingId(bool fVisible) + internal async Task GetNextSiblingIdAsync(bool fVisible) { - ThreadHelper.ThrowIfNotOnUIThread(); - object o = GetProperty(fVisible ? __VSHPROPID.VSHPROPID_NextVisibleSibling : __VSHPROPID.VSHPROPID_NextSibling); + object o = await GetPropertyAsync(fVisible ? __VSHPROPID.VSHPROPID_NextVisibleSibling : __VSHPROPID.VSHPROPID_NextSibling); if (o is int) { @@ -179,33 +176,35 @@ namespace NuGet.VisualStudio { return (uint)o; } + return VSConstants.VSITEMID_NIL; } - internal VsHierarchyItem GetFirstChild(bool fVisible) + internal async Task GetFirstChildAsync(bool fVisible) { - ThreadHelper.ThrowIfNotOnUIThread(); - uint childId = GetFirstChildId(fVisible); + uint childId = await GetFirstChildIdAsync(fVisible); if (childId != VSConstants.VSITEMID_NIL) { return new VsHierarchyItem(_hierarchy, childId); } + return null; } - internal uint GetFirstChildId(bool fVisible) + internal async Task GetFirstChildIdAsync(bool fVisible) { - ThreadHelper.ThrowIfNotOnUIThread(); - object o = GetProperty(fVisible ? __VSHPROPID.VSHPROPID_FirstVisibleChild : __VSHPROPID.VSHPROPID_FirstChild); + object o = await GetPropertyAsync(fVisible ? __VSHPROPID.VSHPROPID_FirstVisibleChild : __VSHPROPID.VSHPROPID_FirstChild); if (o is int) { return unchecked((uint)((int)o)); } + if (o is uint) { return (uint)o; } + return VSConstants.VSITEMID_NIL; } diff --git a/src/NuGet.Clients/NuGet.VisualStudio.Common/IDE/VsHierarchyUtility.cs b/src/NuGet.Clients/NuGet.VisualStudio.Common/IDE/VsHierarchyUtility.cs index bcf516bfb..05469d04e 100644 --- a/src/NuGet.Clients/NuGet.VisualStudio.Common/IDE/VsHierarchyUtility.cs +++ b/src/NuGet.Clients/NuGet.VisualStudio.Common/IDE/VsHierarchyUtility.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; +using System.Threading.Tasks; using Microsoft.VisualStudio; using Microsoft.VisualStudio.Shell; using Microsoft.VisualStudio.Shell.Interop; @@ -31,25 +32,23 @@ namespace NuGet.VisualStudio return projectPath; } - public static bool IsSupported(IVsHierarchy hierarchy, string projectTypeGuid) + public static async Task IsSupportedAsync(IVsHierarchy hierarchy, string projectTypeGuid) { - ThreadHelper.ThrowIfNotOnUIThread(); - - if (IsProjectCapabilityCompliant(hierarchy)) + if (await IsProjectCapabilityCompliantAsync(hierarchy)) { return true; } - return !string.IsNullOrEmpty(projectTypeGuid) && SupportedProjectTypes.IsSupported(projectTypeGuid) && !HasUnsupportedProjectCapability(hierarchy); + return !string.IsNullOrEmpty(projectTypeGuid) && ProjectType.IsSupported(projectTypeGuid) && !HasUnsupportedProjectCapability(hierarchy); } /// Check if this project appears to support NuGet. /// IVsHierarchy representing the project in the solution. /// True if NuGet should enable this project, false if NuGet should ignore the project. /// The project may be packages.config or PackageReference. This method does not tell you which. - public static bool IsProjectCapabilityCompliant(IVsHierarchy hierarchy) + public static async Task IsProjectCapabilityCompliantAsync(IVsHierarchy hierarchy) { - ThreadHelper.ThrowIfNotOnUIThread(); + await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); // NOTE: (AssemblyReferences + DeclaredSourceItems + UserSourceItems) exists solely for compatibility reasons // with existing custom CPS-based projects that existed before "PackageReferences" capability was introduced. @@ -126,7 +125,7 @@ namespace NuGet.VisualStudio foreach (var project in projects.Cast()) { var expandedNodes = - GetExpandedProjectHierarchyItems(project); + await GetExpandedProjectHierarchyItemsAsync(project); Debug.Assert(!results.ContainsKey(project.GetUniqueName())); results[project.GetUniqueName()] = new HashSet(expandedNodes); @@ -150,52 +149,49 @@ namespace NuGet.VisualStudio && expandedNodes != null) { - CollapseProjectHierarchyItems(project, expandedNodes); + await CollapseProjectHierarchyItemsAsync(project, expandedNodes); } } } - private static ICollection GetExpandedProjectHierarchyItems(EnvDTE.Project project) + private static async Task> GetExpandedProjectHierarchyItemsAsync(EnvDTE.Project project) { - ThreadHelper.ThrowIfNotOnUIThread(); - - var projectHierarchyItem = VsHierarchyItem.FromDteProject(project); + var projectHierarchyItem = await VsHierarchyItem.FromDteProjectAsync(project); var solutionExplorerWindow = GetSolutionExplorerHierarchyWindow(); if (solutionExplorerWindow == null) { // If the solution explorer is collapsed since opening VS, this value is null. In such a case, simply exit early. - return new VsHierarchyItem[0]; + return Array.Empty(); } var expandedItems = new List(); + await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); + // processCallback return values: // 0 continue, // 1 don't recurse into, // -1 stop - projectHierarchyItem.WalkDepthFirst( + await projectHierarchyItem.WalkDepthFirstAsync( fVisible: true, - processCallback: - (VsHierarchyItem vsItem, object callerObject, out object newCallerObject) => + processCallbackAsync: + async (VsHierarchyItem vsItem, object callerObject) => { - newCallerObject = null; - if (IsVsHierarchyItemExpanded(vsItem, solutionExplorerWindow)) + if (await IsVsHierarchyItemExpandedAsync(vsItem, solutionExplorerWindow)) { expandedItems.Add(vsItem); } - return 0; + return (0, null); }, callerObject: null); return expandedItems; } - private static void CollapseProjectHierarchyItems(EnvDTE.Project project, ISet ignoredHierarcyItems) + private static async Task CollapseProjectHierarchyItemsAsync(EnvDTE.Project project, ISet ignoredHierarcyItems) { - ThreadHelper.ThrowIfNotOnUIThread(); - - var projectHierarchyItem = VsHierarchyItem.FromDteProject(project); + var projectHierarchyItem = await VsHierarchyItem.FromDteProjectAsync(project); var solutionExplorerWindow = GetSolutionExplorerHierarchyWindow(); if (solutionExplorerWindow == null) @@ -208,39 +204,35 @@ namespace NuGet.VisualStudio // 0 continue, // 1 don't recurse into, // -1 stop - projectHierarchyItem.WalkDepthFirst( + await projectHierarchyItem.WalkDepthFirstAsync( fVisible: true, - processCallback: - (VsHierarchyItem currentHierarchyItem, object callerObject, out object newCallerObject) => + processCallbackAsync: + async (VsHierarchyItem currentHierarchyItem, object callerObject) => { - newCallerObject = null; if (!ignoredHierarcyItems.Contains(currentHierarchyItem)) { - CollapseVsHierarchyItem(currentHierarchyItem, solutionExplorerWindow); + await CollapseVsHierarchyItemAsync(currentHierarchyItem, solutionExplorerWindow); } - return 0; + return (0, null); }, callerObject: null); } - private static void CollapseVsHierarchyItem(VsHierarchyItem vsHierarchyItem, IVsUIHierarchyWindow vsHierarchyWindow) + private static async Task CollapseVsHierarchyItemAsync(VsHierarchyItem vsHierarchyItem, IVsUIHierarchyWindow vsHierarchyWindow) { - ThreadHelper.ThrowIfNotOnUIThread(); - if (vsHierarchyItem == null || vsHierarchyWindow == null) { return; } + await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); vsHierarchyWindow.ExpandItem(AsVsUIHierarchy(vsHierarchyItem), vsHierarchyItem.VsItemID, EXPANDFLAGS.EXPF_CollapseFolder); } - private static bool IsVsHierarchyItemExpanded(VsHierarchyItem hierarchyItem, IVsUIHierarchyWindow uiWindow) + private static async Task IsVsHierarchyItemExpandedAsync(VsHierarchyItem hierarchyItem, IVsUIHierarchyWindow uiWindow) { - ThreadHelper.ThrowIfNotOnUIThread(); - - if (!hierarchyItem.IsExpandable()) + if (!await hierarchyItem.IsExpandableAsync()) { return false; } @@ -248,6 +240,7 @@ namespace NuGet.VisualStudio const uint expandedStateMask = (uint)__VSHIERARCHYITEMSTATE.HIS_Expanded; uint itemState; + await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); uiWindow.GetItemState(AsVsUIHierarchy(hierarchyItem), hierarchyItem.VsItemID, expandedStateMask, out itemState); return ((__VSHIERARCHYITEMSTATE)itemState == __VSHIERARCHYITEMSTATE.HIS_Expanded); } diff --git a/src/NuGet.Clients/NuGet.VisualStudio.Common/IVsProjectAdapter.cs b/src/NuGet.Clients/NuGet.VisualStudio.Common/IVsProjectAdapter.cs index 407e19ed4..9eeaece3a 100644 --- a/src/NuGet.Clients/NuGet.VisualStudio.Common/IVsProjectAdapter.cs +++ b/src/NuGet.Clients/NuGet.VisualStudio.Common/IVsProjectAdapter.cs @@ -24,7 +24,7 @@ namespace NuGet.VisualStudio /// /// MSBuildProjectExtensionsPath project property (e.g. c:\projFoo\obj) /// - string MSBuildProjectExtensionsPath { get; } + Task GetMSBuildProjectExtensionsPathAsync(); IProjectBuildProperties BuildProperties { get; } @@ -36,7 +36,7 @@ namespace NuGet.VisualStudio bool IsDeferred { get; } - bool IsSupported { get; } + Task IsSupportedAsync(); /// /// Comma or Semicolon separated list of NU* diagnostic codes e.g. NU1000,NU1001 @@ -58,7 +58,7 @@ namespace NuGet.VisualStudio /// /// Full path to a parent directory containing project file. /// - string ProjectDirectory { get; } + Task GetProjectDirectoryAsync(); string ProjectName { get; } diff --git a/src/NuGet.Clients/NuGet.VisualStudio.Common/ProjectType.cs b/src/NuGet.Clients/NuGet.VisualStudio.Common/ProjectType.cs new file mode 100644 index 000000000..666b0ac8c --- /dev/null +++ b/src/NuGet.Clients/NuGet.VisualStudio.Common/ProjectType.cs @@ -0,0 +1,91 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; + +namespace NuGet.VisualStudio +{ + public static class ProjectType + { + private static readonly HashSet Supported = new HashSet(StringComparer.OrdinalIgnoreCase) + { + VsProjectTypes.WebSiteProjectTypeGuid, + VsProjectTypes.CsharpProjectTypeGuid, + VsProjectTypes.VbProjectTypeGuid, + VsProjectTypes.CppProjectTypeGuid, + VsProjectTypes.JsProjectTypeGuid, + VsProjectTypes.FsharpProjectTypeGuid, + VsProjectTypes.NemerleProjectTypeGuid, + VsProjectTypes.WixProjectTypeGuid, + VsProjectTypes.SynergexProjectTypeGuid, + VsProjectTypes.NomadForVisualStudioProjectTypeGuid, + VsProjectTypes.TDSProjectTypeGuid, + VsProjectTypes.DxJsProjectTypeGuid, + VsProjectTypes.DeploymentProjectTypeGuid, + VsProjectTypes.CosmosProjectTypeGuid, + VsProjectTypes.ManagementPackProjectTypeGuid, + }; + + private static readonly HashSet Unsupported = new HashSet(StringComparer.OrdinalIgnoreCase) + { + VsProjectTypes.LightSwitchProjectTypeGuid, + VsProjectTypes.InstallShieldLimitedEditionTypeGuid + }; + + // List of project types that cannot have binding redirects added + private static readonly HashSet UnsupportedProjectTypesForBindingRedirects = new HashSet(StringComparer.OrdinalIgnoreCase) + { + VsProjectTypes.WixProjectTypeGuid, + VsProjectTypes.JsProjectTypeGuid, + VsProjectTypes.NemerleProjectTypeGuid, + VsProjectTypes.CppProjectTypeGuid, + VsProjectTypes.SynergexProjectTypeGuid, + VsProjectTypes.NomadForVisualStudioProjectTypeGuid, + VsProjectTypes.DxJsProjectTypeGuid, + VsProjectTypes.CosmosProjectTypeGuid, + }; + + // List of project types that cannot have references added to them + private static readonly HashSet UnsupportedProjectTypesForAddingReferences = new HashSet(StringComparer.OrdinalIgnoreCase) + { + VsProjectTypes.WixProjectTypeGuid, + VsProjectTypes.CppProjectTypeGuid, + }; + + private static readonly HashSet UnsupportedProjectExtension = new HashSet(StringComparer.OrdinalIgnoreCase) + { + ".metaproj", + ".shproj", + ".vcxitems", + ".sqlproj" + }; + + public static bool IsSupported(string projectKind) + { + return Supported.Contains(projectKind); + } + + public static bool IsUnsupported(string projectKind) + { + return Unsupported.Contains(projectKind); + } + + public static bool IsSupportedForBindingRedirects(string projectKind) + { + return !UnsupportedProjectTypesForBindingRedirects.Contains(projectKind, StringComparer.OrdinalIgnoreCase); + } + + public static bool IsSupportedForAddingReferences(string projectKind) + { + return !UnsupportedProjectTypesForAddingReferences.Contains(projectKind, StringComparer.OrdinalIgnoreCase); + } + + public static bool IsSupportedProjectExtension(string projectPath) + { + return !UnsupportedProjectExtension.Contains(Path.GetExtension(projectPath)); + } + } +} diff --git a/src/NuGet.Clients/NuGet.VisualStudio.Common/SupportedProjectTypes.cs b/src/NuGet.Clients/NuGet.VisualStudio.Common/SupportedProjectTypes.cs deleted file mode 100644 index 316051b40..000000000 --- a/src/NuGet.Clients/NuGet.VisualStudio.Common/SupportedProjectTypes.cs +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using NuGet.VisualStudio; - -namespace NuGet.VisualStudio -{ - public static class SupportedProjectTypes - { - private static readonly HashSet _supportedProjectTypes = new HashSet(StringComparer.OrdinalIgnoreCase) - { - VsProjectTypes.WebSiteProjectTypeGuid, - VsProjectTypes.CsharpProjectTypeGuid, - VsProjectTypes.VbProjectTypeGuid, - VsProjectTypes.CppProjectTypeGuid, - VsProjectTypes.JsProjectTypeGuid, - VsProjectTypes.FsharpProjectTypeGuid, - VsProjectTypes.NemerleProjectTypeGuid, - VsProjectTypes.WixProjectTypeGuid, - VsProjectTypes.SynergexProjectTypeGuid, - VsProjectTypes.NomadForVisualStudioProjectTypeGuid, - VsProjectTypes.TDSProjectTypeGuid, - VsProjectTypes.DxJsProjectTypeGuid, - VsProjectTypes.DeploymentProjectTypeGuid, - VsProjectTypes.CosmosProjectTypeGuid, - VsProjectTypes.ManagementPackProjectTypeGuid, - }; - - private static readonly HashSet _unsupportedProjectTypes = new HashSet(StringComparer.OrdinalIgnoreCase) - { - VsProjectTypes.LightSwitchProjectTypeGuid, - VsProjectTypes.InstallShieldLimitedEditionTypeGuid - }; - - // List of project types that cannot have binding redirects added - private static readonly string[] _unsupportedProjectTypesForBindingRedirects = - { - VsProjectTypes.WixProjectTypeGuid, - VsProjectTypes.JsProjectTypeGuid, - VsProjectTypes.NemerleProjectTypeGuid, - VsProjectTypes.CppProjectTypeGuid, - VsProjectTypes.SynergexProjectTypeGuid, - VsProjectTypes.NomadForVisualStudioProjectTypeGuid, - VsProjectTypes.DxJsProjectTypeGuid, - VsProjectTypes.CosmosProjectTypeGuid, - }; - - // List of project types that cannot have references added to them - private static readonly string[] _unsupportedProjectTypesForAddingReferences = - { - VsProjectTypes.WixProjectTypeGuid, - VsProjectTypes.CppProjectTypeGuid, - }; - - private static readonly HashSet _unsupportedProjectExtension = new HashSet(StringComparer.OrdinalIgnoreCase) - { - ".metaproj", - ".shproj", - ".vcxitems", - ".sqlproj" - }; - - public static bool IsSupported(string projectKind) - { - return _supportedProjectTypes.Contains(projectKind); - } - - public static bool IsUnsupported(string projectKind) - { - return _unsupportedProjectTypes.Contains(projectKind); - } - - public static bool IsSupportedForBindingRedirects(string projectKind) - { - return !_unsupportedProjectTypesForBindingRedirects.Contains(projectKind, StringComparer.OrdinalIgnoreCase); - } - - public static bool IsSupportedForAddingReferences(string projectKind) - { - return !_unsupportedProjectTypesForAddingReferences.Contains(projectKind, StringComparer.OrdinalIgnoreCase); - } - - public static bool IsSupportedProjectExtension(string projectPath) - { - return !_unsupportedProjectExtension.Contains(Path.GetExtension(projectPath)); - } - } -} diff --git a/src/NuGet.Clients/NuGet.VisualStudio.Implementation/Extensibility/VsPackageInstaller.cs b/src/NuGet.Clients/NuGet.VisualStudio.Implementation/Extensibility/VsPackageInstaller.cs index 71d85450d..dbe5a9ed0 100644 --- a/src/NuGet.Clients/NuGet.VisualStudio.Implementation/Extensibility/VsPackageInstaller.cs +++ b/src/NuGet.Clients/NuGet.VisualStudio.Implementation/Extensibility/VsPackageInstaller.cs @@ -70,7 +70,7 @@ namespace NuGet.VisualStudio { await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); - IVsHierarchy vsHierarchy = project.ToVsHierarchy(); + IVsHierarchy vsHierarchy = await project.ToVsHierarchyAsync(); if (vsHierarchy != null && VsHierarchyUtility.IsCPSCapabilityCompliant(vsHierarchy)) { diff --git a/src/NuGet.Clients/NuGet.VisualStudio.Implementation/Extensibility/VsPathContextProvider.cs b/src/NuGet.Clients/NuGet.VisualStudio.Implementation/Extensibility/VsPathContextProvider.cs index b40d8df64..f58b38498 100644 --- a/src/NuGet.Clients/NuGet.VisualStudio.Implementation/Extensibility/VsPathContextProvider.cs +++ b/src/NuGet.Clients/NuGet.VisualStudio.Implementation/Extensibility/VsPathContextProvider.cs @@ -325,7 +325,15 @@ namespace NuGet.VisualStudio private async Task> GetProjectsInSolutionAsync(DTE dte) { IEnumerable allProjects = await EnvDTESolutionUtility.GetAllEnvDTEProjectsAsync(dte); - IEnumerable supportedProjects = allProjects.Where(EnvDTEProjectUtility.IsSupported); + var supportedProjects = new List(); + foreach (Project project in allProjects) + { + if (await EnvDTEProjectUtility.IsSupportedAsync(project)) + { + supportedProjects.Add(project); + } + } + return supportedProjects; } diff --git a/test/EndToEnd/API.Test.dll b/test/EndToEnd/API.Test.dll new file mode 100644 index 000000000..0750fcd34 Binary files /dev/null and b/test/EndToEnd/API.Test.dll differ diff --git a/test/NuGet.Clients.Tests/NuGet.PackageManagement.VisualStudio.Test/ProjectSystems/LegacyPackageReferenceProjectTests.cs b/test/NuGet.Clients.Tests/NuGet.PackageManagement.VisualStudio.Test/ProjectSystems/LegacyPackageReferenceProjectTests.cs index 97b1cfc87..e513ee87d 100644 --- a/test/NuGet.Clients.Tests/NuGet.PackageManagement.VisualStudio.Test/ProjectSystems/LegacyPackageReferenceProjectTests.cs +++ b/test/NuGet.Clients.Tests/NuGet.PackageManagement.VisualStudio.Test/ProjectSystems/LegacyPackageReferenceProjectTests.cs @@ -53,8 +53,8 @@ namespace NuGet.PackageManagement.VisualStudio.Test Directory.CreateDirectory(testMSBuildProjectExtensionsPath); var projectAdapter = Mock.Of(); Mock.Get(projectAdapter) - .SetupGet(x => x.MSBuildProjectExtensionsPath) - .Returns(testMSBuildProjectExtensionsPath); + .Setup(x => x.GetMSBuildProjectExtensionsPathAsync()) + .Returns(Task.FromResult(testMSBuildProjectExtensionsPath)); var testProject = new LegacyPackageReferenceProject( projectAdapter, @@ -72,7 +72,7 @@ namespace NuGet.PackageManagement.VisualStudio.Test // Verify Mock.Get(projectAdapter) - .VerifyGet(x => x.MSBuildProjectExtensionsPath, Times.AtLeastOnce); + .Verify(x => x.GetMSBuildProjectExtensionsPathAsync(), Times.AtLeastOnce); } } @@ -107,8 +107,8 @@ namespace NuGet.PackageManagement.VisualStudio.Test Directory.CreateDirectory(testMSBuildProjectExtensionsPath); var projectAdapter = Mock.Of(); Mock.Get(projectAdapter) - .SetupGet(x => x.MSBuildProjectExtensionsPath) - .Returns(testMSBuildProjectExtensionsPath); + .Setup(x => x.GetMSBuildProjectExtensionsPathAsync()) + .Returns(Task.FromResult(testMSBuildProjectExtensionsPath)); Mock.Get(projectAdapter) .SetupGet(x => x.FullProjectPath) @@ -130,7 +130,7 @@ namespace NuGet.PackageManagement.VisualStudio.Test // Verify Mock.Get(projectAdapter) - .VerifyGet(x => x.MSBuildProjectExtensionsPath, Times.AtLeastOnce); + .Verify(x => x.GetMSBuildProjectExtensionsPathAsync(), Times.AtLeastOnce); } } @@ -165,8 +165,8 @@ namespace NuGet.PackageManagement.VisualStudio.Test Directory.CreateDirectory(testMSBuildProjectExtensionsPath); var projectAdapter = Mock.Of(); Mock.Get(projectAdapter) - .SetupGet(x => x.MSBuildProjectExtensionsPath) - .Returns(testMSBuildProjectExtensionsPath); + .Setup(x => x.GetMSBuildProjectExtensionsPathAsync()) + .Returns(Task.FromResult(testMSBuildProjectExtensionsPath)); Mock.Get(projectAdapter) .SetupGet(x => x.FullProjectPath) @@ -186,7 +186,7 @@ namespace NuGet.PackageManagement.VisualStudio.Test // Verify Mock.Get(projectAdapter) - .VerifyGet(x => x.MSBuildProjectExtensionsPath, Times.AtLeastOnce); + .Verify(x => x.GetMSBuildProjectExtensionsPathAsync(), Times.AtLeastOnce); } } @@ -1203,8 +1203,8 @@ namespace NuGet.PackageManagement.VisualStudio.Test var testMSBuildProjectExtensionsPath = Path.Combine(fullPath, "obj"); Directory.CreateDirectory(testMSBuildProjectExtensionsPath); projectAdapter - .Setup(x => x.MSBuildProjectExtensionsPath) - .Returns(testMSBuildProjectExtensionsPath); + .Setup(x => x.GetMSBuildProjectExtensionsPathAsync()) + .Returns(Task.FromResult(testMSBuildProjectExtensionsPath)); return projectAdapter.Object; } diff --git a/test/NuGet.Clients.Tests/NuGet.PackageManagement.VisualStudio.Test/ProjectSystems/LegacyPackageReferenceRestoreUtilityTests.cs b/test/NuGet.Clients.Tests/NuGet.PackageManagement.VisualStudio.Test/ProjectSystems/LegacyPackageReferenceRestoreUtilityTests.cs index 656a4bdfa..c996583fb 100644 --- a/test/NuGet.Clients.Tests/NuGet.PackageManagement.VisualStudio.Test/ProjectSystems/LegacyPackageReferenceRestoreUtilityTests.cs +++ b/test/NuGet.Clients.Tests/NuGet.PackageManagement.VisualStudio.Test/ProjectSystems/LegacyPackageReferenceRestoreUtilityTests.cs @@ -361,8 +361,9 @@ namespace NuGet.PackageManagement.VisualStudio.Test Assert.True(File.Exists(projectLockFilePath)); // delete existing restore output files - File.Delete(Path.Combine(vsProjectAdapter.MSBuildProjectExtensionsPath, "project.assets.json")); - File.Delete(Path.Combine(vsProjectAdapter.MSBuildProjectExtensionsPath, NoOpRestoreUtilities.NoOpCacheFileName)); + string msBuildProjectExtensionsPath = await vsProjectAdapter.GetMSBuildProjectExtensionsPathAsync(); + File.Delete(Path.Combine(msBuildProjectExtensionsPath, "project.assets.json")); + File.Delete(Path.Combine(msBuildProjectExtensionsPath, NoOpRestoreUtilities.NoOpCacheFileName)); // add a new package var newPackageContext = new SimpleTestPackageContext("packageA", "1.0.1"); @@ -390,7 +391,7 @@ namespace NuGet.PackageManagement.VisualStudio.Test Assert.False(restoreSummary.NoOpRestore); } - var lockFilePath = Path.Combine(vsProjectAdapter.MSBuildProjectExtensionsPath, "project.assets.json"); + var lockFilePath = Path.Combine(msBuildProjectExtensionsPath, "project.assets.json"); Assert.True(File.Exists(lockFilePath)); var lockFile = new LockFileFormat().Read(lockFilePath); @@ -490,9 +491,11 @@ namespace NuGet.PackageManagement.VisualStudio.Test Assert.False(restoreSummary.NoOpRestore); } + string msBuildProjectExtensionsPath = await vsProjectAdapter.GetMSBuildProjectExtensionsPathAsync(); + // Initial asserts Assert.True(File.Exists(projectLockFilePath)); - var assetsFilePath = Path.Combine(vsProjectAdapter.MSBuildProjectExtensionsPath, "project.assets.json"); + var assetsFilePath = Path.Combine(msBuildProjectExtensionsPath, "project.assets.json"); Assert.True(File.Exists(assetsFilePath)); // Assert that there is no warning logged into assets file @@ -500,7 +503,7 @@ namespace NuGet.PackageManagement.VisualStudio.Test Assert.False(assetsFile.LogMessages.Any()); // delete existing restore output files - File.Delete(Path.Combine(vsProjectAdapter.MSBuildProjectExtensionsPath, "project.assets.json")); + File.Delete(Path.Combine(msBuildProjectExtensionsPath, "project.assets.json")); // install a new package projectServices.SetupInstalledPackages( @@ -867,8 +870,9 @@ namespace NuGet.PackageManagement.VisualStudio.Test Assert.True(File.Exists(projectLockFilePath)); // delete existing restore output files - File.Delete(Path.Combine(vsProjectAdapter.MSBuildProjectExtensionsPath, "project.assets.json")); - File.Delete(Path.Combine(vsProjectAdapter.MSBuildProjectExtensionsPath, NoOpRestoreUtilities.NoOpCacheFileName)); + string msBuildProjectExtensionsPath = await vsProjectAdapter.GetMSBuildProjectExtensionsPathAsync(); + File.Delete(Path.Combine(msBuildProjectExtensionsPath, "project.assets.json")); + File.Delete(Path.Combine(msBuildProjectExtensionsPath, NoOpRestoreUtilities.NoOpCacheFileName)); // clean packages folder Directory.Delete(testSolutionManager.GlobalPackagesFolder, true); @@ -1001,7 +1005,7 @@ namespace NuGet.PackageManagement.VisualStudio.Test Assert.True(File.Exists(projectLockFilePath)); // delete existing restore output files - File.Delete(Path.Combine(vsProjectAdapter.MSBuildProjectExtensionsPath, "project.assets.json")); + File.Delete(Path.Combine(await vsProjectAdapter.GetMSBuildProjectExtensionsPathAsync(), "project.assets.json")); // clean packages folder Directory.Delete(testSolutionManager.GlobalPackagesFolder, true); @@ -1153,7 +1157,7 @@ namespace NuGet.PackageManagement.VisualStudio.Test sourceRepositoryProvider.GetRepositories(), sourceRepositoryProvider.GetRepositories(), CancellationToken.None); // Assert - var lockFilePath = Path.Combine(vsProjectAdapterA.MSBuildProjectExtensionsPath, "project.assets.json"); + var lockFilePath = Path.Combine(await vsProjectAdapterA.GetMSBuildProjectExtensionsPathAsync(), "project.assets.json"); Assert.True(File.Exists(lockFilePath)); } @@ -1225,7 +1229,7 @@ namespace NuGet.PackageManagement.VisualStudio.Test sourceRepositoryProvider.GetRepositories(), sourceRepositoryProvider.GetRepositories(), CancellationToken.None); // Assert - var assetsFilePath = Path.Combine(vsProjectAdapterA.MSBuildProjectExtensionsPath, "project.assets.json"); + var assetsFilePath = Path.Combine(await vsProjectAdapterA.GetMSBuildProjectExtensionsPathAsync(), "project.assets.json"); Assert.True(File.Exists(assetsFilePath)); var assetsFile = new LockFileFormat().Read(assetsFilePath); @@ -1346,7 +1350,7 @@ namespace NuGet.PackageManagement.VisualStudio.Test CancellationToken.None); // Assert - var assetsFilePath = Path.Combine(vsProjectAdapterA.MSBuildProjectExtensionsPath, "project.assets.json"); + var assetsFilePath = Path.Combine(await vsProjectAdapterA.GetMSBuildProjectExtensionsPathAsync(), "project.assets.json"); Assert.True(File.Exists(assetsFilePath)); var assetsFile = new LockFileFormat().Read(assetsFilePath); @@ -1827,7 +1831,9 @@ namespace NuGet.PackageManagement.VisualStudio.Test Assert.True(File.Exists(projectLockFilePath)); - var lockFilePath = Path.Combine(vsProjectAdapterA.MSBuildProjectExtensionsPath, "project.assets.json"); + string msBuildProjectExtensionsPathA = await vsProjectAdapterA.GetMSBuildProjectExtensionsPathAsync(); + + var lockFilePath = Path.Combine(msBuildProjectExtensionsPathA, "project.assets.json"); Assert.True(File.Exists(lockFilePath)); var lockFile = new LockFileFormat().Read(lockFilePath); @@ -1835,8 +1841,8 @@ namespace NuGet.PackageManagement.VisualStudio.Test Assert.Equal("1.0.0", resolvedVersion.ToNormalizedString()); // delete existing restore output files - File.Delete(Path.Combine(vsProjectAdapterA.MSBuildProjectExtensionsPath, "project.assets.json")); - File.Delete(Path.Combine(vsProjectAdapterA.MSBuildProjectExtensionsPath, NoOpRestoreUtilities.NoOpCacheFileName)); + File.Delete(Path.Combine(msBuildProjectExtensionsPathA, "project.assets.json")); + File.Delete(Path.Combine(msBuildProjectExtensionsPathA, NoOpRestoreUtilities.NoOpCacheFileName)); //clear packageA 1.0.0 from global packages folder var packageAPath = Path.Combine(testSolutionManager.GlobalPackagesFolder, "packagea", "1.0.0"); @@ -2008,8 +2014,8 @@ namespace NuGet.PackageManagement.VisualStudio.Test Assert.Equal(PackageDependencyType.Project, lockFile.Targets[0].Dependencies[1].Type); // Act - File.Delete(Path.Combine(vsProjectAdapterA.MSBuildProjectExtensionsPath, NoOpRestoreUtilities.NoOpCacheFileName)); - File.Delete(Path.Combine(vsProjectAdapterB.MSBuildProjectExtensionsPath, NoOpRestoreUtilities.NoOpCacheFileName)); + File.Delete(Path.Combine(await vsProjectAdapterA.GetMSBuildProjectExtensionsPathAsync(), NoOpRestoreUtilities.NoOpCacheFileName)); + File.Delete(Path.Combine(await vsProjectAdapterB.GetMSBuildProjectExtensionsPathAsync(), NoOpRestoreUtilities.NoOpCacheFileName)); restoreSummaries = await DependencyGraphRestoreUtility.RestoreAsync( testSolutionManager, @@ -2156,7 +2162,7 @@ namespace NuGet.PackageManagement.VisualStudio.Test Assert.False(restoreSummary.NoOpRestore); } - var assetsFilePath = Path.Combine(vsProjectAdapterA.MSBuildProjectExtensionsPath, "project.assets.json"); + var assetsFilePath = Path.Combine(await vsProjectAdapterA.GetMSBuildProjectExtensionsPathAsync(), "project.assets.json"); Assert.True(File.Exists(assetsFilePath)); var assetsFile = new LockFileFormat().Read(assetsFilePath); @@ -2276,7 +2282,7 @@ namespace NuGet.PackageManagement.VisualStudio.Test Assert.False(restoreSummary.NoOpRestore); } - var assetsFilePath = Path.Combine(vsProjectAdapter.MSBuildProjectExtensionsPath, "project.assets.json"); + var assetsFilePath = Path.Combine(await vsProjectAdapter.GetMSBuildProjectExtensionsPathAsync(), "project.assets.json"); Assert.True(File.Exists(assetsFilePath)); var assetsFile = new LockFileFormat().Read(assetsFilePath); diff --git a/test/NuGet.Clients.Tests/NuGet.PackageManagement.VisualStudio.Test/ProjectSystems/TestVSProjectAdapter.cs b/test/NuGet.Clients.Tests/NuGet.PackageManagement.VisualStudio.Test/ProjectSystems/TestVSProjectAdapter.cs index 24378be42..0aa78e06e 100644 --- a/test/NuGet.Clients.Tests/NuGet.PackageManagement.VisualStudio.Test/ProjectSystems/TestVSProjectAdapter.cs +++ b/test/NuGet.Clients.Tests/NuGet.PackageManagement.VisualStudio.Test/ProjectSystems/TestVSProjectAdapter.cs @@ -54,12 +54,9 @@ namespace NuGet.PackageManagement.VisualStudio.Test } } - public string MSBuildProjectExtensionsPath + public async Task GetMSBuildProjectExtensionsPathAsync() { - get - { - return Path.Combine(ProjectDirectory, "obj"); - } + return Path.Combine(await GetProjectDirectoryAsync(), "obj"); } public IProjectBuildProperties BuildProperties { get; } = Mock.Of(); @@ -72,7 +69,7 @@ namespace NuGet.PackageManagement.VisualStudio.Test public bool IsDeferred => false; - public bool IsSupported => true; + public Task IsSupportedAsync() => Task.FromResult(true); public string NoWarn { @@ -100,13 +97,7 @@ namespace NuGet.PackageManagement.VisualStudio.Test } } - public string ProjectDirectory - { - get - { - return Path.GetDirectoryName(FullProjectPath); - } - } + public Task GetProjectDirectoryAsync() => Task.FromResult(Path.GetDirectoryName(FullProjectPath)); public string ProjectName => ProjectNames.ShortName; diff --git a/test/TestExtensions/API.Test/InternalAPITestHook.cs b/test/TestExtensions/API.Test/InternalAPITestHook.cs index 251013bc2..1c2f4b5ee 100644 --- a/test/TestExtensions/API.Test/InternalAPITestHook.cs +++ b/test/TestExtensions/API.Test/InternalAPITestHook.cs @@ -156,10 +156,13 @@ namespace API.Test }); } - public static async Task MigrateJsonProject(string projectName) + public static IVsProjectJsonToPackageReferenceMigrateResult MigrateJsonProject(string projectName) { - var migrator = ServiceLocator.GetComponent(); - return (IVsProjectJsonToPackageReferenceMigrateResult)await migrator.MigrateProjectJsonToPackageReferenceAsync(projectName); + return ThreadHelper.JoinableTaskFactory.Run(async () => + { + var migrator = ServiceLocator.GetComponent(); + return (IVsProjectJsonToPackageReferenceMigrateResult)await migrator.MigrateProjectJsonToPackageReferenceAsync(projectName); + }); } public static bool IsFileExistsInProject(string projectUniqueName, string filePath) @@ -178,7 +181,7 @@ namespace API.Test if (!string.IsNullOrEmpty(solutionProjectPath) && PathUtility.GetStringComparerBasedOnOS().Equals(solutionProjectPath, projectUniqueName)) { - return await EnvDTEProjectUtility.ContainsFile(project, filePath); + return await EnvDTEProjectUtility.ContainsFileAsync(project, filePath); } }