在MSBuild中,有GetDirectoryNameOfFileAbove
属性函数。
如何使用PowerShell实现相同目标?
应该更好地使用紧凑语法,因为这是您必须粘贴到每个入口点脚本以查找其包含的内容。
这个问题的想法:
相对路径变得很糟糕,因为它们看起来像"../../../../../../scripts/smth"
,很难编写和维护。
注册模块不是一个好的选择,因为(a)你从SCC得到这个,而不是通过安装(b)你通常在不同的光盘位置有不同的版本,所有这些都在同一时间,(c)这是一个当技术上只有本地信息就足够时,对环境的过度依赖。
MSBuild执行此操作的方式(自v4起)如下:删除标记文件(例如,root.here或其他),使用GetDirectoryNameOfFileAbove
获取该文件夹的绝对路径,等等!你有了本地root来构建路径。
也许这不是使用PowerShell的正确方法,所以我也很感激这些方向。
答案 0 :(得分:1)
您可以访问当前文件夹: $ invoker = Split-Path -Parent $ MyInvocation.MyCommand.Path
那个的父母是: $ parent = Split-Path -Parent $ MyInvocation.MyCommand.Path | Split-Path -Parent
答案 1 :(得分: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:编辑了脚本,发现当从cmdline使用dotsourcing(具有任何上下文级别)调用脚本时,$MyInvocation.MyCommand.Path
通常为NULL,因此当前假设为ScriptName
。