Пример #1
0
        public static async Task DoWorkInWriterLockAsync(Project project, IVsHierarchy hierarchy, Action <MsBuildProject> action)
        {
            await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();

            var vsProject = (IVsProject)hierarchy;
            UnconfiguredProject unconfiguredProject = GetUnconfiguredProject(vsProject);

            if (unconfiguredProject != null)
            {
                var service = unconfiguredProject.ProjectService.Services.ProjectLockService;
                if (service != null)
                {
                    using (ProjectWriteLockReleaser x = await service.WriteLockAsync())
                    {
                        await x.CheckoutAsync(unconfiguredProject.FullPath);

                        ConfiguredProject configuredProject = await unconfiguredProject.GetSuggestedConfiguredProjectAsync();

                        MsBuildProject buildProject = await x.GetProjectAsync(configuredProject);

                        if (buildProject != null)
                        {
                            action(buildProject);
                        }

                        await x.ReleaseAsync();
                    }

                    await unconfiguredProject.ProjectService.Services.ThreadingPolicy.SwitchToUIThread();

                    project.Save();
                }
            }
        }
Пример #2
0
        private static async Task DoWorkInWriterLock(IVsProject project, Action <MsBuildProject> action)
        {
            UnconfiguredProject unconfiguredProject = GetUnconfiguredProject(project);

            if (unconfiguredProject != null)
            {
                var service = unconfiguredProject.ProjectService.Services.ProjectLockService;
                if (service != null)
                {
                    using (ProjectWriteLockReleaser x = await service.WriteLockAsync())
                    {
                        await x.CheckoutAsync(unconfiguredProject.FullPath);

                        ConfiguredProject configuredProject = await unconfiguredProject.GetSuggestedConfiguredProjectAsync();

                        MsBuildProject buildProject = await x.GetProjectAsync(configuredProject);

                        if (buildProject != null)
                        {
                            action(buildProject);
                        }

                        await x.ReleaseAsync();
                    }

                    await unconfiguredProject.ProjectService.Services.ThreadingPolicy.SwitchToUIThread();
                }
            }
        }
Пример #3
0
        private async Task RemoveItems(ProjectItemGroupElement parent, Dictionary <string, ProjectItemElement> items, IReadOnlyCollection <string> itemsToRemove, ProjectWriteLockReleaser access)
        {
            await access.CheckoutAsync(itemsToRemove);

            foreach (var path in itemsToRemove)
            {
                RemoveItem(parent, items, path);
            }
        }
Пример #4
0
        private async Task RenameItems(Dictionary <string, ProjectItemElement> items, IReadOnlyDictionary <string, string> itemsToRename, ProjectWriteLockReleaser access)
        {
            await access.CheckoutAsync(itemsToRename.Keys);

            foreach (var kvp in itemsToRename)
            {
                ProjectItemElement item;
                if (items.TryGetValue(kvp.Key, out item))
                {
                    items.Remove(kvp.Key);
                    item.Include     = kvp.Value;
                    items[kvp.Value] = item;
                }
            }
        }
Пример #5
0
        public async Task OpenProjectForWriteAsync(ConfiguredProject project, Action <Project> action, CancellationToken cancellationToken = default(CancellationToken))
        {
            Requires.NotNull(project, nameof(project));
            Requires.NotNull(project, nameof(action));

            using (ProjectWriteLockReleaser access = await _projectLockService.WriteLockAsync(cancellationToken))
            {
                await access.CheckoutAsync(project.UnconfiguredProject.FullPath)
                .ConfigureAwait(true);

                Project evaluatedProject = await access.GetProjectAsync(project, cancellationToken)
                                           .ConfigureAwait(true);

                // Deliberately not async to reduce the type of
                // code you can run while holding the lock.
                action(evaluatedProject);
            }
        }
        public async Task OpenProjectXmlForWriteAsync(UnconfiguredProject project, Action <ProjectRootElement> action, CancellationToken cancellationToken = default)
        {
            Requires.NotNull(project, nameof(project));
            Requires.NotNull(project, nameof(action));

            using (ProjectWriteLockReleaser access = await _projectLockService.WriteLockAsync(cancellationToken))
            {
                await access.CheckoutAsync(project.FullPath);

                ProjectRootElement rootElement = await access.GetProjectXmlAsync(project.FullPath, cancellationToken);

                // Deliberately not async to reduce the type of
                // code you can run while holding the lock.
                action(rootElement);

                // Avoid blocking thread on Dispose
                await access.ReleaseAsync();
            }
        }
