windows - 每次我从文件资源管理器打开终端时如何获取PowerShell当前位置

标签 windows powershell

我可以使用Windows File Explorer在任何目录中打开PowerShell窗口。
我想在每次打开新的PowerShell窗口时运行脚本,并使用在脚本中打开该脚本的当前目录。

使用$profile可以自动执行脚本,但是$pwd变量没有用于打开PowerShell窗口的目录,但是具有C:\WINDOWS\system32。我知道PowerShell以C:\WINDOWS\system32开头,运行$profile以及与文件资源管理器一起使用的下一个更改位置。从$profile执行脚本时,或者在PowerShell窗口打开后,还有另一种方法可以自动执行脚本时,如何获取文件资源管理器的当前目录?

最佳答案

注意:以下答案提供了基于Windows PowerShell的预安装文件浏览器快捷菜单命令的解决方案。

如果修改这些命令(需要拥有管理特权来拥有注册表项的所有权)或创建自定义命令是一种选择,则可以从以下注册表项(或其自定义副本)中删除NoWorkingDirectory值:

HKEY_CLASSES_ROOT\Directory\shell\Powershell
HKEY_CLASSES_ROOT\Directory\Background\shell\Powershell

这样做将使原始文件夹在调用PowerShell之前成为工作目录,以便$PROFILE已经可以看到该工作目录,就像通过文件资源管理器的地址栏提交powershell.exe一样。[1]

Shadowfax在对该问题的评论中提供了重要的指针:

按住Shift键,然后在文件资源管理器中的文件夹或窗口背景中调用Open PowerShell window here快捷菜单命令时,powershell.exe最初以C:\Windows\System32作为工作目录[1]开始,但随后指示更改为原始文件夹通过传递Set-Location命令作为参数;例如,特定的命令可能如下所示:
"PowerShell.exe" -noexit -command Set-Location -literalPath 'C:\Users\jdoe'

顺便说一句:该快捷菜单命令的定义方式有缺陷,因为它不适用于碰巧包含'字符的文件夹路径。

在加载$PROFILE时,C:\Windows\System32仍然有效,因为传递给-command的任何命令直到配置文件加载后才被处理。

如果确实需要在$PROFILE中知道打开 session 后的工作目录,请使用以下解决方法:
$workingDir = [Environment]::GetCommandLineArgs()[-1] -replace "'"
[Environment]::GetCommandLineArgs()以参数数组( token )的形式返回调用命令行,因此[-1]返回最后一个参数(假定为工作目录路径); -replace "'"从结果中删除封闭的'...'

但是,为了使使$PROFILE文件检测到(最终)有效的工作目录(位置),而与如何调用PowerShell 无关,需要做更多的工作。

以下是一种相当健壮的方法,但请注意,完全健壮的解决方案将变得更加复杂:
# See if Set-Location was passed and extract the
# -LiteralPath or (possibly implied) -Path argument.
$workingDir = if ([Environment]::CommandLine -match '\b(set-location|cd|chdir\sl)\s+(-(literalpath|lp|path|PSPath)\s+)?(?<path>(?:\\").+?(?:\\")|"""[^"]+|''[^'']+|[^ ]+)') {
    $Matches.path -replace '^(\\"|"""|'')' -replace '\\"$'
  } else { # No Set-Location command passed, use the current dir.
    $PWD.ProviderPath
  }

解决方案的复杂性来自多种因素:
  • Set-Location具有多个别名。
  • 可以使用-Path-LiteralPath或其别名-PSPath在位置上传递路径。
  • 可以使用不同的引用样式(\"...\""""..."""'...'),或者可以不引用路径。

  • 该命令可能仍然失败:
  • 如果启动命令使用参数名称的前缀缩写,例如-lit-LiteralPath
  • 如果除路径之外的命名参数位于set-location(例如-PassThru)之后。
  • 如果字符串set-location嵌入在PowerShell最终解析为字符串文字而不是命令的内容中。
  • 如果通过-EncodedCommand将启动命令作为Base64编码的字符串传递。


  • [1]当您在文件资源管理器的地址栏中键入powershell.exe时,在启动PowerShell之前将当前打开的文件夹设为工作目录,并且没有传递用于更改工作目录的启动命令;在这种情况下,$PROFILE已经可以看到(最终)有效的工作目录。

    关于windows - 每次我从文件资源管理器打开终端时如何获取PowerShell当前位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57016644/

    相关文章:

    windows - Git 是否可以通过网络共享?

    windows - 如何在不受区域设置影响的情况下将今天的日期与文件的最后修改日期进行比较?

    powershell - 从powershell脚本同步调用.bat文件

    windows - Powershell 的环境变量

    windows - 使用 PowerShell 在表中格式化三个数据列表

    windows - 模拟用户事件

    c# - 光标位置函数返回错误值

    windows - 打开文件选择器对话框时出现 Glib-GIO-ERROR

    powershell - 如何获取azure函数应用程序凭据?

    javascript - Powershell 向下滚动网页/Powershell 截图