0

在 MSBuild 中,有GetDirectoryNameOfFileAbove属性函数。

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

最好有紧凑的语法,因为这是您必须粘贴到每个入口点脚本中才能找到其包含的内容。


这个问题的想法:

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

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

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


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

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

4

2 回答 2

1

您可以访问当前文件夹: $invoker= Split-Path -Parent $MyInvocation.MyCommand.Path

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

于 2013-02-01T09:37:54.280 回答
0

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

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

于 2013-01-30T14:41:08.593 回答