C++获取商店应用(msix应用)桌面快捷方式的安装目录

news/2024/9/20 19:48:06

image

传统应用的快捷方式目标指向可执行文件的路径,但是对于商店应用(也叫msix打包应用),则指向一个奇怪的字符串,使用IShellLink::GetPath获取路径时,则得到的是空字符串,而我们的最终目的是要拿到应用的安装路径,那该怎么办呢?

首先解释一下,那个奇怪的字符串叫AUMID(App User Model Id),由应用包系列名称AppInfo.PackageFamilyName和应用标识符AppInfo.Id组成。

分3步获取安装目录

1,先获取快捷方式的PIDL

HRESULT hr = S_OK;
IShellLinkW* psl = NULL;
IPersistFile* psf = NULL;
LPITEMIDLIST pidlLnk = NULL;
do
{hr = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLinkW, (LPVOID*)&psl);if (FAILED(hr)) {break;}hr = psl->QueryInterface(IID_IPersistFile, (LPVOID*)&psf);if (FAILED(hr)) {break;}//加载快捷方式hr = psf->Load(L"C:\\Users\\Xyy\\Desktop\\Microsoft Teams - 快捷方式.lnk", STGM_READ);if (FAILED(hr)) {break;}//获取快捷方式hr = psl->GetIDList(&pidlLnk);if (FAILED(hr)) {break;}
} while (false);
//释放资源
if (pidlLnk) ILFree(pidlLnk);

2,通过PIDL获取应用的AUMID

这里要注意,并非所有拿不到路径的快捷方式都是商店应用,因此要判断快捷方式的父目录是否是FOLDERID_AppsFolder,这是一个虚拟目录

...
LPITEMIDLIST pidlAppsFolder = NULL;
PWSTR ppszName = NULL;
do
{...//获取FOLDERID_AppsFolder的PIDLhr = SHGetKnownFolderIDList(FOLDERID_AppsFolder, 0, NULL, &pidlAppsFolder);if (FAILED(hr)) {break;}//判断当前快捷方式的父目录是否是FOLDERID_AppsFolderif (!ILIsParent(pidlAppsFolder, pidlLnk, FALSE)) {printf("此快捷方式不是商店应用");break;}//根据PIDL获取AUMIDhr = SHGetNameFromIDList(pidlLnk, SIGDN_PARENTRELATIVEPARSING, &ppszName);if (FAILED(hr)) {break;}
} while (false);
//释放资源
...
if (pidlAppsFolder) ILFree(pidlAppsFolder);
if (ppszName) CoTaskMemFree(ppszName);

3,通过AUMID解析出packageFamily,再根据PackageManager解析出安装目录

PackageManagerWinRT的类型,如何在c++中使用WinRT,请参考C++/WinRT

以下代码需要管理员权限才能运行。

//根据AUMID拿到packageFamily
std::wstring fullString(ppszName);
size_t pos = fullString.find(L'!');
if (pos == std::wstring::npos) {break;
}
std::wstring packageFamily = fullString.substr(0, pos);std::wstring installPath = L"";
PackageManager packageManager;
//通过packageFamily查找所有包
auto packages = packageManager.FindPackages(packageFamily);
for (auto package : packages) {auto listEnties = package.GetAppListEntries();for (auto entry : listEnties) {if (entry.AppUserModelId() == ppszName) {installPath == package.InstalledPath();break;}}if (!installPath.empty()) {break;}
}
if (installPath.empty()) {break;
}
//找到安装目录
printf("找到安装目录:%ls", installPath.c_str());

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/47433.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

原生鸿蒙的成长史中,书写着无数鸿蒙先锋的故事

千帆并进破风云,浩瀚星河耀苍穹。 2024年6月21日,是属于鸿蒙的:HarmonyOS NEXT鸿蒙星河版Beta测试开启,5000多个鸿蒙原生应用已全部启动开发,其中超1500家已完成上架,鸿蒙生态设备数量超9亿,已有254万HarmonyOS开发者投入到鸿蒙世界的开发中,开发者服务调用次数827亿次…

鸿蒙先锋共筑星河 |科技浪潮中的教育革新,看南京大学教授的HarmonyOS教学之路

在科技的浩渺海洋中,每一次技术革新都如同激起的浪潮,推动着社会不断前进。HarmonyOS的崛起,不仅引领移动应用开发领域的新方向,也为高校教育带来了前所未有的机遇。高校老师们通过应用与实践,开展教学和研究工作,培养出一大批具备创新能力的人才。 南京大学教授刘钦,以其敏锐的…

vue样式

1.局部样式,在style标签上加stoped,样式只在当前组件生效,原理是编译后给当前组件内所有标签加上data-v-hash属性,给样式生成属性选择器 .myClass[data-v-hash] {color: red; },不加scoped样式在全局生效。 <style scoped> .myClass {color: red; } </style> …

FUM论文阅读笔记

FUM: Fine-grained and Fast User Modeling for News Recommendation Abstract 现存的问题: ​ 现有方法通常先将用户点击的新闻独立编码为新闻嵌入,然后将其聚合为用户嵌入。然而,这些方法忽略了同一用户点击的不同新闻之间的词级交互,而这种交互包含丰富的细节线索来推断…

从专业领域到代码世界:一位全科医生到全栈开发者的HarmonyOS跨界之旅

2024年6月23日,在华为开发者大会(HDC 2024)HarmonyOS开发者一站式服务分论坛上,汇集了华为专家、各行各业的开发者们,共同探讨如何在HarmonyOS的赋能下为行业和社会创造更多价值。特别要提及其中一位开发者陈胜歌,他于6月22日受邀参加了在东莞三丫坡举办的HDC 2024开发者…

匿名内部类再开发时候的使用

public interface USB { public void open(); } public class Test { public static void main(String[] args) { method( new USB(){ @Override public void open() { System.out.println("打开u成功"); } });//这里通过匿名内部类创建了接口对象,传入下面的method方…

Modbus转Profibus网关在汽车行业的应用

Modbus转Profibus网关(XD-MDPB100)应用于汽车行业,主要体现在提升自动化水平、优化数据传输以及实现设备间的无缝连接等方面。Modbus协议转Profibus协议网关是实现Modbus设备和Profibus设备之间通信的桥梁,在本文中,我们将介绍Modbus转Profibus网关(XD-MDPB100)在汽车行…