这应该是一个简单的任务,但是我已经看到过几次关于如何获取已执行cmdlet所在目录的路径的尝试,结果好坏参半。例如,当我执行C:\temp\myscripts\mycmdlet。我想能够将C:\temp\myscripts存储在mycmdlet.ps1中的一个变量中。

这是一个有效的解决方案(尽管有点麻烦):

$invocation = (Get-Variable MyInvocation).Value
$directorypath = Split-Path $invocation.MyCommand.Path
$settingspath = $directorypath + '\settings.xml'

另一个人建议这样的解决方案,它只适用于我们的测试环境:

$settingspath = '.\settings.xml'

我非常喜欢后一种方法,与每次都将文件路径解析为参数相比,我更喜欢这种方法,但我无法让它在我的开发环境中工作。我该怎么办?这与PowerShell的配置方式有关吗?


当前回答

在以下ide中调试时,大多数答案都不能工作:

PS-ISE (PowerShell ISE) VS Code (Visual Studio Code)

因为在这些$PSScriptRoot是空的,Resolve-Path .\(和类似的)将导致不正确的路径。

Freakydinde的答案是解决这些情况的唯一答案,所以我对其进行了投票,但我不认为该答案中的Set-Location是真正需要的。所以我修正了这个问题,让代码更清晰一些:

$directorypath = if ($PSScriptRoot) { $PSScriptRoot } `
    elseif ($psise) { split-path $psise.CurrentFile.FullPath } `
    elseif ($psEditor) { split-path $psEditor.GetEditorContext().CurrentFile.Path }

其他回答

你还可以使用:

(Resolve-Path .\).Path

括号中的部分返回一个PathInfo对象。

(PowerShell 2.0起可用。)

试试这个:

$WorkingDir = Convert-Path .

要只获取当前文件夹名称,您还可以使用:

(Split-Path -Path (Get-Location) -Leaf)

在以下ide中调试时,大多数答案都不能工作:

PS-ISE (PowerShell ISE) VS Code (Visual Studio Code)

因为在这些$PSScriptRoot是空的,Resolve-Path .\(和类似的)将导致不正确的路径。

Freakydinde的答案是解决这些情况的唯一答案,所以我对其进行了投票,但我不认为该答案中的Set-Location是真正需要的。所以我修正了这个问题,让代码更清晰一些:

$directorypath = if ($PSScriptRoot) { $PSScriptRoot } `
    elseif ($psise) { split-path $psise.CurrentFile.FullPath } `
    elseif ($psEditor) { split-path $psEditor.GetEditorContext().CurrentFile.Path }

Path通常为空。这个功能比较安全。

function Get-ScriptDirectory
{
    $Invocation = (Get-Variable MyInvocation -Scope 1).Value;
    if($Invocation.PSScriptRoot)
    {
        $Invocation.PSScriptRoot;
    }
    Elseif($Invocation.MyCommand.Path)
    {
        Split-Path $Invocation.MyCommand.Path
    }
    else
    {
        $Invocation.InvocationName.Substring(0,$Invocation.InvocationName.LastIndexOf("\"));
    }
}