mirror of
https://github.com/modernw/AppInstallerForWin8.git
synced 2026-04-11 16:57:18 +10:00
Updates for WebUI:
· [Important] Fixed the destruction issue with PriReader (caused by incorrect pointer types leading to unexecuted object destruction tasks). · [Important] Added a program execution selection interface for packages containing multiple applications (still using WebUI). Issue: Since the selection window is set to close when losing focus, checking the "Launch when ready" option after successful installation causes the pop-up window to disappear when a Toast notification appears (due to focus loss). Currently, the selection window can only be displayed by clicking a button. · [Optimization] Reduced the creation of PriReader objects to lower memory and storage consumption. (Translated by DeepSeek)
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
// Microsoft Visual C++ generated resource script.
|
||||
//
|
||||
#include <Windows.h>
|
||||
#include "resource.h"
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// 中文(简体,中国) resources
|
||||
@@ -115,8 +114,8 @@ IDR_MANIFEST1 RT_MANIFEST "res/manifest.xml"
|
||||
//
|
||||
|
||||
IDR_VERSION_ZH_CN VERSIONINFO
|
||||
FILEVERSION 1,0,1,7
|
||||
PRODUCTVERSION 1,0,1,7
|
||||
FILEVERSION 1,0,1,9
|
||||
PRODUCTVERSION 1,0,1,9
|
||||
FILEFLAGSMASK 0x0L
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@@ -133,9 +132,9 @@ BEGIN
|
||||
BEGIN
|
||||
VALUE "CompanyName", "Bruce Winter"
|
||||
VALUE "FileDescription", "应用安装程序"
|
||||
VALUE "FileVersion", "1.0.1.7"
|
||||
VALUE "FileVersion", "1.0.1.9"
|
||||
VALUE "LegalCopyright", "\\xA9Bruce Winter. All rights reserved."
|
||||
VALUE "ProductVersion", "1.0.1.7"
|
||||
VALUE "ProductVersion", "1.0.1.9"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
@@ -145,8 +144,8 @@ BEGIN
|
||||
END
|
||||
|
||||
IDR_VERSION_EN_US VERSIONINFO
|
||||
FILEVERSION 1,0,1,7
|
||||
PRODUCTVERSION 1,0,1,7
|
||||
FILEVERSION 1,0,1,9
|
||||
PRODUCTVERSION 1,0,1,9
|
||||
FILEFLAGSMASK 0x0L
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@@ -163,9 +162,9 @@ BEGIN
|
||||
BEGIN
|
||||
VALUE "CompanyName", "Bruce Winter"
|
||||
VALUE "FileDescription", "App Installer"
|
||||
VALUE "FileVersion", "1.0.1.7"
|
||||
VALUE "FileVersion", "1.0.1.9"
|
||||
VALUE "LegalCopyright", "\\xA9Bruce Winter. All rights reserved."
|
||||
VALUE "ProductVersion", "1.0.1.7"
|
||||
VALUE "ProductVersion", "1.0.1.9"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
@@ -239,6 +238,9 @@ BEGIN
|
||||
PAGE_1_APP "Microsoft Store 应用"
|
||||
PAGE_2_LOADING "请稍候..."
|
||||
PAGE_2_INSTALLING "正在安装 %d%%"
|
||||
APPLIST_WINTITLE "应用选择列表"
|
||||
APPLIST_TITLE "你要从哪个应用开始?"
|
||||
APPLIST_BUTTON_CANCEL "取消"
|
||||
CLHELP_1 "命令行参数说明:\n\n"
|
||||
CLHELP_2 "\t/?, /Help\n\t显示帮助窗口 (命令行参数说明)\n\n"
|
||||
CLHELP_3 "\t/DisableFrame\n\t禁止使用自绘的窗口边框\n\n"
|
||||
@@ -404,6 +406,9 @@ BEGIN
|
||||
PAGE_1_APP "Microsoft Store App"
|
||||
PAGE_2_LOADING "Please wait..."
|
||||
PAGE_2_INSTALLING "Installing %d%%"
|
||||
APPLIST_WINTITLE "App Select List"
|
||||
APPLIST_TITLE "Which app do you want to start with?"
|
||||
APPLIST_BUTTON_CANCEL "Cancel"
|
||||
CLHELP_1 "Usage:\n\n"
|
||||
CLHELP_2 "\t/?, /Help\n\tDisplay help window (command line parameter description).\n\n"
|
||||
CLHELP_3 "\t/DisableFrame\n\tDisable the use of self-drawn window borders.\n\n"
|
||||
|
||||
@@ -138,6 +138,11 @@
|
||||
<AdditionalDependencies>shlwapi.lib;dwmapi.lib;crypt32.lib;$(OutDir)PackageManager.lib;$(OutDir)AppLauncher.lib;$(OutDir)Base64Img.lib;$(OutDir)ToastNotification.lib;$(OutDir)PriReader2.lib;$(OutDir)CertificateManager.lib</AdditionalDependencies>
|
||||
<UACExecutionLevel>RequireAdministrator</UACExecutionLevel>
|
||||
</Link>
|
||||
<Manifest>
|
||||
<AdditionalManifestFiles>app.manifest %(AdditionalManifestFiles)</AdditionalManifestFiles>
|
||||
<InputResourceManifests>
|
||||
</InputResourceManifests>
|
||||
</Manifest>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
|
||||
<ClCompile>
|
||||
@@ -191,6 +196,9 @@
|
||||
</Link>
|
||||
<Manifest>
|
||||
<EnableDpiAwareness>false</EnableDpiAwareness>
|
||||
<AdditionalManifestFiles>app.manifest %(AdditionalManifestFiles)</AdditionalManifestFiles>
|
||||
<InputResourceManifests>
|
||||
</InputResourceManifests>
|
||||
</Manifest>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
|
||||
@@ -252,6 +260,7 @@
|
||||
<ResourceCompile Include="AppInstaller.rc" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="CustomMarshalers" />
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Drawing">
|
||||
<HintPath>C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.Drawing.dll</HintPath>
|
||||
|
||||
17
AppInstaller/app.manifest
Normal file
17
AppInstaller/app.manifest
Normal file
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
|
||||
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
|
||||
<application>
|
||||
<!-- Windows 10 -->
|
||||
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
|
||||
<!-- Windows 8.1 -->
|
||||
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
|
||||
<!-- Windows Vista -->
|
||||
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
|
||||
<!-- Windows 7 -->
|
||||
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
|
||||
<!-- Windows 8 -->
|
||||
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
|
||||
</application>
|
||||
</compatibility>
|
||||
</assembly>
|
||||
@@ -31,18 +31,20 @@ std::wstring GetFileNameWithoutExtension (const std::wstring &filePath)
|
||||
return GetFileNameWithoutExtension (filePath.c_str ());
|
||||
}
|
||||
|
||||
std::string GetLogoBase64FromReader (PackageReader &reader, IStream **getOutput = NULL)
|
||||
std::string GetLogoBase64FromReader (PackageReader &reader, IStream **getOutput = NULL, PriReader *priread = NULL)
|
||||
{
|
||||
if (!&reader) return std::string ("");
|
||||
if (!reader.isAvailable ()) return std::string ("");
|
||||
std::wstring logoPath = reader.getPropertyLogo ();
|
||||
if (logoPath.empty () || logoPath.length () == 0) return std::string ("");
|
||||
PriReader pri (reader.getPriFileStream ());
|
||||
if (pri.isAvailable ())
|
||||
PriReader *pri = ((priread != NULL) ? priread : new PriReader (reader.getPriFileStream ()));
|
||||
if (pri->isAvailable ())
|
||||
{
|
||||
std::wstring logoPathFromPri = pri.findFilePathValue (logoPath);
|
||||
std::wstring logoPathFromPri = pri->findFilePathValue (logoPath);
|
||||
if (!logoPathFromPri.empty () && logoPath.length () > 0) logoPath = logoPathFromPri;
|
||||
}
|
||||
if (priread == NULL) delete pri;
|
||||
pri = NULL;
|
||||
IStream *imgfile = reader.extractFileToStream (logoPath);
|
||||
if (getOutput) *getOutput = imgfile;
|
||||
if (!imgfile)
|
||||
@@ -289,3 +291,527 @@ std::string GetLogoBase64FromReader (PackageReader &reader, IStream **getOutput
|
||||
}
|
||||
return b64res;
|
||||
}
|
||||
|
||||
std::string GetBase64FromPath (PackageReader &reader, LPCWSTR lpswImgPath, IStream **getOutput = NULL, PriReader *priread = NULL)
|
||||
{
|
||||
if (!&reader) return std::string ("");
|
||||
if (!reader.isAvailable ()) return std::string ("");
|
||||
if (!lpswImgPath) return std::string ("");
|
||||
std::wstring logoPath = std::wstring (lpswImgPath);
|
||||
if (logoPath.empty () || logoPath.length () == 0) return std::string ("");
|
||||
PriReader *pri = ((priread != NULL) ? priread : new PriReader (reader.getPriFileStream ()));
|
||||
if (pri->isAvailable ())
|
||||
{
|
||||
std::wstring logoPathFromPri = pri->findFilePathValue (logoPath);
|
||||
if (!logoPathFromPri.empty () && logoPath.length () > 0) logoPath = logoPathFromPri;
|
||||
}
|
||||
if (priread == NULL) delete pri;
|
||||
pri = NULL;
|
||||
IStream *imgfile = reader.extractFileToStream (logoPath);
|
||||
if (getOutput) *getOutput = imgfile;
|
||||
if (!imgfile)
|
||||
{
|
||||
std::wstring fileName = GetFileNameWithoutExtension (logoPath);
|
||||
IAppxPackageReader *appxreader = reader.getAppxPackageReader ();
|
||||
CComPtr <IAppxFilesEnumerator> fe = NULL;
|
||||
HRESULT hr = appxreader->GetPayloadFiles (&fe);
|
||||
if (SUCCEEDED (hr) && fe)
|
||||
{
|
||||
std::vector <std::wstring> files;
|
||||
BOOL hasCurrent = FALSE;
|
||||
hr = fe->GetHasCurrent (FALSE);
|
||||
while (SUCCEEDED (hr) && hasCurrent)
|
||||
{
|
||||
CComPtr <IAppxFile> ifile = NULL;
|
||||
hr = fe->GetCurrent (&ifile);
|
||||
if (SUCCEEDED (hr) && ifile)
|
||||
{
|
||||
LPWSTR lpstr = NULL;
|
||||
if (SUCCEEDED (ifile->GetName (&lpstr)) && lpstr)
|
||||
{
|
||||
std::wstring strWillSearch = StringToUpper (StringTrim (lpstr));
|
||||
std::wstring strWillToSearch = StringToUpper (StringTrim (fileName));
|
||||
if (StrStrW (strWillSearch.c_str (), strWillToSearch.c_str ()))
|
||||
{
|
||||
bool isFind = LabelEqual (PathFindExtensionW (lpstr), L".png");
|
||||
if (!isFind) isFind = LabelEqual (PathFindExtensionW (lpstr), L".jpg");
|
||||
if (!isFind) isFind = LabelEqual (PathFindExtensionW (lpstr), L".jpeg");
|
||||
if (!isFind) isFind = LabelEqual (PathFindExtensionW (lpstr), L".bmp");
|
||||
if (isFind)
|
||||
{
|
||||
std::wstring temp (L"");
|
||||
if (lpstr) temp += lpstr;
|
||||
if (temp.length () > 0) push_no_repeat (files, temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
bool isFindSuit = false;
|
||||
{
|
||||
std::map <int, std::wstring> scaleFiles;
|
||||
std::wregex pattern (L"(scale-(\\d+))");
|
||||
for (auto it : files)
|
||||
{
|
||||
if (StrStrW (it.c_str (), L"contrast-")) continue;
|
||||
std::wsmatch match;
|
||||
if (std::regex_search (it, match, pattern))
|
||||
{
|
||||
int temp = StrToIntW (match [1].str ().c_str ());
|
||||
if (!temp)
|
||||
{
|
||||
scaleFiles [temp] = it;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (scaleFiles.find (GetDPI ()) != scaleFiles.end ())
|
||||
{
|
||||
isFindSuit = true;
|
||||
logoPath = scaleFiles [GetDPI ()];
|
||||
}
|
||||
else
|
||||
{
|
||||
bool isFindScale = false;
|
||||
for (auto it : scaleFiles)
|
||||
{
|
||||
if (it.first >= GetDPI ())
|
||||
{
|
||||
isFindScale = true;
|
||||
logoPath = scaleFiles [GetDPI ()];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!isFindScale)
|
||||
{
|
||||
for (auto it : scaleFiles)
|
||||
{
|
||||
if (it.first >= 100)
|
||||
{
|
||||
isFindScale = true;
|
||||
logoPath = scaleFiles [GetDPI ()];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!isFindScale)
|
||||
{
|
||||
for (auto it : scaleFiles)
|
||||
{
|
||||
isFindScale = true;
|
||||
logoPath = scaleFiles [GetDPI ()];
|
||||
break;
|
||||
}
|
||||
}
|
||||
isFindSuit = isFindScale;
|
||||
}
|
||||
}
|
||||
if (!isFindSuit)
|
||||
{
|
||||
std::map <int, std::wstring> scaleFiles;
|
||||
std::wregex pattern (L"(scale-(\\d+))");
|
||||
for (auto it : files)
|
||||
{
|
||||
if (StrStrW (it.c_str (), L"contrast-white")) continue;
|
||||
std::wsmatch match;
|
||||
if (std::regex_search (it, match, pattern))
|
||||
{
|
||||
int temp = StrToIntW (match [1].str ().c_str ());
|
||||
if (!temp)
|
||||
{
|
||||
scaleFiles [temp] = it;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (scaleFiles.find (GetDPI ()) != scaleFiles.end ())
|
||||
{
|
||||
isFindSuit = true;
|
||||
logoPath = scaleFiles [GetDPI ()];
|
||||
}
|
||||
else
|
||||
{
|
||||
bool isFindScale = false;
|
||||
for (auto it : scaleFiles)
|
||||
{
|
||||
if (it.first >= GetDPI ())
|
||||
{
|
||||
isFindScale = true;
|
||||
logoPath = scaleFiles [GetDPI ()];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!isFindScale)
|
||||
{
|
||||
for (auto it : scaleFiles)
|
||||
{
|
||||
if (it.first >= 100)
|
||||
{
|
||||
isFindScale = true;
|
||||
logoPath = scaleFiles [GetDPI ()];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!isFindScale)
|
||||
{
|
||||
for (auto it : scaleFiles)
|
||||
{
|
||||
isFindScale = true;
|
||||
logoPath = scaleFiles [GetDPI ()];
|
||||
break;
|
||||
}
|
||||
}
|
||||
isFindSuit = isFindScale;
|
||||
}
|
||||
}
|
||||
if (!isFindSuit)
|
||||
{
|
||||
std::map <int, std::wstring> scaleFiles;
|
||||
std::wregex pattern (L"(scale-(\\d+))");
|
||||
for (auto it : files)
|
||||
{
|
||||
if (StrStrW (it.c_str (), L"contrast-black")) continue;
|
||||
std::wsmatch match;
|
||||
if (std::regex_search (it, match, pattern))
|
||||
{
|
||||
int temp = StrToIntW (match [1].str ().c_str ());
|
||||
if (!temp)
|
||||
{
|
||||
scaleFiles [temp] = it;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (scaleFiles.find (GetDPI ()) != scaleFiles.end ())
|
||||
{
|
||||
isFindSuit = true;
|
||||
logoPath = scaleFiles [GetDPI ()];
|
||||
}
|
||||
else
|
||||
{
|
||||
bool isFindScale = false;
|
||||
for (auto it : scaleFiles)
|
||||
{
|
||||
if (it.first >= GetDPI ())
|
||||
{
|
||||
isFindScale = true;
|
||||
logoPath = scaleFiles [GetDPI ()];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!isFindScale)
|
||||
{
|
||||
for (auto it : scaleFiles)
|
||||
{
|
||||
if (it.first >= 100)
|
||||
{
|
||||
isFindScale = true;
|
||||
logoPath = scaleFiles [GetDPI ()];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!isFindScale)
|
||||
{
|
||||
for (auto it : scaleFiles)
|
||||
{
|
||||
isFindScale = true;
|
||||
logoPath = scaleFiles [GetDPI ()];
|
||||
break;
|
||||
}
|
||||
}
|
||||
isFindSuit = isFindScale;
|
||||
}
|
||||
}
|
||||
if (!isFindSuit)
|
||||
{
|
||||
for (auto it : files)
|
||||
{
|
||||
logoPath = std::wstring (L"") + it;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
imgfile = reader.extractFileToStream (logoPath);
|
||||
}
|
||||
if (getOutput) *getOutput = imgfile;
|
||||
if (!imgfile) return std::string ("");
|
||||
std::string b64res ("");
|
||||
LPSTR szRes = StreamToBase64 (imgfile);
|
||||
if (!getOutput)
|
||||
{
|
||||
if (imgfile)
|
||||
{
|
||||
imgfile->Release ();
|
||||
imgfile = NULL;
|
||||
}
|
||||
}
|
||||
if (!szRes) return b64res;
|
||||
if (szRes) b64res += szRes;
|
||||
free (szRes);
|
||||
if (b64res.length () > 0)
|
||||
{
|
||||
b64res = "data:image/png;base64," + b64res;
|
||||
}
|
||||
return b64res;
|
||||
}
|
||||
|
||||
std::wstring GetBase64FromPathW (PackageReader &reader, LPCWSTR lpswImgPath, IStream **getOutput = NULL, PriReader *priread = NULL)
|
||||
{
|
||||
if (!&reader) return std::wstring (L"");
|
||||
if (!reader.isAvailable ()) return std::wstring (L"");
|
||||
if (!lpswImgPath) return std::wstring (L"");
|
||||
std::wstring logoPath = std::wstring (lpswImgPath);
|
||||
if (logoPath.empty () || logoPath.length () == 0) return std::wstring (L"");
|
||||
PriReader *pri = ((priread != NULL) ? priread : new PriReader (reader.getPriFileStream ()));
|
||||
if (pri->isAvailable ())
|
||||
{
|
||||
std::wstring logoPathFromPri = pri->findFilePathValue (logoPath);
|
||||
if (!logoPathFromPri.empty () && logoPath.length () > 0) logoPath = logoPathFromPri;
|
||||
}
|
||||
if (priread == NULL) delete pri;
|
||||
pri = NULL;
|
||||
IStream *imgfile = reader.extractFileToStream (logoPath);
|
||||
if (getOutput) *getOutput = imgfile;
|
||||
if (!imgfile)
|
||||
{
|
||||
std::wstring fileName = GetFileNameWithoutExtension (logoPath);
|
||||
IAppxPackageReader *appxreader = reader.getAppxPackageReader ();
|
||||
CComPtr <IAppxFilesEnumerator> fe = NULL;
|
||||
HRESULT hr = appxreader->GetPayloadFiles (&fe);
|
||||
if (SUCCEEDED (hr) && fe)
|
||||
{
|
||||
std::vector <std::wstring> files;
|
||||
BOOL hasCurrent = FALSE;
|
||||
hr = fe->GetHasCurrent (FALSE);
|
||||
while (SUCCEEDED (hr) && hasCurrent)
|
||||
{
|
||||
CComPtr <IAppxFile> ifile = NULL;
|
||||
hr = fe->GetCurrent (&ifile);
|
||||
if (SUCCEEDED (hr) && ifile)
|
||||
{
|
||||
LPWSTR lpstr = NULL;
|
||||
if (SUCCEEDED (ifile->GetName (&lpstr)) && lpstr)
|
||||
{
|
||||
std::wstring strWillSearch = StringToUpper (StringTrim (lpstr));
|
||||
std::wstring strWillToSearch = StringToUpper (StringTrim (fileName));
|
||||
if (StrStrW (strWillSearch.c_str (), strWillToSearch.c_str ()))
|
||||
{
|
||||
bool isFind = LabelEqual (PathFindExtensionW (lpstr), L".png");
|
||||
if (!isFind) isFind = LabelEqual (PathFindExtensionW (lpstr), L".jpg");
|
||||
if (!isFind) isFind = LabelEqual (PathFindExtensionW (lpstr), L".jpeg");
|
||||
if (!isFind) isFind = LabelEqual (PathFindExtensionW (lpstr), L".bmp");
|
||||
if (isFind)
|
||||
{
|
||||
std::wstring temp (L"");
|
||||
if (lpstr) temp += lpstr;
|
||||
if (temp.length () > 0) push_no_repeat (files, temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
bool isFindSuit = false;
|
||||
{
|
||||
std::map <int, std::wstring> scaleFiles;
|
||||
std::wregex pattern (L"(scale-(\\d+))");
|
||||
for (auto it : files)
|
||||
{
|
||||
if (StrStrW (it.c_str (), L"contrast-")) continue;
|
||||
std::wsmatch match;
|
||||
if (std::regex_search (it, match, pattern))
|
||||
{
|
||||
int temp = StrToIntW (match [1].str ().c_str ());
|
||||
if (!temp)
|
||||
{
|
||||
scaleFiles [temp] = it;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (scaleFiles.find (GetDPI ()) != scaleFiles.end ())
|
||||
{
|
||||
isFindSuit = true;
|
||||
logoPath = scaleFiles [GetDPI ()];
|
||||
}
|
||||
else
|
||||
{
|
||||
bool isFindScale = false;
|
||||
for (auto it : scaleFiles)
|
||||
{
|
||||
if (it.first >= GetDPI ())
|
||||
{
|
||||
isFindScale = true;
|
||||
logoPath = scaleFiles [GetDPI ()];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!isFindScale)
|
||||
{
|
||||
for (auto it : scaleFiles)
|
||||
{
|
||||
if (it.first >= 100)
|
||||
{
|
||||
isFindScale = true;
|
||||
logoPath = scaleFiles [GetDPI ()];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!isFindScale)
|
||||
{
|
||||
for (auto it : scaleFiles)
|
||||
{
|
||||
isFindScale = true;
|
||||
logoPath = scaleFiles [GetDPI ()];
|
||||
break;
|
||||
}
|
||||
}
|
||||
isFindSuit = isFindScale;
|
||||
}
|
||||
}
|
||||
if (!isFindSuit)
|
||||
{
|
||||
std::map <int, std::wstring> scaleFiles;
|
||||
std::wregex pattern (L"(scale-(\\d+))");
|
||||
for (auto it : files)
|
||||
{
|
||||
if (StrStrW (it.c_str (), L"contrast-white")) continue;
|
||||
std::wsmatch match;
|
||||
if (std::regex_search (it, match, pattern))
|
||||
{
|
||||
int temp = StrToIntW (match [1].str ().c_str ());
|
||||
if (!temp)
|
||||
{
|
||||
scaleFiles [temp] = it;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (scaleFiles.find (GetDPI ()) != scaleFiles.end ())
|
||||
{
|
||||
isFindSuit = true;
|
||||
logoPath = scaleFiles [GetDPI ()];
|
||||
}
|
||||
else
|
||||
{
|
||||
bool isFindScale = false;
|
||||
for (auto it : scaleFiles)
|
||||
{
|
||||
if (it.first >= GetDPI ())
|
||||
{
|
||||
isFindScale = true;
|
||||
logoPath = scaleFiles [GetDPI ()];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!isFindScale)
|
||||
{
|
||||
for (auto it : scaleFiles)
|
||||
{
|
||||
if (it.first >= 100)
|
||||
{
|
||||
isFindScale = true;
|
||||
logoPath = scaleFiles [GetDPI ()];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!isFindScale)
|
||||
{
|
||||
for (auto it : scaleFiles)
|
||||
{
|
||||
isFindScale = true;
|
||||
logoPath = scaleFiles [GetDPI ()];
|
||||
break;
|
||||
}
|
||||
}
|
||||
isFindSuit = isFindScale;
|
||||
}
|
||||
}
|
||||
if (!isFindSuit)
|
||||
{
|
||||
std::map <int, std::wstring> scaleFiles;
|
||||
std::wregex pattern (L"(scale-(\\d+))");
|
||||
for (auto it : files)
|
||||
{
|
||||
if (StrStrW (it.c_str (), L"contrast-black")) continue;
|
||||
std::wsmatch match;
|
||||
if (std::regex_search (it, match, pattern))
|
||||
{
|
||||
int temp = StrToIntW (match [1].str ().c_str ());
|
||||
if (!temp)
|
||||
{
|
||||
scaleFiles [temp] = it;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (scaleFiles.find (GetDPI ()) != scaleFiles.end ())
|
||||
{
|
||||
isFindSuit = true;
|
||||
logoPath = scaleFiles [GetDPI ()];
|
||||
}
|
||||
else
|
||||
{
|
||||
bool isFindScale = false;
|
||||
for (auto it : scaleFiles)
|
||||
{
|
||||
if (it.first >= GetDPI ())
|
||||
{
|
||||
isFindScale = true;
|
||||
logoPath = scaleFiles [GetDPI ()];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!isFindScale)
|
||||
{
|
||||
for (auto it : scaleFiles)
|
||||
{
|
||||
if (it.first >= 100)
|
||||
{
|
||||
isFindScale = true;
|
||||
logoPath = scaleFiles [GetDPI ()];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!isFindScale)
|
||||
{
|
||||
for (auto it : scaleFiles)
|
||||
{
|
||||
isFindScale = true;
|
||||
logoPath = scaleFiles [GetDPI ()];
|
||||
break;
|
||||
}
|
||||
}
|
||||
isFindSuit = isFindScale;
|
||||
}
|
||||
}
|
||||
if (!isFindSuit)
|
||||
{
|
||||
for (auto it : files)
|
||||
{
|
||||
logoPath = std::wstring (L"") + it;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
imgfile = reader.extractFileToStream (logoPath);
|
||||
}
|
||||
if (getOutput) *getOutput = imgfile;
|
||||
if (!imgfile) return std::wstring (L"");
|
||||
std::wstring b64res (L"");
|
||||
LPWSTR szRes = StreamToBase64W (imgfile);
|
||||
if (!getOutput)
|
||||
{
|
||||
if (imgfile)
|
||||
{
|
||||
imgfile->Release ();
|
||||
imgfile = NULL;
|
||||
}
|
||||
}
|
||||
if (!szRes) return b64res;
|
||||
if (szRes) b64res += szRes;
|
||||
free (szRes);
|
||||
if (b64res.length () > 0)
|
||||
{
|
||||
b64res = L"data:image/png;base64," + b64res;
|
||||
}
|
||||
return b64res;
|
||||
}
|
||||
@@ -28,6 +28,16 @@
|
||||
using namespace System;
|
||||
using namespace System::Windows::Forms;
|
||||
using namespace System::Threading;
|
||||
using namespace msclr::interop;
|
||||
|
||||
int GetScreenWidth ()
|
||||
{
|
||||
return GetSystemMetrics (SM_CXSCREEN);
|
||||
}
|
||||
int GetScreenHeight ()
|
||||
{
|
||||
return GetSystemMetrics (SM_CYSCREEN);
|
||||
}
|
||||
|
||||
#define toInt(_String_Managed_Object_) Int32::Parse (_String_Managed_Object_)
|
||||
#define toDouble(_String_Managed_Object_) Double::Parse (_String_Managed_Object_)
|
||||
@@ -177,27 +187,23 @@ std::wstring StrPrintFormatW (LPCWSTR format, ...)
|
||||
|
||||
void SetWebBrowserEmulation ()
|
||||
{
|
||||
// 获取应用程序的可执行文件名
|
||||
String ^appName = System::IO::Path::GetFileNameWithoutExtension (System::Windows::Forms::Application::ExecutablePath);
|
||||
const wchar_t *appNameWChar = (const wchar_t *)(void *)System::Runtime::InteropServices::Marshal::StringToHGlobalUni (appName);
|
||||
BOOL is64Bit = FALSE;
|
||||
IsWow64Process (GetCurrentProcess (), &is64Bit);
|
||||
String^ appName = System::IO::Path::GetFileName (Application::ExecutablePath); // 包含扩展名
|
||||
IntPtr appNamePtr = System::Runtime::InteropServices::Marshal::StringToHGlobalUni (appName);
|
||||
const wchar_t* appNameWChar = static_cast<const wchar_t*>(appNamePtr.ToPointer ());
|
||||
BOOL isWow64 = FALSE;
|
||||
IsWow64Process (GetCurrentProcess (), &isWow64);
|
||||
HKEY hKey;
|
||||
long regOpenResult = ERROR_SUCCESS;
|
||||
if (is64Bit)
|
||||
LPCWSTR keyPath = isWow64
|
||||
? L"SOFTWARE\\WOW6432Node\\Microsoft\\Internet Explorer\\Main\\FeatureControl\\FEATURE_BROWSER_EMULATION"
|
||||
: L"SOFTWARE\\Microsoft\\Internet Explorer\\Main\\FeatureControl\\FEATURE_BROWSER_EMULATION";
|
||||
LONG result = RegOpenKeyExW (HKEY_CURRENT_USER, keyPath, 0, KEY_WRITE, &hKey);
|
||||
if (result == ERROR_SUCCESS)
|
||||
{
|
||||
regOpenResult = RegOpenKeyExW (HKEY_CURRENT_USER, L"SOFTWARE\\WOW6432Node\\Microsoft\\Internet Explorer\\Main\\FeatureControl\\FEATURE_BROWSER_EMULATION", 0, KEY_WRITE, &hKey);
|
||||
}
|
||||
else
|
||||
{
|
||||
regOpenResult = RegOpenKeyExW (HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Internet Explorer\\Main\\FeatureControl\\FEATURE_BROWSER_EMULATION", 0, KEY_WRITE, &hKey);
|
||||
}
|
||||
if (regOpenResult == ERROR_SUCCESS)
|
||||
{
|
||||
DWORD ie11Mode = 11001;
|
||||
RegSetValueExW (hKey, appNameWChar, 0, REG_DWORD, (const BYTE *)&ie11Mode, sizeof (DWORD));
|
||||
DWORD value = 11001;
|
||||
RegSetValueExW (hKey, appNameWChar, 0, REG_DWORD, reinterpret_cast<const BYTE*>(&value), sizeof (value));
|
||||
RegCloseKey (hKey);
|
||||
}
|
||||
System::Runtime::InteropServices::Marshal::FreeHGlobal (appNamePtr);
|
||||
}
|
||||
|
||||
#include <windows.h>
|
||||
@@ -237,6 +243,17 @@ bool IsIeVersion10 ()
|
||||
RegCloseKey (hKey);
|
||||
return isIe10;
|
||||
}
|
||||
bool IsWindows10AndLater ()
|
||||
{
|
||||
OSVERSIONINFOEX osvi = {0};
|
||||
osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFOEX);
|
||||
osvi.dwMajorVersion = 10;
|
||||
DWORDLONG conditionMask = 0;
|
||||
VER_SET_CONDITION (conditionMask, VER_MAJORVERSION, VER_GREATER_EQUAL);
|
||||
if (VerifyVersionInfoW (&osvi, VER_MAJORVERSION, conditionMask)) return TRUE;
|
||||
DWORD error = GetLastError ();
|
||||
return (error == ERROR_OLD_WIN_VERSION) ? FALSE : FALSE;
|
||||
}
|
||||
|
||||
size_t EnumerateFilesW (const std::wstring &directory, const std::wstring &filter,
|
||||
std::vector <std::wstring> &outFiles, bool recursive = false)
|
||||
@@ -313,6 +330,136 @@ HRESULT SetCurrentAppUserModelID (PCWSTR appID)
|
||||
|
||||
void ProgressCallback (unsigned progress);
|
||||
void ToastPressCallback ();
|
||||
void OutputDebugStringFormatted (const wchar_t* format, ...);
|
||||
|
||||
public ref class AppWindow: public Form
|
||||
{
|
||||
private:
|
||||
WebBrowser ^webUI;
|
||||
std::vector <appmap> *appItems = new std::vector <appmap> ();
|
||||
System::Collections::Generic::Dictionary <String ^, Delegate ^> ^jsFunctionHandlers;
|
||||
public:
|
||||
AppWindow ()
|
||||
{
|
||||
this->Visible = false;
|
||||
jsFunctionHandlers = gcnew System::Collections::Generic::Dictionary <String ^, Delegate ^> ();
|
||||
this->FormBorderStyle = System::Windows::Forms::FormBorderStyle::None;
|
||||
this->ShowInTaskbar = false;
|
||||
this->TopMost = true;
|
||||
this->Size = System::Drawing::Size (392, 494);
|
||||
if (IsWindows10AndLater ()) this->MinimumSize = System::Drawing::Size (392, 226);
|
||||
else this->MinimumSize = System::Drawing::Size (392, 129);
|
||||
if (IsWindows10AndLater ()) this->MaximumSize = System::Drawing::Size (392, 522);
|
||||
else this->MaximumSize = System::Drawing::Size (368, 394);
|
||||
this->Text = rcString (APPLIST_WINTITLE);
|
||||
webUI = gcnew WebBrowser ();
|
||||
webUI->Dock = DockStyle::Fill;
|
||||
this->Controls->Add (webUI);
|
||||
String ^rootDir = System::IO::Path::GetDirectoryName (System::Windows::Forms::Application::ExecutablePath);
|
||||
String ^htmlFilePath = System::IO::Path::Combine (rootDir, "HTML\\Libs\\AppList.html");
|
||||
if (IsIeVersion10 ()) htmlFilePath = System::IO::Path::Combine (rootDir, "HTML\\Libs\\AppListIE10.html"); // IE10 (Win8) 特供
|
||||
if (IsWindows10AndLater ()) htmlFilePath = System::IO::Path::Combine (rootDir, "HTML\\Libs\\AppListWin10.html"); // Windows 10 及以上版本的风格
|
||||
webUI->Navigate (htmlFilePath);
|
||||
webUI->ObjectForScripting = this;
|
||||
this->webUI->IsWebBrowserContextMenuEnabled = false;
|
||||
webUI->DocumentCompleted += gcnew WebBrowserDocumentCompletedEventHandler (this, &AppWindow::OnDocumentCompleted);
|
||||
this->StartPosition = FormStartPosition::CenterScreen;
|
||||
this->Deactivate += gcnew EventHandler (this, &AppWindow::eventOnDeactivate);
|
||||
}
|
||||
void OnDocumentCompleted (Object ^sender, WebBrowserDocumentCompletedEventArgs ^e)
|
||||
{
|
||||
CallJSFunction ("SetText", gcnew array <Object ^> {
|
||||
"span-title",
|
||||
rcString (APPLIST_TITLE)
|
||||
});
|
||||
CallJSFunction ("SetText", gcnew array <Object ^> {
|
||||
"button-cancel-window",
|
||||
rcString (APPLIST_BUTTON_CANCEL)
|
||||
});
|
||||
this->Visible = true;
|
||||
Thread ^thread = gcnew Thread (gcnew ThreadStart (this, &AppWindow::InvokeRefreshAppItems));
|
||||
thread->Start ();
|
||||
}
|
||||
void SendAppData (std::vector<appmap> apps)
|
||||
{
|
||||
if (appItems) delete appItems;
|
||||
appItems = nullptr;
|
||||
appItems = new std::vector <appmap> ();
|
||||
for (auto it : apps)
|
||||
{
|
||||
appItems->push_back (it);
|
||||
}
|
||||
this->InvokeRefreshAppItems ();
|
||||
}
|
||||
void eventLaunchApp (String ^appModelUserId)
|
||||
{
|
||||
DWORD dwPId = 0;
|
||||
LaunchApp ((marshal_as <std::wstring> (appModelUserId)).c_str (), &dwPId);
|
||||
this->Close ();
|
||||
}
|
||||
void eventCancelWindow ()
|
||||
{
|
||||
if (this->IsHandleCreated) this->Close ();
|
||||
}
|
||||
void eventOnDeactivate (Object ^sender, EventArgs ^e)
|
||||
{
|
||||
if (this->IsHandleCreated) this->Close ();
|
||||
}
|
||||
~AppWindow ()
|
||||
{
|
||||
if (appItems) delete appItems;
|
||||
appItems = nullptr;
|
||||
}
|
||||
private:
|
||||
Object ^CallJSFunction (String ^functionName, ... array<Object^> ^args)
|
||||
{
|
||||
if (webUI->Document != nullptr)
|
||||
{
|
||||
try
|
||||
{
|
||||
return webUI->Document->InvokeScript (functionName, args);
|
||||
}
|
||||
catch (Exception^ ex)
|
||||
{
|
||||
MessageBox::Show ("Error calling JavaScript function: " + ex->Message);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
void InvokeRefreshAppItems ()
|
||||
{
|
||||
if (this->InvokeRequired)
|
||||
{
|
||||
this->Invoke (gcnew Action (this, &AppWindow::RefreshAppItems));
|
||||
}
|
||||
else
|
||||
{
|
||||
RefreshAppItems ();
|
||||
}
|
||||
}
|
||||
void RefreshAppItems ()
|
||||
{
|
||||
CallJSFunction ("ClearListItems", gcnew array <Object ^> { });
|
||||
bool isWin10 = IsWindows10AndLater ();
|
||||
size_t height = ((appItems->size ()) * (isWin10 ? 50 : 60)) + (isWin10 ? 206 : 120);
|
||||
if (height < (isWin10 ? 522 : 394)) this->Height = height;
|
||||
else this->Height = 522;
|
||||
this->Left = (GetScreenWidth () - this->Width) / 2;
|
||||
this->Top = (GetScreenHeight () - this->Height) / 2;
|
||||
for (auto it : *appItems)
|
||||
{
|
||||
String ^colorStr = gcnew String (it [L"BackgroundColor"].c_str ());
|
||||
if (LabelEqual (it [L"BackgroundColor"], L"transparent")) colorStr = ColorToHtml (GetAeroColor ());
|
||||
CallJSFunction ("AddListItems", gcnew array <Object ^> {
|
||||
gcnew String (it [L"AppUserModelID"].c_str ()),
|
||||
gcnew String (it [L"Square44x44LogoBase64"].c_str ()),
|
||||
colorStr,
|
||||
gcnew String (it [L"DisplayName"].c_str ())
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public ref class MainWnd: public Form
|
||||
{
|
||||
@@ -432,7 +579,9 @@ public ref class MainWnd: public Form
|
||||
{
|
||||
this->Visible = true;
|
||||
this->setLaunchWhenReadyJS (m_initConfig.readBoolValue (L"Settings", L"LaunchWhenReady", true));
|
||||
#ifdef _DEBUG
|
||||
if (IsIeVersion10 ()) hideFrameJS (false);
|
||||
#endif
|
||||
Thread ^thread = gcnew Thread (gcnew ThreadStart (this, &MainWnd::taskReadFile));
|
||||
thread->Start ();
|
||||
Thread ^thread2 = gcnew Thread (gcnew ThreadStart (this, &MainWnd::taskCountDarkMode));
|
||||
@@ -468,6 +617,7 @@ public ref class MainWnd: public Form
|
||||
thread->SetApartmentState (ApartmentState::STA);
|
||||
thread->Start ();
|
||||
} break;
|
||||
case 3: break;
|
||||
case 4:
|
||||
{
|
||||
// this->setButtonDisabledJS (true);
|
||||
@@ -481,6 +631,17 @@ public ref class MainWnd: public Form
|
||||
m_pkgInfo.getApplicationUserModelIDs (ids);
|
||||
DWORD dwPId = 0;
|
||||
if (ids.size () == 1) LaunchApp (ids [0].c_str (), &dwPId);
|
||||
else if (ids.size () > 1)
|
||||
{
|
||||
AppWindow ^appWnd = gcnew AppWindow ();
|
||||
std::vector <appmap> apps;
|
||||
m_pkgInfo.getApplications (apps);
|
||||
appWnd->SendAppData (apps);
|
||||
appWnd->StartPosition = FormStartPosition::CenterScreen;
|
||||
//appWnd->Owner = this;
|
||||
appWnd->Show ();
|
||||
//appWnd->ShowDialog ();
|
||||
}
|
||||
}
|
||||
// this->setButtonDisabledJS (false);
|
||||
} break;
|
||||
@@ -490,6 +651,17 @@ public ref class MainWnd: public Form
|
||||
} break;
|
||||
}
|
||||
}
|
||||
void invokeEventOnPress_button1 ()
|
||||
{
|
||||
if (this->InvokeRequired)
|
||||
{
|
||||
this->Invoke (gcnew Action (this, &MainWnd::eventOnPress_button1));
|
||||
}
|
||||
else
|
||||
{
|
||||
eventOnPress_button1 ();
|
||||
}
|
||||
}
|
||||
void eventOnPress_button2 ()
|
||||
{
|
||||
|
||||
@@ -830,18 +1002,21 @@ public ref class MainWnd: public Form
|
||||
setPicBoxVisibilityJS (false);
|
||||
if (serial > 1)
|
||||
{
|
||||
std::string res = m_pkgInfo.getPropertyLogoBase64 ();
|
||||
if (m_pkgInfo.getPropertyLogoIStream () && !res.empty () && res.length () > 10)
|
||||
if (serial = 2)
|
||||
{
|
||||
std::string b64logo = res;
|
||||
// MessageBox::Show (gcnew String ((std::string ("Base 64 String: ") + b64logo).c_str ()));
|
||||
this->setStoreLogoJS (gcnew String (res.c_str ()));
|
||||
setPicBoxVisibilityJS (true);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->setStoreLogoJS ("./Libs/Images/StoreLogo.png");
|
||||
setPicBoxVisibilityJS (false);
|
||||
std::string res = m_pkgInfo.getPropertyLogoBase64 ();
|
||||
if (m_pkgInfo.getPropertyLogoIStream () && !res.empty () && res.length () > 10)
|
||||
{
|
||||
std::string b64logo = res;
|
||||
// MessageBox::Show (gcnew String ((std::string ("Base 64 String: ") + b64logo).c_str ()));
|
||||
this->setStoreLogoJS (gcnew String (res.c_str ()));
|
||||
setPicBoxVisibilityJS (true);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->setStoreLogoJS ("./Libs/Images/StoreLogo.png");
|
||||
setPicBoxVisibilityJS (false);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -896,6 +1071,17 @@ public ref class MainWnd: public Form
|
||||
pTaskbarList->Release ();
|
||||
}
|
||||
}
|
||||
void invokeSetTaskbarProgress (int value)
|
||||
{
|
||||
if (this->InvokeRequired)
|
||||
{
|
||||
this->Invoke (gcnew Action <int> (this, &MainWnd::setTaskbarProgress), value);
|
||||
}
|
||||
else
|
||||
{
|
||||
setTaskbarProgress (value);
|
||||
}
|
||||
}
|
||||
void clearTaskbarProgress ()
|
||||
{
|
||||
IntPtr hwnd = this->Handle;
|
||||
@@ -911,6 +1097,17 @@ public ref class MainWnd: public Form
|
||||
pTaskbarList->Release ();
|
||||
}
|
||||
}
|
||||
void invokeClearTaskbarProgress ()
|
||||
{
|
||||
if (this->InvokeRequired)
|
||||
{
|
||||
this->Invoke (gcnew Action (this, &MainWnd::clearTaskbarProgress));
|
||||
}
|
||||
else
|
||||
{
|
||||
clearTaskbarProgress ();
|
||||
}
|
||||
}
|
||||
bool invokeGetLaunchWhenReady ()
|
||||
{
|
||||
if (this->InvokeRequired)
|
||||
@@ -985,10 +1182,7 @@ public ref class MainWnd: public Form
|
||||
if (status == InstallStatus::Success)
|
||||
{
|
||||
invokeSetPage (4);
|
||||
if (this->invokeGetLaunchWhenReady ())
|
||||
{
|
||||
if (reader.isPackageApplication ()) this->eventOnPress_button1 (); // 用于启用 APP
|
||||
}
|
||||
if (m_pkgInfo.applications.size () == 1 && !m_silentMode) this->eventOnPress_button1 (); // 用于启用 APP
|
||||
Thread ^closeThread = gcnew Thread (gcnew ThreadStart (this, &MainWnd::taskCountCancel));
|
||||
closeThread->IsBackground = true;
|
||||
closeThread->Start ();
|
||||
@@ -1003,7 +1197,7 @@ public ref class MainWnd: public Form
|
||||
closeThread->Start ();
|
||||
}
|
||||
}
|
||||
this->clearTaskbarProgress ();
|
||||
this->invokeClearTaskbarProgress ();
|
||||
std::wstring title = StrPrintFormatW (GetRCString_cpp (PAGE_4_TITLE).c_str (), m_pkgInfo.getPropertyName ().c_str ());
|
||||
std::wstring text (L"");
|
||||
if (GetLastErrorDetailTextLength ()) text += GetLastErrorDetailText ();
|
||||
@@ -1015,7 +1209,12 @@ public ref class MainWnd: public Form
|
||||
}
|
||||
void taskCountCancel ()
|
||||
{
|
||||
for (char cnt = 0; cnt < 100; cnt ++)
|
||||
int size = (int)m_pkgInfo.applications.size ();
|
||||
if (size < 1) size = 1;
|
||||
if (size > 5) size = 5;
|
||||
if (m_silentMode) size = 1; // 不耽误时间
|
||||
int tcnt = size * 100;
|
||||
for (int cnt = 0; cnt < tcnt; cnt ++)
|
||||
{
|
||||
if (!this->IsHandleCreated) break;
|
||||
Thread::Sleep (50);
|
||||
@@ -1052,7 +1251,7 @@ public ref class MainWnd: public Form
|
||||
}
|
||||
public:
|
||||
[STAThread]
|
||||
void Button1_PressEvent () { eventOnPress_button1 (); }
|
||||
void Button1_PressEvent () { invokeEventOnPress_button1 (); }
|
||||
[STAThread]
|
||||
void Button2_PressEvent () { eventOnPress_button2 (); }
|
||||
[STAThread]
|
||||
@@ -1075,7 +1274,7 @@ public ref class MainWnd: public Form
|
||||
StrPrintFormatW (GetRCString_cpp (PAGE_2_INSTALLING).c_str (), (int)value).c_str ()
|
||||
)
|
||||
);
|
||||
this->setTaskbarProgress ((unsigned)value);
|
||||
this->invokeSetTaskbarProgress ((unsigned)value);
|
||||
}
|
||||
bool launchInstalledApp ()
|
||||
{
|
||||
|
||||
@@ -323,7 +323,8 @@ std::vector <std::wstring> applicationItems =
|
||||
L"DisplayName",
|
||||
L"BackgroundColor",
|
||||
L"ForegroundText",
|
||||
L"ShortName"
|
||||
L"ShortName",
|
||||
L"Square44x44Logo"
|
||||
};
|
||||
typedef std::wstring strlabel, StringLabel;
|
||||
std::wstring StringTrim (const std::wstring &str)
|
||||
|
||||
@@ -89,9 +89,40 @@ struct PackageInfomation
|
||||
this->properties.description = reader.getPropertyDescription ();
|
||||
this->properties.publisher = reader.getPropertyPublisher ();
|
||||
}
|
||||
this->properties.logoBase64 = GetLogoBase64FromReader (reader, &this->properties.logoStream);
|
||||
this->properties.logoBase64 = GetLogoBase64FromReader (reader, &this->properties.logoStream, &pri);
|
||||
this->prerequisites.osMinVersion = reader.getPrerequisiteOSMinVersion ();
|
||||
reader.getApplications (this->applications);
|
||||
for (auto &it : this->applications)
|
||||
{
|
||||
for (auto &sit : it)
|
||||
{
|
||||
if (LabelEqual (sit.first, L"AppUserModelID")) continue;
|
||||
else if (LabelEqual (sit.first, L"Id")) continue;
|
||||
else if (LabelEqual (sit.first, L"DisplayName"))
|
||||
{
|
||||
if (isMsResourceLabel (sit.second))
|
||||
{
|
||||
std::wstring temp (L"");
|
||||
temp += pri.findStringValue (sit.second);
|
||||
it [L"DisplayName"] = temp;
|
||||
}
|
||||
}
|
||||
else if (LabelEqual (sit.first, L"ShortName"))
|
||||
{
|
||||
if (isMsResourceLabel (sit.second))
|
||||
{
|
||||
std::wstring temp (L"");
|
||||
temp += pri.findStringValue (sit.second);
|
||||
it [L"ShortName"] = temp;
|
||||
}
|
||||
}
|
||||
else if (LabelEqual (sit.first, L"Square44x44Logo"))
|
||||
{
|
||||
sit.second = pri.findFilePathValue (sit.second);
|
||||
it [strlabel (L"Square44x44LogoBase64")] = GetBase64FromPathW (reader, sit.second.c_str (), NULL, &pri);
|
||||
}
|
||||
}
|
||||
}
|
||||
reader.getCapabilities (capabilities);
|
||||
reader.getDependencies (dependencies);
|
||||
return reader.isAvailable ();
|
||||
|
||||
@@ -316,7 +316,7 @@ class PriReader
|
||||
PriReader (): priReader (NULL) {}
|
||||
void destroy ()
|
||||
{
|
||||
if (!priReader) return;
|
||||
if (priReader == NULL) return;
|
||||
DestroyPriReader (priReader);
|
||||
priReader = NULL;
|
||||
}
|
||||
|
||||
@@ -3,10 +3,12 @@
|
||||
<assemblyIdentity version="1.0.0.0" processorArchitecture="*" name="Company.Product.Name" type="win32" />
|
||||
<application xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
<windowsSettings>
|
||||
<dpiAware xmlns=
|
||||
"https://schemas.microsoft.com/SMI/2005/WindowsSettings">
|
||||
True/PM
|
||||
</dpiAware>
|
||||
<!-- Windows 8 -->
|
||||
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
|
||||
<!-- Windows 8.1 -->
|
||||
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
|
||||
<!-- Windows 10 / Windows 11 -->
|
||||
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
|
||||
</windowsSettings>
|
||||
</application>
|
||||
<description></description>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -316,7 +316,7 @@ class PriReader
|
||||
PriReader (): priReader (NULL) {}
|
||||
void destroy ()
|
||||
{
|
||||
if (!priReader) return;
|
||||
if (priReader == NULL) return;
|
||||
DestroyPriReader (priReader);
|
||||
priReader = NULL;
|
||||
}
|
||||
|
||||
@@ -32,3 +32,32 @@ LPSTR StreamToBase64 (HISTREAM ifile)
|
||||
lstrcpyA (lpszStr, res.c_str ());
|
||||
return lpszStr;
|
||||
}
|
||||
|
||||
LPWSTR StreamToBase64W (HISTREAM ifile)
|
||||
{
|
||||
if (!ifile) return NULL;
|
||||
IStream *pStream = (IStream *)ifile;
|
||||
LARGE_INTEGER liZero = {};
|
||||
pStream->Seek (liZero, STREAM_SEEK_SET, nullptr);
|
||||
STATSTG statstg;
|
||||
pStream->Stat (&statstg, STATFLAG_NONAME);
|
||||
ULARGE_INTEGER uliSize = statstg.cbSize;
|
||||
std::vector<BYTE> buffer (uliSize.QuadPart);
|
||||
ULONG bytesRead;
|
||||
pStream->Read (buffer.data (), static_cast<ULONG>(buffer.size ()), &bytesRead);
|
||||
DWORD base64Size = 0;
|
||||
if (!CryptBinaryToStringW (buffer.data (), bytesRead, CRYPT_STRING_BASE64 | CRYPT_STRING_NOCRLF, nullptr, &base64Size))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
std::vector <WCHAR> base64Buffer (base64Size);
|
||||
if (!CryptBinaryToStringW (buffer.data (), bytesRead, CRYPT_STRING_BASE64 | CRYPT_STRING_NOCRLF, base64Buffer.data (), &base64Size))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
std::wstring res = std::wstring (base64Buffer.begin (), base64Buffer.end ());
|
||||
LPWSTR lpszStr = (LPWSTR)calloc (res.capacity (), sizeof (WCHAR));
|
||||
if (!lpszStr) return NULL;
|
||||
lstrcpyW (lpszStr, res.c_str ());
|
||||
return lpszStr;
|
||||
}
|
||||
|
||||
@@ -14,3 +14,5 @@ typedef HANDLE HISTREAM;
|
||||
typedef char *LPSTR;
|
||||
|
||||
extern "C" BASE64IMG_API LPSTR StreamToBase64 (HISTREAM ifile);
|
||||
|
||||
extern "C" BASE64IMG_API LPWSTR StreamToBase64W (HISTREAM ifile);
|
||||
|
||||
@@ -1652,6 +1652,10 @@ class PriReader
|
||||
if (xmlreader) delete xmlreader;
|
||||
xmlreader = nullptr;
|
||||
if (IsFileExists (txmlpath)) DeleteFileW (txmlpath.c_str ());
|
||||
if (IsFileExists (txmlpath.substr (0, txmlpath.length () - 4)))
|
||||
{
|
||||
DeleteFileW (txmlpath.substr (0, txmlpath.length () - 4).c_str ());
|
||||
}
|
||||
txmlpath = L"";
|
||||
prifile = L"";
|
||||
}
|
||||
@@ -1760,6 +1764,10 @@ class PriReader
|
||||
}
|
||||
bool res = this->create (tempPriFile);
|
||||
DeleteFileW (tempPriFile.c_str ());
|
||||
if (IsFileExists (tempPriFile.substr (0, tempPriFile.length () - 4)))
|
||||
{
|
||||
DeleteFileW (tempPriFile.substr (0, tempPriFile.length () - 4).c_str ());
|
||||
}
|
||||
return res;
|
||||
}
|
||||
// 获取到的指针需要 free 手动释放。
|
||||
@@ -1905,7 +1913,7 @@ void DestroyPriReader (HPRIREADER hpr)
|
||||
{
|
||||
if (!hpr) return;
|
||||
PriReader *ptr = (PriReader *)hpr;
|
||||
delete hpr;
|
||||
delete ptr;
|
||||
return;
|
||||
}
|
||||
// 返回的字符串只能肯定不是宽字符串,而不确定具体的编码方式(可能为 ANSI 也有可能为 UTF-8)
|
||||
|
||||
Reference in New Issue
Block a user