Update application UI and functionality
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
YMhut Box 软件许可与服务协议
|
||||
|
||||
更新日期:2026 年 7 月 25 日
|
||||
|
||||
请在安装和使用 YMhut Box 前完整阅读本协议。点击“我已阅读并同意”或继续安装,即表示您已理解并同意本协议的全部内容;如不同意,请退出安装程序。
|
||||
|
||||
一、许可范围
|
||||
|
||||
1. YMhut Box 授予您一项有限的、非独占的、不可转让的使用许可,用于在您拥有或合法管理的 Windows 设备上安装和使用本软件。
|
||||
2. 本许可不代表软件、品牌、界面设计或相关服务的所有权发生转移。
|
||||
3. 未经明确授权,不得利用本软件从事违法活动、破坏系统或网络安全、侵害他人权益,或规避第三方服务的付费、地区及版权限制。
|
||||
|
||||
二、安装、更新与卸载
|
||||
|
||||
1. 安装程序会检查 Windows 版本、系统架构、目标目录、磁盘空间以及必要运行组件。
|
||||
2. 当 WebView2 Runtime 或 Microsoft Visual C++ x64 Runtime 缺失时,安装程序可能从微软官方地址下载并安装相应组件,并可能请求管理员权限。
|
||||
3. 升级或修复安装将尽量保留用户设置和本地数据;卸载前请自行备份重要内容。
|
||||
|
||||
三、数据与网络访问
|
||||
|
||||
1. 软件设置、缓存、登录凭据和运行日志原则上保存在本机;敏感登录信息按产品实现使用 Windows 系统能力进行保护。
|
||||
2. 天气、更新、反馈、网络音乐和其他联网功能会访问相应服务提供方。具体可用性、内容和处理规则同时受该服务提供方条款约束。
|
||||
3. 为诊断故障,软件可能在本机记录必要的错误信息。日志不应被用于存储用户主动输入的密码等敏感内容。
|
||||
|
||||
四、第三方组件与服务
|
||||
|
||||
1. 软件可能包含或调用微软运行库、硬件监控组件及其他第三方组件。相关组件的权利由其权利人享有,并适用各自的许可或服务条款。
|
||||
2. 对于跳转至第三方网站、下载地址或服务产生的内容、费用、账户及可用性,应以第三方实际规则为准。
|
||||
|
||||
五、功能与风险提示
|
||||
|
||||
1. 硬件监控结果受设备、驱动、权限和传感器能力影响,仅供参考。
|
||||
2. 系统优化、注册表、服务、电源、网络和驱动相关操作可能改变系统行为。请在执行前阅读变更预览并保留可用备份或还原点。
|
||||
3. 因设备差异、系统策略、第三方服务中断或不可抗力,部分功能可能暂时不可用。
|
||||
|
||||
六、责任限制
|
||||
|
||||
在法律允许的范围内,YMhut Box 不对因错误配置、未经授权的系统操作、第三方服务变化、网络故障或用户未备份数据造成的间接损失承担责任。本条不排除依法不得限制或排除的责任。
|
||||
|
||||
七、协议更新与终止
|
||||
|
||||
1. 软件功能、服务方式或合规要求发生变化时,本协议可能更新。重要变更将在软件或发布渠道中提示。
|
||||
2. 如您违反本协议或利用软件从事违法行为,相关使用许可可以被终止。
|
||||
3. 协议终止后,您应停止使用并可通过系统卸载功能移除软件。
|
||||
|
||||
八、联系与反馈
|
||||
|
||||
您可以通过 YMhut Box 内置反馈页面提交功能建议、问题报告或协议相关咨询。
|
||||
@@ -482,6 +482,11 @@ begin
|
||||
QueueInstallOutput(Text, True, True);
|
||||
end;
|
||||
|
||||
procedure LogBootstrapEvent(const EventName, Value: string);
|
||||
begin
|
||||
Log('YMHUT_EVENT:' + EventName + '|' + Value);
|
||||
end;
|
||||
|
||||
procedure LogCurrentExtractFile();
|
||||
var
|
||||
FileName: string;
|
||||
@@ -718,28 +723,67 @@ begin
|
||||
Result := FmtMessage(CustomMessage(Key), [Value1, Value2]);
|
||||
end;
|
||||
|
||||
function DownloadAndInstallPrerequisite(const Url, FileName, Arguments, FriendlyName: string; var NeedsRestart: Boolean): Boolean;
|
||||
function AcquireAndInstallPrerequisite(
|
||||
const Url, DownloadFileName, BundledFileName, Arguments, FriendlyName: string;
|
||||
const Bundled: Boolean; var NeedsRestart: Boolean): Boolean;
|
||||
var
|
||||
Attempt: Integer;
|
||||
Downloaded: Boolean;
|
||||
LastDownloadError: string;
|
||||
ResultCode: Integer;
|
||||
ExecutablePath: string;
|
||||
begin
|
||||
Result := False;
|
||||
ExecutablePath := ExpandConstant('{tmp}\' + FileName);
|
||||
DownloadPage.Clear;
|
||||
DownloadPage.Add(Url, FileName, '');
|
||||
if not WizardSilent then
|
||||
DownloadPage.Show;
|
||||
try
|
||||
DownloadPage.Download;
|
||||
except
|
||||
if DownloadPage.AbortedByUser then
|
||||
RaiseException(FormatCustomMessage('DependencyDownloadCancelled', FriendlyName))
|
||||
else
|
||||
RaiseException(FormatCustomMessage2('DependencyDownloadFailed', FriendlyName, GetExceptionMessage));
|
||||
end;
|
||||
if not WizardSilent then
|
||||
DownloadPage.Hide;
|
||||
if Bundled then
|
||||
begin
|
||||
LogBootstrapEvent('DEPENDENCY', 'bundled|' + FriendlyName);
|
||||
ExtractTemporaryFile(BundledFileName);
|
||||
ExecutablePath := ExpandConstant('{tmp}\' + BundledFileName);
|
||||
end
|
||||
else
|
||||
begin
|
||||
ExecutablePath := ExpandConstant('{tmp}\' + DownloadFileName);
|
||||
Downloaded := False;
|
||||
LastDownloadError := '';
|
||||
for Attempt := 1 to 3 do
|
||||
begin
|
||||
LogBootstrapEvent('DEPENDENCY', 'download|' + FriendlyName);
|
||||
DownloadPage.Clear;
|
||||
DownloadPage.Add(Url, DownloadFileName, '');
|
||||
if not WizardSilent then
|
||||
DownloadPage.Show;
|
||||
try
|
||||
try
|
||||
DownloadPage.Download;
|
||||
Downloaded := True;
|
||||
except
|
||||
if DownloadPage.AbortedByUser then
|
||||
RaiseException(FormatCustomMessage('DependencyDownloadCancelled', FriendlyName))
|
||||
else
|
||||
LastDownloadError := GetExceptionMessage;
|
||||
end;
|
||||
finally
|
||||
if not WizardSilent then
|
||||
DownloadPage.Hide;
|
||||
end;
|
||||
|
||||
if Downloaded then
|
||||
Break;
|
||||
if Attempt < 3 then
|
||||
begin
|
||||
LogBootstrapEvent('DEPENDENCY', 'retry|' + FriendlyName);
|
||||
Sleep(Attempt * 1500);
|
||||
end;
|
||||
end;
|
||||
|
||||
if not Downloaded then
|
||||
RaiseException(FormatCustomMessage2('DependencyDownloadFailed', FriendlyName, LastDownloadError));
|
||||
end;
|
||||
|
||||
if not FileExists(ExecutablePath) then
|
||||
RaiseException(FormatCustomMessage2('DependencyDownloadFailed', FriendlyName, 'downloaded file is missing'));
|
||||
|
||||
LogBootstrapEvent('DEPENDENCY', 'install|' + FriendlyName);
|
||||
if not Exec(ExecutablePath, Arguments, '', SW_HIDE, ewWaitUntilTerminated, ResultCode) then
|
||||
RaiseException(FormatCustomMessage('DependencyStartFailed', FriendlyName));
|
||||
|
||||
@@ -749,9 +793,16 @@ begin
|
||||
if (ResultCode = 3010) or (ResultCode = 1641) then
|
||||
NeedsRestart := True;
|
||||
|
||||
LogBootstrapEvent('DEPENDENCY', 'complete|' + FriendlyName);
|
||||
Result := True;
|
||||
end;
|
||||
|
||||
procedure SetSetupFailure(var ResultText: string; const MessageText: string);
|
||||
begin
|
||||
ResultText := MessageText;
|
||||
LogBootstrapEvent('FAILURE', MessageText);
|
||||
end;
|
||||
|
||||
procedure CopyIfExists(const Source, TargetDir: string);
|
||||
begin
|
||||
if FileExists(Source) then
|
||||
@@ -900,46 +951,57 @@ end;
|
||||
function PrepareToInstall(var NeedsRestart: Boolean): string;
|
||||
begin
|
||||
AppendInstallOutput('Prepare system prerequisites.');
|
||||
LogBootstrapEvent('STAGE', 'prerequisites');
|
||||
Result := '';
|
||||
#if Int(QAIsolated) == 1
|
||||
Exit;
|
||||
#endif
|
||||
if (ExistingInstallDir <> '') and IsProtectedInstallPath(ExistingInstallDir) and (not IsAdminInstallMode) then
|
||||
begin
|
||||
Result := CustomMessage('ProtectedInstallNeedsAdmin');
|
||||
SetSetupFailure(Result, CustomMessage('ProtectedInstallNeedsAdmin'));
|
||||
Exit;
|
||||
end;
|
||||
|
||||
if IsProtectedInstallPath(WizardDirValue) and (not IsAdminInstallMode) then
|
||||
begin
|
||||
Result := CustomMessage('ProtectedInstallNeedsAdmin');
|
||||
SetSetupFailure(Result, CustomMessage('ProtectedInstallNeedsAdmin'));
|
||||
Exit;
|
||||
end;
|
||||
|
||||
try
|
||||
if not IsWebView2Installed() then
|
||||
if IsWebView2Installed() then
|
||||
LogBootstrapEvent('DEPENDENCY', 'ready|' + GetCustomMessageValue('WebView2RuntimeName'))
|
||||
else
|
||||
begin
|
||||
DownloadAndInstallPrerequisite('{#WebView2BootstrapperUrl}', 'MicrosoftEdgeWebView2Setup.exe', '/silent /install', GetCustomMessageValue('WebView2RuntimeName'), NeedsRestart);
|
||||
AcquireAndInstallPrerequisite(
|
||||
'{#WebView2BootstrapperUrl}', 'MicrosoftEdgeWebView2Setup.exe',
|
||||
'MicrosoftEdgeWebView2RuntimeInstallerX64.exe', '/silent /install',
|
||||
GetCustomMessageValue('WebView2RuntimeName'), BundledWebView2Included = 1, NeedsRestart);
|
||||
|
||||
if not WaitForWebView2Installed(60) then
|
||||
begin
|
||||
Result := GetCustomMessageValue('WebView2StillMissing');
|
||||
SetSetupFailure(Result, GetCustomMessageValue('WebView2StillMissing'));
|
||||
Exit;
|
||||
end;
|
||||
end;
|
||||
|
||||
if (not IsVCRedistInstalled()) then
|
||||
if IsVCRedistInstalled() then
|
||||
LogBootstrapEvent('DEPENDENCY', 'ready|' + GetCustomMessageValue('VCRuntimeName'))
|
||||
else
|
||||
begin
|
||||
DownloadAndInstallPrerequisite('{#VCRedistUrl}', 'vc_redist.x64.exe', '/install /quiet /norestart', GetCustomMessageValue('VCRuntimeName'), NeedsRestart);
|
||||
AcquireAndInstallPrerequisite(
|
||||
'{#VCRedistUrl}', 'vc_redist.x64.exe', 'vc_redist.x64.exe',
|
||||
'/install /quiet /norestart', GetCustomMessageValue('VCRuntimeName'),
|
||||
BundledVCRedistIncluded = 1, NeedsRestart);
|
||||
|
||||
if not WaitForVCRedistInstalled(10) then
|
||||
begin
|
||||
Result := GetCustomMessageValue('VCRuntimeStillMissing');
|
||||
SetSetupFailure(Result, GetCustomMessageValue('VCRuntimeStillMissing'));
|
||||
Exit;
|
||||
end;
|
||||
end;
|
||||
except
|
||||
Result := GetExceptionMessage;
|
||||
SetSetupFailure(Result, GetExceptionMessage);
|
||||
end;
|
||||
end;
|
||||
|
||||
@@ -954,6 +1016,7 @@ begin
|
||||
if CurStep = ssInstall then
|
||||
begin
|
||||
LastInstallProgressPercent := -1;
|
||||
LogBootstrapEvent('STAGE', 'files');
|
||||
AppendInstallOutput(CustomMessage('InstallOutputClean'));
|
||||
CleanLegacyInstallLayout();
|
||||
AppendInstallOutput(CustomMessage('InstallOutputExtract'));
|
||||
@@ -961,6 +1024,7 @@ begin
|
||||
else if CurStep = ssPostInstall then
|
||||
begin
|
||||
FlushInstallOutput();
|
||||
LogBootstrapEvent('STAGE', 'finalize');
|
||||
AppendInstallOutput(CustomMessage('InstallOutputPostInstall'));
|
||||
#if Int(QAIsolated) == 0
|
||||
MigrateLegacyData();
|
||||
@@ -980,6 +1044,7 @@ begin
|
||||
if LastInstallProgressPercent <> 100 then
|
||||
begin
|
||||
LastInstallProgressPercent := 100;
|
||||
LogBootstrapEvent('PROGRESS', '100|' + ExpandConstant(CurrentFileName));
|
||||
FlushInstallOutput();
|
||||
end;
|
||||
Exit;
|
||||
@@ -991,6 +1056,7 @@ begin
|
||||
if ProgressPercent <> LastInstallProgressPercent then
|
||||
begin
|
||||
LastInstallProgressPercent := ProgressPercent;
|
||||
LogBootstrapEvent('PROGRESS', IntToStr(ProgressPercent) + '|' + ExpandConstant(CurrentFileName));
|
||||
FlushInstallOutput();
|
||||
end;
|
||||
end;
|
||||
|
||||
Reference in New Issue
Block a user