Lnk快捷方式存取(Win32, C++)

52 篇文章 0 订阅

将快捷方式的操作做了一个简单封装, 方便使用.

 

//解析Lnk内容
{
    CLnkHelper obj;
    obj.Load(_T("123.lnk"));
    SHELL_LINK_INFO info = obj.GetInfo();
    //TODO 使用info的内容
}

//创建(另存为)快捷方式
{
    CLnkHelper obj;
    SHELL_LINK_INFO info;
    //TODO 修改info的内容

    obj.SetInfo(info);
    obj.Save(_T("456.lnk"));
}

 

CLnkHelper.h

#pragma once

#include <stdint.h>
#include <string>
#include <shobjidl.h>

#ifdef _UNICODE
using _tstring = std::wstring;
using _tfstream = std::wfstream;
#else
using _tstring = std::string;
using _tfstream = std::fstream;
#endif

typedef struct _SHELL_LINK_INFO
{
    _tstring strFile;       //目标路径
    _tstring strDesc;       //描述
    _tstring strArgs;       //参数
    _tstring strDir;        //工作目录
    _tstring strIconPath;   //图标路径
    _tstring strPathRel;    //相对路径
    WORD wHotkey;           //快捷键
    int iShowCmd;           //显示命令
    int iIcon;              //图标索引

    _SHELL_LINK_INFO()
        :
        wHotkey(0),
        iShowCmd(0),
        iIcon(0)
    {

    }

}SHELL_LINK_INFO;

class CLnkHelper
{
public:
    CLnkHelper();
    ~CLnkHelper();

    //
    // @brief: 加载快捷方式
    // @param: strFile          文件路径
    // @ret: bool               操作结果
    // {@link https://learn.microsoft.com/zh-cn/windows/win32/api/objidl/nf-objidl-ipersistfile-load}.
    bool Load(const _tstring& strFile);

    //
    // @brief: 快捷方式保存
    // @param: strFile          文件路径
    // @ret: bool               操作结果
    // {@link https://learn.microsoft.com/zh-cn/windows/win32/api/objidl/nf-objidl-ipersistfile-save}.
    bool Save(const _tstring& strFile);

    //
    // @brief: 获取信息
    // @param: void
    // @ret: SHELL_LINK_INFO    信息内容
    SHELL_LINK_INFO GetInfo() const;

    //
    // @brief: 设置信息
    // @param: info             信息内容
    // @ret: bool               操作结果
    bool SetInfo(const SHELL_LINK_INFO& info);

    //
    // @remark 
    // @brief: 尝试查找快捷方式目标
    // @param: hwnd             对话框的父窗口的句柄
    // @param: fFlags           操作标志
    // @ret: bool               操作结果
    // {@link https://learn.microsoft.com/zh-cn/windows/win32/api/shobjidl_core/nf-shobjidl_core-ishelllinka-resolve}.
    bool Resolve(HWND hwnd, DWORD fFlags = SLR_NO_UI);

    //
    // @brief: 获取/设置目标路径
    // @param: strFile          目标路径
    // @param: fFlags           路径类型标志(SLGP_SHORTPATH, SLGP_RAWPATH, SLGP_RELATIVEPRIORITY)
    // @ret: bool               操作结果
    // {@link https://learn.microsoft.com/zh-cn/windows/win32/api/shobjidl_core/nf-shobjidl_core-ishelllinka-getpath}.
    // {@link https://learn.microsoft.com/zh-cn/windows/win32/api/shobjidl_core/nf-shobjidl_core-ishelllinka-setpath}.
    bool GetPath(_tstring& strFile, DWORD fFlags = SLGP_RAWPATH) const;
    _tstring GetPath(DWORD fFlags = SLGP_RAWPATH) const;
    bool SetPath(const _tstring& strFile);

    //
    // @brief: 获取/设置描述文本
    // @param: strDesc          描述文本
    // @ret: bool               操作结果
    // {@link https://learn.microsoft.com/zh-cn/windows/win32/api/shobjidl_core/nf-shobjidl_core-ishelllinka-getdescription}.
    // {@link https://learn.microsoft.com/zh-cn/windows/win32/api/shobjidl_core/nf-shobjidl_core-ishelllinka-setdescription}.
    bool GetDescription(_tstring& strDesc) const;
    _tstring GetDescription() const;
    bool SetDescription(const _tstring& strDesc);

