如何以编程方式在我的项目中包含一个文件?

use*_*322 39 c# projects-and-solutions visual-studio-2010 visual-studio winforms

背景

我正在制作一个帮助应用程序来重新格式化一些代码文件并创建新的代码文件,这些代码文件将被添加到我的其他项目中,所以我可以立即使用新代码,但是我在添加新代码文件时遇到了麻烦自动进入我的项目.顺便说一下,它在c#中,帮助应用程序是WinForms.

尝试失败

这个问题唯一的答案有两种方法,但我不能让它们中的任何一种起作用.第一个我找不到Microsoft.Build要引用的程序集,而在另一个中显然没有足够的参数用于命令行.

如何在不使用第三方应用程序的情况下以编程方式将文件包含到项目中?

基本上,我正在寻找相当于这个:

......但是使用代码完成了.

要求

这些是我认为解决方案应该提供的功能:

  • 选择包含我们要添加文件的项目解决方案
  • 选择要添加文件的项目
  • 选择项目中的目录
  • 当然,我们正在添加的文件

进展

通过用户@ psubsee2003的帮助,我能够在我的计算机上的Microsoft.Build.dll文件C:\Windows\Microsoft.NET\Framework\v4.0.30319夹中找到该文件,并通过将我的项目的目标框架更改为版本4 完整配置文件而不是默认的客户端配置文件来成功导入它.

我发现了如何使用该AddItem方法:

var p = new Microsoft.Build.Evaluation.Project(@"C:\projects\MyProject.csproj");
p.AddItem("Compile", @"C:\folder\file.cs");
p.Save();
Run Code Online (Sandbox Code Playgroud)

该文件将出现在项目的根文件夹中,除非项目已经有一个文件夹folder,在这种情况下文件将放在那里.因此,基本上该文件将被放置在原始文件的路径中找到的最深的文件夹链中,该路径将朝向根文件夹.

Boo*_*750 29

它适用于我只是将它添加到ProjectFolder,并以此编程方式添加文件夹.

var p = new Microsoft.Build.Evaluation.Project(@"C:\projects\BabDb\test\test.csproj");
        p.AddItem("Folder", @"C:\projects\BabDb\test\test2");
        p.AddItem("Compile", @"C:\projects\BabDb\test\test2\Class1.cs");
        p.Save();
Run Code Online (Sandbox Code Playgroud)

  • @AminM `if (p.Items.FirstOrDefault(i => i.EvaluatedInclude == newItemPath) == null) { p.AddItem("Build", newItemPath); p.Save(); }` (7认同)

Cai*_*ard 11

作为Boot750答案的补充(首先建议作为他的答案的编辑,但似乎一些短视的同行评审员认为我正在与Boot750交谈,当我实际采用他与OP交谈的方向时):

您应该注意,new Microsoft.Build.Evaluation.Project(path)实际调用会导致项目加载到Microsoft.Build.Evaluation程序集维护的全局高速缓存中.new Project(path)使用相同的路径再次调用,而不首先从全局集合中卸载它/重新启动应用程序将导致异常,例如:

项目集合中已存在具有相同项目(具有相同全局属性和工具版本的项目),其路径为"YOUR_PATH".要将等效项加载到此项目集合中,请先卸载此项目.

即使变量p超出范围.

因此,如果您计划重复使用Load/AddItem/Save模式,则可能需要采用更像这样的模式:

 var p =
Microsoft.Build.Evaluation
  .ProjectCollection.GlobalProjectCollection
    .LoadedProjects.FirstOrDefault(pr => pr.FullPath == projFilePath);

if (p == null)
   p = new Microsoft.Build.Evaluation.Project(projFilePath);
Run Code Online (Sandbox Code Playgroud)


rer*_*run 7

最简单的方法是修改Project文件.由于它只是一个MSBUILD文件,VS将接收更改并提示重新加载项目.将项目文件作为XML加载并找到第一个<Compile Include="Name of File.cs" />.插入新的<Compile Include="NewFile.CS" />和完成的.

作为另一种选择,您可以删除所有<Compile>标记并替换它们<Compile Include="*.cs" />


Aet*_*bmo 6

只是添加到@ caius-jard的响应中

一旦项目进入GlobalProjectCollection,它就会保存在内存中,并且不会反映对该项目进行的任何手动更改。这包括更新.csproj文件和使用VS删除生成的文件。

如果删除生成的文件并再次运行代码,则项目将更新为包含生成的文件中的2个。使用ReevaluateIfNecessary()函数在使用之前更新项目实例,如下所示:

var p = Microsoft.Build.Evaluation
        .ProjectCollection.GlobalProjectCollection
        .LoadedProjects.FirstOrDefault(pr => pr.FullPath == projFilePath);

if (p == null)
    p = new Microsoft.Build.Evaluation.Project(projFilePath);

// Update instance of project
p.ReevaluateIfNecessary();

// Check folder is not already in the project
var folderLoc = @"C:\projects\BabDb\test\test2";
if(p.Items.FirstOrDefault(i => i.EvaluatedInclude == folderLoc) == null)
    p.AddItem("Folder", folderLoc);

// Check file is not already in the project
var fileLoc = @"C:\projects\BabDb\test\test2\Class1.cs";
if(p.Items.FirstOrDefault(i => i.EvaluatedInclude == fileLoc) == null)
    p.AddItem("Compile", fileLoc);

p.Save();
Run Code Online (Sandbox Code Playgroud)


小智 -1

您可以使用 T4 文本模板。有关详细信息,请参阅http://msdn.microsoft.com/en-us/library/vstudio/bb126445(v=vs.100).aspx

  • 即使链接是完整的答案,您的答案也应该保留。请至少添加一个简短的解释。 (3认同)