是否有一个API公开start命令搜索的路径?

问题描述 投票:3回答:2

start搜索了哪些路径?此路径列表是否可通过WMI,注册表,WSH shell文件夹常量,.NET方法或任何其他Windows API进行查询?

cmd控制台中,start命令有点神奇。假设您的默认Web浏览器是Firefox。您还安装了Chrome和Opera,但它们既未设置为默认值,也未与任何文件类型相关联,也未在%PATH%中设置。考虑以下示例:

start "" opera https://stackoverflow.com

......为什么这样做?

mind blown

重要的是,对于所有start命令的优点,当使用start启动该应用程序时,检索应用程序的PID或窗口句柄仍然是危险的。在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"

失败。

batch-file winapi cmd
2个回答
3
投票

我记得在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来搜索上面提到的注册表路径。


3
投票

Aaditi

这可能与您正在做的事情有关(而不是为什么某些东西以它的方式工作)。

从以前的答案

Can I create shorthand names for use inside cmd?

Doskey /?

你可以这样做doskey cddesk=cd "%userprofile%\desktop"

然后输入cddesk

通过将所有宏放在批处理文件中,您可以自动加载。当然你也可以用批量文件来做这件事。

从技术参考到Windows 2000注册表,Microsoft,2000。

AutoRun HKCU\Software\Microsoft\Command Processor

数据类型范围默认值

REG_SZ命令列表此条目没有默认值。

描述

包含每次启动Cmd.exe时执行的命令。

另请参阅此批处理文件qazxsw poi列出特殊名称。

在命令提示符https://pastebin.com/A2qLw8r3

或者在开始 - 运行(Winkey + R)只是start shell:desktop

编辑

我在这里补充一些注意事项。

这是关于使用shell:desktop命令打开可执行文件。大量规则适用于不可执行文件。

不使用Start CMD预处理命令行并将fQFN发送到Start - 所以它的CMD搜索路径而不是CreateProcess


CreateProcess是ShellExecute的文档。一切都最终调用CreateProcess https://docs.microsoft.com/en-us/windows/desktop/shell/launch。此处还详细介绍了CMD预处理https://docs.microsoft.com/en-us/windows/desktop/api/processthreadsapi/nf-processthreadsapi-createprocessw。此外,https://books.google.com.au/books/about/Windows_NT_Shell_Scripting.html?id=jrdQAAAAMAAJ&redir_esc=y还提供了三种启动文件方式的文档。总结在这里start /?

一些有趣的事实。 CMD如果无法识别文件扩展名将尝试执行它。 Command to run a .bat file将内容嗅到未知文件ShellExecute

引用rojo:感谢链接转储。我很难理解https://docs.microsoft.com/en-us/windows/desktop/com/filetype-key如何能够让我不必完全限定路径名。这是我的首要问题。 “要使用ShellExecute或ShellExecuteEx,您的应用程序必须指定要对其执行操作的文件或文件夹对象,以及指定操作的动词。”这是我要问的“指定文件或文件夹对象”部分。

它使用CreateProcess下的6个步骤,如果没有,它会使用App Paths。如果未指定动词,则使用默认动词(通常为“打开”)。在这里查看我的答案ShellExecute

所以它是4种技术的交集。与MSDos的兼容性,IBM for OS / 2所做的更改以及Microsoft针对Windows 2000更新,启动程序CreateProcess的标准Windows方式,以及Windows 95,我们获得了基于OLE的shell函数

引用来自rojo:Snap!你是对的!在PowerShell中,我能够创建一个How do i automate the simulation of right clicking a file and selecting the first option using vbscript对象,设置System.Diagnostics.Process,然后启动“wordpad”,没有任何文件扩展名或完全限定的路径。将$ps.StartInfo.UseShellExecute = $true设置为.UseShellExecute property会导致执行失败。很有意思!

© www.soinside.com 2019 - 2024. All rights reserved.