C语言或C++通过IShellLinkA创建或解析lnk快捷方式(使用char字符数组)

news2024/11/17 11:32:28

本例程用到的COM接口有IShellLinkA和IPersistFile。
请注意因为函数参数的类型不为BSTR,所以这两个接口可直接传char *或wchar_t *字符串,不需要提前转化为BSTR类型。

C语言的写法:

/* 这个程序只能在C编译器下编译成功, 请确保源文件的扩展名为c */
#define COBJMACROS
#include <stdio.h>
#include <ShObjIdl.h>

// char *字符串转wchar_t *字符串
wchar_t *gb2312_to_utf16(const char *s)
{
	int n;
	wchar_t *ws;

	n = MultiByteToWideChar(CP_ACP, 0, s, -1, NULL, 0);
	ws = calloc(n, sizeof(wchar_t));
	if (ws != NULL)
		MultiByteToWideChar(CP_ACP, 0, s, -1, ws, n);
	return ws;
}

// 创建快捷方式
void create_shortcut(const char *name, const char *target, const char *desc)
{
	wchar_t *ws;
	IPersistFile *file;
	IShellLinkA *link;
	HRESULT hr;

	hr = CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, &IID_IShellLinkA, &link);
	if (SUCCEEDED(hr))
	{
		// 以下两个函数可直接传char *字符串
		IShellLinkA_SetPath(link, target);
		IShellLinkA_SetDescription(link, desc);

		hr = IShellLinkA_QueryInterface(link, &IID_IPersistFile, &file);
		if (SUCCEEDED(hr))
		{
			ws = gb2312_to_utf16(name);
			hr = IPersistFile_Save(file, ws, TRUE); // 第二个参数不是BSTR类型, 而是LPCOLESTR类型, 直接传wchar_t *字符串即可
													// 第三个参数决定是否将此文件用作后续的工作文件
			free(ws);

			if (SUCCEEDED(hr))
				printf("创建快捷方式%s成功\n", name);
			else
				printf("创建快捷方式%s失败\n", name);
			IPersistFile_Release(file);
		}
		IShellLinkA_Release(link);
	}
}

// 解析快捷方式
void read_shortcut(const char *name)
{
	char target[MAX_PATH]; // 在Windows系统中, 路径的最大长度是MAX_PATH
	char desc[INFOTIPSIZE]; // 在Windows系统中, 快捷方式描述的最大长度是INFOTIPSIZE
	wchar_t *ws;
	IPersistFile *file;
	IShellLinkA *link;
	HRESULT hr;

	hr = CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, &IID_IShellLinkA, &link);
	if (SUCCEEDED(hr))
	{
		hr = IShellLinkA_QueryInterface(link, &IID_IPersistFile, &file);
		if (SUCCEEDED(hr))
		{
			ws = gb2312_to_utf16(name);
			hr = IPersistFile_Load(file, ws, STGM_READ);
			free(ws);
			if (SUCCEEDED(hr))
			{
				printf("解析快捷方式%s成功\n", name);
				hr = IShellLinkA_GetPath(link, target, MAX_PATH, NULL, SLGP_RAWPATH);
				if (SUCCEEDED(hr))
					printf("链接目标: %s\n", target);

				hr = IShellLinkA_GetDescription(link, desc, INFOTIPSIZE);
				if (SUCCEEDED(hr))
					printf("描述: %s\n", desc);
			}
			else
				printf("解析快捷方式%s失败\n", name);
			IPersistFile_Release(file);
		}
		IShellLinkA_Release(link);
	}
}

// 解析开始菜单中Office 2010的所有快捷方式
void read_office2010_links()
{
	char *folder = "C:\\Documents and Settings\\All Users\\「开始」菜单\\程序\\Microsoft Office";
	char path[MAX_PATH];
	HANDLE find;
	WIN32_FIND_DATAA find_data;

	// 请注意: _s结尾的字符串操作函数, 凡是命名为MaxCount的参数, 都要记得减去1, 否则字符数组刚好满的时候程序会崩溃
	_snprintf_s(path, sizeof(path), sizeof(path) - 1, "%s\\*.lnk", folder);
	find = FindFirstFileA(path, &find_data);
	if (find != INVALID_HANDLE_VALUE)
	{
		do
		{
			_snprintf_s(path, sizeof(path), sizeof(path) - 1, "%s\\%s", folder, find_data.cFileName);
			read_shortcut(path);
		} while (FindNextFileA(find, &find_data));
		FindClose(find);
	}
}