    //
    // @brief: 获取/设置工作目录
    // @param: strDir           工作目录
    // @ret: bool               操作结果
    // {@link https://learn.microsoft.com/zh-cn/windows/win32/api/shobjidl_core/nf-shobjidl_core-ishelllinka-getworkingdirectory}.
    // {@link https://learn.microsoft.com/zh-cn/windows/win32/api/shobjidl_core/nf-shobjidl_core-ishelllinka-setworkingdirectory}.
    bool GetWorkingDirectory(_tstring& strDir) const;
    _tstring GetWorkingDirectory() const;
    bool SetWorkingDirectory(const _tstring& strDir);

    //
    // @brief: 获取/设置命令行参数
    // @param: strArgs          命令行参数
    // @ret: bool               操作结果
    // {@link https://learn.microsoft.com/zh-cn/windows/win32/api/shobjidl_core/nf-shobjidl_core-ishelllinka-getarguments}.
    // {@link https://learn.microsoft.com/zh-cn/windows/win32/api/shobjidl_core/nf-shobjidl_core-ishelllinka-setarguments}.
    bool GetArguments(_tstring& strArgs) const;
    _tstring GetArguments() const;
    bool SetArguments(const _tstring& strArgs);

    //
    // @brief: 获取/设置快捷键
    // @param: bModifier        修饰键(HOTKEYF_ALT, HOTKEYF_CONTROL, HOTKEYF_EXT, HOTKEYF_SHIFT)
    // @param: bKey             普通键
    // @ret: bool               操作结果
    // {@link https://learn.microsoft.com/zh-cn/windows/win32/api/shobjidl_core/nf-shobjidl_core-ishelllinka-gethotkey}.
    // {@link https://learn.microsoft.com/zh-cn/windows/win32/api/shobjidl_core/nf-shobjidl_core-ishelllinka-sethotkey}.
    bool GetHotkey(BYTE& bModifier, BYTE& bKey) const;
    WORD GetHotkey() const;
    bool SetHotkey(BYTE bModifier, BYTE bKey);
    bool SetHotkey(WORD wHotkey);

    //
    // @brief: 获取/设置显示命令
    // @param: iShowCmd         显示命令(SW_SHOWNORMAL, SW_SHOWMAXIMIZED, SW_SHOWMINIMIZED)
    // @ret: bool               操作结果
    // {@link https://learn.microsoft.com/zh-cn/windows/win32/api/shobjidl_core/nf-shobjidl_core-ishelllinka-getshowcmd}.
    // {@link https://learn.microsoft.com/zh-cn/windows/win32/api/shobjidl_core/nf-shobjidl_core-ishelllinka-setshowcmd}.
    bool CLnkHelper::GetShowCmd(int& iShowCmd) const;
    int CLnkHelper::GetShowCmd() const;
    bool CLnkHelper::SetShowCmd(int iShowCmd);

    //
    // @brief: 获取/设置图标位置
    // @param: strIconPath      图标路径
    // @param: iIcon            图标索引
    // @ret: bool               操作结果
    // {@link https://learn.microsoft.com/zh-cn/windows/win32/api/shobjidl_core/nf-shobjidl_core-ishelllinka-geticonlocation}.
    // {@link https://learn.microsoft.com/zh-cn/windows/win32/api/shobjidl_core/nf-shobjidl_core-ishelllinka-seticonlocation}.
    bool GetIconLocation(_tstring& strIconPath, int& iIcon) const;
    _tstring GetIconLocation(int* piIcon = nullptr) const;
    bool SetIconLocation(const _tstring& IconPath, int iIcon);

    //
    // @brief: 设置相对路径
    // @param: strPathRel       相对路径
    // @ret: bool               操作结果
    // {@link https://learn.microsoft.com/zh-cn/windows/win32/api/shobjidl_core/nf-shobjidl_core-ishelllinka-setrelativepath}.
    bool GetRelativePath(_tstring& strPathRel) const;
    _tstring GetRelativePath() const;
    bool SetRelativePath(const _tstring& strPathRel);

private:

