我该如何在msbuild中调用静态类方法?

4
如何从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>


我不理解你的问题。msbuild 是一个用于构建(编译/链接)的实用程序,而不是一种编程语言。你具体想做什么? - Assaf Lavie
抱歉,我已经更新了问题。 - Draco
3个回答

21

如果您只是想要做一些简单的事情,那么自定义任务可能过于复杂了。我认为Draco正在询问MSBuild 4中的属性函数功能

下面是一个通过使用静态函数设置属性的示例(直接从上述页面提取):

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

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

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

或者,也许您想要像 内联任务 这样更疯狂的东西。


1
内联任务非常棒,就像在MSBuild脚本中的LINQPad脚本一样!感谢您的启发! - Allon Guralnek
请参阅 https://shades-of-orange.com/post/Using-Static-Methods-from-the-NET-Framework-in-MSBuild-a-List-of-All-Property-Functions 以获取可用类型列表。 - Mike Rosoft
原链接无法打开 :( - Tatranskymedved

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

通常,最灵活的选项是创建一个自定义的 MSBuild 任务。以下是所有未经测试的代码,只是为了让你有个思路:

在你的 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;
        }
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接