在C 中使用AssocqueryString获取可执行路径



helo!我需要查询C 中的完整路径,例如" Meshlab" ->" C: Program Files VCG Meshlab Meshlab Meshlab.exe"

此信息存在于hkey_local_machine Software Microsoft Windows currentversion App Paths中,但是我不想直接使用注册表,因此我正在使用这样的cooperquerystring:

#include "pch.h"
#include <iostream>
#include <Windows.h>
#include <Shlwapi.h>
int main()
{
    char* executablePath = nullptr;
    DWORD executablePathLen = 0;
    std::string shortName = "mspaint";
    HRESULT res = AssocQueryStringA(ASSOCF_OPEN_BYEXENAME,
        ASSOCSTR_EXECUTABLE,
        shortName.c_str(),
        NULL,
        executablePath,
        &executablePathLen);
    executablePath = new char[executablePathLen];

    res = AssocQueryStringA(ASSOCF_OPEN_BYEXENAME,
        ASSOCSTR_EXECUTABLE,
        shortName.c_str(),
        NULL,
        executablePath,
        &executablePathLen);
    std::cout << executablePath; // prints: C:Windowssystem32mspaint.exe
    delete[] executablePath;
    std::cin.get();
}

对于MSpaint,它可以按预期工作,但是对于Meshlab而言,它却没有。hresult是error_no_association

有什么想法我错过了吗?

更新:也可以从C: Program Files(X86( Foobar2000 Foobar2000.exe与Foobar200一起使用。我怀疑它必须与32/64位注册表有关。我正在使用Windows 10 64位,我的应用程序是64位

我相信 ASSOCF_OPEN_BYEXENAME:ASSOCSTR_EXECUTABLE搜索 HKEY_CLASSES_ROOTApplications

ShellExecuteEx搜索"普通目录"和应用路径密钥:

查找应用程序可执行文件

ShellExecuteEx函数以其lpfile参数中的可执行文件的名称调用时,有几个地方可以查看该文件。我们建议在App Paths注册表子键中注册您的申请。这样做避免了需要修改系统路径环境变量的应用程序。

在以下位置寻求文件:

  • 当前的工作目录。

  • 仅Windows目录(未搜索子目录(。

  • Windows System32目录。

  • 路径环境变量中列出的目录。

  • hkey_local_machine software Microsoft Windows CurrentVersion App Paths

(hkey_current_user也用于Windows的最新版本(

关联API更专注于文件关联。

如果您要执行文件,则应只使用ShellExecuteEx。如果您只想找到完全合格的路径,则可以使用一些辅助功能为您完成一些工作:

FindExecutable似乎很有希望,但它具有一些兼容性解决方法,并且还可以找到用于打开注册类型的可执行文件(c:foobar.txt可能会解决到c:WindowsNotepad.exe等,因为它使用ASSOCSTR_EXECUTABLE(,

如果您想自动寻找.exe和.bat之类的扩展名,则可以使用PathResolve(..., PRF_REQUIREABSOLUTE|PRF_VERIFYEXISTS|PRF_TRYPROGRAMEXTENSIONS|PRF_DONTFINDLNK),但是必须小心搜索字符串不包含也不包含:

如果您只想寻找.exe,则必须在不存在的情况下手动附加扩展程序,然后致电PathFindOnPath(, NULL)

这些功能都没有在应用程序路径密钥中看起来,它们不使用与ShellExecuteEx完全相同的搜索顺序(per windir%之前的system32?(,它们很可能仅限于max_path。

如果这些功能(或您自己的等效版本(失败,则可以检查应用程序路径密钥。从注册表中阅读时,如果没有扩展名,则必须附加.exe,并且使用SHQueryValueEx这样的辅助功能,该功能将扩展REG_EXPAND_SZ字符串。

最新更新