-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathtargetlnk.h
83 lines (67 loc) · 1.59 KB
/
targetlnk.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#pragma once
#include "shlobj_core.h"
#include "strcvt.h"
#include "windows.h"
#include "wrl.h"
#include <string>
class CoInitializeHelper
{
public:
CoInitializeHelper()
{
CoInitializeEx(nullptr, COINIT_MULTITHREADED);
}
~CoInitializeHelper()
{
CoUninitialize();
}
};
inline HRESULT path_from_shortcut(const std::wstring &shortcut_filename, std::wstring &path)
{
Microsoft::WRL::ComPtr<IShellLinkW> shell_link;
CoInitializeHelper co_helper;
HRESULT hr = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&shell_link));
if (FAILED(hr))
{
return hr;
}
Microsoft::WRL::ComPtr<IPersistFile> persistFile; // = (IPersistFile *)shell_link;
hr = shell_link.As(&persistFile);
if (FAILED(hr))
{
return hr;
}
hr = persistFile->Load(shortcut_filename.c_str(), STGM_READ);
if (FAILED(hr))
{
return hr;
}
LPITEMIDLIST itemIdList{ NULL };
hr = shell_link->GetIDList(&itemIdList);
if (FAILED(hr))
{
return hr;
}
wchar_t target_path[MAX_PATH];
hr = E_FAIL;
if (SHGetPathFromIDList(itemIdList, target_path))
{
path = std::wstring(target_path);
hr = S_OK;
}
if (itemIdList != NULL)
{
CoTaskMemFree(itemIdList);
}
return hr;
}
inline std::string target_of_lnk(const std::string &lnk)
{
std::wstring path;
HRESULT hr = path_from_shortcut(strcvt::CvtLocalStringToWString(lnk), path);
if (SUCCEEDED(hr))
{
return strcvt::CvtWStringToLocalString(path);
}
return "";
}