    //
    // @brief: 初始化
    // @ret: bool               操作结果
    bool Initialized();

    //
    // @brief: 反初始化
    // @ret: void               无
    void Uninitialize();

private:

    IShellLink* m_SheelLink;    //Shell 链接接口对象指针
    IPersistFile* m_ppf;        //存储链接信息接口对象指针
    bool m_bInit;
};

CLnkHelper.cpp

#include "CLnkHelper.h"
#include <shlguid.h>

CLnkHelper::CLnkHelper()
    :
    m_SheelLink(nullptr),
    m_ppf(nullptr),
    m_bInit(false)
{
    this->Initialized();
}


CLnkHelper::~CLnkHelper()
{
    this->Uninitialize();
}

bool CLnkHelper::Initialized()
{
    HRESULT hr = S_OK;
    hr = ::CoInitializeEx(nullptr, COINIT_MULTITHREADED);
    if (FAILED(hr))
    {
        return false;
    }

    m_bInit = true;

    hr = ::CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&m_SheelLink);
    if (FAILED(hr))
    {
        return false;
    }

    hr = m_SheelLink->QueryInterface(IID_IPersistFile, (void**)&m_ppf);
    if (FAILED(hr))
    {
        return false;
    }

    return true;
}

void CLnkHelper::Uninitialize()
{
    if (m_ppf)
    {
        m_ppf->Release();
        m_ppf = nullptr;
    }

    if (m_SheelLink)
    {
        m_SheelLink->Release();
        m_SheelLink = nullptr;
    }

    if (m_bInit)
    {
        (void)::CoUninitialize();
    }
}

bool CLnkHelper::Load(const _tstring& strFile)
{
    HRESULT hr = S_OK;

    if (!m_ppf)
    {
        return false;
    }

    hr = m_ppf->Load(strFile.c_str(), STGM_READWRITE);
    if (FAILED(hr))
    {
        return false;
    }

    return true;
}

bool CLnkHelper::Save(const _tstring& strFile)
{
    HRESULT hr = S_OK;
    if (!m_ppf)
    {
        return false;
    }

    hr = m_ppf->Save(strFile.c_str(), true);
    return SUCCEEDED(hr);
}

SHELL_LINK_INFO CLnkHelper::GetInfo() const
{
    SHELL_LINK_INFO info;

    if (m_SheelLink)
    {
        WIN32_FIND_DATA wfd = { 0 };
        TCHAR szBuf[MAX_PATH * 4] = { 0 };
        HRESULT hr = S_OK;
        hr = m_SheelLink->GetPath(szBuf, _countof(szBuf), &wfd, SLGP_RAWPATH);
        if (SUCCEEDED(hr))
        {
            info.strFile = szBuf;
        }

        hr = m_SheelLink->GetPath(szBuf, _countof(szBuf), &wfd, SLGP_RELATIVEPRIORITY);
        if (SUCCEEDED(hr))
        {
            info.strPathRel = szBuf;
        }

        hr = m_SheelLink->GetDescription(szBuf, _countof(szBuf));
        if (SUCCEEDED(hr))
        {
            info.strDesc = szBuf;
        }

        hr = m_SheelLink->GetWorkingDirectory(szBuf, _countof(szBuf));
        if (SUCCEEDED(hr))
        {
            info.strDir = szBuf;
        }

        hr = m_SheelLink->GetArguments(szBuf, _countof(szBuf));
        if (SUCCEEDED(hr))
        {
            info.strArgs = szBuf;
        }

        int iIcon = 0;
        hr = m_SheelLink->GetIconLocation(szBuf, _countof(szBuf), &iIcon);
        if (SUCCEEDED(hr))
        {
            info.strIconPath = szBuf;
            info.iIcon = iIcon;
        }

        int iShowCmd = 0;
        hr = m_SheelLink->GetShowCmd(&iShowCmd);
        if (SUCCEEDED(hr))
        {
            info.iShowCmd = iShowCmd;
        }

        WORD wHotkey = 0;
        hr = m_SheelLink->GetHotkey(&wHotkey);
        if (SUCCEEDED(hr))
        {
            info.wHotkey = wHotkey;
        }
    }

    return info;
}

