Merge branch 'SCADA系统测试'
This commit is contained in:
@@ -163,9 +163,11 @@ namespace YY.Admin.Core.SqlSugar
|
|||||||
config.ConnectionString = CryptogramUtil.Decrypt(config.ConnectionString);
|
config.ConnectionString = CryptogramUtil.Decrypt(config.ConnectionString);
|
||||||
}
|
}
|
||||||
|
|
||||||
// SQLite 相对路径默认依赖进程工作目录;快捷方式/从不同目录启动会在别处生成空库,表现为发布后菜单全空
|
// SQLite 相对路径会解析到 LocalApplicationData\Data(见 ResolveSqliteConnectionToAbsolutePath)
|
||||||
if (config.DbType == DbType.Sqlite && !string.IsNullOrWhiteSpace(config.ConnectionString))
|
if (config.DbType == DbType.Sqlite && !string.IsNullOrWhiteSpace(config.ConnectionString))
|
||||||
{
|
{
|
||||||
|
// 安装包随带的 Admin.NET.db / Slave.db 在安装目录;运行时代码只读写可写目录。首启若无用户库则从安装目录复制模板。
|
||||||
|
TrySeedSqliteFromInstallDirectory(config.ConnectionString);
|
||||||
config.ConnectionString = ResolveSqliteConnectionToAbsolutePath(config.ConnectionString);
|
config.ConnectionString = ResolveSqliteConnectionToAbsolutePath(config.ConnectionString);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -266,7 +268,41 @@ namespace YY.Admin.Core.SqlSugar
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 将 SQLite 连接串中的相对 DataSource 解析为基于应用程序基目录的绝对路径。
|
/// 首次启动时:若用户数据目录中尚无该 SQLite 文件,且安装目录(exe 旁)存在同名库,则复制一份作为初始模板。
|
||||||
|
/// 否则安装包内随带的菜单/配置永远不会被用到(实际始终读写 %LocalAppData%\YY.Admin\Data\)。
|
||||||
|
/// </summary>
|
||||||
|
private static void TrySeedSqliteFromInstallDirectory(string connectionString)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var builder = new SqliteConnectionStringBuilder(connectionString);
|
||||||
|
var ds = builder.DataSource;
|
||||||
|
if (string.IsNullOrWhiteSpace(ds) || Path.IsPathFullyQualified(ds))
|
||||||
|
return;
|
||||||
|
|
||||||
|
var fileName = Path.GetFileName(ds.TrimStart('.', '/', '\\'));
|
||||||
|
if (string.IsNullOrWhiteSpace(fileName))
|
||||||
|
fileName = "Admin.NET.db";
|
||||||
|
|
||||||
|
var dataDir = AppWritablePaths.EnsureDirectoryExists(AppWritablePaths.DataDirectory);
|
||||||
|
var targetPath = Path.Combine(dataDir, fileName);
|
||||||
|
if (File.Exists(targetPath))
|
||||||
|
return;
|
||||||
|
|
||||||
|
var bundledPath = Path.Combine(AppContext.BaseDirectory, fileName);
|
||||||
|
if (!File.Exists(bundledPath))
|
||||||
|
return;
|
||||||
|
|
||||||
|
File.Copy(bundledPath, targetPath, overwrite: false);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// 忽略:后续仍可按空库走建表/基准种子
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将 SQLite 连接串中的相对 DataSource 解析为 %LocalAppData%\YY.Admin\Data\ 下绝对路径(适配 Program Files 只读安装)。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private static string ResolveSqliteConnectionToAbsolutePath(string connectionString)
|
private static string ResolveSqliteConnectionToAbsolutePath(string connectionString)
|
||||||
{
|
{
|
||||||
@@ -284,7 +320,7 @@ namespace YY.Admin.Core.SqlSugar
|
|||||||
return connectionString;
|
return connectionString;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Program Files 等安装目录对普通用户只读;SQLite 库放到 LocalApplicationData
|
// Program Files 等安装目录对普通用户只读;运行期 SQLite 放到 LocalApplicationData(首启可由 TrySeedSqliteFromInstallDirectory 从安装目录拷贝模板)
|
||||||
var dataDir = AppWritablePaths.EnsureDirectoryExists(AppWritablePaths.DataDirectory);
|
var dataDir = AppWritablePaths.EnsureDirectoryExists(AppWritablePaths.DataDirectory);
|
||||||
var fileName = Path.GetFileName(ds.TrimStart('.', '/', '\\'));
|
var fileName = Path.GetFileName(ds.TrimStart('.', '/', '\\'));
|
||||||
if (string.IsNullOrWhiteSpace(fileName))
|
if (string.IsNullOrWhiteSpace(fileName))
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ using FluentValidation;
|
|||||||
using Mapster;
|
using Mapster;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using NewLife;
|
using NewLife;
|
||||||
|
using System.Configuration;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
@@ -73,6 +74,46 @@ namespace YY.Admin
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 写入用户级 AppSettings(user.config)。若文件损坏(如缺少 configSections),删除后重试一次。
|
||||||
|
/// </summary>
|
||||||
|
private static void PersistSkinTypeUserSettingSafe()
|
||||||
|
{
|
||||||
|
for (var attempt = 0; attempt < 2; attempt++)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
AppSettings.Default.SkinType = AppSettingsViewModel.GetSkinType().ToInt();
|
||||||
|
AppSettings.Default.Save();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
catch (ConfigurationErrorsException ex)
|
||||||
|
{
|
||||||
|
if (attempt == 0)
|
||||||
|
{
|
||||||
|
var path = ex.Filename;
|
||||||
|
if (string.IsNullOrWhiteSpace(path) && ex.InnerException is ConfigurationErrorsException inner)
|
||||||
|
path = inner.Filename;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrWhiteSpace(path) && File.Exists(path))
|
||||||
|
File.Delete(path);
|
||||||
|
AppSettings.Default.Reload();
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// 删除/Reload 失败则向上抛出原异常
|
||||||
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected override Window CreateShell()
|
protected override Window CreateShell()
|
||||||
{
|
{
|
||||||
return Container.Resolve<LoginWindow>();
|
return Container.Resolve<LoginWindow>();
|
||||||
@@ -178,9 +219,8 @@ namespace YY.Admin
|
|||||||
_logger = Container.Resolve<ILoggerService>();
|
_logger = Container.Resolve<ILoggerService>();
|
||||||
// 初始化全局异常处理(通过解析触发构造函数注册)
|
// 初始化全局异常处理(通过解析触发构造函数注册)
|
||||||
Container.Resolve<GlobalExceptionHandler>();
|
Container.Resolve<GlobalExceptionHandler>();
|
||||||
// 保存默认主题
|
// 保存默认主题(用户级 user.config;损坏时自动删文件并重载)
|
||||||
AppSettings.Default.SkinType = AppSettingsViewModel.GetSkinType().ToInt();
|
PersistSkinTypeUserSettingSafe();
|
||||||
AppSettings.Default.Save();
|
|
||||||
|
|
||||||
_logger.Information("应用程序已启动");
|
_logger.Information("应用程序已启动");
|
||||||
|
|
||||||
|
|||||||
@@ -68,6 +68,16 @@ if errorlevel 1 (
|
|||||||
exit /b 1
|
exit /b 1
|
||||||
)
|
)
|
||||||
|
|
||||||
|
REM <20>˵<EFBFBD><CBB5><EFBFBD>ҵ<EFBFBD><D2B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> SQLite<74><65><EFBFBD><EFBFBD>Ŀ<EFBFBD><C4BF><EFBFBD>³<EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȫ<EFBFBD><C8AB>һ<EFBFBD>ݣ<EFBFBD>dotnet publish Ĭ<>ϲ<EFBFBD><CFB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
if exist "Admin.NET.db" (
|
||||||
|
copy /Y "Admin.NET.db" "publish\" >nul
|
||||||
|
echo <20>Ѹ<EFBFBD><D1B8><EFBFBD> Admin.NET.db<64><62><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ<EFBFBD><C4BF>һ<EFBFBD>£<EFBFBD><C2A3><EFBFBD><EFBFBD>˵<EFBFBD><CBB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ã<EFBFBD>
|
||||||
|
)
|
||||||
|
if exist "Slave.db" (
|
||||||
|
copy /Y "Slave.db" "publish\" >nul
|
||||||
|
echo <20>Ѹ<EFBFBD><D1B8><EFBFBD> Slave.db
|
||||||
|
)
|
||||||
|
|
||||||
REM <20><><EFBFBD><EFBFBD> Updates Ŀ¼<C4BF><C2BC><EFBFBD><EFBFBD><EFBFBD>ư汾<C6B0>ļ<EFBFBD>
|
REM <20><><EFBFBD><EFBFBD> Updates Ŀ¼<C4BF><C2BC><EFBFBD><EFBFBD><EFBFBD>ư汾<C6B0>ļ<EFBFBD>
|
||||||
echo [3/4] <20><><EFBFBD><EFBFBD><EFBFBD>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>...
|
echo [3/4] <20><><EFBFBD><EFBFBD><EFBFBD>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>...
|
||||||
if not exist "publish\Updates" mkdir "publish\Updates"
|
if not exist "publish\Updates" mkdir "publish\Updates"
|
||||||
|
|||||||
Binary file not shown.
418
yy-admin-master/installer/ChineseSimplified.isl
Normal file
418
yy-admin-master/installer/ChineseSimplified.isl
Normal file
@@ -0,0 +1,418 @@
|
|||||||
|
; *** Inno Setup version 6.5.0+ Chinese Simplified messages ***
|
||||||
|
;
|
||||||
|
; To download user-contributed translations of this file, go to:
|
||||||
|
; https://jrsoftware.org/files/istrans/
|
||||||
|
;
|
||||||
|
; Note: When translating this text, do not add periods (.) to the end of
|
||||||
|
; messages that didn't have them already, because on those messages Inno
|
||||||
|
; Setup adds the periods automatically (appending a period would result in
|
||||||
|
; two periods being displayed).
|
||||||
|
;
|
||||||
|
; Maintained by Zhenghan Yang
|
||||||
|
; Email: 847320916@QQ.com
|
||||||
|
; Translation based on network resource
|
||||||
|
; The latest Translation is on https://github.com/kira-96/Inno-Setup-Chinese-Simplified-Translation
|
||||||
|
;
|
||||||
|
|
||||||
|
[LangOptions]
|
||||||
|
; The following three entries are very important. Be sure to read and
|
||||||
|
; understand the '[LangOptions] section' topic in the help file.
|
||||||
|
LanguageName=简体中文
|
||||||
|
; If Language Name display incorrect, uncomment next line
|
||||||
|
; LanguageName=<7B80><4F53><4E2D><6587>
|
||||||
|
; About LanguageID, to reference link:
|
||||||
|
; https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-lcid/a9eac961-e77d-41a6-90a5-ce1a8b0cdb9c
|
||||||
|
LanguageID=$0804
|
||||||
|
; About CodePage, to reference link:
|
||||||
|
; https://docs.microsoft.com/en-us/windows/win32/intl/code-page-identifiers
|
||||||
|
LanguageCodePage=936
|
||||||
|
; If the language you are translating to requires special font faces or
|
||||||
|
; sizes, uncomment any of the following entries and change them accordingly.
|
||||||
|
;DialogFontName=
|
||||||
|
;DialogFontSize=9
|
||||||
|
;DialogFontBaseScaleWidth=7
|
||||||
|
;DialogFontBaseScaleHeight=15
|
||||||
|
;WelcomeFontName=Segoe UI
|
||||||
|
;WelcomeFontSize=14
|
||||||
|
|
||||||
|
[Messages]
|
||||||
|
|
||||||
|
; *** 应用程序标题
|
||||||
|
SetupAppTitle=安装
|
||||||
|
SetupWindowTitle=安装 - %1
|
||||||
|
UninstallAppTitle=卸载
|
||||||
|
UninstallAppFullTitle=%1 卸载
|
||||||
|
|
||||||
|
; *** Misc. common
|
||||||
|
InformationTitle=信息
|
||||||
|
ConfirmTitle=确认
|
||||||
|
ErrorTitle=错误
|
||||||
|
|
||||||
|
; *** SetupLdr messages
|
||||||
|
SetupLdrStartupMessage=现在将安装 %1。您想要继续吗?
|
||||||
|
LdrCannotCreateTemp=无法创建临时文件。安装程序已中止
|
||||||
|
LdrCannotExecTemp=无法执行临时目录中的文件。安装程序已中止
|
||||||
|
HelpTextNote=
|
||||||
|
|
||||||
|
; *** 启动错误消息
|
||||||
|
LastErrorMessage=%1。%n%n错误 %2: %3
|
||||||
|
SetupFileMissing=安装目录中缺少文件 %1。请修正这个问题或者获取程序的新副本。
|
||||||
|
SetupFileCorrupt=安装文件已损坏。请获取程序的新副本。
|
||||||
|
SetupFileCorruptOrWrongVer=安装文件已损坏,或是与这个安装程序的版本不兼容。请修正这个问题或获取新的程序副本。
|
||||||
|
InvalidParameter=无效的命令行参数:%n%n%1
|
||||||
|
SetupAlreadyRunning=安装程序正在运行。
|
||||||
|
WindowsVersionNotSupported=此程序不支持当前计算机运行的 Windows 版本。
|
||||||
|
WindowsServicePackRequired=此程序需要 %1 服务包 %2 或更高版本。
|
||||||
|
NotOnThisPlatform=此程序不能在 %1 上运行。
|
||||||
|
OnlyOnThisPlatform=此程序只能在 %1 上运行。
|
||||||
|
OnlyOnTheseArchitectures=此程序只能安装到为下列处理器架构设计的 Windows 版本中:%n%n%1
|
||||||
|
WinVersionTooLowError=此程序需要 %1 版本 %2 或更高。
|
||||||
|
WinVersionTooHighError=此程序不能安装于 %1 版本 %2 或更高。
|
||||||
|
AdminPrivilegesRequired=在安装此程序时您必须以管理员身份登录。
|
||||||
|
PowerUserPrivilegesRequired=在安装此程序时您必须以管理员身份或有权限的用户组身份登录。
|
||||||
|
SetupAppRunningError=安装程序发现 %1 当前正在运行。%n%n请先关闭正在运行的程序,然后点击“确定”继续,或点击“取消”退出。
|
||||||
|
UninstallAppRunningError=卸载程序发现 %1 当前正在运行。%n%n请先关闭正在运行的程序,然后点击“确定”继续,或点击“取消”退出。
|
||||||
|
|
||||||
|
; *** 启动问题
|
||||||
|
PrivilegesRequiredOverrideTitle=选择安装程序模式
|
||||||
|
PrivilegesRequiredOverrideInstruction=选择安装模式
|
||||||
|
PrivilegesRequiredOverrideText1=%1 可以为所有用户安装(需要管理员权限),或仅为您安装。
|
||||||
|
PrivilegesRequiredOverrideText2=%1 可以仅为您安装,或为所有用户安装(需要管理员权限)。
|
||||||
|
PrivilegesRequiredOverrideAllUsers=为所有用户安装(&A)
|
||||||
|
PrivilegesRequiredOverrideAllUsersRecommended=为所有用户安装(&A) (建议选项)
|
||||||
|
PrivilegesRequiredOverrideCurrentUser=仅为我安装(&M)
|
||||||
|
PrivilegesRequiredOverrideCurrentUserRecommended=仅为我安装(&M) (建议选项)
|
||||||
|
|
||||||
|
; *** 其他错误
|
||||||
|
ErrorCreatingDir=安装程序无法创建目录“%1”
|
||||||
|
ErrorTooManyFilesInDir=无法在目录“%1”中创建文件,因为里面包含太多文件
|
||||||
|
|
||||||
|
; *** 安装程序公共消息
|
||||||
|
ExitSetupTitle=退出安装程序
|
||||||
|
ExitSetupMessage=安装程序尚未完成。如果现在退出,将不会安装该程序。%n%n您之后可以再次运行安装程序完成安装。%n%n现在退出安装程序吗?
|
||||||
|
AboutSetupMenuItem=关于安装程序(&A)...
|
||||||
|
AboutSetupTitle=关于安装程序
|
||||||
|
AboutSetupMessage=%1 版本 %2%n%3%n%n%1 主页:%n%4
|
||||||
|
AboutSetupNote=
|
||||||
|
TranslatorNote=简体中文翻译由Kira(847320916@qq.com)维护。项目地址:https://github.com/kira-96/Inno-Setup-Chinese-Simplified-Translation
|
||||||
|
|
||||||
|
; *** 按钮
|
||||||
|
ButtonBack=< 上一步(&B)
|
||||||
|
ButtonNext=下一步(&N) >
|
||||||
|
ButtonInstall=安装(&I)
|
||||||
|
ButtonOK=确定
|
||||||
|
ButtonCancel=取消
|
||||||
|
ButtonYes=是(&Y)
|
||||||
|
ButtonYesToAll=全是(&A)
|
||||||
|
ButtonNo=否(&N)
|
||||||
|
ButtonNoToAll=全否(&O)
|
||||||
|
ButtonFinish=完成(&F)
|
||||||
|
ButtonBrowse=浏览(&B)...
|
||||||
|
ButtonWizardBrowse=浏览(&R)...
|
||||||
|
ButtonNewFolder=新建文件夹(&M)
|
||||||
|
|
||||||
|
; *** “选择语言”对话框消息
|
||||||
|
SelectLanguageTitle=选择安装语言
|
||||||
|
SelectLanguageLabel=选择安装时使用的语言。
|
||||||
|
|
||||||
|
; *** 公共向导文字
|
||||||
|
ClickNext=点击“下一步”继续,或点击“取消”退出安装程序。
|
||||||
|
BeveledLabel=
|
||||||
|
BrowseDialogTitle=浏览文件夹
|
||||||
|
BrowseDialogLabel=在下面的列表中选择一个文件夹,然后点击“确定”。
|
||||||
|
NewFolderName=新建文件夹
|
||||||
|
|
||||||
|
; *** “欢迎”向导页
|
||||||
|
WelcomeLabel1=欢迎使用 [name] 安装向导
|
||||||
|
WelcomeLabel2=现在将安装 [name/ver] 到您的电脑中。%n%n建议您在继续安装前关闭所有其他应用程序。
|
||||||
|
|
||||||
|
; *** “密码”向导页
|
||||||
|
WizardPassword=密码
|
||||||
|
PasswordLabel1=这个安装程序有密码保护。
|
||||||
|
PasswordLabel3=请输入密码,然后点击“下一步”继续。密码区分大小写。
|
||||||
|
PasswordEditLabel=密码(&P):
|
||||||
|
IncorrectPassword=您输入的密码不正确,请重新输入。
|
||||||
|
|
||||||
|
; *** “许可协议”向导页
|
||||||
|
WizardLicense=许可协议
|
||||||
|
LicenseLabel=请在继续安装前阅读以下重要信息。
|
||||||
|
LicenseLabel3=请仔细阅读下列许可协议。在继续安装前您必须同意这些协议条款。
|
||||||
|
LicenseAccepted=我同意此协议(&A)
|
||||||
|
LicenseNotAccepted=我不同意此协议(&D)
|
||||||
|
|
||||||
|
; *** “信息”向导页
|
||||||
|
WizardInfoBefore=信息
|
||||||
|
InfoBeforeLabel=请在继续安装前阅读以下重要信息。
|
||||||
|
InfoBeforeClickLabel=准备好继续安装后,点击“下一步”。
|
||||||
|
WizardInfoAfter=信息
|
||||||
|
InfoAfterLabel=请在继续安装前阅读以下重要信息。
|
||||||
|
InfoAfterClickLabel=准备好继续安装后,点击“下一步”。
|
||||||
|
|
||||||
|
; *** “用户信息”向导页
|
||||||
|
WizardUserInfo=用户信息
|
||||||
|
UserInfoDesc=请输入您的信息。
|
||||||
|
UserInfoName=用户名(&U):
|
||||||
|
UserInfoOrg=组织(&O):
|
||||||
|
UserInfoSerial=序列号(&S):
|
||||||
|
UserInfoNameRequired=您必须输入用户名。
|
||||||
|
|
||||||
|
; *** “选择目标目录”向导页
|
||||||
|
WizardSelectDir=选择目标位置
|
||||||
|
SelectDirDesc=您想将 [name] 安装在哪里?
|
||||||
|
SelectDirLabel3=安装程序将安装 [name] 到下面的文件夹中。
|
||||||
|
SelectDirBrowseLabel=点击“下一步”继续。如果您想选择其他文件夹,点击“浏览”。
|
||||||
|
DiskSpaceGBLabel=至少需要有 [gb] GB 的可用磁盘空间。
|
||||||
|
DiskSpaceMBLabel=至少需要有 [mb] MB 的可用磁盘空间。
|
||||||
|
CannotInstallToNetworkDrive=安装程序无法安装到一个网络驱动器。
|
||||||
|
CannotInstallToUNCPath=安装程序无法安装到一个 UNC 路径。
|
||||||
|
InvalidPath=您必须输入一个带驱动器卷标的完整路径,例如:%n%nC:\APP%n%n或UNC路径:%n%n\\server\share
|
||||||
|
InvalidDrive=您选定的驱动器或 UNC 共享不存在或不能访问。请选择其他位置。
|
||||||
|
DiskSpaceWarningTitle=磁盘空间不足
|
||||||
|
DiskSpaceWarning=安装程序至少需要 %1 KB 的可用空间才能安装,但选定驱动器只有 %2 KB 的可用空间。%n%n您一定要继续吗?
|
||||||
|
DirNameTooLong=文件夹名称或路径太长。
|
||||||
|
InvalidDirName=文件夹名称无效。
|
||||||
|
BadDirName32=文件夹名称不能包含下列任何字符:%n%n%1
|
||||||
|
DirExistsTitle=文件夹已存在
|
||||||
|
DirExists=文件夹:%n%n%1%n%n已经存在。您一定要安装到这个文件夹中吗?
|
||||||
|
DirDoesntExistTitle=文件夹不存在
|
||||||
|
DirDoesntExist=文件夹:%n%n%1%n%n不存在。您想要创建此文件夹吗?
|
||||||
|
|
||||||
|
; *** “选择组件”向导页
|
||||||
|
WizardSelectComponents=选择组件
|
||||||
|
SelectComponentsDesc=您想安装哪些程序组件?
|
||||||
|
SelectComponentsLabel2=选中您想安装的组件;取消您不想安装的组件。然后点击“下一步”继续。
|
||||||
|
FullInstallation=完全安装
|
||||||
|
; if possible don't translate 'Compact' as 'Minimal' (I mean 'Minimal' in your language)
|
||||||
|
CompactInstallation=简洁安装
|
||||||
|
CustomInstallation=自定义安装
|
||||||
|
NoUninstallWarningTitle=组件已存在
|
||||||
|
NoUninstallWarning=安装程序检测到下列组件已安装在您的电脑中:%n%n%1%n%n取消选中这些组件不会卸载它们。%n%n确定要继续吗?
|
||||||
|
ComponentSize1=%1 KB
|
||||||
|
ComponentSize2=%1 MB
|
||||||
|
ComponentsDiskSpaceGBLabel=当前选择的组件需要至少 [gb] GB 的磁盘空间。
|
||||||
|
ComponentsDiskSpaceMBLabel=当前选择的组件需要至少 [mb] MB 的磁盘空间。
|
||||||
|
|
||||||
|
; *** “选择附加任务”向导页
|
||||||
|
WizardSelectTasks=选择附加任务
|
||||||
|
SelectTasksDesc=您想要安装程序执行哪些附加任务?
|
||||||
|
SelectTasksLabel2=选择您想要安装程序在安装 [name] 时执行的附加任务,然后点击“下一步”。
|
||||||
|
|
||||||
|
; *** “选择开始菜单文件夹”向导页
|
||||||
|
WizardSelectProgramGroup=选择开始菜单文件夹
|
||||||
|
SelectStartMenuFolderDesc=安装程序应该在哪里放置程序的快捷方式?
|
||||||
|
SelectStartMenuFolderLabel3=安装程序将在下列“开始”菜单文件夹中创建程序的快捷方式。
|
||||||
|
SelectStartMenuFolderBrowseLabel=点击“下一步”继续。如果您想选择其他文件夹,点击“浏览”。
|
||||||
|
MustEnterGroupName=您必须输入一个文件夹名。
|
||||||
|
GroupNameTooLong=文件夹名或路径太长。
|
||||||
|
InvalidGroupName=无效的文件夹名字。
|
||||||
|
BadGroupName=文件夹名不能包含下列任何字符:%n%n%1
|
||||||
|
NoProgramGroupCheck2=不创建开始菜单文件夹(&D)
|
||||||
|
|
||||||
|
; *** “准备安装”向导页
|
||||||
|
WizardReady=准备安装
|
||||||
|
ReadyLabel1=安装程序准备就绪,现在可以开始安装 [name] 到您的电脑。
|
||||||
|
ReadyLabel2a=点击“安装”继续此安装程序。如果您想重新考虑或修改任何设置,点击“上一步”。
|
||||||
|
ReadyLabel2b=点击“安装”继续此安装程序。
|
||||||
|
ReadyMemoUserInfo=用户信息:
|
||||||
|
ReadyMemoDir=目标位置:
|
||||||
|
ReadyMemoType=安装类型:
|
||||||
|
ReadyMemoComponents=已选择组件:
|
||||||
|
ReadyMemoGroup=开始菜单文件夹:
|
||||||
|
ReadyMemoTasks=附加任务:
|
||||||
|
|
||||||
|
; *** TExtractionWizardPage 向导页面与 ExtractArchive
|
||||||
|
ExtractingLabel=正在解压文件...
|
||||||
|
ButtonStopExtraction=停止解压(&S)
|
||||||
|
StopExtraction=您确定要停止解压吗?
|
||||||
|
ErrorExtractionAborted=解压已中止
|
||||||
|
ErrorExtractionFailed=解压失败:%1
|
||||||
|
|
||||||
|
; *** 压缩文件解压失败详情
|
||||||
|
ArchiveIncorrectPassword=压缩文件密码不正确
|
||||||
|
ArchiveIsCorrupted=压缩文件已损坏
|
||||||
|
ArchiveUnsupportedFormat=不支持的压缩文件格式
|
||||||
|
|
||||||
|
; *** TDownloadWizardPage 向导页面和 DownloadTemporaryFile
|
||||||
|
DownloadingLabel2=正在下载文件...
|
||||||
|
ButtonStopDownload=停止下载(&S)
|
||||||
|
StopDownload=您确定要停止下载吗?
|
||||||
|
ErrorDownloadAborted=下载已中止
|
||||||
|
ErrorDownloadFailed=下载失败:%1 %2
|
||||||
|
ErrorDownloadSizeFailed=获取下载大小失败:%1 %2
|
||||||
|
ErrorProgress=无效的进度:%1 / %2
|
||||||
|
ErrorFileSize=文件大小错误:预期 %1,实际 %2
|
||||||
|
|
||||||
|
; *** “正在准备安装”向导页
|
||||||
|
WizardPreparing=正在准备安装
|
||||||
|
PreparingDesc=安装程序正在准备安装 [name] 到您的电脑。
|
||||||
|
PreviousInstallNotCompleted=先前的程序安装或卸载未完成,您需要重启您的电脑以完成。%n%n在重启电脑后,再次运行安装程序以完成 [name] 的安装。
|
||||||
|
CannotContinue=安装程序不能继续。请点击“取消”退出。
|
||||||
|
ApplicationsFound=以下应用程序正在使用将由安装程序更新的文件。建议您允许安装程序自动关闭这些应用程序。
|
||||||
|
ApplicationsFound2=以下应用程序正在使用将由安装程序更新的文件。建议您允许安装程序自动关闭这些应用程序。安装完成后,安装程序将尝试重新启动这些应用程序。
|
||||||
|
CloseApplications=自动关闭应用程序(&A)
|
||||||
|
DontCloseApplications=不要关闭应用程序(&D)
|
||||||
|
ErrorCloseApplications=安装程序无法自动关闭所有应用程序。建议您在继续之前,关闭所有在使用需要由安装程序更新的文件的应用程序。
|
||||||
|
PrepareToInstallNeedsRestart=安装程序必须重启您的计算机。计算机重启后,请再次运行安装程序以完成 [name] 的安装。%n%n是否立即重新启动?
|
||||||
|
|
||||||
|
; *** “正在安装”向导页
|
||||||
|
WizardInstalling=正在安装
|
||||||
|
InstallingLabel=安装程序正在安装 [name] 到您的电脑,请稍候。
|
||||||
|
|
||||||
|
; *** “安装完成”向导页
|
||||||
|
FinishedHeadingLabel=[name] 安装完成
|
||||||
|
FinishedLabelNoIcons=安装程序已在您的电脑中安装了 [name]。
|
||||||
|
FinishedLabel=安装程序已在您的电脑中安装了 [name]。您可以通过已安装的快捷方式运行此应用程序。
|
||||||
|
ClickFinish=点击“完成”退出安装程序。
|
||||||
|
FinishedRestartLabel=为完成 [name] 的安装,安装程序必须重新启动您的电脑。要立即重启吗?
|
||||||
|
FinishedRestartMessage=为完成 [name] 的安装,安装程序必须重新启动您的电脑。%n%n要立即重启吗?
|
||||||
|
ShowReadmeCheck=是,我想查阅自述文件
|
||||||
|
YesRadio=是,立即重启电脑(&Y)
|
||||||
|
NoRadio=否,稍后重启电脑(&N)
|
||||||
|
; used for example as 'Run MyProg.exe'
|
||||||
|
RunEntryExec=运行 %1
|
||||||
|
; used for example as 'View Readme.txt'
|
||||||
|
RunEntryShellExec=查阅 %1
|
||||||
|
|
||||||
|
; *** “安装程序需要下一张磁盘”提示
|
||||||
|
ChangeDiskTitle=安装程序需要下一张磁盘
|
||||||
|
SelectDiskLabel2=请插入磁盘 %1 并点击“确定”。%n%n如果这个磁盘中的文件可以在下列文件夹之外的文件夹中找到,请输入正确的路径或点击“浏览”。
|
||||||
|
PathLabel=路径(&P):
|
||||||
|
FileNotInDir2=“%2”中找不到文件“%1”。请插入正确的磁盘或选择其他文件夹。
|
||||||
|
SelectDirectoryLabel=请指定下一张磁盘的位置。
|
||||||
|
|
||||||
|
; *** 安装阶段消息
|
||||||
|
SetupAborted=安装程序未完成安装。%n%n请修正这个问题并重新运行安装程序。
|
||||||
|
AbortRetryIgnoreSelectAction=选择操作
|
||||||
|
AbortRetryIgnoreRetry=重试(&T)
|
||||||
|
AbortRetryIgnoreIgnore=忽略错误并继续(&I)
|
||||||
|
AbortRetryIgnoreCancel=关闭安装程序
|
||||||
|
RetryCancelSelectAction=选择操作
|
||||||
|
RetryCancelRetry=重试(&T)
|
||||||
|
RetryCancelCancel=取消(&C)
|
||||||
|
|
||||||
|
; *** 安装状态消息
|
||||||
|
StatusClosingApplications=正在关闭应用程序...
|
||||||
|
StatusCreateDirs=正在创建目录...
|
||||||
|
StatusExtractFiles=正在提取文件...
|
||||||
|
StatusDownloadFiles=正在下载文件...
|
||||||
|
StatusCreateIcons=正在创建快捷方式...
|
||||||
|
StatusCreateIniEntries=正在创建 INI 条目...
|
||||||
|
StatusCreateRegistryEntries=正在创建注册表条目...
|
||||||
|
StatusRegisterFiles=正在注册文件...
|
||||||
|
StatusSavingUninstall=正在保存卸载信息...
|
||||||
|
StatusRunProgram=正在完成安装...
|
||||||
|
StatusRestartingApplications=正在重启应用程序...
|
||||||
|
StatusRollback=正在撤销更改...
|
||||||
|
|
||||||
|
; *** 其他错误
|
||||||
|
ErrorInternal2=内部错误:%1
|
||||||
|
ErrorFunctionFailedNoCode=%1 失败
|
||||||
|
ErrorFunctionFailed=%1 失败;错误代码 %2
|
||||||
|
ErrorFunctionFailedWithMessage=%1 失败;错误代码 %2.%n%3
|
||||||
|
ErrorExecutingProgram=无法执行文件:%n%1
|
||||||
|
|
||||||
|
; *** 注册表错误
|
||||||
|
ErrorRegOpenKey=打开注册表项时出错:%n%1\%2
|
||||||
|
ErrorRegCreateKey=创建注册表项时出错:%n%1\%2
|
||||||
|
ErrorRegWriteKey=写入注册表项时出错:%n%1\%2
|
||||||
|
|
||||||
|
; *** INI 错误
|
||||||
|
ErrorIniEntry=在文件“%1”中创建 INI 条目时出错。
|
||||||
|
|
||||||
|
; *** 文件复制错误
|
||||||
|
FileAbortRetryIgnoreSkipNotRecommended=跳过此文件(&S) (不推荐)
|
||||||
|
FileAbortRetryIgnoreIgnoreNotRecommended=忽略错误并继续(&I) (不推荐)
|
||||||
|
SourceIsCorrupted=源文件已损坏
|
||||||
|
SourceDoesntExist=源文件“%1”不存在
|
||||||
|
SourceVerificationFailed=源文件验证失败: %1
|
||||||
|
VerificationSignatureDoesntExist=签名文件“%1”不存在
|
||||||
|
VerificationSignatureInvalid=签名文件“%1”无效
|
||||||
|
VerificationKeyNotFound=签名文件“%1”使用了未知密钥
|
||||||
|
VerificationFileNameIncorrect=文件名不正确
|
||||||
|
VerificationFileTagIncorrect=文件标签不正确
|
||||||
|
VerificationFileSizeIncorrect=文件大小不正确
|
||||||
|
VerificationFileHashIncorrect=文件哈希值不正确
|
||||||
|
ExistingFileReadOnly2=无法替换现有文件,它是只读的。
|
||||||
|
ExistingFileReadOnlyRetry=移除只读属性并重试(&R)
|
||||||
|
ExistingFileReadOnlyKeepExisting=保留现有文件(&K)
|
||||||
|
ErrorReadingExistingDest=尝试读取现有文件时出错:
|
||||||
|
FileExistsSelectAction=选择操作
|
||||||
|
FileExists2=文件已经存在。
|
||||||
|
FileExistsOverwriteExisting=覆盖已存在的文件(&O)
|
||||||
|
FileExistsKeepExisting=保留现有的文件(&K)
|
||||||
|
FileExistsOverwriteOrKeepAll=为所有冲突文件执行此操作(&D)
|
||||||
|
ExistingFileNewerSelectAction=选择操作
|
||||||
|
ExistingFileNewer2=现有的文件比安装程序将要安装的文件还要新。
|
||||||
|
ExistingFileNewerOverwriteExisting=覆盖已存在的文件(&O)
|
||||||
|
ExistingFileNewerKeepExisting=保留现有的文件(&K) (推荐)
|
||||||
|
ExistingFileNewerOverwriteOrKeepAll=为所有冲突文件执行此操作(&D)
|
||||||
|
ErrorChangingAttr=尝试更改下列现有文件的属性时出错:
|
||||||
|
ErrorCreatingTemp=尝试在目标目录创建文件时出错:
|
||||||
|
ErrorReadingSource=尝试读取下列源文件时出错:
|
||||||
|
ErrorCopying=尝试复制下列文件时出错:
|
||||||
|
ErrorDownloading=下载文件时出错:
|
||||||
|
ErrorExtracting=解压压缩文件时出错:
|
||||||
|
ErrorReplacingExistingFile=尝试替换现有文件时出错:
|
||||||
|
ErrorRestartReplace=重启并替换失败:
|
||||||
|
ErrorRenamingTemp=尝试重命名下列目标目录中的一个文件时出错:
|
||||||
|
ErrorRegisterServer=无法注册 DLL/OCX:%1
|
||||||
|
ErrorRegSvr32Failed=RegSvr32 失败;退出代码 %1
|
||||||
|
ErrorRegisterTypeLib=无法注册类库:%1
|
||||||
|
|
||||||
|
; *** 卸载显示名字标记
|
||||||
|
; used for example as 'My Program (32-bit)'
|
||||||
|
UninstallDisplayNameMark=%1 (%2)
|
||||||
|
; used for example as 'My Program (32-bit, All users)'
|
||||||
|
UninstallDisplayNameMarks=%1 (%2, %3)
|
||||||
|
UninstallDisplayNameMark32Bit=32 位
|
||||||
|
UninstallDisplayNameMark64Bit=64 位
|
||||||
|
UninstallDisplayNameMarkAllUsers=所有用户
|
||||||
|
UninstallDisplayNameMarkCurrentUser=当前用户
|
||||||
|
|
||||||
|
; *** 安装后错误
|
||||||
|
ErrorOpeningReadme=尝试打开自述文件时出错。
|
||||||
|
ErrorRestartingComputer=安装程序无法重启电脑,请手动重启。
|
||||||
|
|
||||||
|
; *** 卸载消息
|
||||||
|
UninstallNotFound=文件“%1”不存在。无法卸载。
|
||||||
|
UninstallOpenError=文件“%1”不能被打开。无法卸载。
|
||||||
|
UninstallUnsupportedVer=此版本的卸载程序无法识别卸载日志文件“%1”的格式。无法卸载
|
||||||
|
UninstallUnknownEntry=卸载日志中遇到一个未知条目 (%1)
|
||||||
|
ConfirmUninstall=您确认要完全移除 %1 及其所有组件吗?
|
||||||
|
UninstallOnlyOnWin64=仅允许在 64 位 Windows 中卸载此程序。
|
||||||
|
OnlyAdminCanUninstall=仅使用管理员权限的用户能完成此卸载。
|
||||||
|
UninstallStatusLabel=正在从您的电脑中移除 %1,请稍候。
|
||||||
|
UninstalledAll=已顺利从您的电脑中移除 %1。
|
||||||
|
UninstalledMost=%1 卸载完成。%n%n有部分内容未能被删除,但您可以手动删除它们。
|
||||||
|
UninstalledAndNeedsRestart=为完成 %1 的卸载,需要重启您的电脑。%n%n立即重启电脑吗?
|
||||||
|
UninstallDataCorrupted=文件“%1”已损坏。无法卸载
|
||||||
|
|
||||||
|
; *** 卸载状态消息
|
||||||
|
ConfirmDeleteSharedFileTitle=删除共享的文件吗?
|
||||||
|
ConfirmDeleteSharedFile2=系统表示下列共享的文件已不有其他程序使用。您希望卸载程序删除这些共享的文件吗?%n%n如果删除这些文件,但仍有程序在使用这些文件,则这些程序可能出现异常。如果您不能确定,请选择“否”,在系统中保留这些文件以免引发问题。
|
||||||
|
SharedFileNameLabel=文件名:
|
||||||
|
SharedFileLocationLabel=位置:
|
||||||
|
WizardUninstalling=卸载状态
|
||||||
|
StatusUninstalling=正在卸载 %1...
|
||||||
|
|
||||||
|
; *** Shutdown block reasons
|
||||||
|
ShutdownBlockReasonInstallingApp=正在安装 %1。
|
||||||
|
ShutdownBlockReasonUninstallingApp=正在卸载 %1。
|
||||||
|
|
||||||
|
; The custom messages below aren't used by Setup itself, but if you make
|
||||||
|
; use of them in your scripts, you'll want to translate them.
|
||||||
|
|
||||||
|
[CustomMessages]
|
||||||
|
|
||||||
|
NameAndVersion=%1 版本 %2
|
||||||
|
AdditionalIcons=附加快捷方式:
|
||||||
|
CreateDesktopIcon=创建桌面快捷方式(&D)
|
||||||
|
CreateQuickLaunchIcon=创建快速启动栏快捷方式(&Q)
|
||||||
|
ProgramOnTheWeb=%1 网站
|
||||||
|
UninstallProgram=卸载 %1
|
||||||
|
LaunchProgram=运行 %1
|
||||||
|
AssocFileExtension=将 %2 文件扩展名与 %1 建立关联(&A)
|
||||||
|
AssocingFileExtension=正在将 %2 文件扩展名与 %1 建立关联...
|
||||||
|
AutoStartProgramGroupDescription=启动:
|
||||||
|
AutoStartProgram=自动启动 %1
|
||||||
|
AddonHostProgramNotFound=您选择的文件夹中无法找到 %1。%n%n您要继续吗?
|
||||||
@@ -31,9 +31,9 @@ DisableDirPage=no
|
|||||||
UninstallDisplayIcon={app}\{#MyAppExeName}
|
UninstallDisplayIcon={app}\{#MyAppExeName}
|
||||||
SetupLogging=yes
|
SetupLogging=yes
|
||||||
|
|
||||||
; 向导语言:使用 Inno 自带的 Default.isl(英文)。若本机存在 Languages\ChineseSimplified.isl,
|
; 向导语言:默认简体中文;语言文件与本 .iss 同目录(ChineseSimplified.isl),无需复制到 Inno 目录
|
||||||
; 可改为: Name: "chinesesimp"; MessagesFile: "compiler:Languages\ChineseSimplified.isl"
|
|
||||||
[Languages]
|
[Languages]
|
||||||
|
Name: "chinesesimplified"; MessagesFile: "ChineseSimplified.isl"
|
||||||
Name: "english"; MessagesFile: "compiler:Default.isl"
|
Name: "english"; MessagesFile: "compiler:Default.isl"
|
||||||
|
|
||||||
[Tasks]
|
[Tasks]
|
||||||
|
|||||||
@@ -1,6 +1,19 @@
|
|||||||
@echo off
|
@echo off
|
||||||
chcp 65001 >nul
|
chcp 65001 >nul
|
||||||
cd /d "%~dp0"
|
cd /d "%~dp0"
|
||||||
|
|
||||||
|
if not exist "%~dp0build-installer.ps1" (
|
||||||
|
echo [错误] 未找到同目录下的 build-installer.ps1
|
||||||
|
echo.
|
||||||
|
echo 请从仓库内运行本脚本,例如:
|
||||||
|
echo qhmes\yy-admin-master\installer\build-installer.bat
|
||||||
|
echo 不要只复制 .bat 到桌面;需与 build-installer.ps1 放在同一目录。
|
||||||
|
echo.
|
||||||
|
echo 当前目录: %~dp0
|
||||||
|
pause
|
||||||
|
exit /b 1
|
||||||
|
)
|
||||||
|
|
||||||
echo Running build-installer.ps1 ...
|
echo Running build-installer.ps1 ...
|
||||||
powershell -NoProfile -ExecutionPolicy Bypass -File "%~dp0build-installer.ps1"
|
powershell -NoProfile -ExecutionPolicy Bypass -File "%~dp0build-installer.ps1"
|
||||||
echo.
|
echo.
|
||||||
|
|||||||
@@ -1,16 +1,54 @@
|
|||||||
# Release publish + WebView2 bootstrap download + Inno Setup ISCC
|
# Release publish + WebView2 bootstrap download + Inno Setup ISCC
|
||||||
# Requires Inno Setup 6 (ISCC.exe)
|
# Requires Inno Setup 6 (ISCC.exe)
|
||||||
|
#
|
||||||
|
# 注意:与 YY.Admin\publish.cmd 输出目录不同;本脚本使用 bin\Release\...\win-x64\publish。
|
||||||
|
# 本地 F5 / 双击 bin 下 exe 时,SQLite 实际写在 %LocalAppData%\YY.Admin\Data\(不是工程或 bin 目录)。
|
||||||
|
# 同步步骤会优先把该目录下的库打进 publish,与其它机上「和你本机一致」的安装模板对齐。
|
||||||
|
|
||||||
|
param(
|
||||||
|
[switch]$NoLocalSync
|
||||||
|
)
|
||||||
|
|
||||||
$ErrorActionPreference = 'Stop'
|
$ErrorActionPreference = 'Stop'
|
||||||
$Root = Split-Path -Parent $PSScriptRoot
|
$Root = Split-Path -Parent $PSScriptRoot
|
||||||
$Csproj = Join-Path $Root 'YY.Admin\YY.Admin.csproj'
|
$Csproj = Join-Path $Root 'YY.Admin\YY.Admin.csproj'
|
||||||
$PublishRel = 'YY.Admin\bin\Release\net8.0-windows10.0.19041\win-x64\publish'
|
$Tfm = 'net8.0-windows10.0.19041'
|
||||||
|
$Rid = 'win-x64'
|
||||||
|
$BinReleaseWin64 = Join-Path $Root "YY.Admin\bin\Release\$Tfm\$Rid"
|
||||||
|
$BinDebugWin64 = Join-Path $Root "YY.Admin\bin\Debug\$Tfm\$Rid"
|
||||||
|
$PublishRel = "YY.Admin\bin\Release\$Tfm\$Rid\publish"
|
||||||
$PublishDir = Join-Path $Root $PublishRel
|
$PublishDir = Join-Path $Root $PublishRel
|
||||||
|
$ProjAdmin = Join-Path $Root 'YY.Admin'
|
||||||
|
# 与 SqlSugar 解析一致:相对路径 SQLite 落在当前 Windows 用户的 LocalAppData
|
||||||
|
$DevUserDataDir = if ($env:LOCALAPPDATA) { Join-Path $env:LOCALAPPDATA 'YY.Admin\Data' } else { '' }
|
||||||
|
$DevUserAppSettingsDir = if ($env:LOCALAPPDATA) { Join-Path $env:LOCALAPPDATA 'YY.Admin\AppSettings' } else { '' }
|
||||||
$RedistDir = Join-Path $PSScriptRoot 'redist'
|
$RedistDir = Join-Path $PSScriptRoot 'redist'
|
||||||
$WebView2Exe = Join-Path $RedistDir 'MicrosoftEdgeWebview2Setup.exe'
|
$WebView2Exe = Join-Path $RedistDir 'MicrosoftEdgeWebview2Setup.exe'
|
||||||
$WebView2Url = 'https://go.microsoft.com/fwlink/p/?LinkId=2124703'
|
$WebView2Url = 'https://go.microsoft.com/fwlink/p/?LinkId=2124703'
|
||||||
|
$SnapshotDir = Join-Path ([System.IO.Path]::GetTempPath()) ("yyadmin-publish-snap-{0}" -f [Guid]::NewGuid().ToString('n'))
|
||||||
|
|
||||||
Write-Host '>>> dotnet publish (Release, win-x64)...'
|
Write-Host '>>> dotnet publish (Release, win-x64)...'
|
||||||
|
# publish 会清空输出目录:若你平时只在 publish 里测,先把其中的库暂存,供同步步骤一并参与“最新”比较
|
||||||
|
$hadPublishRoot = Test-Path -LiteralPath $PublishDir
|
||||||
|
if ($hadPublishRoot -and -not $NoLocalSync) {
|
||||||
|
$snapDb = @()
|
||||||
|
foreach ($dbName in @('Admin.NET.db', 'Slave.db')) {
|
||||||
|
$pp = Join-Path $PublishDir $dbName
|
||||||
|
if (Test-Path -LiteralPath $pp) { $snapDb += , $pp }
|
||||||
|
}
|
||||||
|
$pubApps = Join-Path $PublishDir 'AppSettings'
|
||||||
|
$hasPubApps = Test-Path -LiteralPath $pubApps
|
||||||
|
if ($snapDb.Count -gt 0 -or $hasPubApps) {
|
||||||
|
New-Item -ItemType Directory -Force -Path $SnapshotDir | Out-Null
|
||||||
|
foreach ($p in $snapDb) {
|
||||||
|
Copy-Item -LiteralPath $p -Destination (Join-Path $SnapshotDir (Split-Path $p -Leaf)) -Force
|
||||||
|
}
|
||||||
|
if ($hasPubApps) {
|
||||||
|
Copy-Item -LiteralPath $pubApps -Destination (Join-Path $SnapshotDir 'AppSettings') -Recurse -Force
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
dotnet publish $Csproj -c Release `
|
dotnet publish $Csproj -c Release `
|
||||||
-p:IncludeNativeLibrariesForSelfExtract=true `
|
-p:IncludeNativeLibrariesForSelfExtract=true `
|
||||||
-p:EnableCompressionInSingleFile=true `
|
-p:EnableCompressionInSingleFile=true `
|
||||||
@@ -25,6 +63,81 @@ if (-not (Test-Path $cfgPublish)) {
|
|||||||
throw "Missing Configuration\appsettings.json under publish (ExcludeFromSingleFile required). Path: $cfgPublish"
|
throw "Missing Configuration\appsettings.json under publish (ExcludeFromSingleFile required). Path: $cfgPublish"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (-not $NoLocalSync) {
|
||||||
|
Write-Host '>>> Sync local runtime data into publish (databases + AppSettings, match local test)...'
|
||||||
|
|
||||||
|
function Get-BestExistingPath {
|
||||||
|
param([string[]]$Paths)
|
||||||
|
$bestItem = $null
|
||||||
|
foreach ($p in $Paths) {
|
||||||
|
if (-not $p -or -not (Test-Path -LiteralPath $p)) { continue }
|
||||||
|
$fi = Get-Item -LiteralPath $p
|
||||||
|
if (-not $bestItem) { $bestItem = $fi; continue }
|
||||||
|
if ($fi.LastWriteTime -gt $bestItem.LastWriteTime) { $bestItem = $fi; continue }
|
||||||
|
# 修改时间相同(例如复制残留)时优先体积更大的一份,一般数据更全
|
||||||
|
if ($fi.LastWriteTime -eq $bestItem.LastWriteTime -and $fi.Length -gt $bestItem.Length) { $bestItem = $fi }
|
||||||
|
}
|
||||||
|
if ($bestItem) { return $bestItem.FullName }
|
||||||
|
return $null
|
||||||
|
}
|
||||||
|
|
||||||
|
# 同名库:当前用户 LocalAppData(F5 真数据源)、项目根、publish.cmd、bin、publish、快照…
|
||||||
|
foreach ($dbName in @('Admin.NET.db', 'Slave.db')) {
|
||||||
|
$paths = @()
|
||||||
|
if ($DevUserDataDir -and (Test-Path -LiteralPath $DevUserDataDir)) {
|
||||||
|
$paths += (Join-Path $DevUserDataDir $dbName)
|
||||||
|
}
|
||||||
|
$paths += @(
|
||||||
|
(Join-Path $ProjAdmin $dbName),
|
||||||
|
(Join-Path $ProjAdmin "publish\$dbName"),
|
||||||
|
(Join-Path $BinReleaseWin64 $dbName),
|
||||||
|
(Join-Path $BinDebugWin64 $dbName),
|
||||||
|
(Join-Path $BinReleaseWin64 "publish\$dbName"),
|
||||||
|
(Join-Path $BinDebugWin64 "publish\$dbName"),
|
||||||
|
(Join-Path $PublishDir $dbName)
|
||||||
|
)
|
||||||
|
if (Test-Path -LiteralPath $SnapshotDir) {
|
||||||
|
$sp = Join-Path $SnapshotDir $dbName
|
||||||
|
if (Test-Path -LiteralPath $sp) { $paths += $sp }
|
||||||
|
}
|
||||||
|
$src = Get-BestExistingPath -Paths $paths
|
||||||
|
if ($src) {
|
||||||
|
$dst = Join-Path $PublishDir $dbName
|
||||||
|
Copy-Item -LiteralPath $src -Destination $dst -Force
|
||||||
|
$dstItem = Get-Item -LiteralPath $dst
|
||||||
|
$t = $dstItem.LastWriteTime.ToString('yyyy-MM-dd HH:mm')
|
||||||
|
$len = $dstItem.Length
|
||||||
|
Write-Host " $dbName <= $src (publish 时间: $t, 大小: $len 字节)"
|
||||||
|
} else {
|
||||||
|
Write-Host " (skip) $dbName — 未在任意候选路径找到(含当前 publish 文件夹)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# AppSettings\:先 Release、再 Debug,再上一版 publish 下的 AppSettings(后者覆盖,适配只在 publish 目录测试)
|
||||||
|
foreach ($bin in @($BinReleaseWin64, $BinDebugWin64)) {
|
||||||
|
$appSettingsSrc = Join-Path $bin 'AppSettings'
|
||||||
|
if (Test-Path -LiteralPath $appSettingsSrc) {
|
||||||
|
$appSettingsDst = Join-Path $PublishDir 'AppSettings'
|
||||||
|
Copy-Item -LiteralPath $appSettingsSrc -Destination $appSettingsDst -Recurse -Force
|
||||||
|
Write-Host " AppSettings\ <= $appSettingsSrc"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$snapApps = Join-Path $SnapshotDir 'AppSettings'
|
||||||
|
if (Test-Path -LiteralPath $snapApps) {
|
||||||
|
$appSettingsDst = Join-Path $PublishDir 'AppSettings'
|
||||||
|
Copy-Item -LiteralPath $snapApps -Destination $appSettingsDst -Recurse -Force
|
||||||
|
Write-Host " AppSettings\ <= $snapApps (previous publish)"
|
||||||
|
}
|
||||||
|
# 最后覆盖为当前登录 Windows 用户在 LocalAppData 下的设置(与 F5 调试一致)
|
||||||
|
if ($DevUserAppSettingsDir -and (Test-Path -LiteralPath $DevUserAppSettingsDir)) {
|
||||||
|
$appSettingsDst = Join-Path $PublishDir 'AppSettings'
|
||||||
|
Copy-Item -LiteralPath $DevUserAppSettingsDir -Destination $appSettingsDst -Recurse -Force
|
||||||
|
Write-Host " AppSettings\ <= $DevUserAppSettingsDir (LocalAppData)"
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Write-Host '>>> Skip local sync (-NoLocalSync).'
|
||||||
|
}
|
||||||
|
|
||||||
New-Item -ItemType Directory -Force -Path $RedistDir | Out-Null
|
New-Item -ItemType Directory -Force -Path $RedistDir | Out-Null
|
||||||
if (-not (Test-Path $WebView2Exe)) {
|
if (-not (Test-Path $WebView2Exe)) {
|
||||||
Write-Host '>>> Downloading WebView2 Evergreen bootstrapper...'
|
Write-Host '>>> Downloading WebView2 Evergreen bootstrapper...'
|
||||||
|
|||||||
Reference in New Issue
Block a user