C# 如何让Visual Studio 2017接受对csproj文件的修改

C# 如何让Visual Studio 2017接受对csproj文件的修改,c#,msbuild,visual-studio-2017,microsoft.build,C#,Msbuild,Visual Studio 2017,Microsoft.build,我开发了一个代码生成器供内部使用,其中代码资产(POCO)是基于C#接口生成的。代码生成过程以编程方式向csproj文件添加/删除项。工作流程如下:开发人员在Visual Studio 2017中添加新的C#接口,或删除现有的C#接口。如果开发人员先保存项目文件,然后运行代码生成器,那么一切都会按预期进行。代码生成的资产要么添加到项目中(要么删除),VisualStudio会相应地反映这些更改。但是,如果开发人员在运行代码生成器之前未能保存csproj文件,并且删除了C#接口,则不会从项目中删除

我开发了一个代码生成器供内部使用,其中代码资产(POCO)是基于C#接口生成的。代码生成过程以编程方式向csproj文件添加/删除项。工作流程如下:开发人员在Visual Studio 2017中添加新的C#接口,或删除现有的C#接口。如果开发人员先保存项目文件,然后运行代码生成器,那么一切都会按预期进行。代码生成的资产要么添加到项目中(要么删除),VisualStudio会相应地反映这些更改。但是,如果开发人员在运行代码生成器之前未能保存csproj文件,并且删除了C#接口,则不会从项目中删除代码生成的资产,因为Visual Studio不接受csproj文件修改

在代码生成器中,我实际删除对已删除的代码生成文件的引用,并保存csproj文件。我通过在记事本中打开csproj来验证引用的文件是否已从csproj文件中删除。但是,只要我关注Visual Studio,Visual Studio就会发现csproj文件已更改,并询问我是否要放弃、覆盖、另存为等,并且代码生成过程中对csproj文件所做的更改将丢失。VisualStudio将对已删除文件的引用添加回csproj文件中。我尝试过放弃、覆盖、另存为等,但我不会让Visual Studio接受新修改的csproj文件(其中删除了对已删除文件的引用)

以下是我删除代码生成资产的代码:

using Microsoft.Build.Evaluation;
using Microsoft.Build.Logging;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;

    public static void RemoveGeneratedFilesFromProject(String projectPath)
    {
        UnloadAnyProject();

        var project = ProjectCollection.GlobalProjectCollection.LoadedProjects.FirstOrDefault(pr => pr.FullPath == projectPath);

        //ATTEMPT TO SAVE PROJECT IN CASE DEVELOPER DID NOT...
        project.Save();


        //GET A LIST OF ITEMS CONTAINING PATH TO CODE-GENERATED ASSETS ("Generated\API")
        IList<ProjectItem> generatedItemsList = project.GetItems("Compile").Where(item => item.EvaluatedInclude.Contains(@"Generated\Api")).ToList();

        foreach (var item in generatedItemsList)
        {
            project.RemoveItem(item);
        }

        //SAVE PROJECT TO REFLECT ALL OF THE CODE GENERATED ITEMS REMOVED FROM PROJECT FILE
        project.Save();

        UnloadAnyProject();
    }

    private static void UnloadAnyProject()
    {
        ProjectCollection projcoll = ProjectCollection.GlobalProjectCollection;

        foreach (Project project in projcoll.LoadedProjects)
        {
            ProjectCollection mypcollection = project.ProjectCollection;
            mypcollection.UnloadProject(project);
        }
    }
使用Microsoft.Build.Evaluation;
使用Microsoft.Build.Logging;
使用制度;
使用System.Collections.Generic;
使用System.IO;
使用System.Linq;
使用System.Threading.Tasks;
public static void RemoveGeneratedFilesFromProject(字符串projectPath)
{
UnloadAnyProject();
var project=ProjectCollection.GlobalProjectCollection.LoadedProjects.FirstOrDefault(pr=>pr.FullPath==projectPath);
//试图保存项目,以防开发人员未。。。
project.Save();
//获取包含代码生成资产路径的项目列表(“生成的\API”)
IList generatedItemsList=project.GetItems(“编译”)。其中(item=>item.EvaluatedInclude.Contains(@“Generated\Api”)).ToList();
foreach(generatedItemsList中的变量项)
{
项目移除项(项目);
}
//保存项目以反映从项目文件中删除的所有代码生成项
project.Save();
UnloadAnyProject();
}
私有静态void UnloadAnyProject()
{
ProjectCollection projcoll=ProjectCollection.GlobalProjectCollection;
foreach(projcoll.LoadedProjects中的项目)
{
ProjectCollection mypcollection=project.ProjectCollection;
mypcollection.UnloadProject(项目);
}
}
是否可以让Visual Studio只接受新的csproj文件?删除资产时是否需要对csproj文件进行一些设置?如果Visual Studio对修改后的csproj文件犹豫不决,则会妨碍代码生成器用于删除不再需要的代码生成资产(源于物理删除C#接口文件)

编辑

下面是一段视频,展示了在VisualStudio中运行T4生成器的过程,该生成器基于C#接口生成C#资产。我删除了源C#接口,重新运行代码生成器,相应地更新了项目文件,导致项目被重新加载

问题不在于项目被重新加载。问题是代码生成器在Visual Studio之外更新并保存csproj文件,这会导致Visual Studio感到困惑,因为csproj文件已更改。如何让Visual Studio“静默”接受保存到csproj文件的更改


感谢您的帮助。

在将项目文件加载到Visual Studio时自己修改该文件不是一个好主意。即使您找到一种方法强制它重新加载项目,它仍然需要重新加载,这是一个很大的麻烦

最好从T4模板访问
EnvDTE
,并通过该模板修改项目文件。通过此对象,可以访问Visual Studio的项目模型

请注意,默认情况下,用户仍需要保存修改后的项目文件,因为VS会将其视为脏文件,但此行为与您可以通过VS进行的所有其他项目文件修改一致。不过,如果确实需要,您可以强制VS保存项目

以下是访问VS需要执行的操作:

将主机特定属性设置为
true


导入
EnvDTE


获取
dte
对象:


现在您可以完全访问VS的项目API。请注意,使用这种方法,您将失去在VisualStudio之外执行模板的能力


以下是如何在模板旁边添加文件的完整示例:



您是在生成期间从msbuild目标运行代码生成器,还是在生成过程之外作为独立的exe/工具运行代码生成器?大多数生成方法都集成到msbuild中,因此即使在VS中的设计时生成过程中,它们也可以动态添加代码,而无需编辑项目文件。基本上,对project.Save()的第一次调用在VS中无效?它是使用T4文件编写的独立代码生成器。我不知道如何将T4与MS Build集成。第一个project.save()似乎不会影响visual studio。第二次保存发生在删除过时的代码资产之后,VS将被提示重新加载。但是VS在内存中似乎有自己的项目版本,这与我在内存中加载/修改/保存的csproj文件不同