当实现一个microsoft.build.utilities.task如何我可以访问构建的各种环境变量?环境变量、build、microsoft、task

2023-09-03 23:06:37 作者:栽在你心里

在实施microsoft.build.utilities.task如何我可以访问构建的各种环境变量?

When implementing a microsoft.build.utilities.task how to i get access to the various environmental variables of the build?

例如TARGETPATH​​

For example "TargetPath"

我知道我可以通过它的任务XML的一部分

I know i can pass it in as part of the task XML

<MyTask TargetPath="$(TargetPath)" />

但我不希望强制任务的消费者需要做的,如果我可以访问变量code。

But i don't want to force the consumer of the task to have to do that if I can access the variable in code.

http://msdn.microsoft.com/ EN-US /库/ microsoft.build.utilities.task.aspx

推荐答案

我计算出如何做到这一点

I worked out how to do this

public static class BuildEngineExtensions
{
    const BindingFlags bindingFlags = BindingFlags.NonPublic | BindingFlags.FlattenHierarchy | BindingFlags.Instance | BindingFlags.Public;

    public static IEnumerable GetEnvironmentVariable(this IBuildEngine buildEngine, string key,bool throwIfNotFound)
    {
        var projectInstance = GetProjectInstance(buildEngine);

        var items = projectInstance.Items
            .Where(x => string.Equals(x.ItemType, key, StringComparison.InvariantCultureIgnoreCase)).ToList();
        if (items.Count > 0)
        {
            return items.Select(x => x.EvaluatedInclude);
        }


        var properties = projectInstance.Properties
            .Where(x => string.Equals(x.Name, key, StringComparison.InvariantCultureIgnoreCase)).ToList();
        if (properties.Count > 0)
        {
            return properties.Select(x => x.EvaluatedValue);
        }

        if (throwIfNotFound)
        {
            throw new Exception(string.Format("Could not extract from '{0}' environmental variables.", key));
        }

        return Enumerable.Empty();
    }

    static ProjectInstance GetProjectInstance(IBuildEngine buildEngine)
    {
        var buildEngineType = buildEngine.GetType();
        var targetBuilderCallbackField = buildEngineType.GetField("targetBuilderCallback", bindingFlags);
        if (targetBuilderCallbackField == null)
        {
            throw new Exception("Could not extract targetBuilderCallback from " + buildEngineType.FullName);
        }
        var targetBuilderCallback = targetBuilderCallbackField.GetValue(buildEngine);
        var targetCallbackType = targetBuilderCallback.GetType();
        var projectInstanceField = targetCallbackType.GetField("projectInstance", bindingFlags);
        if (projectInstanceField == null)
        {
            throw new Exception("Could not extract projectInstance from " + targetCallbackType.FullName);
        }
        return (ProjectInstance)projectInstanceField.GetValue(targetBuilderCallback);
    }
}

和它可以像这样

string targetPath = buildEngine.GetEnvironmentVariable("TargetPath", true).First();
string intermediateAssembly = buildEngine.GetEnvironmentVariable("IntermediateAssembly", true).First();
IEnumerable<string> referencePaths = buildEngine.GetEnvironmentVariable("ReferencePath", true);

是的,它是丑陋的黑魔法,但它的工作原理。

Yes it is ugly and black magic but it works.