C# 如何以编程方式在我的项目中包含文件?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18544354/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to programmatically include a file in my project?
提问by user1306322
Background
背景
I'm making a helper application that reformats some code files and creates new code files, which are to be added to my other project, so I could use the new code right away, but I'm having serious trouble adding that new code file into my project automatically. By the way it's in c# and the helper app is WinForms.
我正在制作一个帮助应用程序,它重新格式化一些代码文件并创建新的代码文件,这些文件将添加到我的其他项目中,因此我可以立即使用新代码,但是我在添加新代码文件时遇到了严重的问题自动进入我的项目。顺便说一下,它是在 c# 中,而辅助应用程序是 WinForms。
Failed attempts
失败的尝试
This question's only answer has two ways of doing that, but I couldn't make any of them work. With the first I can't find a Microsoft.Build
assembly to reference, and in the other there are clearly not enough arguments for a command line.
This question's only answer有两种方法可以做到这一点,但我无法使它们中的任何一个起作用。第一个我找不到Microsoft.Build
要引用的程序集,而另一个显然没有足够的命令行参数。
Question
题
How do I programmatically include a file into a project without the use of third-party applications?
如何在不使用第三方应用程序的情况下以编程方式将文件包含到项目中?
Basically, I'm looking for the equivalent of this:
基本上,我正在寻找与此等效的内容:
...But done using code.
...但使用代码完成。
Requirements
要求
These are the features I suppose the solution should offer:
这些是我认为解决方案应该提供的功能:
- Select the solutionwhich has the projectwe're adding the file to
- Select projectinto which the file is to be added
- Select directorywithin the project
- And, of course, the filewhich we're adding
- 选择包含我们要将文件添加到的项目的解决方案
- 选择要添加文件的项目
- 选择项目中的目录
- 当然,我们要添加的文件
Progress
进步
With user @psubsee2003's help I was able to find the Microsoft.Build.dll
file in C:\Windows\Microsoft.NET\Framework\v4.0.30319
folder on my computer and successfully import it by changing my project's target framework to version 4 Full profile, not the default Client profile.
在用户@psubsee2003 的帮助下,我能够在我的计算机上的Microsoft.Build.dll
文件C:\Windows\Microsoft.NET\Framework\v4.0.30319
夹中找到该文件,并通过将我的项目的目标框架更改为版本 4 Full profile而不是默认的 Client profile来成功导入它。
And I found how to use the AddItem
method:
我找到了如何使用该AddItem
方法:
var p = new Microsoft.Build.Evaluation.Project(@"C:\projects\MyProject.csproj");
p.AddItem("Compile", @"C:\folder\file.cs");
p.Save();
The file will appear in project's root folder unless the project already had a folder called folder
, in which case the file will be placed there. So basically the file will be placed in the deepest folder chain found in the original file's path going towards the root folder.
该文件将出现在项目的根文件夹中,除非项目已经有一个名为 的文件夹folder
,在这种情况下,文件将被放置在那里。所以基本上该文件将被放置在原始文件路径中找到的最深的文件夹链中,该路径指向根文件夹。
回答by tlango
You could use T4 Text Templates. See http://msdn.microsoft.com/en-us/library/vstudio/bb126445(v=vs.100).aspxfor more information.
您可以使用 T4 文本模板。有关详细信息,请参阅http://msdn.microsoft.com/en-us/library/vstudio/bb126445(v=vs.100).aspx。
回答by rerun
The simplest way to do this is to modify the Project file. As it is just an MSBUILD file, VS will pick up the change and prompt up to reload the project. Load the project file as an XML and find the first <Compile Include="Name of File.cs" />
. Insert a new <Compile Include="NewFile.CS" />
and your done.
最简单的方法是修改项目文件。由于它只是一个 MSBUILD 文件,VS 将获取更改并提示重新加载项目。将项目文件作为 XML 加载并找到第一个<Compile Include="Name of File.cs" />
. 插入一个新的<Compile Include="NewFile.CS" />
并完成。
As another option you can remove all the <Compile>
tags and replace them with <Compile Include="*.cs" />
作为另一种选择,您可以删除所有<Compile>
标签并将其替换为<Compile Include="*.cs" />
回答by Boot750
It worked for my just adding the it to the ProjectFolder, and also add the folder programmatically like this.
它适用于我只是将它添加到 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();
回答by Caius Jard
As a supplement to Boot750's answer (first suggested as an edit to his answer but re-posted as a standalone)
作为 Boot750 答案的补充(首先建议作为对他的答案的编辑,但作为独立重新发布)
You should note that the call to new Microsoft.Build.Evaluation.Project(path)
actually causes the project to be loaded into a global cache maintained by the Microsoft.Build.Evaluation
assembly. Calling new Project(path)
again with the same path, without unloading it from the global collection first/restarting your app will cause an exception like:
您应该注意到调用new Microsoft.Build.Evaluation.Project(path)
实际上会导致项目加载到Microsoft.Build.Evaluation
程序集维护的全局缓存中。new Project(path)
使用相同的路径再次调用,而不首先从全局集合中卸载它/重新启动您的应用程序将导致如下异常:
An equivalent project (a project with the same global properties and tools version) is already present in the project collection, with the path "YOUR_PATH". To load an equivalent into this project collection, unload this project first.
项目集合中已存在等效项目(具有相同全局属性和工具版本的项目),其路径为“YOUR_PATH”。要将等效项加载到此项目集合中,请先卸载此项目。
even if the variable p
has gone out of scope.
即使变量p
已经超出范围。
You might hence need to adopt a pattern more like this, if you plan to use the Load/AddItem/Save pattern repeatedly:
因此,如果您计划重复使用 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);
回答by Aetbmo
Just to add to the response from @caius-jard
只是为了添加到@caius-jard 的回复中
Once the project is in the GlobalProjectCollection it's held in memory and does not reflect any manual changes made to the project. This includes updating the .csproj file and using VS to remove the generated files.
一旦项目在 GlobalProjectCollection 中,它就会保存在内存中,并且不会反映对项目所做的任何手动更改。这包括更新 .csproj 文件和使用 VS 删除生成的文件。
If you remove the generated file and run the code again the project will update to contain 2 of the generated file. Use the ReevaluateIfNecessary() function to update the instance of the project before use like this:
如果您删除生成的文件并再次运行代码,项目将更新为包含 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();
回答by AbuDawood
I know that this is an old post. However, I was in need of this option and didn't find the suitable one as I wished. So, I developed a VS extension with extended features. You can set the file types, and then, select the list of projects' directory that you want their files to be loaded into the project once they get generated.
我知道这是一个旧帖子。然而,我需要这个选项并且没有找到我希望的合适的选项。因此,我开发了一个具有扩展功能的 VS 扩展。您可以设置文件类型,然后选择您希望文件在生成后加载到项目中的项目目录列表。