int main()
{
	CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);

	create_shortcut("示例快捷方式.lnk", "C:\\WINDOWS\\system32\\shell32.dll", "Windows XP界面真好看啊!");
	read_shortcut("示例快捷方式.lnk");
	read_office2010_links();

	CoUninitialize();
	return 0;
}

C++的写法:

#include <iostream>
#include <ShObjIdl.h>

using namespace std;

// char *字符串转wchar_t *字符串
wchar_t *gb2312_to_utf16(const char *s)
{
	int n;
	wchar_t *ws;

	n = MultiByteToWideChar(CP_ACP, 0, s, -1, NULL, 0);
	ws = new wchar_t[n];
	if (ws != NULL)
		MultiByteToWideChar(CP_ACP, 0, s, -1, ws, n);
	return ws;
}

// 创建快捷方式
void create_shortcut(const char *name, const char *target, const char *desc)
{
	wchar_t *ws;
	IPersistFile *file;
	IShellLinkA *link;
	HRESULT hr;

	hr = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&link));
	if (SUCCEEDED(hr))
	{
		// 以下两个函数可直接传char *字符串
		link->SetPath(target);
		link->SetDescription(desc);

		hr = link->QueryInterface(&file);
		if (SUCCEEDED(hr))
		{
			ws = gb2312_to_utf16(name);
			hr = file->Save(ws, TRUE); // 第一个参数不是BSTR类型, 而是LPCOLESTR类型, 直接传wchar_t *字符串即可
									   // 第二个参数决定是否将此文件用作后续的工作文件
			delete[] ws;

			if (SUCCEEDED(hr))
				cout << "创建快捷方式" << name << "成功" << endl;
			else
				cout << "创建快捷方式" << name << "失败" << endl;
			file->Release();
		}
		link->Release();
	}
}

// 解析快捷方式
void read_shortcut(const char *name)
{
	char target[MAX_PATH]; // 在Windows系统中, 路径的最大长度是MAX_PATH
	char desc[INFOTIPSIZE]; // 在Windows系统中, 快捷方式描述的最大长度是INFOTIPSIZE
	wchar_t *ws;
	IPersistFile *file;
	IShellLinkA *link;
	HRESULT hr;

	hr = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&link));
	if (SUCCEEDED(hr))
	{
		hr = link->QueryInterface(&file);
		if (SUCCEEDED(hr))
		{
			ws = gb2312_to_utf16(name);
			hr = file->Load(ws, STGM_READ);
			delete[] ws;
			if (SUCCEEDED(hr))
			{
				cout << "解析快捷方式" << name << "成功" << endl;
				hr = link->GetPath(target, MAX_PATH, NULL, SLGP_RAWPATH);
				if (SUCCEEDED(hr))
					cout << "链接目标: " << target << endl;

				hr = link->GetDescription(desc, INFOTIPSIZE);
				if (SUCCEEDED(hr))
					cout << "描述: " << desc << endl;
			}
			else
				cout << "解析快捷方式" << name << "失败" << endl;
			file->Release();
		}
		link->Release();
	}
}

// 解析开始菜单中Office 2010的所有快捷方式
void read_office2010_links()
{
	char *folder = "C:\\Documents and Settings\\All Users\\「开始」菜单\\程序\\Microsoft Office";
	char path[MAX_PATH];
	HANDLE find;
	WIN32_FIND_DATAA find_data;

	// 请注意: _s结尾的字符串操作函数, 凡是命名为MaxCount的参数, 都要记得减去1, 否则字符数组刚好满的时候程序会崩溃
	_snprintf_s(path, sizeof(path) - 1, "%s\\*.lnk", folder);
	find = FindFirstFileA(path, &find_data);
	if (find != INVALID_HANDLE_VALUE)
	{
		do
		{
			_snprintf_s(path, sizeof(path) - 1, "%s\\%s", folder, find_data.cFileName);
			read_shortcut(path);
		} while (FindNextFileA(find, &find_data));
		FindClose(find);
	}
}

int main()
{
	CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);

	create_shortcut("示例快捷方式.lnk", "C:\\WINDOWS\\system32\\shell32.dll", "Windows XP界面真好看啊!");
	read_shortcut("示例快捷方式.lnk");
	read_office2010_links();

	CoUninitialize();
	return 0;
}

程序创建的lnk快捷方式:

