我正在创建一个应用程序,它会将一些文件和文件夹添加到Visual Studio中加载的现有项目中。这有效,但它总是会弹出一条消息告诉用户(我)刷新项目以显示新文件。
使用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();
}
}
答案 0 :(得分:0)
很老了,但我会发表评论。也许它可以帮助别人。
问题是“project.Save();”
解决方案将此视为“外部”变更。 不用这一行就试试你的代码。
答案 1 :(得分:0)
年龄更大了,但我今天必须解决这个问题,所以不管它的价值,这就是我所做的。
首先,据我所知,如果没有 Visual Studio 提示用户重新加载项目,则无法使用 Microsoft.Build.Evaluation 更新项目。您必须调用 project.Save()
将更新写入项目 XML,Visual Studio 会“看到”文件更改并显示提示。
您可以做什么 - 这看起来是实体框架所做的,尽管 with Powershell - 是使用 EnvDTE 而不是 Microsoft.Build.Evaluation。 EnvDTE 可用 on 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()
似乎是幂等的,因此您可以将同一个文件垃圾邮件到项目中,而不必担心它是否已经存在。