添加程序位置检查与重定位功能,确保程序在正确的根目录运行

This commit is contained in:
2025-08-07 05:59:53 +08:00
parent 734d3bb348
commit 334e30b257

236
Update.cs
View File

@@ -202,6 +202,12 @@ namespace CheckDownload
PositionFormToBottomRight(); PositionFormToBottomRight();
try try
{ {
// 首先检查程序是否在正确的根目录位置
if (await CheckAndRelocateIfNeeded())
{
return; // 如果需要重定位,则退出当前程序
}
await UpdateFile(); await UpdateFile();
} }
finally finally
@@ -1955,5 +1961,235 @@ namespace CheckDownload
CopyDirectory(subDir, targetSubDir); CopyDirectory(subDir, targetSubDir);
} }
} }
/// <summary>
/// 检查当前程序是否在正确的根目录位置,如果不在则复制到根目录并运行
/// </summary>
/// <returns>如果需要重定位并成功启动新程序返回true否则返回false</returns>
private async Task<bool> 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; // 出错时继续正常流程
}
}
/// <summary>
/// 下载MD5文件用于位置检查轻量级版本
/// </summary>
/// <returns>临时MD5文件路径失败返回null</returns>
private async Task<string> 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;
}
}
/// <summary>
/// 从MD5文件确定项目根目录
/// </summary>
/// <param name="md5FilePath">MD5文件路径</param>
/// <returns>项目根目录路径</returns>
private async Task<string> 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 { }
}
}
/// <summary>
/// 获取当前程序在项目中的相对路径
/// </summary>
/// <returns>相对路径</returns>
private string GetRelativePathInProject()
{
try
{
// 这里可以根据实际需要调整,默认假设程序在根目录
// 如果程序应该在子目录中,可以在这里指定
return "";
}
catch
{
return "";
}
}
/// <summary>
/// 将程序重定位到根目录并运行
/// </summary>
/// <param name="currentPath">当前程序路径</param>
/// <param name="targetPath">目标程序路径</param>
/// <returns>成功返回true</returns>
private async Task<bool> 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;
}
}
} }
} }