【问题标题】:How to Do MSBuild's GetDirectoryNameOfFileAbove in PowerShell?如何在 PowerShell 中执行 MSBuild 的 GetDirectoryNameOfFileAbove?
【发布时间】:2013-01-30 14:00:39
【问题描述】:

在 MSBuild 中,有 GetDirectoryNameOfFileAbove 属性函数。

如何使用 PowerShell 实现相同的目标?

最好使用简洁的语法,因为您必须将其粘贴到每个入口点脚本中才能找到其包含内容。


本题思路:

  • 在源代码控制中有一个大型解决方案。它的某些部分是相对自主的。
  • 它在根目录下的已知文件夹中有一个用于共享脚本和可重用函数的位置。
  • 项目中散布着许多入口点脚本(您明确执行的文件),所有这些都包括共享脚本。
  • 从入口点脚本定位共享脚本的便捷方法是什么?

相对路径效果不佳,因为它们看起来像 "../../../../../../scripts/smth",难以编写和维护。

注册模块不是一个好的选择,因为 (a) 您是从 SCC 获得的,而不是通过安装 (b) 您通常同时在不同的磁盘位置有不同的版本,并且 (c) 这是一个当技术上仅本地信息就足够时,对环境的过度依赖。


执行此操作的 MSBuild 方法(从 v4 开始)如下:删除一个标记文件(例如,root.here 或其他),使用 GetDirectoryNameOfFileAbove 获取该文件夹的绝对路径,等等!你有本地根目录来构建路径。

也许这不是使用 powershell 的正确方法,所以我也会感谢这些指示。

【问题讨论】:

    标签: powershell msbuild


    【解决方案1】:

    您可以这样访问当前文件夹: $invoker= 拆分路径-父 $MyInvocation.MyCommand.Path

    所以那个的父母是: $parent=Split-Path -Parent $MyInvocation.MyCommand.Path|Split-Path -Parent

    【讨论】:

    • 这不是一个好的答案,因为:(1) $MyInvocation.MyCommand.Path 通常为 NULL,并且 (2) 获得一次父级很简单,但您必须寻找祖先文件夹使用标记文件——是否有一种巧妙的递归方式仍然是一个悬而未决的问题。
    • 它通常不为空,它在脚本运行时起作用。也在这里stackoverflow.com/questions/5466329/…
    • 有时“不经常”还不够好 ;-) 例如,当使用 -Command 调用 powershell.exe 时,它​​会点源脚本,然后调用其中的函数。 MyCommand.Path 在这种情况下不起作用。
    • Definition 是一个有趣的秘诀,但我认为它应该采用$script:MyInvocation.MyCommand.Definition 形式,以便在函数中工作。希望有一些简单可靠的东西(比如 $(MSBuildThisFileDirectory),它是根据社区反馈添加到 v4 中的)。
    【解决方案2】:

    一个快速而肮脏的解决方案如下所示:

    function GetDirectoryNameOfFileAbove($markerfile)
    {
        $result = ""
        $path = $MyInvocation.ScriptName
        while(($path -ne "") -and ($path -ne $null) -and ($result -eq "")) 
        { 
            if(Test-Path $(Join-Path $path $markerfile)) {$result=$path}
            $path = Split-Path $path 
        }
        if($result -eq "") {throw "Could not find marker file $markerfile in parent folders."}
        return $result
    }
    

    它可以被压缩成一行以植入脚本,但它仍然过于 C#-ish,我认为它可能会通过一些 PS 管道/LINQ 风格的魔法来缩短。

    UPD:编辑脚本,发现当从cmdline用dotsourcing(任何上下文级别)调用脚本时$MyInvocation.MyCommand.Path经常为NULL,所以当前假设是ScriptName

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-01-26
      • 1970-01-01
      • 1970-01-01
      • 2021-12-14
      • 1970-01-01
      • 2017-10-14
      • 2013-07-24
      相关资源
      最近更新 更多