程序运行结果:

创建快捷方式示例快捷方式.lnk成功
解析快捷方式示例快捷方式.lnk成功
链接目标: C:\WINDOWS\system32\shell32.dll
描述: Windows XP界面真好看啊!
解析快捷方式C:\Documents and Settings\All Users\「开始」菜单\程序\Microsoft Offi
ce\Microsoft Access 2010.lnk成功
链接目标: C:\WINDOWS\Installer\{90140000-0011-0000-0000-0000000FF1CE}\accicons.e
xe
描述: 使用 Microsoft Access 创建数据库和程序来跟踪与管理信息。
解析快捷方式C:\Documents and Settings\All Users\「开始」菜单\程序\Microsoft Offi
ce\Microsoft Excel 2010.lnk成功
链接目标: C:\WINDOWS\Installer\{90140000-0011-0000-0000-0000000FF1CE}\xlicons.ex
e
描述: 使用 Microsoft Excel 执行计算、分析信息以及可视化电子表格中的数据。
解析快捷方式C:\Documents and Settings\All Users\「开始」菜单\程序\Microsoft Offi
ce\Microsoft InfoPath Designer 2010.lnk成功
链接目标: C:\WINDOWS\Installer\{90140000-0011-0000-0000-0000000FF1CE}\inficon.ex
e
描述: 使用 Microsoft InfoPath 设计动态表单,以便在整个组织中收集和重用信息。
解析快捷方式C:\Documents and Settings\All Users\「开始」菜单\程序\Microsoft Offi
ce\Microsoft InfoPath Filler 2010.lnk成功
链接目标: C:\WINDOWS\Installer\{90140000-0011-0000-0000-0000000FF1CE}\inficon.ex
e
描述: 使用 Microsoft InfoPath 填写动态表单,以便在整个组织中收集和重用信息。
解析快捷方式C:\Documents and Settings\All Users\「开始」菜单\程序\Microsoft Offi
ce\Microsoft OneNote 2010.lnk成功
链接目标: C:\WINDOWS\Installer\{90140000-0011-0000-0000-0000000FF1CE}\joticon.ex
e
描述: 使用 Microsoft OneNote 搜集、组织、查找和共享您的笔记和信息。
解析快捷方式C:\Documents and Settings\All Users\「开始」菜单\程序\Microsoft Offi
ce\Microsoft Outlook 2010.lnk成功
链接目标: C:\WINDOWS\Installer\{90140000-0011-0000-0000-0000000FF1CE}\outicon.ex
e
描述: 使用 Microsoft Outlook 发送和接收电子邮件;管理日程、联系人和任务;以及记
录活动。
解析快捷方式C:\Documents and Settings\All Users\「开始」菜单\程序\Microsoft Offi
ce\Microsoft PowerPoint 2010.lnk成功
链接目标: C:\WINDOWS\Installer\{90140000-0011-0000-0000-0000000FF1CE}\pptico.exe

描述: 使用 Microsoft PowerPoint 创建和编辑用于幻灯片播放、会议和网页的演示文稿。

解析快捷方式C:\Documents and Settings\All Users\「开始」菜单\程序\Microsoft Offi
ce\Microsoft Project 2010.lnk成功
链接目标: C:\WINDOWS\Installer\{90140000-003B-0000-0000-0000000FF1CE}\pj11icon.e
xe
描述: 使用 Microsoft Project 计划、跟踪和管理项目,以及与工作组交流。
解析快捷方式C:\Documents and Settings\All Users\「开始」菜单\程序\Microsoft Offi
ce\Microsoft Publisher 2010.lnk成功
链接目标: C:\WINDOWS\Installer\{90140000-0011-0000-0000-0000000FF1CE}\pubs.exe
描述: 使用 Microsoft Publisher 创建新闻稿和小册子等专业品质出版物及营销素材。
解析快捷方式C:\Documents and Settings\All Users\「开始」菜单\程序\Microsoft Offi
ce\Microsoft SharePoint Workspace 2010.lnk成功
链接目标: C:\WINDOWS\Installer\{90140000-0011-0000-0000-0000000FF1CE}\grvicons.e
xe
描述: 使用 Microsoft SharePoint Workspace 将 SharePoint 网站同步到您的计算机并处
理其内容,就像始终连接到网站一样。
解析快捷方式C:\Documents and Settings\All Users\「开始」菜单\程序\Microsoft Offi
ce\Microsoft Visio 2010.lnk成功
链接目标: C:\WINDOWS\Installer\{90140000-0057-0000-0000-0000000FF1CE}\visicon.ex
e
描述: 使用 Microsoft Visio 创建、编辑和共享图表。
解析快捷方式C:\Documents and Settings\All Users\「开始」菜单\程序\Microsoft Offi
ce\Microsoft Word 2010.lnk成功
链接目标: C:\WINDOWS\Installer\{90140000-0011-0000-0000-0000000FF1CE}\wordicon.e
xe
描述: 使用 Microsoft Word 创建和编辑具有专业外观的文档,如信函、论文、报告和小册
子。
请按任意键继续. . .

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

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

