Microsoft.Build.Evaluation.Project 在VS中添加文件夹和文件强制刷新项目 [英] Microsoft.Build.Evaluation.Project add folder and file force refresh of project in VS

查看:123
本文介绍了Microsoft.Build.Evaluation.Project 在VS中添加文件夹和文件强制刷新项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am creating an app that will add some files and folders to an existing project which is loaded in Visual studio. That works but it will always pop up a message telling the user (me) to refresh the project to show the new files.

当使用实体框架并添加迁移时,它会将文件添加到当前加载的项目中,并且不会询问用户.我希望能够做同样的事情.

When using Entity Framework and adding a migration it will add a file to a project that is currently loaded and it doesn't ask the user. I would like to be able to do the same thing.

这可能吗?如果有人不知道答案,他们是否知道我可以如何深入研究 EF 并添加迁移以了解他们是如何做到的?

Is this possible? If someone doesn't know the answer do they know how I might delve into EF and add migration to see how they do it?

这是我用来编辑项目文件的代码:

Here is the code that I am using to edit the project file:

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();
        }
    }

推荐答案

我年纪更大了,但我今天必须解决这个问题,所以为了它的价值,这就是我所做的.

Even older, but I had to solve this problem today, so for what it's worth, here's what I did.

首先,据我所知,如果没有 Visual Studio 提示用户重新加载项目,则无法使用 Microsoft.Build.Evaluation 更新项目.您必须调用 project.Save() 将更新写入项目 XML,Visual Studio 会看到"文件更改并显示提示.

Firstly, as far as I can tell, you can't update a project using Microsoft.Build.Evaluation without Visual Studio prompting the user to reload it. You have to call project.Save() to write your updates to the project XML, and Visual Studio 'sees' the file change and displays the prompt.

可以做什么 - 这看起来是实体框架所做的,尽管with Powershell - 使用 EnvDTE 而不是 Microsoft.Build.Evaluation.EnvDTE 在 NuGet 上可用,最新版本支持 .NET Framework 4.5 和 .NET Standard 2,所以它应该是非常广泛兼容的.

What you can do - and this looks to be what Entity Framework does, albeit with Powershell - is use EnvDTE instead of Microsoft.Build.Evaluation. EnvDTE is available on NuGet and the latest version supports .NET Framework 4.5 and .NET Standard 2, so it should be pretty widely compatible.

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

With EnvDTE you get a reference to a Project object and call AddFromFile(absoluteFilePath) - there are also other Add() methods if needed.

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

If you have the full file path to your project, you can get a project file using:

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() 是以下扩展方法:

...where EnumerateProjects() is the following extension method:

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 是 ProjectItem projectItem &&projectItem.SubProject != null 检查处理后一种情况.

A Project in EnvDTE might actually be a project, or it might be a solution folder containing projects - the candidateProject is ProjectItem projectItem && projectItem.SubProject != null check handles the latter scenario.

EnvDTE 的 Project.AddFromFile() 将文件弹出到解决方案资源管理器中,没有项目重新加载提示.

EnvDTE's Project.AddFromFile() pops the file into Solution Explorer with no project reload prompt.

最后,AddFromFile() 似乎是幂等的,因此您可以将同一个文件垃圾邮件到项目中,而不必担心它是否已经存在.

Finally, AddFromFile() seems to be idempotent, so you can spam the same file into the project without worrying if it already exists.

这篇关于Microsoft.Build.Evaluation.Project 在VS中添加文件夹和文件强制刷新项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