这是一个已知问题,在 .NET 5.0 中仍未修复,PowerShell Core 7.1 是基于该问题构建的(在撰写本文时,两者都处于预览状态,但我不希望修复以及时发布这些版本)。
见GitHub issue #11305。
但是,有一个解决方法实际上通常更可取:
[System.Diagnostics.Process]::GetCurrentProcess().MainModule.FileName
# Shorter, but slower equivalent (works only from PowerShell):
# (Get-Process -Id $PID).MainModule.FileName
[System.Diagnostics.Process]::GetCurrentProcess().MainModule.FileName 优于 [Environment]::GetCommandLineArgs()[0] 的原因有两个:
请注意,.NET 5.0+ 将有一个专用的 [Environment]::ProcessPath 属性,它的性能也会更好 - 请参阅 GitHub PR #42768。
如果您想获得[Environment]::GetCommandLineArgs() 的更正 版本——也就是说,真正的可执行文件存储在索引0 中,而真正的参数 在剩余的元素:
# Get the original array...
# Note: Modifying the array directly works, but you can enclose
# the call in @(...) in order to create a *copy* of it.
$cmdLineArgs = [Environment]::GetCommandLineArgs()
# ... and fix the entry for the executable (index 0)
$cmdLineArgs[0] = [Diagnostics.Process]::GetCurrentProcess().MainModule.FileName
通过从cmd.exe 调用 PowerShell CLI 进行演示:
C:>pwsh -noprofile -c "$a=[Environment]::GetCommandLineArgs(); $a[0]=[Diagnostics.Process]::GetCurrentProcess().MainModule.FileName; $a"
C:\Program Files\PowerShell\6\pwsh.exe
-noprofile
-c
$a=[Environment]::GetCommandLineArgs(); $a[0]=[Diagnostics.Process]::GetCurrentProcess().MainModule.FileName; $a