嘿!我需要在C ++中查询应用程序的完整路径,例如“ meshlab”->“ C:\ Program Files \ VCG \ MeshLab \ meshlab.exe”
此信息存在于HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Windows \ CurrentVersion \ App Paths中,但我不想直接使用注册表,因此我正在使用AssocQueryString,如下所示:
#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:\Windows\system32\mspaint.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位
答案 0 :(得分:0)
我相信ASSOCF_OPEN_BYEXENAME:ASSOCSTR_EXECUTABLE
搜索HKEY_CLASSES_ROOT\Applications
。
ShellExecuteEx
搜索“普通目录”和the App Paths key:
查找可执行文件
使用可执行文件的名称(在其lpFile参数中)调用
ShellExecuteEx
函数时,该函数会在多个位置查找文件。我们建议您在“应用程序路径”注册表子项中注册您的应用程序。这样做避免了应用程序需要修改系统PATH环境变量。在以下位置搜索文件:
当前工作目录。
仅Windows目录(不搜索子目录)。
Windows \ System32目录。
PATH环境变量中列出的目录。
- HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Windows \ CurrentVersion \ App路径
(HKEY_CURRENT_USER也用于Windows的最新版本)
Assoc API更侧重于文件关联。
如果只打算执行文件,则应仅使用ShellExecuteEx
。如果您只想找到完全合格的路径,则可以使用一些帮助器功能为您完成一些工作:
FindExecutable
看起来很有希望,但是它有一些compatibility workarounds,并且还会找到用于打开注册类型的可执行文件(c:\foo\bar.txt
可能会解析为c:\Windows\Notepad.exe
等,因为它使用ASSOCSTR_EXECUTABLE
)
如果要自动查找.exe和.bat之类的扩展名,则可以使用PathResolve(..., PRF_REQUIREABSOLUTE|PRF_VERIFYEXISTS|PRF_TRYPROGRAMEXTENSIONS|PRF_DONTFINDLNK)
,但必须注意搜索字符串中不包含\
或:
。 / p>
如果只想查找.exe,则必须手动添加扩展名(如果扩展名不存在),然后调用PathFindOnPath(, NULL)
。
这两个函数都不在“应用程序路径”键中查找,它们没有使用与ShellExecuteEx
完全相同的搜索顺序(%windir%之前是system32?),并且很可能仅限于MAX_PATH。
如果这些功能(或您自己的等效版本)失败,则可以检查“应用程序路径”键。从注册表中读取内容时,如果没有扩展名,则必须附加.exe并使用SHQueryValueEx
之类的辅助函数来扩展REG_EXPAND_SZ
字符串。