Я использую MSBuild для нашего процесса CI, и я пытаюсь найти способ получить имя папки выше в иерархии файловой системы. Эта папка будет содержать все инструменты для CI.

Папка, которую я ищу, может быть расположена в разных местах на каждом компьютере.

Допустим, сценарий MSBuild выполняется в D: \ Workdir \ BlaBla \ Project1, а интересующая меня папка - D: \ Workdir \ CI.

Я хотел бы, чтобы сценарий проходил через файловую систему следующим образом:

  1. Посмотрите в текущем каталоге (D: \ WorkDir \ BlaBla \ Project1), проверьте папку CI (не найдена)
  2. Поднимитесь по иерархии (D: \ Workdir \ BlaBla) и проверьте папку CI (не найдена)
  3. Поднимитесь снова (D: \ Workdir) и проверьте папку CI (Найдено!)

Возможно ли это в MSBuild?


ПРИМЕЧАНИЯ

Чтобы уточнить, я хочу получить результат (расположение папки) в свойстве.


Вот что у меня есть до сих пор и я пытаюсь это улучшить;)

<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>

Это работает, но не оптимально ...

1
Stécy 29 Авг 2011 в 22:06

2 ответа

Лучший ответ

Вы можете сделать это с помощью встроенной задачи:

<?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>
2
tintoy 30 Авг 2011 в 14:52

Да, вы можете использовать тег «Exec» и установить его атрибут «Command» в любой цели MS Build. Откройте файл проекта в текстовом режиме, и вы можете добавить свою команду в Target, которая вам может понадобиться (например, Target «BeforeBuild», если вы хотите, чтобы ваш скрипт выполнялся до сборки)

РЕДАКТИРОВАТЬ:

Откройте файл проекта в текстовом режиме, перейдите в раздел: . Добавьте узел Exec в этот целевой узел. Когда вы закончите, ваш целевой узел может выглядеть так:

<Target Name="BeforeBuild">
    <Exec Command="yourscript or any DOS command" />
    ... if you had anything before in this section leave them as is
</Target>
0
Arun 29 Авг 2011 в 18:22