Как Windows находит файлы, введенные в оболочку?
Я искал этот вопрос на сайте, но, похоже, его никогда не задавали, поэтому я решил поделиться ответом с любым, кто его ищет.
В: Когда я ввожу имя исполняемых файлов в cmd.exe, через функции запуска оболочки или из пакетного файла, как Windows находит внешний исполняемый файл для вызова?
3 ответа
Я не понимаю, что означает "функция выполнения оболочки", поэтому я ее проигнорирую.
Но правила запуска исполняемого файла из командной строки CMD.EXE или из командного файла следующие:
Если для исполняемого файла указан путь (абсолютный или относительный), то ищется только этот путь.
Если указано только имя исполняемого файла (и, возможно, расширение), то
Сначала найдите текущую папку
Затем ищите папки в переменной окружения PATH (в указанном порядке)
В каждой из найденных папок используйте предоставленное расширение. Если расширение файла не указано, найдите файлы, которые соответствуют расширениям, найденным в переменной среды PATHEXT (в указанном порядке).
Первый найденный соответствующий файл - тот, который исполняется.
РЕДАКТИРОВАТЬ
Дэвид Кенди указал мне на некоторую устаревшую документацию NT, которая точно описывает процесс поиска, и она в основном соответствует тому, что я написал выше. См. Запуск приложений из NT Shell
Я был бы рад, если бы кто-нибудь мог опубликовать ссылки на аналогичную документацию CMD.EXE для более поздних версий Windows, особенно если бы она была написана Microsoft. Обратите внимание, что документация по NT, ссылка на которую приведена выше, не была написана Microsoft, хотя она размещена на их сайте.
Вот отладка 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"
Смотрите CreateProcess.
- Каталог, из которого загружено приложение.
- Текущий каталог для родительского процесса.
- 32-разрядный системный каталог Windows. Используйте функцию GetSystemDirectory, чтобы получить путь к этому каталогу. Windows Me/98/95: системный каталог Windows. Используйте функцию GetSystemDirectory, чтобы получить путь к этому каталогу.
- 16-разрядный системный каталог Windows. Нет функции, которая получает путь к этому каталогу, но она ищется. Название этого каталога - System.
- Каталог Windows. Используйте функцию GetWindowsDirectory, чтобы получить путь к этому каталогу.
- Каталоги, перечисленные в переменной среды PATH. Обратите внимание, что эта функция не выполняет поиск пути для приложения, указанного в разделе реестра "Путь к приложению". Чтобы включить этот путь для каждого приложения в последовательность поиска, используйте функцию ShellExecute.