Как Windows находит файлы, вводимые в оболочку?

Я искал этот вопрос по сайту, но похоже, что его никогда не спрашивали, поэтому я решил поделиться с ним тем, кто его ищет.

В: Когда я ввожу имя исполняемых файлов в cmd.exe, через функции выполнения оболочки или из пакетного файла, как Windows определяет внешний исполняемый файл, который будет вызываться?

Ответ 1

Я не понимаю, к чему относится "функция выполнения оболочки", поэтому я проигнорирую ее.

Но правила запуска исполняемого файла из командной строки CMD.EXE или из командного файла следующие:

  • Если для исполняемого файла (абсолютного или относительного) указан путь, то выполняется поиск только этого пути.

  • Если указано только исполняемое имя (и, возможно, расширение), то

    • Сначала найдите текущую папку

    • Затем найдите папки в переменной среды PATH (в указанном порядке)

  • Внутри каждой найденной папки используйте предоставленное расширение. Если расширение файла не указано, тогда найдите файлы, которые соответствуют расширениям, найденным в переменной среды PATHEXT (в указанном порядке).

Первый найденный файл соответствия - тот, который выполняется.


ИЗМЕНИТЬ

Дэвид Кенди указал мне на какую-то устаревшую документацию NT, которая точно описывает процесс поиска, и в основном соответствует тому, что я написал выше. См. Запуск приложений из оболочки NT

Мне бы очень понравилось, если бы кто-нибудь мог опубликовать ссылки на похожие документы CMD.EXE для более поздних версий Windows, особенно если он был написан Microsoft. Обратите внимание, что связанный выше код NT не был написан Microsoft, хотя он размещен на их сайте.

Ответ 2

Здесь отладка CMD с помощью CreateProcessW, чтобы начать edit.com.

Microsoft (R) Windows Debugger Version 6.2.9200.20512 X86
Copyright (c) Microsoft Corporation. All rights reserved.

CommandLine: C:\Windows\System32\cmd.exe
Symbol search path is: srv*C:\tmp*http://msdl.microsoft.com/download/symbols;c:\tmp
Executable search path is: 
ModLoad: 49fe0000 4a030000   cmd.exe 
ModLoad: 76dd0000 76ef7000   ntdll.dll
ModLoad: 75860000 7593b000   C:\Windows\system32\kernel32.dll
ModLoad: 76a20000 76ae6000   C:\Windows\system32\ADVAPI32.dll
ModLoad: 76d00000 76dc2000   C:\Windows\system32\RPCRT4.dll
ModLoad: 75b20000 75bca000   C:\Windows\system32\msvcrt.dll
(58c.918): Break instruction exception - code 80000003 (first chance)
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for ntdll.dll - 
eax=00000000 ebx=00000000 ecx=0027f9a0 edx=76e29a94 esi=fffffffe edi=76e2b6f8
eip=76e17dfe esp=0027f9b8 ebp=0027f9e8 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
ntdll!DbgBreakPoint:
76e17dfe cc              int     3
0:000> bp kernel32!CreateProcessW
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for C:\Windows\system32\kernel32.dll - 
breakpoint 0 redefined
0:000> g
Breakpoint 0 hit
eax=0027f590 ebx=00000000 ecx=00000000 edx=00000000 esi=4a005200 edi=00000001
eip=75861c01 esp=0027f4b4 ebp=0027f674 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
kernel32!CreateProcessW:
75861c01 8bff            mov     edi,edi
0:000> kb
ChildEBP RetAddr  Args to Child              
WARNING: Stack unwind information not available. Following frames may be wrong.
0027f4b0 49fe4568 00316078 003175a8 00000000 kernel32!CreateProcessW
0027f674 49fe4315 00317508 00000000 00000000 cmd!ExecPgm+0x20a
0027f8d4 49fe43a8 00317508 00000000 00000000 cmd!ECWork+0x7f
0027f8ec 49fe43ce 00317508 e3a3ec47 00000001 cmd!ExtCom+0x47
0027fd48 49fe185f 00317508 00000002 7588372f cmd!FindFixAndRun+0xb3
0027fd98 49ff70d4 00000000 00317508 4a0041b0 cmd!Dispatch+0x14a
0027fddc 49fe985b 00000001 000a0f38 000a1840 cmd!main+0x21a
0027fe20 758a4911 7ffdb000 0027fe6c 76e0e4b6 cmd!_initterm_e+0x163
0027fe2c 76e0e4b6 7ffdb000 7871d1d4 00000000 kernel32!BaseThreadInitThunk+0x12
0027fe6c 76e0e489 49fe9797 7ffdb000 00000000 ntdll!RtlInitializeExceptionChain+0x63
0027fe84 00000000 49fe9797 7ffdb000 00000000 ntdll!RtlInitializeExceptionChain+0x36
0:000> du 316078
00316078  "C:\Windows\system32\edit.com"

Ответ 3

См. CreateProcess.

  • Каталог, из которого загружено приложение.
  • Текущий каталог для родительского процесса.
  • 32-разрядный системный каталог ОС Windows. Используйте функцию GetSystemDirectory, чтобы получить путь к этому каталогу. Windows Me/98/95: системный каталог Windows. Используйте функцию GetSystemDirectory, чтобы получить путь к этому каталогу.
  • 16-битный системный каталог ОС Windows. Нет функции, которая получает путь к этому каталогу, но выполняется поиск. Имя этого каталога - System.
  • Каталог Windows. Используйте функцию GetWindowsDirectory, чтобы получить путь к этому каталогу.
  • Каталоги, перечисленные в переменной среды PATH. Обратите внимание, что эта функция не ищет путь к каждому приложению, указанный в разделе реестра приложений. Чтобы включить этот путь для каждого приложения в последовательности поиска, используйте функцию ShellExecute.