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

时间:2013-08-31 04:00:43

标签: c# winforms visual-studio-2010 visual-studio projects-and-solutions

背景

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

尝试失败

This question唯一的答案有两种方法,但我不能让它们中的任何一种都有效。第一个我找不到要引用的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();

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

6 个答案:

答案 0 :(得分:25)

我只是将它添加到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();

答案 1 :(得分:9)

作为Boot750答案的补充(首先建议作为他的答案的编辑,但作为一个独立的重新发布)

您应该注意,对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);

答案 2 :(得分:5)

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

作为另一种选择,您可以删除所有<Compile>代码并将其替换为<Compile Include="*.cs" />

答案 3 :(得分:5)

只是添加@ 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();

答案 4 :(得分:1)

我知道这是旧帖子。但是,我需要此选项,但没有找到想要的合适选项。因此,我开发了具有扩展功能的VS扩展。您可以设置文件类型,然后选择要在生成文件后将其文件加载到项目中的项目目录列表。

Market (free) | Source-Code

答案 5 :(得分:0)

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