PowerShell函数获取运行脚本名称异常:导入调用后结果不符
获取调用脚本的正确文件名(PowerShell)
当函数被外部导入(比如通过点源加载或模块)时,固定调用栈索引、直接读取$MyInvocation.MyCommand.Path的方法会失效,因为上下文会变成函数所在文件而非调用者脚本。以下是两种可靠的实现方式:
方法1:遍历调用栈定位脚本文件
通过遍历调用栈帧,筛选出类型为ExternalScript的条目(即真正的脚本文件),避免固定索引的不确定性:
function Get-CallerScriptName { $callStack = Get-PSCallStack foreach ($frame in $callStack) { # 筛选出脚本文件类型的调用帧 if ($frame.InvocationInfo.MyCommand.CommandType -eq 'ExternalScript' -and $frame.Location) { return [System.IO.Path]::GetFileName($frame.Location) } } return $null }
方法2:从调用者作用域获取MyInvocation
直接访问调用者作用域的MyInvocation变量,获取其ScriptName属性(调用脚本的完整路径):
function Get-CallerScriptName { # 从上层作用域获取调用者的MyInvocation $callerInvocation = Get-Variable -Name MyInvocation -Scope 1 -ValueOnly if ($callerInvocation.ScriptName) { return [System.IO.Path]::GetFileName($callerInvocation.ScriptName) } return $null }
为什么原有方法失效?
- 固定调用栈索引(如
$callStack[2]):当函数被导入时,调用栈的层数会增加,固定索引会指向错误的帧(比如函数所在文件或内部调用)。 $MyInvocation.MyCommand.Path:该属性返回的是当前函数所在文件的路径,而非调用这个函数的脚本路径。
测试验证
- 将函数保存到
Utils.ps1 - 在
TestScript.ps1中导入并调用:
. .\Utils.ps1 Get-CallerScriptName # 应返回 TestScript.ps1
内容的提问来源于stack exchange,提问作者dcaz
相关产品推荐
相关产品推荐

