使用 MSBuild,如何将变量设置为在文件系统层次结构中更高位置找到的文件夹名称?

发布于 2024-12-01 23:50:05 字数 864 浏览 0 评论 0原文

我正在使用 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>

这有效,但它不是最佳的......

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 works but it is not optimal...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

筑梦 2024-12-08 23:50:05

您可以使用内联任务来执行此操作:

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

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>

菊凝晚露 2024-12-08 23:50:05

是的,您可以使用“Exec”标签并在 MS Build 的任何目标中设置其“Command”属性。以文本模式打开项目文件,您可以在您可能想要的目标中添加命令(例如,如果您希望脚本在构建之前执行,则目标为“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>

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>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文