bool CLnkHelper::SetInfo(const SHELL_LINK_INFO& info)
{
    if (!m_SheelLink)
    {
        return false;
    }

    m_SheelLink->SetPath(info.strFile.c_str());
    m_SheelLink->SetRelativePath(info.strPathRel.c_str(), 0);
    m_SheelLink->SetDescription(info.strDesc.c_str());
    m_SheelLink->SetArguments(info.strArgs.c_str());
    m_SheelLink->SetIconLocation(info.strIconPath.c_str(), info.iIcon);
    m_SheelLink->SetWorkingDirectory(info.strDir.c_str());
    m_SheelLink->SetHotkey(info.wHotkey);
    m_SheelLink->SetShowCmd(info.iShowCmd);

    return true;
}

bool CLnkHelper::Resolve(HWND hwnd, DWORD fFlags)
{
    if (!m_SheelLink)
    {
        return false;
    }

    HRESULT hr = S_OK;
    hr = m_SheelLink->Resolve(hwnd, fFlags);
    return SUCCEEDED(hr);
}

bool CLnkHelper::GetPath(_tstring& strFile, DWORD fFlags/* = SLGP_RAWPATH*/) const
{
    if (!m_SheelLink)
    {
        return false;
    }

    WIN32_FIND_DATA wfd = { 0 };
    TCHAR szBuf[MAX_PATH * 4] = { 0 };
    HRESULT hr = S_OK;
    hr = m_SheelLink->GetPath(szBuf, _countof(szBuf), &wfd, fFlags);
    if (SUCCEEDED(hr))
    {
        strFile = szBuf;
    }

    return SUCCEEDED(hr);
}

_tstring CLnkHelper::GetPath(DWORD fFlags/* = SLGP_RAWPATH*/) const
{
    if (!m_SheelLink)
    {
        return _tstring();
    }

    WIN32_FIND_DATA wfd = { 0 };
    TCHAR szBuf[MAX_PATH * 4] = { 0 };
    HRESULT hr = S_OK;
    hr = m_SheelLink->GetPath(szBuf, _countof(szBuf), &wfd, fFlags);
    if (SUCCEEDED(hr))
    {
        return szBuf;
    }

    return _tstring();
}

bool CLnkHelper::SetPath(const _tstring& strFile)
{
    if (!m_SheelLink)
    {
        return false;
    }

    HRESULT hr = S_OK;
    hr = m_SheelLink->SetPath(strFile.c_str());
    return SUCCEEDED(hr);
}

bool CLnkHelper::GetDescription(_tstring& strDesc) const
{
    if (!m_SheelLink)
    {
        return false;
    }

    HRESULT hr = S_OK;
    TCHAR szBuf[MAX_PATH * 4] = { 0 };
    hr = m_SheelLink->GetDescription(szBuf, _countof(szBuf));
    if (SUCCEEDED(hr))
    {
        strDesc = szBuf;
    }

    return SUCCEEDED(hr);
}

_tstring CLnkHelper::GetDescription() const
{
    if (!m_SheelLink)
    {
        return _tstring();
    }

    HRESULT hr = S_OK;
    TCHAR szBuf[MAX_PATH * 4] = { 0 };
    hr = m_SheelLink->GetDescription(szBuf, _countof(szBuf));
    if (SUCCEEDED(hr))
    {
        return szBuf;
    }

    return _tstring();
}

bool CLnkHelper::SetDescription(const _tstring& strDesc)
{
    if (!m_SheelLink)
    {
        return false;
    }

    HRESULT hr = S_OK;
    hr = m_SheelLink->SetDescription(strDesc.c_str());

    return SUCCEEDED(hr);
}

