开发者

Using MSBuild, how to set a variable to a folder name to be found higher in the filesystem hierarchy?

I'm using MSBuild for our CI process and I'm trying to find a way to get the folder name of a folder higher up in the filesystem hierarchy. This folder would hold all the tools for the CI.

The folder I'm looking for can be located at various places on each PC.

Let's say that the MSBuild script is executing in the D:\Workdir\BlaBla\Project1 and the folder I'm interested in is D:\Workdir\CI

I would like the script to traverse the filesystem as follows:

  1. Look in current dir (D:\WorkDir\BlaBla\Project1), check for CI folder (not found)
  2. Go up in the hierarchy (D:\Workdir\BlaBla) and check for CI folder (not found)
  3. Go up again (D:\Workdir) and check for CI folder (Found!)

Is this feasible in MSBuild?


NOTES

Just to clarify, I want to get the result (the location of the folder) in a property.


Here's what I have so far and trying to better it ;)

<PropertyGroup>
    <CI_PathName Condition=" Exists ('..\CI') ">..\CI</CI_PathName >
    <CI_PathName Condition=" Exists ('..\..\CI') ">..\..\CI</CI_PathName >
    <CI_PathName Condition=" Exists ('..\..\..\CI') ">..\..\..\CI</CI_PathName >
</PropertyGroup>

This wo开发者_运维技巧rks but it is not optimal...


You can do this using an inline task:

<?xml version="1.0" encoding="utf-8" ?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<UsingTask
    TaskName="FindParentDirectory"
    TaskFactory="CodeTaskFactory"
    AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">

    <ParameterGroup>
        <BaseDirectory ParameterType="Microsoft.Build.Framework.ITaskItem" Required="true" />
        <TargetDirectoryName ParameterType="System.String" Required="true" />
        <TargetDirectory ParameterType="System.String" Output="true" />
    </ParameterGroup>
    <Task>
        <Using Namespace="System.IO" />
        <Code Type="Fragment" Language="cs">
            <![CDATA[
                string baseDirectoryPath = BaseDirectory.GetMetadata("FullPath");
                DirectoryInfo baseDirectory = new DirectoryInfo(baseDirectoryPath);
                DirectoryInfo[] childDirectories = baseDirectory.GetDirectories(TargetDirectoryName);
                if (childDirectories.Length == 1)
                {
                    TargetDirectory = childDirectories[0].FullName;

                    return true;
                }

                while (baseDirectory != baseDirectory.Root)
                {
                    baseDirectory = baseDirectory.Parent;
                    if (baseDirectory.Name == TargetDirectoryName)
                    {
                        TargetDirectory = baseDirectory.FullName;

                        return true;
                    }

                    childDirectories = baseDirectory.GetDirectories(TargetDirectoryName);
                    if (childDirectories.Length == 1)
                    {
                        TargetDirectory = childDirectories[0].FullName;

                        return true;
                    }
                }

                Log.LogError("Unable to find recursively find a directory called '{0}' in a parent of '{1}'.", TargetDirectoryName, baseDirectoryPath);

                return false;

            ]]>
        </Code>
    </Task>
</UsingTask>

<Target Name="Build">
    <FindParentDirectory
        BaseDirectory="$(MSBuildProjectDirectory)"
        TargetDirectoryName="Development">

        <Output
            TaskParameter="TargetDirectory"
            PropertyName="TargetDir" />
    </FindParentDirectory>

    <Message
        Text="TargetDir = '$(TargetDir)'"
        Importance="high" />
</Target>


Yes, you can use the "Exec" tag and set its "Command" attribute in any Target of MS Build. Open the project file in text mode and you can add your command inside the Target that you might want (for example, Target "BeforeBuild", if you want your script to be executed before the Build)

EDIT:

Open your project file in text mode, navigate to the section: <Target Name="BeforeBuild">. Add the Exec node within this Target Node. Once you are done your Target node might look like this:

<Target Name="BeforeBuild">
    <Exec Command="yourscript or any DOS command" />
    ... if you had anything before in this section leave them as is
</Target>
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