Batch file 如何进行MSBuild';批处理文件中的GetDirectoryNameOffileOver是什么?

Batch file 如何进行MSBuild';批处理文件中的GetDirectoryNameOffileOver是什么?,batch-file,msbuild,Batch File,Msbuild,在MSBuild中,有一个GetDirectoryNameOfFileAbove函数,用于查找包含特定文件的第一个祖先目录 对于那些不熟悉MSBuild函数的人,下面是一个示例 我有一个文件: c:\projects\root.txt 我希望能够运行以下脚本: c:\projects\everything\foo\bar\myscript.cmd 我想找到c:\projects\,因为它是c:\projects\everything\foo\bar\中包含该文件的最接近的祖先。脚本还应该能够检测

在MSBuild中,有一个
GetDirectoryNameOfFileAbove
函数,用于查找包含特定文件的第一个祖先目录

对于那些不熟悉MSBuild函数的人,下面是一个示例

我有一个文件:

c:\projects\root.txt

我希望能够运行以下脚本:

c:\projects\everything\foo\bar\myscript.cmd

我想找到
c:\projects\
,因为它是
c:\projects\everything\foo\bar\
中包含该文件的最接近的祖先。脚本还应该能够检测文件何时不存在于任何祖先中,并且只获取一个空字符串

如何在(Windows)批处理脚本中实现相同的功能

@echo off
setlocal EnableDelayedExpansion

set "theFile=%~1"

rem Get the path of this Batch file, i.e. "c:\projects\everything\foo\bar\"
set "myPath=%~DP0"

rem Process it as a series of ancestor directories
rem i.e. "c:\" "c:\projects\" "c:\projects\everything\" etc...
rem and search the file in each ancestor, taking as result the last one

set "result="
set "thisParent="
set "myPath=%myPath:~0,-1%"
for %%a in ("%myPath:\=" "%") do (
   set "thisParent=!thisParent!%%~a\"
   if exist "!thisParent!%theFile%" set "result=!thisParent!"
)

if defined result (
   echo %result%
) else (
   echo There is not such file in my ancestors
)
将文件名作为此批处理文件的参数。例如,如果将此文件命名为
getdirectorynameoffielabove.bat
,则可以这样使用它:

GetDirectoryNameOfFileAbove root.txt
将文件名作为此批处理文件的参数。例如,如果将此文件命名为
getdirectorynameoffielabove.bat
,则可以这样使用它:

GetDirectoryNameOfFileAbove root.txt
我可以把那首曲子命名为2(长线)。代码很短。解释很长

@rem will search up to 8 levels up from here
@Set Ancestry=.;..;..\..;..\..\..;..\..\..\..;..\..\..\..\..;..\..\..\..\..\..;..\..\..\..\..\..\..;..\..\..\..\..\..\..;..\..\..\..\..\..\..\..;..\..\..\..\..\..\..\..\..;
@REM %~dp$Ancestry:1 -- search paths in Ancestry for arg 1
@REM finds files of any type, not just exe
@REM LocalTop is either the folder where arg 1 (%1) was found or empty
@Set LocalTop=%~dp$Ancestry:1
工作原理:

  • 祖先是一系列可以看的地方:。然后…,然后。。。。等等我停在8层。添加更多,尽管我从未需要更多的级别
  • 下一行使用cmd的魔力。请注意,此语法仅适用于%0..%9或带有for变量的for语句
  • 从获取/?:

    %~$PATH:I   - searches the directories listed in the PATH
                   environment variable and expands %I to the
                   fully qualified name of the first one found
                   If the environment variable name is not
                   defined or the file is not found by the
                   search, then this modifier expands to the
                   empty string
    
    对我来说不明显的是,它不限于环境变量“PATH”。您可以提供任何变量,这就是上面的祖先。

    我可以在2(长线)中命名该调谐。代码很短。解释很长

    @rem will search up to 8 levels up from here
    @Set Ancestry=.;..;..\..;..\..\..;..\..\..\..;..\..\..\..\..;..\..\..\..\..\..;..\..\..\..\..\..\..;..\..\..\..\..\..\..;..\..\..\..\..\..\..\..;..\..\..\..\..\..\..\..\..;
    @REM %~dp$Ancestry:1 -- search paths in Ancestry for arg 1
    @REM finds files of any type, not just exe
    @REM LocalTop is either the folder where arg 1 (%1) was found or empty
    @Set LocalTop=%~dp$Ancestry:1
    
    工作原理:

  • 祖先是一系列可以看的地方:。然后…,然后。。。。等等我停在8层。添加更多,尽管我从未需要更多的级别
  • 下一行使用cmd的魔力。请注意,此语法仅适用于%0..%9或带有for变量的for语句
  • 从获取/?:

    %~$PATH:I   - searches the directories listed in the PATH
                   environment variable and expands %I to the
                   fully qualified name of the first one found
                   If the environment variable name is not
                   defined or the file is not found by the
                   search, then this modifier expands to the
                   empty string
    

    对我来说不明显的是,它不限于环境变量“PATH”。您可以提供任何变量,即上面的祖先。

    您是指文件的父目录吗
    for%%J in(“\path\to\your\file.txt”)do for%%I in(“%~dpJ.”)do echo%%~nxI
    (如果您直接在命令提示符下尝试此操作,请将每个
    %%
    替换为
    %
    )您能提供一个示例来说明这是如何工作的吗?只是用一个示例编辑了这个问题。谢谢你是说一个文件的父目录
    for%%J in(“\path\to\your\file.txt”)do for%%I in(“%~dpJ.”)do echo%%~nxI
    (如果您直接在命令提示符下尝试此操作,请将每个
    %%
    替换为
    %
    )您能提供一个示例来说明这是如何工作的吗?只是用一个示例编辑了这个问题。谢谢