bool CLnkHelper::GetWorkingDirectory(_tstring& strDir) const
{
    if (!m_SheelLink)
    {
        return false;
    }

    HRESULT hr = S_OK;
    TCHAR szBuf[MAX_PATH * 4] = { 0 };
    hr = m_SheelLink->GetWorkingDirectory(szBuf, _countof(szBuf));
    if (SUCCEEDED(hr))
    {
        strDir = szBuf;
    }

    return SUCCEEDED(hr);
}

_tstring CLnkHelper::GetWorkingDirectory() const
{
    if (!m_SheelLink)
    {
        return _tstring();
    }

    HRESULT hr = S_OK;
    TCHAR szBuf[MAX_PATH * 4] = { 0 };
    hr = m_SheelLink->GetWorkingDirectory(szBuf, _countof(szBuf));
    if (SUCCEEDED(hr))
    {
        return szBuf;
    }

    return _tstring();
}

bool CLnkHelper::SetWorkingDirectory(const _tstring& strDir)
{
    if (!m_SheelLink)
    {
        return false;
    }

    HRESULT hr = S_OK;
    hr = m_SheelLink->SetWorkingDirectory(strDir.c_str());
    return SUCCEEDED(hr);
}

bool CLnkHelper::GetArguments(_tstring& strArgs) const
{
    if (!m_SheelLink)
    {
        return false;
    }

    HRESULT hr = S_OK;
    TCHAR szBuf[MAX_PATH * 4] = { 0 };
    hr = m_SheelLink->GetArguments(szBuf, _countof(szBuf));
    if (SUCCEEDED(hr))
    {
        strArgs = szBuf;
    }

    return SUCCEEDED(hr);
}

_tstring CLnkHelper::GetArguments() const
{
    if (!m_SheelLink)
    {
        return _tstring();
    }

    HRESULT hr = S_OK;
    TCHAR szBuf[MAX_PATH * 4] = { 0 };
    hr = m_SheelLink->GetArguments(szBuf, _countof(szBuf));
    if (SUCCEEDED(hr))
    {
        return szBuf;
    }

    return _tstring();
}

bool CLnkHelper::SetArguments(const _tstring& strArgs)
{
    if (!m_SheelLink)
    {
        return false;
    }

    HRESULT hr = S_OK;
    hr = m_SheelLink->SetArguments(strArgs.c_str());
    return SUCCEEDED(hr);
}

bool CLnkHelper::GetHotkey(BYTE& bModifier, BYTE& bKey) const
{
    if (!m_SheelLink)
    {
        return false;
    }

    HRESULT hr = S_OK;
    WORD wHotkey = 0;
    hr = m_SheelLink->GetHotkey(&wHotkey);
    if (SUCCEEDED(hr))
    {
        bModifier = HIBYTE(wHotkey);
        bKey = LOBYTE(wHotkey);
    }

    return SUCCEEDED(hr);
}

WORD CLnkHelper::GetHotkey() const
{
    if (!m_SheelLink)
    {
        return 0;
    }

    HRESULT hr = S_OK;
    WORD wHotkey = 0;
    hr = m_SheelLink->GetHotkey(&wHotkey);
    if (SUCCEEDED(hr))
    {
        return wHotkey;
    }

    return 0;
}

bool CLnkHelper::SetHotkey(BYTE bModifier, BYTE bKey)
{
    if (!m_SheelLink)
    {
        return false;
    }

    HRESULT hr = S_OK;
    hr = m_SheelLink->SetHotkey(MAKEWORD(bKey, bModifier));
    return SUCCEEDED(hr);
}


bool CLnkHelper::SetHotkey(WORD wHotkey)
{
    if (!m_SheelLink)
    {
        return false;
    }

    HRESULT hr = S_OK;
    hr = m_SheelLink->SetHotkey(wHotkey);
    return SUCCEEDED(hr);
}

bool CLnkHelper::GetShowCmd(int& iShowCmd) const
{
    if (!m_SheelLink)
    {
        return false;
    }

    HRESULT hr = S_OK;
    hr = m_SheelLink->GetShowCmd(&iShowCmd);
    return SUCCEEDED(hr);
}

