mirror of
https://github.com/modernw/App-Installer-For-Windows-8.x-Reset.git
synced 2026-06-20 14:10:59 +10:00
Update Shell.
This commit is contained in:
@@ -0,0 +1,161 @@
|
||||
#pragma once
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include "nstring.h"
|
||||
#include "rctools.h"
|
||||
#include "filepath.h"
|
||||
#include "raii.h"
|
||||
|
||||
// 允许忽视命令行前缀。如当命令行前缀为“-”"/"时,且开启此项,则输入“-args”与"/args"和"args" 是等效的
|
||||
#define CMDARG_IGNOREPREFIXS 0b001
|
||||
// 允许参数后跟着值,如“/args=file”,但要求必须配置后缀,且是有效的字符
|
||||
#define CMDARG_ENABLEPARAMS 0b010
|
||||
// 当 CMDARG_ENABLEPARAMS 开启时允许参数为空。如 “/args=file”和"/args"都是允许的
|
||||
#define CMDARG_IGNOREPARAMS 0b100
|
||||
// 命令行参数
|
||||
struct cmdarg
|
||||
{
|
||||
std::vector <std::wstring> prefixs; // 允许无前缀(长度为 0)
|
||||
std::vector <std::wstring> commands; // 参数(长度不能为 0,不能为空)
|
||||
std::vector <std::wstring> postfixs; // 允许无后缀(长度为 0)
|
||||
std::wstring uniquelabel; // 唯一标识,参数名
|
||||
std::wstring description; // 描述,用于生成帮助文本
|
||||
DWORD flags; // 标志
|
||||
};
|
||||
#define CMDARG_PREFIXS_DEFAULT {L"-", L"/"}
|
||||
#define CMDARG_POSTFIXS_DEFAULT {}
|
||||
std::vector <cmdarg> g_argslist = {
|
||||
{CMDARG_PREFIXS_DEFAULT, {L"silent", L"quiet", L"passive"}, CMDARG_POSTFIXS_DEFAULT, L"silent", GetRCStringSW (0), CMDARG_IGNOREPREFIXS},
|
||||
{CMDARG_PREFIXS_DEFAULT, {L"verysilent", L"veryquiet"}, CMDARG_POSTFIXS_DEFAULT, L"verysilent", GetRCStringSW (0), CMDARG_IGNOREPREFIXS},
|
||||
{CMDARG_PREFIXS_DEFAULT, {L"multiple", L"filelist"}, {L"="}, L"multiple", GetRCStringSW (0), CMDARG_IGNOREPREFIXS | CMDARG_ENABLEPARAMS}
|
||||
};
|
||||
bool IsFile (const std::wstring &path)
|
||||
{
|
||||
return IsPathExists (path);
|
||||
}
|
||||
bool IsURI (const std::wstring &str)
|
||||
{
|
||||
try
|
||||
{
|
||||
auto uristr = gcnew System::String (str.c_str ());
|
||||
auto uri = gcnew System::Uri (uristr);
|
||||
return uri != nullptr;
|
||||
}
|
||||
catch (...) { return false; }
|
||||
}
|
||||
enum class paramtype
|
||||
{
|
||||
string,
|
||||
file,
|
||||
uri
|
||||
};
|
||||
struct cmdkey
|
||||
{
|
||||
std::wnstring key; // 键
|
||||
paramtype type; // 键类型,当传入的参数是存在的文件路径时(如“C:\1.txt”)则键的类型为文件。同理也可设置为 uri
|
||||
operator std::wnstring () { return key; }
|
||||
operator LPCWSTR () { return key.c_str (); }
|
||||
cmdkey (const std::wstring &k): key (k)
|
||||
{
|
||||
if (IsFile (k)) type = paramtype::file;
|
||||
else if (IsURI (k)) type = paramtype::uri;
|
||||
else type = paramtype::string;
|
||||
}
|
||||
cmdkey (const std::wstring &k, paramtype pt): key (k), type (pt) {}
|
||||
bool operator == (const cmdkey &r) const { return key == r.key; }
|
||||
bool operator > (const cmdkey &r) const { return key > r.key; }
|
||||
bool operator < (const cmdkey &r) const { return key < r.key; }
|
||||
};
|
||||
struct cmdvalue
|
||||
{
|
||||
std::wstring value; // 值
|
||||
paramtype type;
|
||||
bool isnull; // 当参数不支持跟着值时,或允许时值为空时设置为真。
|
||||
};
|
||||
// 对于从命令行获取到的 argv 和 argc,argc 最小为 1,argv 的第一个元素指向程序。所以 startpos 为 1。
|
||||
void ParseCmdArgs (LPWSTR *argv, DWORD argc, std::map <cmdkey, cmdvalue> &parseresult, DWORD startpos = 1)
|
||||
{
|
||||
for (size_t i = startpos; i < argc; i ++)
|
||||
{
|
||||
std::wnstring arg = argv [i];
|
||||
arg = arg.trim ();
|
||||
if (IsFile (arg)) parseresult [cmdkey (arg, paramtype::file)] = cmdvalue {L"", paramtype::file, true};
|
||||
else if (IsURI (arg)) parseresult [cmdkey (arg, paramtype::uri)] = cmdvalue {L"", paramtype::uri, true};
|
||||
else
|
||||
{
|
||||
for (auto &it : g_argslist)
|
||||
{
|
||||
std::set <std::wnstring> prefixs;
|
||||
for (auto &it_s : it.prefixs) prefixs.insert (it_s);
|
||||
int cmdhead = -1;
|
||||
for (auto &it_s : prefixs)
|
||||
{
|
||||
auto plen = GetNormalizeStringLength (it_s);
|
||||
auto parg = GetStringLeft (arg, plen);
|
||||
if (it_s == parg) { cmdhead = plen; break; }
|
||||
}
|
||||
if (((it.flags & CMDARG_IGNOREPREFIXS) || !it.prefixs.size () || !prefixs.size ()) && cmdhead < 0)
|
||||
{
|
||||
if (!arg.length ()) continue;
|
||||
cmdhead = 0;
|
||||
}
|
||||
if (cmdhead < 0) continue;
|
||||
int postfixhead = -1;
|
||||
std::set <std::wnstring> commands;
|
||||
for (auto &it_s : it.commands) if (GetNormalizeStringLength (it_s)) commands.insert (it_s);
|
||||
if (commands.empty ()) continue;
|
||||
for (auto &it_s : commands)
|
||||
{
|
||||
auto clen = it_s.length ();
|
||||
auto carg = GetStringLeft (arg.substr (cmdhead), clen);
|
||||
if (it_s == carg) { postfixhead = cmdhead + clen; }
|
||||
}
|
||||
if (postfixhead < 0) continue;
|
||||
std::set <std::wnstring> postfixs;
|
||||
for (auto &it_s : it.postfixs) if (GetNormalizeStringLength (it_s)) postfixs.insert (it_s);
|
||||
if (!(it.flags & CMDARG_ENABLEPARAMS)) it.postfixs.clear ();
|
||||
if ((it.flags & CMDARG_ENABLEPARAMS) && postfixs.size ())
|
||||
{
|
||||
int valuehead = -1;
|
||||
auto rightpart = StringTrim (GetStringRight (arg, lstrlenW (arg.c_str ()) - postfixhead));
|
||||
if (it.flags & CMDARG_IGNOREPARAMS)
|
||||
{
|
||||
if (!rightpart.length ()) { parseresult [cmdkey (it.uniquelabel, paramtype::string)] = cmdvalue {L"", paramtype::string, true}; break; }
|
||||
}
|
||||
for (auto &it_s : postfixs)
|
||||
{
|
||||
auto plen = it_s.length ();
|
||||
auto parg = GetStringLeft (rightpart, plen);
|
||||
if (it_s == parg) { valuehead = plen; break; }
|
||||
}
|
||||
if (valuehead < 0) continue;
|
||||
else
|
||||
{
|
||||
auto value = rightpart.substr (valuehead);
|
||||
paramtype ptype = paramtype::string;
|
||||
if (IsFile (value)) ptype = paramtype::file;
|
||||
else if (IsURI (StringTrim (value))) ptype = paramtype::uri;
|
||||
parseresult [cmdkey (it.uniquelabel, paramtype::string)] = cmdvalue {value, ptype, false};
|
||||
}
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
parseresult [cmdkey (it.uniquelabel, paramtype::string)] = cmdvalue {L"", paramtype::string, true};
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
void ParseCmdLine (LPCWSTR lpCommandLine, std::map <cmdkey, cmdvalue> &parseresult)
|
||||
{
|
||||
int argc = 0;
|
||||
LPWSTR *alpstr = CommandLineToArgvW (lpCommandLine, &argc);
|
||||
destruct relt ([&alpstr] () {
|
||||
if (alpstr) LocalFree (alpstr);
|
||||
});
|
||||
ParseCmdArgs (alpstr, argc, parseresult, 0);
|
||||
}
|
||||
Reference in New Issue
Block a user