这应该是一个简单的任务,但我已经看到了几次尝试如何获取执行cmdlet所在目录的路径,并且成功。例如,当我在c:\temp\myscripts\mycmdlet.ps1
处执行c:\temp\myscripts\settings.xml
设置文件时,我希望能够将c:\temp\myscripts
存储在mycmdlet.ps1
内的变量中。
这是一个有效的解决方案(虽然有点麻烦):
$invocation = (Get-Variable MyInvocation).Value
$directorypath = Split-Path $invocation.MyCommand.Path
$settingspath = $directorypath + '\settings.xml'
另一个人建议这个解决方案仅适用于我们的测试环境:
$settingspath = '.\settings.xml'
我非常喜欢后一种方法,并且更喜欢每次都必须将文件路径解析为参数,但我不能让它在我的开发环境中工作。有没有人建议做什么?它与PowerShell的配置方式有关吗?
答案 0 :(得分:231)
是的,应该有效。但如果您需要查看绝对路径,这就是您所需要的:
(Get-Item -Path ".\").FullName
答案 1 :(得分:114)
执行此操作的可靠方法就像您展示$MyInvocation.MyCommand.Path
。
使用相对路径将基于$ pwd,PowerShell,应用程序的当前目录或.NET API的当前工作目录。
答案 2 :(得分:77)
最简单的方法似乎是使用以下预定义变量:
$PSScriptRoot
about_Automatic_Variables
和about_Scripts
都声明:
在PowerShell 2.0中,此变量仅在脚本模块(.psm1)中有效。从PowerShell 3.0开始,它在所有脚本中都有效。
我这样用:
$MyFileName = "data.txt"
$filebase = Join-Path $PSScriptRoot $MyFileName
答案 3 :(得分:42)
答案 4 :(得分:32)
路径通常为空。这个功能更安全。
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("\"));
}
}
答案 5 :(得分:24)
尝试:
(Get-Location).path
或:
($pwd).path
答案 6 :(得分:15)
Get-Location
将返回当前位置:
$Currentlocation=Get-Location
答案 7 :(得分:11)
我喜欢一行solution:)
$scriptDir = Split-Path -Path $MyInvocation.MyCommand.Definition -Parent
答案 8 :(得分:9)
试试这个:
$WorkingDir = Convert-Path .
答案 9 :(得分:3)
在Powershell 3及以上版本中,您只需使用
即可 $PSScriptRoot
答案 10 :(得分:2)
此函数将提示位置设置为脚本路径,以不同的方式获取vscode,psise和pwd之间的脚本路径:
function Set-CurrentLocation
{
$currentPath = $PSScriptRoot # AzureDevOps, Powershell
if (!$currentPath) { $currentPath = Split-Path $pseditor.GetEditorContext().CurrentFile.Path -ErrorAction SilentlyContinue } # VSCode
if (!$currentPath) { $currentPath = Split-Path $psISE.CurrentFile.FullPath -ErrorAction SilentlyContinue } # PsISE
if ($currentPath) { Set-Location $currentPath }
}
答案 11 :(得分:2)
在以下IDE中进行调试时,大多数答案无效:
因为其中$PSScriptRoot
为空,而Resolve-Path .\
(及类似名称)将导致路径错误。
Freakydinde's answer是解决这些情况的唯一方法,因此我投票赞成,但我认为答案中的Set-Location
确实不是所需要的。因此,我对其进行了修复,并使代码更加清晰:
$directorypath = if ($PSScriptRoot) { $PSScriptRoot } `
elseif ($psise) { split-path $psise.CurrentFile.FullPath } `
elseif ($psEditor) { split-path $psEditor.GetEditorContext().CurrentFile.Path }
答案 12 :(得分:1)
你会认为使用'。\'作为路径意味着它是调用路径。但不是所有的时间。例如,如果您在作业ScriptBlock中使用它。在这种情况下,它可能指向%profile%\ Documents。
答案 13 :(得分:1)
这是我想出来的。它是一个包含多种查找路径方法、使用当前位置、过滤空\空结果并返回第一个非空值的数组。
@((
($MyInvocation.MyCommand.Module.ModuleBase),
($PSScriptRoot),
(Split-Path -Parent -Path $MyInvocation.MyCommand.Definition -ErrorAction SilentlyContinue),
(Get-Location | Select-Object -ExpandProperty Path)
) | Where-Object { $_ })[0]
答案 14 :(得分:0)
要扩展@Cradle的答案:你还可以写一个multi-purpose function,根据OP的问题得到相同的结果:
Function Get-AbsolutePath {
[CmdletBinding()]
Param(
[parameter(
Mandatory=$false,
ValueFromPipeline=$true
)]
[String]$relativePath=".\"
)
if (Test-Path -Path $relativePath) {
return (Get-Item -Path $relativePath).FullName -replace "\\$", ""
} else {
Write-Error -Message "'$relativePath' is not a valid path" -ErrorId 1 -ErrorAction Stop
}
}
答案 15 :(得分:0)
对于一个解决方案而言,以下是对我有用的解决方案。
$currFolderName = (Get-Location).Path.Substring((Get-Location).Path.LastIndexOf("\")+1)
最后的1是忽略/。
感谢使用Get-Location cmdlet的上述帖子
答案 16 :(得分:0)
如果只需要当前目录的名称,则可以执行以下操作:
((Get-Location) | Get-Item).Name
假设您正在C:\ Temp \ Location \ MyWorkingDirectory>中工作
输出
MyWorkingDirectory
答案 17 :(得分:0)
我也遇到了类似的问题,这使我很麻烦,因为我正在编写用PowerShell(完整的最终用户GUI应用程序)编写的程序,并且我需要从磁盘加载很多文件和资源。
以我的经验,使用.
代表当前目录是不可靠的。它应该代表当前的工作目录,但通常不是。
看来PowerShell保存了.
中已从其中调用PowerShell的位置。
更确切地说,首次启动PowerShell时,默认情况下,它将在您的主用户目录中启动。通常是您的用户帐户目录,类似C:\USERS\YOUR USER NAME
。
之后,PowerShell会在向您显示PowerShell提示符或运行脚本之前,将目录更改为您从中调用它的目录,或者更改为您正在执行脚本的目录。但这是在PowerShell应用本身最初在您的主用户目录中启动之后发生的。
.
代表PowerShell在其中启动的初始目录。因此,.
仅表示当前目录,以防万一您从所需目录中调用PowerShell。如果以后在PowerShell代码中更改目录,则在每种情况下更改似乎都不会反映在.
内部。
在某些情况下,.
代表当前的工作目录,而在另一些情况下,从中调用PowerShell(本身,而不是脚本)的目录可能导致不一致的结果。
因此,我使用调用程序脚本。内含单个命令的PowerShell脚本:
POWERSHELL
。
这将确保从所需目录中调用PowerShell,从而使.
代表当前目录。但是,只有在以后在PowerShell代码中不更改目录时,它才有效。
对于脚本,我使用的调用程序脚本与我提到的上一个脚本相似,不同之处在于它包含文件选项:
POWERSHELL -FILE DRIVE:\PATH\SCRIPT NAME.PS1
。
这样可以确保PowerShell在当前工作目录中启动。
无论脚本位于何处,只需单击脚本即可从主用户目录中调用PowerShell。
结果是,当前工作目录是脚本所在的目录,而PowerShell调用目录是C:\USERS\YOUR USER NAME
,而.
根据情况返回这两个目录之一,这是荒谬的。
但是要避免所有这些麻烦并使用调用程序脚本,您可以根据要表示当前工作的天气情况,简单地使用$PWD
或$PSSCRIPTROOT
而不是.
来表示当前目录调用脚本的目录或目录。
而且,由于某种原因,如果您想检索.
返回的两个目录中的另一个,则可以使用$HOME
。
我个人只是在使用PowerShell开发的应用程序的根目录中包含调用程序脚本,该脚本会调用我的主应用程序脚本,并且只记得永远不要在应用程序的源代码中更改当前的工作目录,因此我不必担心关于这一点,我可以使用.
来表示当前目录并在我的应用程序中支持相对文件寻址,而不会出现任何问题。
这应该可以在PowerShell的较新版本(比版本2更高)中使用。