在VS中添加文件夹和文件后如何强制刷新 Microsoft.Build.Evaluation.Project 项目?

4
我正在创建一个应用程序,将一些文件和文件夹添加到已在Visual Studio中加载的现有项目中。这可以实现,但它总是会弹出一个消息告诉用户(我)需要刷新项目以显示新文件。

enter image description here

使用Entity Framework并添加迁移时,它会向当前加载的项目中添加一个文件,而且不会询问用户。我希望能够做到同样的事情。
这是可能的吗?如果有人不知道答案,他们是否知道我如何深入研究EF并添加迁移以查看它们是如何做到的?
以下是我用来编辑项目文件的代码:
using Microsoft.Build.Evaluation;

 internal class ProjectFileHandler
    {
        private void AddMigrationFolder(Project project, string     projectFileLocation, string name)
        {
            var loc = Path.Combine(projectFileLocation.Substring(0, projectFileLocation.LastIndexOf("\\")), name);
            project.AddItem("Folder", loc);            
        }

        internal void AddMigrationFile(string projectfileLocation, string migrationFolderName, string fileLocation)
        {
            var project = new Project(projectfileLocation);
            AddMigrationFolder(project, projectfileLocation, migrationFolderName);

            project.AddItem("Compile", fileLocation);

            project.Save();
        }
    }

你找到解决方案了吗? - david rosko
我记得我使用了DTE来完成这个。如果有帮助的话,我把它放在了这个项目中:https://github.com/twistedtwig/NHibernateRepository - Jon
2个回答

0

虽然这篇文章有点老,但我还是要留下评论。也许对其他人有帮助。

问题出在"project.Save();"这一行。

解决方案是将其识别为"外部"更改。 不加入这一行代码再试试看。


我也遇到了这个问题。如果你不使用project.Save(),那么它会提示你覆盖项目文件。此外,我希望在调用构建之前包含这个更改。有人有解决方案吗? - Ven

0

虽然这是一个老问题,但我今天不得不解决它,所以就算只有一点点价值,我也想分享一下我的解决方法。

首先,据我所知,如果你使用Microsoft.Build.Evaluation更新项目,没有Visual Studio提示用户重新加载,你是无法完成更新的。你必须调用project.Save()将你的更新写入项目XML文件中,然后Visual Studio会“看到”文件更改并显示提示。

但你可以使用EnvDTE来代替Microsoft.Build.Evaluation,这似乎就是Entity Framework所做的,尽管使用Powershell。EnvDTE可在NuGet上获取,最新版本支持.NET Framework 4.5和.NET Standard 2,因此应该相当兼容。

使用EnvDTE,您可以获取对Project对象的引用并调用AddFromFile(absoluteFilePath) - 如果需要,还有其他Add()方法。

如果您拥有项目的完整文件路径,则可以使用以下方式获取项目文件:

using System.Linq;
using System.Runtime.InteropServices;
using EnvDTE;

var dte = (DTE)Marshal.GetActiveObject("VisualStudio.DTE");

var project = dte
    .Solution
    .EnumerateProjects()
    .First(p => p.FullName == fullPathToProject);

...其中EnumerateProjects()是以下扩展方法:

using EnvDTE;
using System.Collections;
using System.Collections.Generic;

internal static class EnvDteExtensions
{
    public static IEnumerable<Project> EnumerateProjects(
        this Solution solution)
    {
        return Enumerate(solution.Projects);
    }

    private static IEnumerable<Project> Enumerate(IEnumerable items)
    {
        foreach (var item in items)
        {
            var candidateProject = item;

            if (candidateProject is ProjectItem projectItem &&
                projectItem.SubProject != null)
            {
                candidateProject = projectItem.SubProject;
            }

            if (!(candidateProject is Project project))
            {
                continue;
            }

            yield return project;

            try
            {
                if (project.ProjectItems == null)
                {
                    continue;
                }
            }
            catch
            {
                continue;
            }

            foreach (var subProject in Enumerate(project.ProjectItems))
            {
                yield return subProject;
            }
        }
    }
}

在EnvDTE中,Project可能实际上是一个项目,也可能是包含项目的解决方案文件夹 - candidateProject is ProjectItem projectItem && projectItem.SubProject != null检查处理后一种情况。

EnvDTE的Project.AddFromFile()将文件弹出到解决方案资源管理器中,而不需要重新加载项目。

最后,AddFromFile()似乎是幂等的,因此您可以将相同的文件重复添加到项目中,而不必担心它是否已经存在。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接