如何从msbuild调用静态类方法?

时间:2009-03-24 09:38:25

标签: msbuild

如何从msbuild调用类静态方法并将其结果存储在列表中?

编辑:好的,让我再解释一下。我正在使用sandcastle帮助文件构建器为我的应用程序生成文档。其中一个要求是您必须按如下方式指定文档源:

<DocumentationSources>
    <DocumentationSource sourceFile="$(MSBuildProjectDirectory)\..\src\myApp\bin\Debug\myApp.exe" xmlns="" />
    <DocumentationSource sourceFile="$(MSBuildProjectDirectory)\..\src\myApp\bin\Debug\myApp.xml" xmlns="" />
</DocumentationSources>

Sandcastle帮助文件构建器附带一个utils程序集,它可以从指定目录中检索所有dll和xml文件。我想从这个程序集中调用该方法,并将其结果存储为<DocumentationSource>的列表。这是一个返回Collection<string>

的静态方法

3 个答案:

答案 0 :(得分:17)

如果你想做一些简单的事情,自定义任务很棒,但潜在的过度杀伤力。我相信Draco正在询问Property Functions feature in MSBuild 4

使用静态函数设置属性的示例(直接从上页翻录):

<Today>$([System.DateTime]::Now)</Today>

并在参数上调用静态函数:

$([Class]:: Property.Method(Parameters))

或者,也许你想要像inline tasks这样疯狂的东西。

答案 1 :(得分:3)

创建一个自定义任务,调用该静态方法并返回一个ITaskItem数组。

或者

您可以尝试使用MSBuild Extension Pack Assembly.Invoke

<PropertyGroup>
  <StaticMethodAssemblyPath>path</StaticMethodAssemblyPath>
</PropertyGroup>

<MSBuild.ExtensionPack.Framework.Assembly TaskAction="Invoke" 
                                          NetArguments="@(ArgsM)" 
                                          NetClass="StaticMethodClassName" 
                                          NetMethod="StaticMethodName" 
                                          NetAssembly="${StaticMethodAssemblyPath}">
        <Output TaskParameter="Result" PropertyName="R"/>
</MSBuild.ExtensionPack.Framework.Assembly>

答案 2 :(得分:2)

通常,最灵活的选择是创建custom MSBuild task。这是所有未经测试的代码,只是为了给你一个想法:

在你的msbuild文件中:

<UsingTask TaskName="FindFiles" AssemblyFile="FindFiles.dll" />

<!-- 
As you'll see below, SearchDirectory and SearchPatterns are input parameters,
MatchingFiles is an output parameter, SourceFiles is an ItemGroup assigned to
the output.
-->
<FindFiles SearchDirectory="$(MyDirectory)" SearchPatterns="*.dll;*.xml">
    <Output ItemName="SourceFiles" TaskParameter="MatchingFiles" />
</FindFiles>

<!-- You can then use the generated ItemGroup output elsewhere. -->
<DocumentationSources>
    <DocumentationSource sourceFile="@(SourceFiles)" xmlns="" />
</DocumentationSources>

FindFiles.cs:

using System;
using System.IO;
using System.Collections.Generic;

using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;

namespace FindFiles
{
    public class FindFiles : Task
    {
        // input parameter
        [Required]
        public string SearchDirectory { get; set; }

        // output parameter
        [Required]
        public string[] SearchPatterns { get; set; }

        [Output]
        public string[] MatchingFiles { get; private set; }

        private bool ValidateParameters()
        {
            if (String.IsNullOrEmpty(SearchDirectory))
            {
                return false;
            }
            if (!Directory.Exists(SearchDirectory))
            {
                return false;
            }
            if (SearchPatterns == null || SearchPatterns.Length == 0)
            {
                return false;
            }
            return true;
        }

        // MSBuild tasks use the command pattern, this is where the magic happens,
        // refactor as needed
        public override bool Execute()
        {
            if (!ValidateParameters())
            {
                return false;
            }
            List<string> matchingFiles = new List<string>();
            try
            {

                foreach (string searchPattern in SearchPatterns)
                {
                    matchingFiles.AddRange(
                        Directory.GetFiles(SearchDirectory, searchPattern)
                        );
                }
            }
            catch (IOException)
            {
                // it might be smarter to just let this exception fly, depending on
                // how you want the task to behave
                return false;
            }
            MatchingFiles = matchingFiles.ToArray();
            return true;
        }
    }
}
相关问题