Есть ли API, который предоставляет пути, которые ищет команда start? - PullRequest
3 голосов
/ 24 марта 2019

Какие пути ищут start? Запрашивается ли этот список путей через WMI, реестр, константы папок оболочки WSH, методы .NET или любой другой API Windows?

В консоли cmd команда start является своего рода волшебством. Скажем, ваш браузер по умолчанию - Firefox. У вас также установлены Chrome и Opera, но они не установлены по умолчанию и не связаны ни с какими типами файлов, ни в вашем% PATH%. Рассматривая следующий пример:

start "" opera https://stackoverflow.com

... почему это работает?

mind blown

Причина, по которой это имеет значение, заключается в том, что при всех сильных сторонах команды start все еще опасно получать PID или дескриптор окна приложения, когда это приложение было запущено с start. В среде cmd я бы предпочел использовать wmic process call create в цикле for /F для захвата PID. Так есть ли способ, которым я могу научить wmic process call create запускать «оперу», «iexplore», «outlook», «winword» или другие приложения, как start, без полной квалификации drive:\\path\\to\\executable?

Мне показалось, что я нашел решение, отсканировав HKLM\Software\Clients рекурсивно на shell\open\command, а затем временно добавив каждое ссылочное местоположение в% 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%

Это работает достаточно хорошо, но все равно не имеет доступа к start. Например:

start "" wordpad

работает, тогда как

wmic process call create "wordpad.exe"

выходит из строя.

Ответы [ 2 ]

3 голосов
/ 24 марта 2019

Edit2

Это может представлять интерес в отношении того, что вы делаете (в отличие от того, почему что-то работает так, как работает).

Из предыдущего ответа

Можно ли создать сокращенные имена для использования внутри cmd?

См. Doskey /?.

Вы можете сделать это doskey cddesk=cd "%userprofile%\desktop"

Затем введите cddesk.

Поместив все свои макросы в пакетный файл, вы можете загрузить авто.Конечно, вы можете сделать это и с пакетными файлами.

Из Технического справочника по реестру Windows 2000, Microsoft, 2000.

AutoRun HKCU\Software\Microsoft\Command Processor

Тип данных Диапазон Значение по умолчанию

REG_SZ список команд Для этой записи нет значения по умолчанию.

Описание

Содержит команды, которые выполняются при каждом запуске Cmd.exe.

Также смотрите этот пакетный файл https://pastebin.com/A2qLw8r3, в котором перечислены специальные имена.

В командной строке start shell:desktop

Или в Пуск - Выполнить (Winkey + R) просто shell:desktop

Редактировать

Я просто добавлю несколько предостережений здесь.

Это касается открытия исполняемых файлов с помощью команды Start.Огромное количество правил применяется к неисполняемым файлам.

Не используется Start CMD предварительно обрабатывает командную строку и отправляет FQFN на CreateProcess - так что CMD ищет путь не CreateProcess.


https://docs.microsoft.com/en-us/windows/desktop/shell/launch - документация для ShellExecute.Все заканчивается вызовом CreateProcess https://docs.microsoft.com/en-us/windows/desktop/api/processthreadsapi/nf-processthreadsapi-createprocessw. Plus Предварительная обработка CMD подробно описана здесь https://books.google.com.au/books/about/Windows_NT_Shell_Scripting.html?id=jrdQAAAAMAAJ&redir_esc=y. Также start /? предоставляет документацию для всех трех способов запуска файлов.Сводка здесь Команда для запуска .bat файла

Несколько забавных фактов.CMD, если не может распознать расширение файла, попытается выполнить его.ShellExecute будет обнюхивать неизвестные файлы https://docs.microsoft.com/en-us/windows/desktop/com/filetype-key.

цитата из rojo: Спасибо за дамп ссылки.Я пытаюсь понять, как ShellExecute может избавить меня от необходимости полностью определять имена путей.Это был мой основной вопрос. «Чтобы использовать ShellExecute или ShellExecuteEx, ваше приложение должно указать объект файла или папки, который должен быть обработан на , и глагол, определяющий операцию». Это часть «указать объект файла или папки», о которой я спрашиваю.

Он использует 6 шагов в CreateProcess и, если ничего не получается, он использует пути к приложениям,Если глагол не указан, используется глагол по умолчанию (обычно открытый).Смотрите мой ответ здесь Как мне автоматизировать симуляцию щелчка правой кнопкой мыши по файлу и выбора первой опции, используя vbscript .

Итак, это пересечение 4 технологий.Совместимость с MSDos, изменения, сделанные IBM для OS / 2 и обновленные Microsoft для Windows 2000, стандартный способ запуска программ CreateProcess для Windows, а с Windows 95 мы получили функции оболочки, основанные на OLE

цитата из Рохо: Snap!Ты прав!В PowerShell мне удалось создать объект System.Diagnostics.Process, задать $ps.StartInfo.UseShellExecute = $true, а затем запустить «wordpad» без расширения файла или полного пути.Установка .UseShellExecute property в $false привела к сбою выполнения.Как интересно!

3 голосов
/ 24 марта 2019

Я помню дискуссию на эту тему либо на DosTips.com, либо здесь, на SO, но я не могу ее найти.Надеемся, что кто-нибудь сделает это, и мы сможем пометить этот вопрос как дубликат.

Мы знаем, что пакетные файлы будут искать текущий каталог, а затем переменную пути, чтобы найти исполняемый файл.Команда START также ищет следующий путь в реестре

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths

Таким образом, у вас есть несколько вариантов поиска исполняемого файла.

Вы можете использовать команду WHERE, которая ищет текущий каталоги каталоги в переменной PATH.

where notepad.exe

Вы также можете просто искать переменную пути с помощью команды FOR.

for %%I in (notepad.exe) do echo %%~$PATH:I

И, конечно, вы можете искать путь в реестрекак я упоминал выше, выполняя REG QUERY.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...