int CLnkHelper::CLnkHelper::GetShowCmd() const
{
    if (!m_SheelLink)
    {
        return 0;
    }

    HRESULT hr = S_OK;
    int iShowCmd = 0;
    hr = m_SheelLink->GetShowCmd(&iShowCmd);

    if (SUCCEEDED(hr))
    {
        return iShowCmd;
    }

    return 0;
}

bool CLnkHelper::SetShowCmd(int iShowCmd)
{
    if (!m_SheelLink)
    {
        return false;
    }

    HRESULT hr = S_OK;
    hr = m_SheelLink->SetShowCmd(iShowCmd);
    return SUCCEEDED(hr);
}

bool CLnkHelper::GetIconLocation(_tstring& IconPath, int& iIcon) const
{
    if (!m_SheelLink)
    {
        return false;
    }

    HRESULT hr = S_OK;
    TCHAR szBuf[MAX_PATH * 4] = { 0 };
    hr = m_SheelLink->GetIconLocation(szBuf, _countof(szBuf), &iIcon);
    if (SUCCEEDED(hr))
    {
        IconPath = szBuf;
    }

    return SUCCEEDED(hr);
}

_tstring CLnkHelper::GetIconLocation(int* piIcon/* = nullptr*/) const
{
    if (!m_SheelLink)
    {
        return _tstring();
    }

    HRESULT hr = S_OK;
    TCHAR szBuf[MAX_PATH * 4] = { 0 };
    int iIcon = 0;
    hr = m_SheelLink->GetIconLocation(szBuf, _countof(szBuf), &iIcon);
    if (SUCCEEDED(hr))
    {
        if (piIcon)
        {
            *piIcon = iIcon;
        }

        return szBuf;
    }

    return _tstring();
}

bool CLnkHelper::SetIconLocation(const _tstring& IconPath, int iIcon)
{
    if (!m_SheelLink)
    {
        return false;
    }

    HRESULT hr = S_OK;
    hr = m_SheelLink->SetIconLocation(IconPath.c_str(), iIcon);
    return SUCCEEDED(hr);
}

bool CLnkHelper::GetRelativePath(_tstring& strPathRel) const
{
    if (!m_SheelLink)
    {
        return false;
    }

    WIN32_FIND_DATA wfd = { 0 };
    TCHAR szBuf[MAX_PATH * 4] = { 0 };
    HRESULT hr = S_OK;
    hr = m_SheelLink->GetPath(szBuf, _countof(szBuf), &wfd, SLGP_RELATIVEPRIORITY);
    if (SUCCEEDED(hr))
    {
        strPathRel = szBuf;
    }

    return SUCCEEDED(hr);
}

_tstring CLnkHelper::GetRelativePath() const
{
    if (!m_SheelLink)
    {
        return _tstring();
    }

    WIN32_FIND_DATA wfd = { 0 };
    TCHAR szBuf[MAX_PATH * 4] = { 0 };
    HRESULT hr = S_OK;
    hr = m_SheelLink->GetPath(szBuf, _countof(szBuf), &wfd, SLGP_RELATIVEPRIORITY);
    if (SUCCEEDED(hr))
    {
        return szBuf;
    }

    return _tstring();
}

bool CLnkHelper::SetRelativePath(const _tstring& strRelativePath)
{
    if (!m_SheelLink)
    {
        return false;
    }

    HRESULT hr = S_OK;
    hr = m_SheelLink->SetRelativePath(strRelativePath.c_str(), 0);
    return SUCCEEDED(hr);
}

测试

main.cpp

#include <iostream>
#include <vector>
#include <map>
#include <stdarg.h>
#include <tchar.h>
#include <windows.h>
#include <thread>
#include <strsafe.h>
#include "Win32Utils/CLnkHelper.h"
#include "Win32Utils/CPathUtils.h"

int _tmain(int argc, LPCTSTR argv[])
{
    setlocale(LC_ALL, "");

    CLnkHelper obj;
    obj.Load(_T("123.lnk"));
    SHELL_LINK_INFO info = obj.GetInfo();
    obj.SetInfo(info);
    obj.Save(_T("123.lnk"));

    return 0;
}

 

 

 

 

  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值