Reputation: 24466
What paths are searched by start
? Is this path list queryable via WMI, the registry, WSH shell folder constants, .NET methods, or any other Windows API?
In a cmd
console, the start
command is sort of magic. Say your default web browser is Firefox. You also have Chrome and Opera installed, but they are neither set as default, nor associated with any file types, nor in your %PATH%. Considering the following example:
start "" opera https://stackoverflow.com
... why does that work?
The reason this matters is that, for all the start
command's strengths, it is still perilous to retrieve an application's PID or window handle when that application was launched with start
. In a cmd
environment I'd prefer to use wmic process call create
in a for /F
loop to capture the PID. So is there a way I can teach wmic process call create
to launch "opera" or "iexplore" or "outlook" or "winword" or other applications as start
can without fully qualifying the drive:\\path\\to\\executable
?
I thought I was on to a solution by scanning HKLM\Software\Clients
recursively for shell\open\command
, then adding each referenced location temporarily to %PATH%:
rem // temp add installed clients to %PATH% to make "call :display" behave like "start"
setlocal enabledelayedexpansion
for %%a in (HKLM HKCU) do for /f "tokens=2*" %%I in (
'REG QUERY %%a\Software\Clients /s /f command /k /ve ^| find "(Default)"'
) do if "%%~I"=="REG_EXPAND_SZ" (
if /i "%%~xJ"==".exe" (
if "!PATH:%%~J\..=!"=="!PATH!" path !PATH!;%%~J\..
) else for %%# in (%%J) do if /i "%%~x#"==".exe" (
if "!PATH:%%~#\..=!"=="!PATH!" path !PATH!;%%~#\..
)
) else (
if /i "%%~xJ"==".exe" (
if "!PATH:%%~dpJ=!"=="!PATH!" path !PATH!;%%~dpJ
) else (
for %%# in (%%J) do if /i "%%~x#"==".exe" (
if "!PATH:%%~dp#=!"=="!PATH!" path !PATH!;%%~dp#
)
)
)
endlocal & path %PATH%
That works reasonably well, but it still falls short of what start
can access. For example:
start "" wordpad
works, whereas
wmic process call create "wordpad.exe"
fails.
Upvotes: 3
Views: 195
Reputation: 194
Edit2
This may be of interest regards to what you are doing (as opposed to why something works the way it does).
From a previous answer
Can I create shorthand names for use inside cmd?
See
Doskey /?
.You could do this
doskey cddesk=cd "%userprofile%\desktop"
Then type
cddesk
.By putting all your macros in a batch file you can autoload. Of course you could do this with batchfiles too.
From Technical Reference to the Windows 2000 Registry, Microsoft, 2000.
AutoRun HKCU\Software\Microsoft\Command Processor
Data type Range Default value
REG_SZ list of commands There is no default value for this entry.
Description
Contains commands which are executed each time you start Cmd.exe.
Also see this batchfile https://pastebin.com/A2qLw8r3 that list special names.
In a command prompt
start shell:desktop
Or in Start - Run (Winkey + R) just
shell:desktop
Edit
I'll just add some caveats here.
This is about opening executables using Start
command. A massive amount of rules apply to non executable files.
Not using Start
CMD pre-processes the command line and sends a FQFN to CreateProcess
- so it's CMD that searches the path not CreateProcess
.
https://learn.microsoft.com/en-us/windows/desktop/shell/launch is the documentation for ShellExecute. Everything ends up calling CreateProcess https://learn.microsoft.com/en-us/windows/desktop/api/processthreadsapi/nf-processthreadsapi-createprocessw. Plus CMD preprocessing is detailed here https://books.google.com.au/books/about/Windows_NT_Shell_Scripting.html?id=jrdQAAAAMAAJ&redir_esc=y. Also start /?
provides documentation for all three ways to start files. A summary is here Command to run a .bat file
Some fun facts. CMD if it can't recognise a file extension will attempt to execute it. ShellExecute
will content sniff unknown files https://learn.microsoft.com/en-us/windows/desktop/com/filetype-key.
quote from rojo: Thanks for the link dump. I'm struggling to understand how
ShellExecute
can save me from having to fully qualify path names though. That was my primary question. "To use ShellExecute or ShellExecuteEx, your application must specify the file or folder object that is to be acted on, and a verb that specifies the operation." It's the "specify the file or folder object" part that I'm asking about.
It uses the 6 steps under CreateProcess and if that turns up nothing it uses App Paths. If a verb is not specified the default verb is used (usually Open). See my answer here How do i automate the simulation of right clicking a file and selecting the first option using vbscript.
So it an intersection of 4 technologies. Compatibility with MSDos, changes made by IBM for OS/2 and updated by Microsoft for Windows 2000, the standard windows way of starting programs CreateProcess, and with Windows 95 we got shell functions which are based on OLE
quote from rojo: Snap! You're right! In PowerShell I was able to create a
System.Diagnostics.Process
object, set$ps.StartInfo.UseShellExecute = $true
, and then start "wordpad" without any file extension or fully qualified path. Setting the.UseShellExecute property
to$false
caused the execution to fail. How interesting!
Upvotes: 3
Reputation: 14290
I remember a discussion about this very topic either on DosTips.com or here on SO but I cannot find it. Hopefully somebody does so we can mark this question as a duplicate.
We know that the batch files will search the current directory and then the path variable to find an executable. The START
command also searches the following Registry path
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths
So you have a few options to find the executable.
You can use the WHERE
command which searches the current directory and the directories in the PATH variable.
where notepad.exe
You can also just search the path variable with a FOR
command.
for %%I in (notepad.exe) do echo %%~$PATH:I
And of course you can search the registry path as I mentioned above by doing a REG QUERY.
Upvotes: 3