Пример #7
0
        private static async Task DoWorkInWriterLockInternal(Project project, IVsHierarchy hierarchy, Action <MsBuildProject> action)
        {
            UnconfiguredProject unconfiguredProject = GetUnconfiguredProject((IVsProject)hierarchy);

            if (unconfiguredProject != null)
            {
                var service = unconfiguredProject.ProjectService.Services.ProjectLockService;
                if (service != null)
                {
                    // WriteLockAsync will move us to a background thread.
                    using (ProjectWriteLockReleaser x = await service.WriteLockAsync())
                    {
                        await x.CheckoutAsync(unconfiguredProject.FullPath);

                        ConfiguredProject configuredProject = await unconfiguredProject.GetSuggestedConfiguredProjectAsync();

                        MsBuildProject buildProject = await x.GetProjectAsync(configuredProject);

                        if (buildProject != null)
                        {
                            action(buildProject);
                        }

                        await x.ReleaseAsync();
                    }

                    // perform the save synchronously
                    await Task.Run(() =>
                    {
                        // move to the UI thread for the rest of this method
                        unconfiguredProject.ProjectService.Services.ThreadingPolicy.SwitchToUIThread();

                        var fileSystem = new PhysicalFileSystem(@"c:\");
                        fileSystem.MakeFileWritable(project.FullName);
                        project.Save();
                    }
                                   );
                }
            }
        }
        /// <summary>
        /// Deletes items from the project, and optionally from disk.
        /// Note: Delete and Remove commands are handled via IVsHierarchyDeleteHandler3, not by
        /// IAsyncCommandGroupHandler and first asks us we CanRemove nodes. If yes then RemoveAsync is called.
        /// We can remove only nodes that are standard and based on project items, i.e. nodes that
        /// are created by default IProjectDependenciesSubTreeProvider implementations and have
        /// DependencyNode.GenericDependencyFlags flags and IRule with Context != null, in order to obtain
        /// node's itemSpec. ItemSpec then used to remove a project item having same Include.
        /// </summary>
        /// <param name="nodes">The nodes that should be deleted.</param>
        /// <param name="deleteOptions">A value indicating whether the items should be deleted from disk as well as
        /// from the project file.
        /// </param>
        /// <exception cref="InvalidOperationException">Thrown when <see cref="IProjectTreeProvider.CanRemove"/>
        /// would return <c>false</c> for this operation.</exception>
        public override async Task RemoveAsync(IImmutableSet <IProjectTree> nodes,
                                               DeleteOptions deleteOptions = DeleteOptions.None)
        {
            if (deleteOptions.HasFlag(DeleteOptions.DeleteFromStorage))
            {
                throw new NotSupportedException();
            }

            // Get the list of shared import nodes.
            IEnumerable <IProjectTree> sharedImportNodes = nodes.Where(node =>
                                                                       node.Flags.Contains(DependencyTreeFlags.SharedProjectFlags));

            // Get the list of normal reference Item Nodes (this excludes any shared import nodes).
            IEnumerable <IProjectTree> referenceItemNodes = nodes.Except(sharedImportNodes);

            using (ProjectWriteLockReleaser access = await ProjectLockService.WriteLockAsync())
            {
                Project project = await access.GetProjectAsync(ActiveConfiguredProject).ConfigureAwait(true);

                // Handle the removal of normal reference Item Nodes (this excludes any shared import nodes).
                foreach (IProjectTree node in referenceItemNodes)
                {
                    if (node.BrowseObjectProperties == null || node.BrowseObjectProperties.Context == null)
                    {
                        // if node does not have an IRule with valid ProjectPropertiesContext we can not
                        // get it's itemsSpec. If nodes provided by custom IProjectDependenciesSubTreeProvider
                        // implementation, and have some custom IRule without context, it is not a problem,
                        // since they wouldnot have DependencyNode.GenericDependencyFlags and we would not
                        // end up here, since CanRemove would return false and Remove command would not show
                        // up for those nodes.
                        continue;
                    }

                    IProjectPropertiesContext nodeItemContext = node.BrowseObjectProperties.Context;
                    ProjectItem unresolvedReferenceItem       = project.GetItemsByEvaluatedInclude(nodeItemContext.ItemName)
                                                                .FirstOrDefault(item => string.Equals(item.ItemType,
                                                                                                      nodeItemContext.ItemType,
                                                                                                      StringComparison.OrdinalIgnoreCase));

                    Report.IfNot(unresolvedReferenceItem != null, "Cannot find reference to remove.");
                    if (unresolvedReferenceItem != null)
                    {
                        await access.CheckoutAsync(unresolvedReferenceItem.Xml.ContainingProject.FullPath)
                        .ConfigureAwait(true);

                        project.RemoveItem(unresolvedReferenceItem);
                    }
                }

                IDependenciesSnapshot snapshot = DependenciesSnapshotProvider.CurrentSnapshot;
                Requires.NotNull(snapshot, nameof(snapshot));
                if (snapshot == null)
                {
                    return;
                }

                // Handle the removal of shared import nodes.
                ProjectRootElement projectXml = await access.GetProjectXmlAsync(UnconfiguredProject.FullPath)
                                                .ConfigureAwait(true);

                foreach (IProjectTree sharedImportNode in sharedImportNodes)
                {
                    string sharedFilePath = UnconfiguredProject.GetRelativePath(sharedImportNode.FilePath);
                    if (string.IsNullOrEmpty(sharedFilePath))
                    {
                        continue;
                    }

                    IDependency sharedProjectDependency = snapshot.FindDependency(sharedFilePath, topLevel: true);
                    if (sharedProjectDependency != null)
                    {
                        sharedFilePath = sharedProjectDependency.Path;
                    }

                    // Find the import that is included in the evaluation of the specified ConfiguredProject that
                    // imports the project file whose full path matches the specified one.
                    IEnumerable <ResolvedImport> matchingImports = from import in project.Imports
                                                                   where import.ImportingElement.ContainingProject == projectXml
                                                                   where PathHelper.IsSamePath(import.ImportedProject.FullPath, sharedFilePath)
                                                                   select import;
                    foreach (ResolvedImport importToRemove in matchingImports)
                    {
                        ProjectImportElement importingElementToRemove = importToRemove.ImportingElement;
                        Report.IfNot(importingElementToRemove != null,
                                     "Cannot find shared project reference to remove.");
                        if (importingElementToRemove != null)
                        {
                            await access.CheckoutAsync(importingElementToRemove.ContainingProject.FullPath)
                            .ConfigureAwait(true);

                            importingElementToRemove.Parent.RemoveChild(importingElementToRemove);
                        }
                    }
                }
            }
        }
Пример #9
0
 private async Task RenameItems(Dictionary<string, ProjectItemElement> items, IReadOnlyDictionary<string, string> itemsToRename, ProjectWriteLockReleaser access) {
     await access.CheckoutAsync(itemsToRename.Keys);
     foreach (var kvp in itemsToRename) {
         ProjectItemElement item;
         if (items.TryGetValue(kvp.Key, out item)) {
             items.Remove(kvp.Key);
             item.Include = kvp.Value;
             items[kvp.Value] = item;
         }
     }
 }
Пример #10
0
 private async Task RemoveItems(ProjectItemGroupElement parent, Dictionary<string, ProjectItemElement> items, IReadOnlyCollection<string> itemsToRemove, ProjectWriteLockReleaser access) {
     await access.CheckoutAsync(itemsToRemove);
     foreach (var path in itemsToRemove) {
         RemoveItem(parent, items, path);
     }
 }