我正在一个代码生成场景中工作,其中生成了整个解决方案,包括项目、文件夹、*.cs 文件和作品。
目前,我以编程方式将所有文件生成为文本文件,没有结构(DOM)。我想知道 .NET / VS 生态系统中是否有这样的 API 可以帮助获得对此的更多控制。
本质上能够以编程方式(强类型):
Build Action
等。请注意,我指的不是 CSCodeProvider、Roslyn 或 VS 扩展。但是,VS 扩展是扩展如何访问当前打开的解决方案的一个很好的示例。它使用 MS VS SDK,但我不知道这是否可以用于将解决方案作为 API 而不是在扩展中操作。
任何想法将不胜感激。
对于项目,我使用
Microsoft.Build
库,尤其是 Microsoft.Build.Construction 命名空间。
项目由 ProjectRootElement 类表示。您可以使用
Create
方法创建一个新的,并使用 Save
保存它。检查其他方法来创建项目、更改属性等。例如,为引用创建新的项目组:
/// <summary>
/// Gets the first 'ItemGroup' element in msbuild file that contains an item of specified type.
/// </summary>
/// <param name="projRoot"></param>
/// <param name="itemType">The item type to be searched, for example 'Compile', 'Reference', etc. </param>
/// <returns></returns>
/// <remarks>If none such group was found, a new one is created.</remarks>
private static ProjectItemGroupElement GetOrCreateItemGroupWithItemType(ProjectRootElement projRoot, string itemType)
{
foreach (var item in projRoot.Items)
{
if (item.ItemType == itemType)
{
return item.Parent as ProjectItemGroupElement;
}
}
return projRoot.AddItemGroup();
}
要添加引用,请使用如下方法:
/// <summary>
/// Adds the 'Reference' item into msbuild file.
/// </summary>
/// <param name="itemGroup"></param>
/// <param name="referencePath">Reference full path or a file name.</param>
/// <returns>Created 'Reference' item.</returns>
/// <remarks></remarks>
private static ProjectItemElement AddReferenceItem(ProjectItemGroupElement itemGroup, string referencePath)
{
string refFileName = Path.GetFileName(referencePath);
string refName = Path.GetFileNameWithoutExtension(referencePath);
string refFolder = "";
if (referencePath.Length == refFileName.Length)
{
// referencePath is just a file name without path
refFolder = QuickDevis.Common.CommonUtility.ApplicationStartupPath();
}
else
{
refFolder = Path.GetDirectoryName(referencePath);
}
ProjectItemElement res;
res = itemGroup.AddItem("Reference", refName);
res.AddMetadata("HintPath", Path.Combine(refFolder, refFileName));
return res;
}
一个问题是,
Microsoft.Build
无法创建和编辑 SLN 文件。它只能解析它们。您可以使用 MvsSln 库(我没有测试它)。这已在以编程方式创建解决方案中讨论过。