I traced two halves of it, but I can't make them meet in the middle.
Process Monitor shows it checks the PATHs, and eventually checks HKLM\Software\Microsoft\Windows\CurrentVersion\App Paths\firefox.exe
so that's my answer to how it finds the install location, and then runs it.
That registry key is for Application Registration which says:
When the ShellExecuteEx function is called with the name of an executable file in its lpFile parameter, there are several places where the function looks for the file. We recommend registering your application in the App Paths registry subkey.
- The file is sought in the following locations:
- The current working directory.
- The Windows directory only (no subdirectories are searched).
- The Windows\System32 directory.
- Directories listed in the PATH environment variable.
- Recommended: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths
That implies PowerShell calls the Windows ShellExecuteEx function, which finds FireFox as a registered application, or it tries the same kind of searching itself internally.
Going the other way to try and confirm that, the Start-Process
cmdlet has a parameter set called UseShellExecute
. The 'Notes' of that help says:
This cmdlet is implemented by using the Start method of the System.Diagnostics.Process class. For more information about this method, see Process.Start
Method
Trying to trace through the source code on GitHub:
Here is the PowerShell source code for Start-Process
.
Here, at this line it tries to look up the $FilePath
parameter with CommandDiscovery.LookupCommandInfo
.
Here it checks else if (ParameterSetName.Equals("UseShellExecute"))
Then Here is the .Start()
function which either starts it with ShellExecute
or Process.Start()
OK, not sure if ShellExecute and ShellExecuteEx behave the same, but it could be PS calling Windows, which is doing the search for "FireFox".
That CommandSearcher.LookupCommandInfo
comes in here and follows to TryNormalSearch()
which is implemented here and immediately starts a CommandSearcher
which has a state machine for the things it will search
- SearchState.SearchingAliases
- Functions
- CmdLets
- SearchingBuiltinScripts
- StartSearchingForExternalCommands
- PowerShellPathResolution
- QualifiedFileSystemPath
and there I get lost. I can't follow it any further right now.
- Either it shortcuts straight to Windows doing the lookup
- Or the PowerShell CommandSearcher does the same search somehow
- Or the PowerShell CommandSearcher in some way runs out of searching, and the whole thing falls back to asking Windows search.
- The fact that Process Monitor only logs one query in each PATH folder for "firefox.*" and then goes to the registry key suggests it's not doing this one, or I'd expect many more lookups.
- The fact that it logs one query for "get-firefox.*" in each PATH folder suggests it is PowerShell's command searcher doing the lookup and not Windows.
Hmm.