将t4模板的输出设置为嵌入资源

问题描述 投票:0回答:1

我已经构建了一个t4模板来输出多个文件,但是我需要这些文件作为嵌入内容。

t4 是否提供开箱即用的方法?

如果没有,是否可以通过将每个文件的

<Content>
元素切换为
<EmbeddedResource>
元素来修改项目文件?

c# t4
1个回答
0
投票

以下是我将

ProjectItem
设置为嵌入式资源的方法:在 T4 模板中,我有一个函数接受
Project
对象和一个代表 T4 模板本身的
FileInfo
对象 - 可能有更简单的方法,但我使用...获得模板
FileInfo

var templateFileInfo = new FileInfo(this.Host.TemplateFile);

使用模板

FileInfo
是因为我们需要生成的文件(我的T4模板输出多个文件),这些文件是在解决方案的模板文件“下”生成的。

[真的,我想要的是一个代表模板的

ProjectItem
,这样我就可以遍历自动生成的孩子。如果有更好的方法,请发表评论。]

一旦我有了代表每个 T4 生成文件的

ProjectItem
对象,我将枚举每个
Properties
集合,直到找到该
"BuildAction"
ProjectItem
属性;然后使用常量将其设置为“嵌入式资源”。

private void SetGeneratedFilesAsEmbeddedResources(Project project, FileInfo templateFileInfo)
{
    const string propBuildAction = "BuildAction";

    var generatedProjectItems = GetGeneratedProjectItems(project, templateFileInfo).ToList();

    foreach (var generatedProjectItem in generatedProjectItems)
    {
        var props = generatedProjectItem.Properties;
        if ((VSLangProj.prjBuildAction)props.Item(propBuildAction).Value != VSLangProj.prjBuildAction.prjBuildActionEmbeddedResource)
        {
            props.Item(propBuildAction).Value = VSLangProj.prjBuildAction.prjBuildActionEmbeddedResource;
        }
    }
}

private IEnumerable<ProjectItem> GetGeneratedProjectItems(Project project, FileInfo templateFileInfo)
{
    var templateParentFolder = GetTemplateParentFolder(project, templateFileInfo);

    foreach (ProjectItem item in templateParentFolder.ProjectItems)
    {
        if (item.Kind != EnvDTE.Constants.vsProjectItemKindPhysicalFile || item.Name != templateFileInfo.Name)
        {
            continue;
        }

        foreach (ProjectItem generatedItem in item.ProjectItems)
        {
            yield return generatedItem;
        }
    }
}

private ProjectItem GetTemplateParentFolder(Project project, FileInfo templateFileInfo)
{
    var containingFolderName = templateFileInfo.Directory.Name;

    foreach (ProjectItem item in project.ProjectItems)
    {
        if (item.Kind == EnvDTE.Constants.vsProjectItemKindPhysicalFolder && item.Name == containingFolderName)
        {
            return item;
        }
    }
    
    throw new Exception($"Cannot execute {templateFileInfo.Name} - Unable to locate the \"{containingFolderName}\" folder at the root level.");
}
© www.soinside.com 2019 - 2024. All rights reserved.