可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
Whenever I need to reference a common module or script, I like to use paths relative to the current script file, that way, my script can always find other scripts in the library.
So, what is the best, standard way of determining the directory of the current script? Currently, I\'m doing:
$MyDir = [System.IO.Path]::GetDirectoryName($myInvocation.MyCommand.Definition)
I know in modules (.psm1) you can use $PSScriptRoot
to get this information, but that doesn\'t get set in regular scripts (i.e. .ps1 files).
What\'s the canonical way to get the current PowerShell script file\'s location?
回答1:
PowerShell 3+
# This is an automatic variable set to the current file\'s/module\'s directory
$PSScriptRoot
PowerShell 2
Prior to PowerShell 3, there was not a better way than querying the
MyInvocation.MyCommand.Definition
property for general scripts. I had the
following line at the top of essentially every powershell script I had:
$scriptPath = split-path -parent $MyInvocation.MyCommand.Definition
回答2:
If you are creating a V2 Module, you can use an automatic variable called
$PSScriptRoot
.
From PS > Help automatic_variable
$PSScriptRoot
Contains the directory from which the script module is being executed.
This variable allows scripts to use the module path to access other
resources.
回答3:
For PowerShell 3.0
$PSCommandPath
Contains the full path and file name of the script that is being run.
This variable is valid in all scripts.
The function is then:
function Get-ScriptDirectory {
Split-Path -Parent $PSCommandPath
}
回答4:
Maybe i\'m missing something here... but if you want the present working directory you can just use this: (Get-Location).Path
for a string, or Get-Location
for an object.
Unless you\'re referring to something like this, which I understand after reading the question again.
function Get-Script-Directory
{
$scriptInvocation = (Get-Variable MyInvocation -Scope 1).Value
return Split-Path $scriptInvocation.MyCommand.Path
}
回答5:
I use the automatic variable $ExecutionContext, it works from PowerShell 2 and later.
$ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath(\'.\\\')
$ExecutionContext
Contains an EngineIntrinsics object that represents the
execution context of the Windows PowerShell host. You can
use this variable to find the execution objects that are
available to cmdlets.
回答6:
Very similar to already posted answers, but piping seems more PS-like.
$PSCommandPath | Split-Path -Parent
回答7:
For Powershell 3+
function Get-ScriptDirectory {
if ($psise) {Split-Path $psise.CurrentFile.FullPath}
else {$global:PSScriptRoot}
}
I\'ve placed this function in my profile. Works in ISE using F8/Run Selection too.
回答8:
I needed to know the script name and where it is executing from.
Prefixing \"$global:\" to the MyInvocation structure returns the full path and script name when called from both the main script, and the main line of an imported .PSM1 library file. It also works from within a function in an imported library.
After much fiddling around, I settled on using $global:MyInvocation.InvocationName.
It works reliably with CMD launch, Run With Powershell, and the ISE.
Both local and UNC launches return the correct path.
回答9:
Took me a while to develop something that took the accepted answer and turned it into a robust function.
Not sure about others but I work in an environment with machines on both PowerShell version 2 and 3 so I needed to handle both. The following function offers a graceful fallback:
Function Get-PSScriptRoot
{
$ScriptRoot = \"\"
Try
{
$ScriptRoot = Get-Variable -Name PSScriptRoot -ValueOnly -ErrorAction Stop
}
Catch
{
$ScriptRoot = Split-Path $script:MyInvocation.MyCommand.Path
}
Write-Output $ScriptRoot
}
It also means that the function refers to the Script scope rather than the parent\'s scope as outlined by Michael Sorens in his blog
回答10:
You might also consider split-path -parent $psISE.CurrentFile.Fullpath
if any of the other methods fail. In particular, if you run a file to load a bunch of functions and then execute those functions with-in the ISE shell (or if you run-selected), it seems the Get-Script-Directory
function as above doesn\'t work.
回答11:
function func1()
{
$inv = (Get-Variable MyInvocation -Scope 1).Value
#$inv.MyCommand | Format-List *
$Path1 = Split-Path $inv.scriptname
Write-Host $Path1
}
function Main()
{
func1
}
Main