相关文章

智慧之光:ChatGPT 引领工作效率新纪元

随着科技的不断发展&#xff0c;人工智能&#xff08;AI&#xff09;已经逐渐融入我们的日常生活和工作中。其中&#xff0c;ChatGPT 作为一种先进的 AI 技术&#xff0c;正逐步改变我们的工作方式&#xff0c;提升我们的工作效率。本文灸哥将介绍如何利用ChatGPT提升工作效率&…

intellij idea怎么设置中文

CtrlAltS快捷键打开Settings界面选择Plugins在搜索部分搜索chinese&#xff0c;选择下方的Chinese&#xff08;simplified&#xff09;Language下载最后重启软件即可

数据结构:完全二叉树(递归实现)

如果完全二叉树的深度为h&#xff0c;那么除了第h层外&#xff0c;其他层的节点个数都是满的&#xff0c;第h层的节点都靠左排列。 完全二叉树的编号方法是从上到下&#xff0c;从左到右&#xff0c;根节点为1号节点&#xff0c;设完全二叉树的节点数为sum&#xff0c;某节点编…

leetcode-hot100双指针专题

第一题&#xff1a;移动零 题目链接 283. 移动零 - 力扣&#xff08;LeetCode&#xff09; 解题思路 我们创建两个指针i,j&#xff0c;第一次遍历的时候指针j用来记录当前面有多少非0元素。即遍历的时候每遇到一个非0元素就将其往数组左边挪&#xff0c;第一次遍历完后&…

解决国内 github.com 打不开的准确方法

** 下载watt toolkit&#xff0c; 选择‘github’&#xff0c;点击‘一键加速’&#xff0c;很简单方便 **

【阿里云服务器数据迁移】 同一个账号 不同区域服务器

前言 假如说一台云服务器要过期了,现在新买了一台,有的人会烦恼又要将重新在新的服务器上装环境,部署上线旧服务器上的网站项目, 但是不必烦恼,本文将介绍如何快速将就旧的服务器上的数据迁移到新的服务器上. 包括所有的环境和网站项目噢 ! 步骤 (1) 创建旧服务器自定义镜像…

Llama2中文大模型——牛刀小试

文章目录 Llama2中文大模型——牛刀小试前言更新库导包加载模型对话问答-1对话问答-2对话问答-3对话问答-4对话问答-5 Llama2中文大模型——牛刀小试 前言 Meta开源的Llama从第一版开始&#xff0c;效果就很不错&#xff0c;有很多开源LLM都是基于它训练的&#xff0c;例如Vic…

GPT-5不叫GPT-5?下一代模型会有哪些新功能?

OpenAI首席执行官奥特曼在上周三达沃斯论坛接受媒体采访时表示&#xff0c;他现在的首要任务就是推出下一代大模型&#xff0c;这款模型不一定会命名GPT-5。虽然GPT-5的商标早已经注册。 如果GPT-4目前解决了人类任务的10%&#xff0c;GPT-5应该是15%或者20%。 OpenAI从去年开…

登录kafka报错:Could notstart Jolokia agent: java.net.BindException: Address in use

在执行kafka命令增加或删除topic的时候&#xff0c;发现总是报错。 Address in use&#xff1f;端口还是ip被占用了。只能禁用了&#xff0c;再执行命令。 禁用代码&#xff1a; 然后就可以拉~ 总体步骤&#xff1a; 1.先进入k8s的kafka pod 2.进入kafka的bin目录 3.两个…

PPO学习

openai用tf实现的真的看不懂&#xff0c;大佬的世界… PPO的详细细节 1. 奖励模型和策略的价值头将 query 和 response 的连接作为输入 奖励模型和策略的价值头 不 仅仅查看响应。相反&#xff0c;它将 query 和 response 连接在一起&#xff0c;作为 query_response def ge…

