From 334e30b25794f258a56659b25919bb5edbf3c9f3 Mon Sep 17 00:00:00 2001 From: DouDou Date: Thu, 7 Aug 2025 05:59:53 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E7=A8=8B=E5=BA=8F=E4=BD=8D?= =?UTF-8?q?=E7=BD=AE=E6=A3=80=E6=9F=A5=E4=B8=8E=E9=87=8D=E5=AE=9A=E4=BD=8D?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=EF=BC=8C=E7=A1=AE=E4=BF=9D=E7=A8=8B=E5=BA=8F?= =?UTF-8?q?=E5=9C=A8=E6=AD=A3=E7=A1=AE=E7=9A=84=E6=A0=B9=E7=9B=AE=E5=BD=95?= =?UTF-8?q?=E8=BF=90=E8=A1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Update.cs | 236 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 236 insertions(+) diff --git a/Update.cs b/Update.cs index a6f49e8..bd92ebe 100644 --- a/Update.cs +++ b/Update.cs @@ -202,6 +202,12 @@ namespace CheckDownload PositionFormToBottomRight(); try { + // 首先检查程序是否在正确的根目录位置 + if (await CheckAndRelocateIfNeeded()) + { + return; // 如果需要重定位,则退出当前程序 + } + await UpdateFile(); } finally @@ -1955,5 +1961,235 @@ namespace CheckDownload CopyDirectory(subDir, targetSubDir); } } + + /// + /// 检查当前程序是否在正确的根目录位置,如果不在则复制到根目录并运行 + /// + /// 如果需要重定位并成功启动新程序返回true,否则返回false + private async Task CheckAndRelocateIfNeeded() + { + try + { + UpdateStatus("检查程序位置..."); + + // 首先尝试获取MD5文件以确定根目录 + string tempMd5Path = await DownloadMd5FileForLocationCheck(); + if (string.IsNullOrEmpty(tempMd5Path)) + { + UpdateStatus("无法获取MD5文件,继续正常更新流程"); + return false; + } + + // 解析MD5文件获取根目录 + string correctRootDirectory = await DetermineRootDirectoryFromMd5(tempMd5Path); + if (string.IsNullOrEmpty(correctRootDirectory)) + { + UpdateStatus("无法确定根目录,继续正常更新流程"); + return false; + } + + // 检查当前程序是否在正确的位置 + string currentProgramPath = Application.ExecutablePath; + string currentProgramName = Path.GetFileName(currentProgramPath); + string expectedProgramPath = Path.Combine(correctRootDirectory, GetRelativePathInProject(), currentProgramName); + + // 标准化路径以便比较 + string normalizedCurrentPath = Path.GetFullPath(currentProgramPath).ToLowerInvariant(); + string normalizedExpectedPath = Path.GetFullPath(expectedProgramPath).ToLowerInvariant(); + + if (normalizedCurrentPath.Equals(normalizedExpectedPath)) + { + UpdateStatus("程序已在正确位置"); + // 更新基准目录为正确的根目录 + _baseDirectory = correctRootDirectory; + return false; // 继续正常流程 + } + + // 程序不在正确位置,需要复制到正确位置 + UpdateStatus("程序位置不正确,正在复制到根目录..."); + + return await RelocateProgramToRoot(currentProgramPath, expectedProgramPath); + } + catch (Exception ex) + { + UpdateStatus($"检查程序位置时出错: {ex.Message}"); + return false; // 出错时继续正常流程 + } + } + + /// + /// 下载MD5文件用于位置检查(轻量级版本) + /// + /// 临时MD5文件路径,失败返回null + private async Task DownloadMd5FileForLocationCheck() + { + try + { + string tempDir = Path.GetTempPath(); + string tempMd5Path = Path.Combine(tempDir, $"{_appName}_location_check_{Guid.NewGuid()}.json"); + + // 尝试从123盘下载 + if (await DownloadFromOneDrive($"http://{OneDriveMainDomain}{OneDrivePath}", Md5File, tempMd5Path)) + { + return tempMd5Path; + } + + // 尝试从OSS下载 + if (await DownloadFileWithFallback(Md5File, tempMd5Path)) + { + return tempMd5Path; + } + + return null; + } + catch + { + return null; + } + } + + /// + /// 从MD5文件确定项目根目录 + /// + /// MD5文件路径 + /// 项目根目录路径 + private async Task DetermineRootDirectoryFromMd5(string md5FilePath) + { + try + { + var onlineData = ReadOnlineMd5File(md5FilePath); + if (!ValidateOnlineData(onlineData.Version, onlineData.Md5, onlineData.Data)) + { + return null; + } + + // 使用现有的逻辑确定基准目录 + string currentProgramName = Path.GetFileName(Application.ExecutablePath); + string programPathInMd5 = FindFileInMd5Data(onlineData.Data, currentProgramName); + + if (!string.IsNullOrEmpty(programPathInMd5)) + { + string programDirInMd5 = Path.GetDirectoryName(programPathInMd5) ?? ""; + string currentProgramDir = Path.GetDirectoryName(Application.ExecutablePath); + + if (string.IsNullOrEmpty(programDirInMd5)) + { + return currentProgramDir; // 程序就在根目录 + } + else + { + return FindProjectBaseDirectory(currentProgramDir, programDirInMd5); + } + } + + return Path.GetDirectoryName(Application.ExecutablePath); + } + catch + { + return null; + } + finally + { + // 清理临时文件 + try + { + if (File.Exists(md5FilePath)) + { + File.Delete(md5FilePath); + } + } + catch { } + } + } + + /// + /// 获取当前程序在项目中的相对路径 + /// + /// 相对路径 + private string GetRelativePathInProject() + { + try + { + // 这里可以根据实际需要调整,默认假设程序在根目录 + // 如果程序应该在子目录中,可以在这里指定 + return ""; + } + catch + { + return ""; + } + } + + /// + /// 将程序重定位到根目录并运行 + /// + /// 当前程序路径 + /// 目标程序路径 + /// 成功返回true + private async Task RelocateProgramToRoot(string currentPath, string targetPath) + { + try + { + UpdateStatus("正在复制程序到正确位置..."); + + // 确保目标目录存在 + string targetDir = Path.GetDirectoryName(targetPath); + if (!Directory.Exists(targetDir)) + { + Directory.CreateDirectory(targetDir); + } + + // 如果目标文件已存在,先尝试删除 + if (File.Exists(targetPath)) + { + try + { + // 检查目标文件是否正在运行 + string targetFileName = Path.GetFileNameWithoutExtension(targetPath); + KillProcessByBaseName(targetFileName); + + await Task.Delay(1000); // 等待进程完全退出 + File.Delete(targetPath); + } + catch + { + // 如果无法删除,创建备份名称 + string backupPath = targetPath + ".old"; + if (File.Exists(backupPath)) + { + File.Delete(backupPath); + } + File.Move(targetPath, backupPath); + } + } + + // 复制当前程序到目标位置 + File.Copy(currentPath, targetPath, true); + + UpdateStatus("程序复制完成,正在启动新程序..."); + + // 启动新程序 + var startInfo = new ProcessStartInfo + { + FileName = targetPath, + UseShellExecute = true, + WorkingDirectory = Path.GetDirectoryName(targetPath) + }; + + Process.Start(startInfo); + + UpdateStatus("新程序已启动,当前程序即将退出"); + await Task.Delay(2000); + + // 关闭当前程序 + this.Close(); + return true; + } + catch (Exception ex) + { + UpdateStatus($"重定位程序失败: {ex.Message}"); + return false; + } + } } } \ No newline at end of file