【问题标题】:How can I get PowerShell current location every time I open terminal from file explorer每次从文件资源管理器打开终端时如何获取 PowerShell 当前位置
【发布时间】:2019-07-13 06:13:08
【问题描述】:

我可以使用 Windows 文件资源管理器在任何目录中打开 PowerShell 窗口。 我想在每次打开新的 PowerShell 窗口时运行一个脚本,并使用在脚本中打开它的当前目录。

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

【问题讨论】:

  • 当我试图弄清楚这一点时,我发现当你从文件资源管理器运行 powershell 时,然后在打开的控制台中你写 get-history 你会发现第一个命令是'设置位置-literalpath ';正如您所提到的,配置文件中的脚本将在此命令之前运行,因此位置将是 `c:\windows\system32';可能位置(文件资源管理器)作为参数传递给 powershell 进程。但我仍然不知道如何获得它。
  • 很好的侦探,@Shadowfax;您可以通过[Environment]::CommandLine[Environment]::GetCommandLineArgs() 检查调用命令行。
  • 请允许我给你一个标准的建议给新手:如果一个答案解决了你的问题,请点击它旁边的大复选标记 (✓) 接受它,也可以选择给它投票(up - 投票需要至少 15 个声望点)。如果您发现其他答案有帮助,请给他们投票。接受(您将获得 2 个声望点)和投票可以帮助未来的读者。请参阅this article 了解更多信息。如果您的问题尚未得到完全解答,请提供反馈或self-answer

标签: windows powershell


【解决方案1】:

注意:下面的答案提供了一个基于 预安装 Window 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 中的工作目录在会话打开后是什么,请使用以下解决方法:

$workingDir = [Environment]::GetCommandLineArgs()[-1] -replace "'"

[Environment]::GetCommandLineArgs() 将调用命令行作为参数(令牌)数组返回,因此[-1] 返回 last 参数,假定为工作目录路径; -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 最终解析为 字符串文字 而不是命令的内容中。

  • 如果启动命令作为 Base64 编码的字符串通过 -EncodedCommand 传递。


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

【讨论】:

    【解决方案2】:

    1.打开注册表(命令:regedit

    2.找出路径\HKEY_CLASSES_ROOT\Directory\Background\shell\Powershell\command(不是\HKEY_CLASSES_ROOT\Directory\Background\shell\cmd\command

    3.默认值为powershell.exe -noexit -command Set-Location -literalPath "%V"

    4.你可以改变一些参数,

    ps:您将命令更改为cmd.exe /s /k pushd "%V"。如果这样做,资源管理器中的shift &amp; right button 将打开 cmd,而不是 powershell

    【讨论】:

    • 问题范围之外。他在问如何从文件资源管理器打开时获取 powershell 的位置。
    • 这是有趣的背景信息,但它并没有解决 OP 的问题,即知道 $PROFILE 文件时工作目录 最终会是什么正在处理,这发生在 Set-Location 命令执行之前。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多