如何使用 CodeSmith 工具将生成的文件添加到多个项目

发布于 2024-09-03 17:56:32 字数 189 浏览 4 评论 0原文

我在当前的项目中使用 CodeSmith,并试图解决一个问题。对于我的 CodeSmith 项目 (.csp),我可以选择一个选项,让它自动将所有生成的文件添加到当前项目 (.csproj)。但我希望能够将输出添加到多个项目(.csproj)。 CodeSmith 内部是否有选项允许这样做?或者有没有一种好的方法可以通过编程来做到这一点?

谢谢。

I'm using CodeSmith on my current project and I'm trying to figure out an issue. For my CodeSmith project (.csp) I can select an option to have it automatically add all generated files to the current project (.csproj). But I want to be able to add the output to multiple projects (.csproj). Is there an option inside of CodeSmith to allow this? Or is there a good way to programmatically do that?

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

一影成城 2024-09-10 17:56:32

我无法找到让 CodeSmith 自动处理此问题的方法,因此我最终在代码隐藏文件中编写了一个自定义方法来处理此问题。

一些注意事项:
- proj 文件是 XML,因此相当容易编辑,但保存项目中包含的文件列表的实际“ItemGroup”节点实际上并未以任何特殊方式进行标记。我最终选择了具有“Contains”子节点的“ItemGroup”节点,但可能有更好的方法来确定应该使用哪个。
- 我建议立即更改所有 proj 文件,而不是在创建/更新每个文件时进行更改。否则,如果您从 Visual Studio 启动生成,您可能会收到大量“此项目已更改,您想重新加载吗”
- 如果您的文件处于源代码管理之下(它们是,对吧?!),您将需要处理检出文件并将它们添加到源代码管理以及编辑项目文件。

这是(或多或少)我用来将文件添加到项目的代码:

/// <summary>
/// Adds the given file to the indicated project
/// </summary>
/// <param name="project">The path of the proj file</param>
/// <param name="projectSubDir">The subdirectory of the project that the 
/// file is located in, otherwise an empty string if it is at the project root</param>
/// <param name="file">The name of the file to be added to the project</param>
/// <param name="parent">The name of the parent to group the file to, an 
/// empty string if there is no parent file</param>
public static void AddFileToProject(string project, string projectSubDir, 
        string file, string parent)
{
    XDocument proj = XDocument.Load(project);

    XNamespace ns = "http://schemas.microsoft.com/developer/msbuild/2003";
    var itemGroup = proj.Descendants(ns + "ItemGroup").FirstOrDefault(x => x.Descendants(ns + "Compile").Count() > 0);

    if (itemGroup == null)
        throw new Exception(string.Format("Unable to find an ItemGroup to add the file {1} to the {0} project", project, file));

    //If the file is already listed, don't bother adding it again
    if(itemGroup.Descendants(ns + "Compile").Where(x=>x.Attribute("Include").Value.ToString() == file).Count() > 0)
        return; 

    XElement item = new XElement(ns + "Compile", 
                    new XAttribute("Include", Path.Combine(projectSubDir,file)));

    //This is used to group files together, in this case the file that is 
    //regenerated is grouped as a dependent of the user-editable file that
    //is not changed by the code generator
    if (string.IsNullOrEmpty(parent) == false)
        item.Add(new XElement(ns + "DependentUpon", parent));

    itemGroup.Add(item);

    proj.Save(project); 

}

I was unable to figure out a way to make CodeSmith handle this issue automatically, so I ended up writing a custom method in the Code Behind file to handle this.

A few notes:
- The proj files are XML, and as thus fairly easy to edit, but the actual "ItemGroup" node that holds the list of files that are included in the project isn't actually labeled in any special way. I ended up picking the "ItemGroup" node that has "Contains" child nodes, but there might be a better way to determine which you should use.
- I recommend doing all the proj file changes at once, instead of as each file is created/updated. Otherwise if you launch the generation from Visual Studio, you might get a flood of "This item has changed, would you like to reload"
- If your files are under source control (they are, right?!), you're going to need to handle checking files out and adding them to source control along with editing the proj files.

Here is (more or less) the code I used to add a file to the project:

/// <summary>
/// Adds the given file to the indicated project
/// </summary>
/// <param name="project">The path of the proj file</param>
/// <param name="projectSubDir">The subdirectory of the project that the 
/// file is located in, otherwise an empty string if it is at the project root</param>
/// <param name="file">The name of the file to be added to the project</param>
/// <param name="parent">The name of the parent to group the file to, an 
/// empty string if there is no parent file</param>
public static void AddFileToProject(string project, string projectSubDir, 
        string file, string parent)
{
    XDocument proj = XDocument.Load(project);

    XNamespace ns = "http://schemas.microsoft.com/developer/msbuild/2003";
    var itemGroup = proj.Descendants(ns + "ItemGroup").FirstOrDefault(x => x.Descendants(ns + "Compile").Count() > 0);

    if (itemGroup == null)
        throw new Exception(string.Format("Unable to find an ItemGroup to add the file {1} to the {0} project", project, file));

    //If the file is already listed, don't bother adding it again
    if(itemGroup.Descendants(ns + "Compile").Where(x=>x.Attribute("Include").Value.ToString() == file).Count() > 0)
        return; 

    XElement item = new XElement(ns + "Compile", 
                    new XAttribute("Include", Path.Combine(projectSubDir,file)));

    //This is used to group files together, in this case the file that is 
    //regenerated is grouped as a dependent of the user-editable file that
    //is not changed by the code generator
    if (string.IsNullOrEmpty(parent) == false)
        item.Add(new XElement(ns + "DependentUpon", parent));

    itemGroup.Add(item);

    proj.Save(project); 

}
终弃我 2024-09-10 17:56:32

您是否考虑过只编译成共享程序集 (DLL),然后可供所有项目引用?

我知道这可能不适合您的要求,但我认为这将是实现所有项目都可以使用的单一源的最佳方法之一,并且只有一个代码库可以根据需要进行维护。

Have you thought about just compiling into a shared assembly (DLL) that can then be referenced by all your projects?

I know this may not suit your requirements but I would assume this would be one of the best ways of achieving a single source that all your projects can use and also only one code base to maintain as needed.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文