openEuler操作系统的安装及免密远程连接(超详细版)

一、下载地址 注意&#xff1a;可以先注册华为账号&#xff0c;注册后可享1倍加速 mirrors.huaweicloud.com/openeuler/openEuler-22.03-LTS-SP3/ISO/x86_64/ 二、创建虚拟机步骤 ①选择自定义 ② 根据自己的VMware选择版本 ③选择稍后安装操作系统 ④没有openEuler可以选择…

如何在CentOS使用docker-compose部署Apache Superset并实现公网访问

文章目录 前言1. 使用Docker部署Apache Superset1.1 第一步安装docker 、docker compose1.2 克隆superset代码到本地并使用docker compose启动 2. 安装cpolar内网穿透&#xff0c;实现公网访问3. 设置固定连接公网地址 前言 Superset是一款由中国知名科技公司开源的“现代化的…

“接口”公共规范的遵守者

&#x1f468;‍&#x1f4bb;作者简介&#xff1a;&#x1f468;&#x1f3fb;‍&#x1f393;告别&#xff0c;今天 &#x1f4d4;高质量专栏 &#xff1a;☕java趣味之旅 欢迎&#x1f64f;点赞&#x1f5e3;️评论&#x1f4e5;收藏&#x1f493;关注 &#x1f496;衷心的希…

【C++】命名空间详解

目录 前言 命名空间的定义 命名空间的使用 前言 在C/C中&#xff0c;变量、函数和后面要学到的类都是大量存在的&#xff0c;这些变量、函数和类的名称将都存 在于全局作用域中&#xff0c;可能会导致很多冲突。使用命名空间的目的是对标识符的名称进行本地化&#xff0c; 以…

厂务设备设施中如何使用工具实现预测性维护(PdM)

在现代工业环境中&#xff0c;厂务设备设施的有效维护对于确保生产连续性和降低运营成本至关重要。随着技术的不断发展&#xff0c;预测性维护&#xff08;PdM&#xff09;成为提前发现潜在设备故障的关键。本文将深入研究厂务设备设施如何利用各种先进工具实现预测性维护的目标…

扩散模型公式推导

这篇文章将尝试推导扩散模型 DDPM 中涉及公式&#xff0c;主要参考两个 B 站视频&#xff1a; 大白话AI狗中赤兔 本文所用 PPT 元素均来自 UP 主&#xff0c;狗中赤兔和大白兔AI&#xff0c;特此感谢。 在证明开始&#xff0c;我们需要先对扩散模型有一个整体的认知。扩散模型…

第二证券:大金融板块逆势护盘 北向资金尾盘加速净流入

周一&#xff0c;A股商场低开低走&#xff0c;沪指收盘失守2800点。截至收盘&#xff0c;上证综指跌2.68%&#xff0c;报2756.34点&#xff1b;深证成指跌3.5%&#xff0c;报8479.55点&#xff1b;创业板指跌2.83%&#xff0c;报1666.88点。沪深两市合计成交额7941亿元&#xf…

学习笔记-李沐动手学深度学习(二)(08-09、线性回归、优化算法、Softmax回归、损失函数、图片分类)

总结 以_结尾的方法&#xff0c;好像是原位替换&#xff08;即 原地修改&#xff0c;就地修改变量&#xff09;如 fill_() 感恩的心&#xff1a;&#xff08;沐神的直播环境&#xff09; 08-线性回归基础优化算法 引言&#xff08;如何在美国买房&#xff09; 根据现在行…

Java毕业设计-基于jsp+servlet的学生推荐平台管理系统-第81期

获取源码资料&#xff0c;请移步从戎源码网&#xff1a;从戎源码网_专业的计算机毕业设计网站 项目介绍 基于jspservlet的学生推荐平台管理系统&#xff1a;前端 jsp、jquery&#xff0c;后端 servlet、jdbc&#xff0c;集成用户端和管理后台&#xff0c;用户端浏览书籍课程&…

CSS高级技巧导读

1&#xff0c;精灵图 1.1 为什么需要精灵图&#xff1f; 目的&#xff1a;为了有效地减少服务器接收和发送请求的次数&#xff0c;提高页面的加载速度 核心原理&#xff1a;将网页中的一些小背景图像整合到一张大图中&#xff0c;这样服务器只需要一次请求就可以了 1.2 精灵…