I've developed a code generator for internal use where code assets (POCOs) are generated based off of C# interfaces. The code generation process programmatically adds/removes items to csproj file. The workflow is as follows: a developer adds a new C# interface, or removes an existing C# interface in Visual Studio 2017. If the developer saves the project file first then runs the code generator, then everything works as expected. Code-generated assets are either added to the project (or removed) and Visual Studio reflects those changes accordingly. However, if the developer fails to save the csproj file before running code generator, and has deleted a C# interface, then the code-generated assets are not being removed from the project because Visual Studio is not accepting the csproj file modifications.
Inside the code generator, I'm physically removing the references to the code-generated files that are deleted and am saving the csproj file. I verify that the referenced files are removed from the csproj file by opening the csproj up in notepad. However, as soon as I bring Visual Studio into focus, Visual Studio recognizes that the csproj file has changed and asks if I want to discard, overwrite, save as, etc and the changes made to csproj file from my code generation process are lost. Visual Studio adds the references to the deleted files back into the csproj file. I've tried discard, overwrite, save as, etc and I'm not getting Visual Studio to accept the newly modified csproj file (which has the references to deleted files removed).
Here's my code for removing code-generated assets:
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);
}
}
Is it possible to have Visual Studio just accept the new csproj file? Is there some setting I need to make to csproj file when removing assets? Having Visual Studio balk at the modified csproj file is hindering the usefulness of the code generator for removing code-generated assets no longer needed (stemming from physically deleting a C# interface file).
EDIT
Here's a video showing the process of running the T4 generator inside Visual Studio generating C# assets based on a C# interface. I delete the source C# interface, re-run code generator and the project file is updated accordingly causing the project to be reloaded.
https://www.screencast.com/t/JWTE0LpkXZGX
The problem isn't that the project gets reloaded. The problem is the code generator updates and saves the csproj file outside of Visual Studio, which causes Visual Studio to be confused because the csproj file changed. How do you get Visual Studio to 'silently' accept the changes saved to csproj file?
Thanks for your help.