3

当我调用以下代码时:

Start-Process Firefox

然后 PowerShell 打开浏览器。我可以用其他几个程序来做到这一点,并且它可以工作。我的问题是:如果我键入 Firefox,PowerShell 如何知道要打开哪个程序?我的意思是,我没有使用具体的路径或其他东西......

我虽然它与环境变量有关......但我找不到任何称为Firefox的变量......他怎么知道?

4

2 回答 2

5

我追踪了它的两半,但我不能让它们在中间相遇。

Process Monitor 显示它检查 PATH,并最终检查HKLM\Software\Microsoft\Windows\CurrentVersion\App Paths\firefox.exe,这就是我如何找到安装位置并运行它的答案。

该注册表项用于应用程序注册,其中显示:

当调用 ShellExecuteEx 函数并在其 lpFile 参数中使用可执行文件的名称时,该函数会在多个位置查找该文件。我们建议在 App Paths 注册表子项中注册您的应用程序。

  • 在以下位置查找该文件:
  • 当前工作目录。
  • 仅 Windows 目录(不搜索子目录)。
  • Windows\System32 目录。
  • PATH 环境变量中列出的目录。
  • 推荐:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App 路径

这意味着 PowerShell 调用 Windows ShellExecuteEx 函数,该函数将 FireFox 查找为已注册的应用程序,或者它在内部尝试相同类型的搜索。


换一种方式来尝试确认,Start-Processcmdlet 有一个名为UseShellExecute. 该帮助的“注释”说:

此 cmdlet 是通过使用 System.Diagnostics.Process 类的 Start 方法实现的。有关此方法的更多信息,请参阅Process.Start方法

尝试通过 GitHub 上的源代码进行跟踪:

Start-Process.

在这里,在这一行,它尝试使用 查找$FilePath参数CommandDiscovery.LookupCommandInfo

在这里它检查else if (ParameterSetName.Equals("UseShellExecute"))

然后.Start()启动它的函数ShellExecuteProcess.Start()

好的,不确定 ShellExecute 和 ShellExecuteEx 的行为是否相同,但可能是 PS 调用 Windows,它正在搜索“FireFox”。

进入CommandSearcher.LookupCommandInfo此处并遵循此处TryNormalSearch()实现的内容并立即启动具有状态机的状态机用于它将搜索的内容CommandSearcher

  • SearchState.SearchingAliases
  • 职能
  • CmdLets
  • 搜索内置脚本
  • 开始搜索外部命令
  • PowerShell路径解析
  • 限定文件系统路径

我迷路了。我现在不能再继续下去了。

  • 要么是直接到 Windows 进行查找的快捷方式
  • 或者 PowerShell CommandSearcher 以某种方式进行相同的搜索
  • 或者 PowerShell CommandSearcher 在某种程度上用完了搜索,整个事情又回到了询问 Windows 搜索。
    • Process Monitor 仅在每个 PATH 文件夹中为“firefox.*”记录一个查询,然后转到注册表项这一事实表明它没有执行此操作,或者我希望进行更多查找。
    • 它在每个 PATH 文件夹中记录一个“get-firefox.*”查询这一事实表明它是 PowerShell 的命令搜索器进行查找而不是 Windows。

唔。

于 2016-11-03T07:58:23.150 回答
1

使用Process Monitor我能够跟踪 PowerShell。它首先搜索$env:path变量,然后搜索$profile变量。在我的情况下firefox没有找到,然后它在注册表中搜索了很多内容并以某种方式找到了它。它可能与系统上安装 Firefox 的方式有关。

于 2016-11-03T07:20:05.317 回答