diff --git a/appinstaller/appinstaller.rc b/appinstaller/appinstaller.rc
index dd83c8f..3303a6f 100644
Binary files a/appinstaller/appinstaller.rc and b/appinstaller/appinstaller.rc differ
diff --git a/appinstaller/appinstaller.vcxproj b/appinstaller/appinstaller.vcxproj
index d6f58c1..caf425b 100644
--- a/appinstaller/appinstaller.vcxproj
+++ b/appinstaller/appinstaller.vcxproj
@@ -96,6 +96,7 @@
Windows
true
shlwapi.lib;version.lib;dwmapi.lib;$(OutDir)pkgread.lib;$(OutDir)pkgmgr.lib;$(OutDir)certmgr.lib;$(OutDir)priformatcli.lib;$(OutDir)notice.lib;%(AdditionalDependencies)
+ RequireAdministrator
app.manifest
@@ -132,6 +133,7 @@
true
true
shlwapi.lib;version.lib;dwmapi.lib;$(OutDir)pkgread.lib;$(OutDir)pkgmgr.lib;$(OutDir)certmgr.lib;$(OutDir)priformatcli.lib;$(OutDir)notice.lib;%(AdditionalDependencies)
+ RequireAdministrator
app.manifest
@@ -167,6 +169,7 @@
+
@@ -190,6 +193,7 @@
+
diff --git a/appinstaller/appinstaller.vcxproj.filters b/appinstaller/appinstaller.vcxproj.filters
index f6c5ca5..9ac7b42 100644
--- a/appinstaller/appinstaller.vcxproj.filters
+++ b/appinstaller/appinstaller.vcxproj.filters
@@ -87,6 +87,9 @@
头文件
+
+ 头文件
+
diff --git a/appinstaller/appxinfo.h b/appinstaller/appxinfo.h
index b047d6b..13a94d5 100644
--- a/appinstaller/appxinfo.h
+++ b/appinstaller/appxinfo.h
@@ -12,6 +12,7 @@
#include "nstring.h"
#include "priformatcli.h"
#include "pkgread.h"
+
static std::string ws2utf8 (const std::wstring &ws)
{
std::wstring_convert > conv;
@@ -37,7 +38,7 @@ struct pkginfo
// AppxBundle ԶԴΪܰ AppxBundleԴӦðһͬ AppxBundle
// PKGROLE_* ꡣ
WORD role = 0;
- struct
+ struct
{
std::wstring name,
publisher,
@@ -47,6 +48,39 @@ struct pkginfo
VERSION version, realver;
DWORD architecture;
} identity;
+ // x86: 0
+ // x64: 9
+ // Arm: 5
+ // Neutral: 11
+ // Arm64: 12
+ std::set get_architectures () const
+ {
+ std::set ret;
+ switch (type)
+ {
+ case PKGTYPE_APPX: {
+ switch (identity.architecture)
+ {
+ case PKG_ARCHITECTURE_X86: ret.insert (0); break;
+ case PKG_ARCHITECTURE_X64: ret.insert (9); break;
+ case PKG_ARCHITECTURE_ARM: ret.insert (5); break;
+ case PKG_ARCHITECTURE_ARM64: ret.insert (12); break;
+ case PKG_ARCHITECTURE_NEUTRAL: ret.insert (11); break;
+ }
+ } break;
+ case PKGTYPE_BUNDLE: {
+ if (identity.architecture & PKG_ARCHITECTURE_X86) ret.insert (0);
+ if (identity.architecture & PKG_ARCHITECTURE_X64) ret.insert (9);
+ if (identity.architecture & PKG_ARCHITECTURE_ARM) ret.insert (5);
+ if (identity.architecture & PKG_ARCHITECTURE_ARM64) ret.insert (12);
+ // ڼܹʷչԭǶԵġ
+ if (identity.architecture & (PKG_ARCHITECTURE_X86 | PKG_ARCHITECTURE_X64 | PKG_ARCHITECTURE_ARM))
+ { ret.clear (); ret.insert (11); }
+ if (identity.architecture & PKG_ARCHITECTURE_NEUTRAL) { ret.clear (); ret.insert (11); }
+ }
+ }
+ return ret;
+ }
struct
{
std::wstring display_name;
@@ -91,6 +125,7 @@ struct pkginfo
struct
{
VERSION os_min_version, os_max_version_tested;
+ std::wstring os_min_version_description, os_max_version_tested_description;
} prerequisites;
static pkginfo parse (const std::wstring &filepath)
{
@@ -128,6 +163,8 @@ struct pkginfo
auto prer = pread.get_prerequisites ();
pkg.prerequisites.os_min_version = prer.os_min_version ();
pkg.prerequisites.os_max_version_tested = prer.os_max_version_tested ();
+ pkg.prerequisites.os_min_version_description = prer.os_min_version_description ();
+ pkg.prerequisites.os_max_version_tested_description = prer.os_max_version_tested_description ();
}
{
auto apps = pread.get_applications ();
@@ -299,10 +336,12 @@ struct pkginfo
Value obj (kObjectType);
obj.AddMember ("os_min_version", ver_to_json (prerequisites.os_min_version, alloc), alloc);
obj.AddMember ("os_max_version_tested", ver_to_json (prerequisites.os_max_version_tested, alloc), alloc);
+ obj.AddMember ("os_min_version_description", Value (ws2utf8 (prerequisites.os_min_version_description).c_str (), alloc), alloc);
+ obj.AddMember ("os_max_version_tested_description", Value (ws2utf8 (prerequisites.os_max_version_tested_description).c_str (), alloc), alloc);
doc.AddMember ("prerequisites", obj, alloc);
}
StringBuffer buffer;
- Writer writer (buffer);
+ Writer writer (buffer);
doc.Accept (writer);
std::string utf8 = buffer.GetString ();
std::wstring_convert > conv;
diff --git a/appinstaller/cmdargs.h b/appinstaller/cmdargs.h
index 1a14889..9837544 100644
--- a/appinstaller/cmdargs.h
+++ b/appinstaller/cmdargs.h
@@ -7,6 +7,7 @@
#include "rctools.h"
#include "filepath.h"
#include "raii.h"
+#include "resource.h"
// ǰ統ǰΪ-"/"ʱҿ롰-args"/args""args" ǵЧ
#define CMDARG_IGNOREPREFIXS 0b001
@@ -24,12 +25,14 @@ struct cmdarg
std::wstring description; // ɰı
DWORD flags; // ־
};
-#define CMDARG_PREFIXS_DEFAULT {L"-", L"/"}
+#define CMDARG_PREFIXS_DEFAULT {L"/", L"-"}
#define CMDARG_POSTFIXS_DEFAULT {}
+#define CMDARG_HELP {CMDARG_PREFIXS_DEFAULT, {L"?", L"help", L"h"}, CMDARG_PREFIXS_DEFAULT, L"help", GetRCStringSW (IDS_CMDPARAM_HELP), CMDARG_IGNOREPREFIXS}
std::vector 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}
+ CMDARG_HELP,
+ {CMDARG_PREFIXS_DEFAULT, {L"silent", L"quiet", L"passive"}, CMDARG_POSTFIXS_DEFAULT, L"silent", GetRCStringSW (IDS_CMDPARAM_SILENT), CMDARG_IGNOREPREFIXS},
+ {CMDARG_PREFIXS_DEFAULT, {L"verysilent", L"veryquiet"}, CMDARG_POSTFIXS_DEFAULT, L"verysilent", GetRCStringSW (IDS_CMDPARAM_VERYSILENT), CMDARG_IGNOREPREFIXS},
+ {CMDARG_PREFIXS_DEFAULT, {L"multiple", L"filelist"}, {L"="}, L"multiple", GetRCStringSW (IDS_CMDPARAM_MULTIPLE), CMDARG_IGNOREPREFIXS | CMDARG_ENABLEPARAMS}
};
bool IsFile (const std::wstring &path)
{
diff --git a/appinstaller/localeex.h b/appinstaller/localeex.h
new file mode 100644
index 0000000..e19646b
--- /dev/null
+++ b/appinstaller/localeex.h
@@ -0,0 +1,248 @@
+#pragma once
+#include
+#include
+#include "typestrans.h"
+
+#undef GetLocaleInfo
+std::string GetLocaleInfoA (LCID code, LCTYPE type)
+{
+ char buf [LOCALE_NAME_MAX_LENGTH] = {0};
+ GetLocaleInfoA (code, type, buf, LOCALE_NAME_MAX_LENGTH);
+ return buf;
+}
+std::wstring GetLocaleInfoW (LCID code, LCTYPE type)
+{
+ WCHAR buf [LOCALE_NAME_MAX_LENGTH] = {0};
+ GetLocaleInfoW (code, type, buf, LOCALE_NAME_MAX_LENGTH);
+ return buf;
+}
+void GetLocaleInfo (LCID code, LCTYPE type, std::wstring &output)
+{
+ output = GetLocaleInfoW (code, type);
+}
+void GetLocaleInfo (LCID code, LCTYPE type, std::string &output)
+{
+ output = GetLocaleInfoA (code, type);
+}
+int GetLocaleInfoEx (std::wstring lpLocaleName, LCTYPE type, std::wstring &output)
+{
+ WCHAR buf [LOCALE_NAME_MAX_LENGTH] = {0};
+ int res = GetLocaleInfoEx (lpLocaleName.c_str (), type, buf, LOCALE_NAME_MAX_LENGTH);
+ if (&output) output = std::wstring (buf);
+ return res;
+}
+
+#undef SetLocaleInfo
+BOOL SetLocaleInfoA (LCID code, LCTYPE type, const std::string &lcData)
+{
+ return SetLocaleInfoA (code, type, lcData.c_str ());
+}
+BOOL SetLocaleInfoW (LCID code, LCTYPE type, const std::wstring &lcData)
+{
+ return SetLocaleInfoW (code, type, lcData.c_str ());
+}
+BOOL SetLocaleInfo (LCID code, LCTYPE type, const std::wstring &lcData)
+{
+ return SetLocaleInfoW (code, type, lcData);
+}
+BOOL SetLocaleInfo (LCID code, LCTYPE type, const std::string &lcData)
+{
+ return SetLocaleInfoA (code, type, lcData);
+}
+
+std::string GetLocaleRestrictedCodeFromLcidA (LCID lcid)
+{
+ return GetLocaleInfoA (lcid, 89);
+}
+std::wstring GetLocaleRestrictedCodeFromLcidW (LCID lcid)
+{
+ return GetLocaleInfoW (lcid, 89);
+}
+void GetLocaleRestrictedCodeFromLcid (LCID lcid, std::string &ret)
+{
+ ret = GetLocaleRestrictedCodeFromLcidA (lcid);
+}
+void GetLocaleRestrictedCodeFromLcid (LCID lcid, std::wstring &ret)
+{
+ ret = GetLocaleRestrictedCodeFromLcidW (lcid);
+}
+
+std::string GetLocaleElaboratedCodeFromLcidA (LCID lcid)
+{
+ return GetLocaleInfoA (lcid, 90);
+}
+std::wstring GetLocaleElaboratedCodeFromLcidW (LCID lcid)
+{
+ return GetLocaleInfoW (lcid, 90);
+}
+void GetLocaleElaboratedCodeFromLcid (LCID lcid, std::wstring &ret)
+{
+ ret = GetLocaleElaboratedCodeFromLcidW (lcid);
+}
+void GetLocaleElaboratedCodeFromLcid (LCID lcid, std::string &ret)
+{
+ ret = GetLocaleElaboratedCodeFromLcidA (lcid);
+}
+
+LCID LocaleCodeToLcidW (const std::wstring &localeCode)
+{
+#if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0600)
+ try
+ {
+ BYTE buf [LOCALE_NAME_MAX_LENGTH * sizeof (WCHAR)] = {0};
+ int res = GetLocaleInfoEx (localeCode.c_str (), LOCALE_RETURN_NUMBER | LOCALE_ILANGUAGE, (LPWSTR)buf, LOCALE_NAME_MAX_LENGTH);
+ LCID lcid = *((LCID *)buf);
+ return lcid;
+ }
+ catch (const std::exception &e) {}
+ return LocaleNameToLCID (localeCode.c_str (), 0);
+#else
+ return LocaleNameToLCID (localeCode.c_str (), 0);
+#endif
+}
+LCID LocaleCodeToLcidA (const std::string &localeCode)
+{
+ std::wstring lcWide = StringToWString (std::string (localeCode));
+ return LocaleCodeToLcidW (lcWide.c_str ());
+}
+LCID LocaleCodeToLcid (const std::wstring &loccode)
+{
+ return LocaleCodeToLcidW (loccode.c_str ());
+}
+LCID LocaleCodeToLcid (const std::string &loccode)
+{
+ return LocaleCodeToLcidA (loccode.c_str ());
+}
+
+std::string GetLocaleRestrictedCodeA (LPCSTR lc)
+{
+ return GetLocaleInfoA (LocaleCodeToLcidA (lc), 89);
+}
+std::string GetLocaleRestrictedCodeA (const std::string &lc)
+{
+ return GetLocaleInfoA (LocaleCodeToLcidA (lc.c_str ()), 89);
+}
+std::wstring GetLocaleRestrictedCodeW (LPCWSTR lc)
+{
+ return GetLocaleInfoW (LocaleCodeToLcidW (lc), 89);
+}
+std::wstring GetLocaleRestrictedCodeW (const std::wstring &lc)
+{
+ return GetLocaleInfoW (LocaleCodeToLcidW (lc.c_str ()), 89);
+}
+std::wstring GetLocaleRestrictedCode (const std::wstring &lc) { return GetLocaleRestrictedCodeW (lc); }
+std::string GetLocaleRestrictedCode (const std::string &lc) { return GetLocaleRestrictedCodeA (lc); }
+
+std::string GetLocaleElaboratedCodeA (LPCSTR lc)
+{
+ return GetLocaleInfoA (LocaleCodeToLcidA (lc), 90);
+}
+std::string GetLocaleElaboratedCodeA (const std::string &lc)
+{
+ return GetLocaleInfoA (LocaleCodeToLcidA (lc.c_str ()), 90);
+}
+std::wstring GetLocaleElaboratedCodeW (LPCWSTR lc)
+{
+ return GetLocaleInfoW (LocaleCodeToLcidW (lc), 90);
+}
+std::wstring GetLocaleElaboratedCodeW (const std::wstring &lc)
+{
+ return GetLocaleInfoW (LocaleCodeToLcidW (lc.c_str ()), 90);
+}
+std::wstring GetLocaleElaboratedCode (const std::wstring &lc) { return GetLocaleElaboratedCodeW (lc); }
+std::string GetLocaleElaboratedCode (const std::string &lc) { return GetLocaleElaboratedCodeA (lc); }
+
+std::string LcidToLocaleCodeA (LCID lcid, char divide = '-')
+{
+ return GetLocaleRestrictedCodeFromLcidA (lcid) + divide + GetLocaleElaboratedCodeFromLcidA (lcid);
+}
+std::wstring LcidToLocaleCodeW (LCID lcid, WCHAR divide = L'-')
+{
+#if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0600)
+ try
+ {
+ WCHAR buf [LOCALE_NAME_MAX_LENGTH] = {0};
+ LCIDToLocaleName (lcid, buf, LOCALE_NAME_MAX_LENGTH, 0);
+ return buf;
+ }
+ catch (const std::exception &e) {}
+ return GetLocaleRestrictedCodeFromLcidW (lcid) + divide + GetLocaleElaboratedCodeFromLcidW (lcid);
+#else
+ return GetLocaleRestrictedCodeFromLcidW (lcid) + divide + GetLocaleElaboratedCodeFromLcidW (lcid);
+#endif
+}
+std::wstring LcidToLocaleCode (LCID lcid, WCHAR divide = L'-') { return LcidToLocaleCodeW (lcid, divide); }
+std::string LcidToLocaleCode (LCID lcid, char divide = '-') { return LcidToLocaleCodeA (lcid, divide); }
+
+std::wstring GetUserDefaultLocaleName ()
+{
+#if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0600)
+ try
+ {
+ WCHAR buf [LOCALE_NAME_MAX_LENGTH] = {0};
+ GetUserDefaultLocaleName (buf, LOCALE_NAME_MAX_LENGTH);
+ return buf;
+ }
+ catch (const std::exception &e) {}
+ return LcidToLocaleCodeW (GetUserDefaultLCID ());
+#else
+ return LcidToLocaleCodeW (GetUserDefaultLCID ());
+#endif
+}
+std::wstring GetSystemDefaultLocaleName ()
+{
+#if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0600)
+ try
+ {
+ WCHAR buf [LOCALE_NAME_MAX_LENGTH] = {0};
+ GetSystemDefaultLocaleName (buf, LOCALE_NAME_MAX_LENGTH);
+ return buf;
+ }
+ catch (const std::exception &e) {}
+ return LcidToLocaleCodeW (GetSystemDefaultLCID ());
+#else
+ return LcidToLocaleCodeW (GetSystemDefaultLCID ());
+#endif
+}
+
+std::wstring GetComputerLocaleCodeW ()
+{
+#if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0600)
+ {
+ try
+ {
+ {
+ LCID lcid = GetThreadLocale ();
+ std::wstring tmp = LcidToLocaleCodeW (lcid);
+ if (lcid && tmp.length () > 1) return tmp;
+ }
+ {
+ WCHAR buf [LOCALE_NAME_MAX_LENGTH] = {0};
+ GetUserDefaultLocaleName (buf, LOCALE_NAME_MAX_LENGTH);
+ if (lstrlenW (buf)) return buf;
+ }
+ {
+ WCHAR buf [LOCALE_NAME_MAX_LENGTH] = {0};
+ GetSystemDefaultLocaleName (buf, LOCALE_NAME_MAX_LENGTH);
+ return buf;
+ }
+ }
+ catch (const std::exception &e) {}
+ LCID lcid = GetThreadLocale ();
+ if (!lcid) lcid = GetUserDefaultLCID ();
+ if (!lcid) lcid = GetSystemDefaultLCID ();
+ return LcidToLocaleCodeW (lcid);
+ }
+#else
+ {
+ LCID lcid = GetThreadLocale ();
+ if (!lcid) lcid = GetUserDefaultLCID ();
+ if (!lcid) lcid = GetSystemDefaultLCID ();
+ return LcidToLocaleCodeW (lcid);
+ }
+#endif
+}
+bool LocaleNameCompare (const std::wstring &left, const std::wstring &right)
+{
+ return std::wnstring::equals (left, right) || LocaleCodeToLcidW (left) == LocaleCodeToLcidW (right);
+}
diff --git a/appinstaller/main.cpp b/appinstaller/main.cpp
index cd52474..6e900a0 100644
--- a/appinstaller/main.cpp
+++ b/appinstaller/main.cpp
@@ -5,6 +5,9 @@
#include
#include
#include
+#include
+#include
+#include
#include "cmdargs.h"
#include "themeinfo.h"
#include "mpstr.h"
@@ -14,6 +17,10 @@
#include "ieshell.h"
#include "resmap.h"
#include "appxinfo.h"
+#include "localeex.h"
+#include "pkgmgr.h"
+#include "notice.h"
+#include "certmgr.h"
using namespace System;
using namespace System::Runtime::InteropServices;
@@ -24,6 +31,13 @@ using namespace System::Runtime::InteropServices;
#define DEBUGMODE false
#endif
#define JS_SAFE [MarshalAs (UnmanagedType::SafeArray, SafeArraySubType = VarEnum::VT_VARIANT)]
+enum class CMDPARAM: DWORD
+{
+ NONE = 0b000,
+ SILENT = 0b001,
+ VERYSILENT = 0b011,
+ MULTIPLE = 0b100
+};
LPCWSTR g_lpAppId = L"Microsoft.DesktopAppInstaller";
auto &g_identity = g_lpAppId;
@@ -49,8 +63,21 @@ resxmldoc g_scaleres (
CombinePath (GetProgramRootDirectoryW (), L"VisualElementsManifest.xml")
);
WORD g_wcmdflags = 0;
-std::set g_pkgfiles;
+std::vector g_pkgfiles;
std::vector g_pkginfo;
+std::wstring g_lastfile;
+struct package_installresult
+{
+ HRESULT result = S_OK;
+ std::wstring error;
+ std::wstring reason;
+ bool succeeded () const { return SUCCEEDED (result); }
+ bool failed () const { return FAILED (result); }
+ package_installresult (HRESULT result, const std::wstring &err, const std::wstring &msg): result (result), reason (msg), error (err) {}
+ package_installresult (HRESULT result, const std::wstring &msg): result (result), reason (msg) {}
+ package_installresult () = default;
+};
+std::map g_pkgresult;
HRESULT GetWebBrowser2Interface (System::Windows::Forms::WebBrowser ^fwb, IWebBrowser2 **output)
{
@@ -245,36 +272,167 @@ public ref class SplashForm: public System::Windows::Forms::Form
}
}
};
-bool ReadPackagesTask ()
+System::String ^FormatString (System::String ^fmt, ... array