/
portable.h
117 lines (101 loc) · 2.99 KB
/
portable.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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#ifndef PORTABLE_H_
#define PORTABLE_H_
std::wstring QuoteSpaceIfNeeded(const std::wstring& str) {
if (str.find(L' ') == std::wstring::npos)
return std::move(str);
std::wstring escaped(L"\"");
for (auto c : str) {
if (c == L'"')
escaped += L'"';
escaped += c;
}
escaped += L'"';
return std::move(escaped);
}
std::wstring JoinArgsString(std::vector<std::wstring> lines,
const std::wstring& delimiter) {
std::wstring text;
bool first = true;
for (auto& line : lines) {
if (!first)
text += delimiter;
else
first = false;
text += QuoteSpaceIfNeeded(line);
}
return text;
}
// Construct new command line with portable mode.
std::wstring GetCommand(LPWSTR param) {
std::vector<std::wstring> args;
int argc;
LPWSTR* argv = CommandLineToArgvW(param, &argc);
int insert_pos = 0;
for (int i = 0; i < argc; ++i) {
if (std::wstring(argv[i]).find(L"--") != std::wstring::npos ||
std::wstring(argv[i]).find(L"--single-argument") !=
std::wstring::npos) {
break;
}
insert_pos = i;
}
for (int i = 0; i < argc; ++i) {
// Preserve former arguments.
if (i)
args.push_back(argv[i]);
// Append new arguments.
if (i == insert_pos) {
args.push_back(L"--portable");
{
auto userdata = GetUserDataDir();
args.push_back(L"--user-data-dir=" + userdata);
}
{
auto diskcache = GetDiskCacheDir();
args.push_back(L"--disk-cache-dir=" + diskcache);
}
// Get the command line and append parameters
// Intercept and split the parameters starting with each --,
// and then args.push_back multiple times
// Repeat the above process until the -- sign no longer exists in the
// string
{
auto cr_command_line = GetCrCommandLine();
std::wstring temp = cr_command_line;
while (true) {
auto pos = temp.find(L"--");
if (pos == std::wstring::npos) {
break;
} else {
auto pos2 = temp.find(L" --", pos);
if (pos2 == std::wstring::npos) {
args.push_back(temp);
break;
} else {
args.push_back(temp.substr(pos, pos2 - pos));
temp = temp.substr(0, pos) + temp.substr(pos2 + 1);
}
}
}
}
}
}
LocalFree(argv);
return JoinArgsString(args, L" ");
}
void Portable(LPWSTR param) {
wchar_t path[MAX_PATH];
::GetModuleFileName(nullptr, path, MAX_PATH);
std::wstring args = GetCommand(param);
SHELLEXECUTEINFO sei = {0};
sei.cbSize = sizeof(SHELLEXECUTEINFO);
sei.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI;
sei.lpVerb = L"open";
sei.lpFile = path;
sei.nShow = SW_SHOWNORMAL;
sei.lpParameters = args.c_str();
if (ShellExecuteEx(&sei)) {
ExitProcess(0);
}
}
#endif // PORTABLE_H_