diff --git a/7z-x64.dll b/7z-x64.dll new file mode 100644 index 0000000..f79493c Binary files /dev/null and b/7z-x64.dll differ diff --git a/7z-x86.dll b/7z-x86.dll new file mode 100644 index 0000000..ad2ecc3 Binary files /dev/null and b/7z-x86.dll differ diff --git a/7z.dll b/7z.dll deleted file mode 100644 index 296493a..0000000 Binary files a/7z.dll and /dev/null differ diff --git a/CheckDownload.csproj b/CheckDownload.csproj index f40772e..44ffef7 100644 --- a/CheckDownload.csproj +++ b/CheckDownload.csproj @@ -184,7 +184,8 @@ - + + diff --git a/Form1.cs b/Form1.cs index 6ff985a..4024e1a 100644 --- a/Form1.cs +++ b/Form1.cs @@ -231,10 +231,10 @@ namespace CheckDownload UpdateCount(""); UpdateSize(""); UpdateProgressValue(100); - + // 无需更新时清理临时文件夹 CleanupTempDirectory(); - + // 显示更新完成并等待2秒 UpdateStatus("更新完成"); await Task.Delay(2000); @@ -270,9 +270,9 @@ namespace CheckDownload if (_completedCount == 0 && orderedFileList.Count > 0) { - throw new Exception("所有文件下载失败。"); + throw new Exception("所有文件下载失败。"); } - + await VerifyAndSaveAllFiles(); await DecompressTim7zAsync(); @@ -379,7 +379,7 @@ namespace CheckDownload { string key = onlineProperty.Name; JToken onlineValue = onlineProperty.Value; - + string relativePath = string.IsNullOrEmpty(currentPath) ? key : Path.Combine(currentPath, key); string localFullPath = Path.Combine(_baseDirectory, relativePath); @@ -445,9 +445,9 @@ namespace CheckDownload if (_completedCount == 0 && fileList.Count > 0) { - throw new Exception("所有文件下载失败。"); + throw new Exception("所有文件下载失败。"); } - + await VerifyAndSaveAllFiles(); } @@ -472,10 +472,10 @@ namespace CheckDownload _downloadedFiles[file.Key] = file.Value; } Interlocked.Increment(ref _completedCount); - + int progress = (int)((double)_completedCount / _totalCount * 95); UpdateProgressValue(progress); - + UpdateStatus($"{Path.GetFileName(file.Key)}"); UpdateCount($"{_completedCount}/{_totalCount}"); } @@ -491,7 +491,7 @@ namespace CheckDownload }); await Task.WhenAll(downloadTasks); } - + /// /// 尝试从多个数据源下载单个文件,优先使用123盘,OSS作为备用 /// @@ -516,13 +516,13 @@ namespace CheckDownload { return true; } - + UpdateStatus($"{fileName}"); UpdateCount($"{_completedCount + 1}/{_totalCount}"); string ossKey = $"File/{expectedMd5}"; - + var obj = _ossClient.GetObject(OssBucketName, ossKey); - + string tempDir = Path.GetDirectoryName(tempFilePath); if (!Directory.Exists(tempDir)) { @@ -567,9 +567,9 @@ namespace CheckDownload } UpdateStatus($"检查已存在的临时文件: {fileName}"); - + string actualMd5 = await Task.Run(() => CalculateMD5FromFile(tempFilePath)); - + if (actualMd5.Equals(expectedMd5, StringComparison.OrdinalIgnoreCase)) { UpdateStatus($"临时文件完整,跳过下载: {fileName}"); @@ -613,16 +613,16 @@ namespace CheckDownload UpdateStatus($"正在从123盘下载: {fileName}"); UpdateCount(""); UpdateSize(""); - + string authUrl = GenerateAuthUrl($"http://{OneDriveMainDomain}{OneDrivePath}", fileName); - + UpdateStatus($"使用主域名下载文件..."); UpdateCount(""); UpdateSize(""); - + var request = new HttpRequestMessage(HttpMethod.Get, authUrl) { Version = HttpVersion.Version11 }; request.Headers.Add("User-Agent", "CheckDownload/1.0"); - + using (var response = await _httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead)) { response.EnsureSuccessStatusCode(); @@ -637,7 +637,7 @@ namespace CheckDownload { await DownloadWithProgressAsync(remote, localFile, response.Content.Headers.ContentLength); } - + UpdateStatus($"123盘主域名下载成功: {fileName}"); UpdateCount(""); UpdateSize(""); @@ -656,16 +656,16 @@ namespace CheckDownload UpdateStatus($"正在从123盘备用域名下载: {fileName}"); UpdateCount(""); UpdateSize(""); - + string authUrl = GenerateAuthUrl($"http://{OneDriveBackupDomain}{OneDrivePath}", fileName); - + UpdateStatus($"使用备用域名下载文件..."); UpdateCount(""); UpdateSize(""); - + var request = new HttpRequestMessage(HttpMethod.Get, authUrl) { Version = HttpVersion.Version11 }; request.Headers.Add("User-Agent", "CheckDownload/1.0"); - + using (var response = await _httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead)) { response.EnsureSuccessStatusCode(); @@ -680,7 +680,7 @@ namespace CheckDownload { await DownloadWithProgressAsync(remote, localFile, response.Content.Headers.ContentLength); } - + UpdateStatus($"123盘备用域名下载成功: {fileName}"); UpdateCount(""); UpdateSize(""); @@ -704,14 +704,14 @@ namespace CheckDownload private async Task DownloadFileFromOneDrive(string filePath, string expectedMd5, string localPath) { string fileName = $"File/{expectedMd5}"; - + try { string authUrl = GenerateAuthUrl($"http://{OneDriveMainDomain}{OneDrivePath}", fileName); - + var request = new HttpRequestMessage(HttpMethod.Get, authUrl) { Version = HttpVersion.Version11 }; request.Headers.Add("User-Agent", "CheckDownload/1.0"); - + using (var response = await _httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead)) { response.EnsureSuccessStatusCode(); @@ -726,7 +726,7 @@ namespace CheckDownload { await DownloadWithProgressAsync(remote, localFile, response.Content.Headers.ContentLength); } - + return true; } } @@ -737,10 +737,10 @@ namespace CheckDownload try { string authUrl = GenerateAuthUrl($"http://{OneDriveBackupDomain}{OneDrivePath}", fileName); - + var request = new HttpRequestMessage(HttpMethod.Get, authUrl) { Version = HttpVersion.Version11 }; request.Headers.Add("User-Agent", "CheckDownload/1.0"); - + using (var response = await _httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead)) { response.EnsureSuccessStatusCode(); @@ -755,7 +755,7 @@ namespace CheckDownload { await DownloadWithProgressAsync(remote, localFile, response.Content.Headers.ContentLength); } - + return true; } } @@ -780,9 +780,9 @@ namespace CheckDownload UpdateCount(""); UpdateSize(""); var failedThisRound = new ConcurrentDictionary(); - + await PerformDownloads(filesToRetry, failedThisRound); - + filesToRetry = new Dictionary(failedThisRound); if (filesToRetry.Any() && i < MaxDownloadRetries - 1) @@ -834,7 +834,7 @@ namespace CheckDownload UpdateStatus($"所有DNS服务器均无法解析域名: {domain}"); return new List(); } - + /// /// 验证所有下载文件的MD5完整性并保存到目标位置,处理文件占用情况 /// @@ -914,7 +914,7 @@ namespace CheckDownload UpdateProgressValue(100); } } - + /// /// 尝试将文件从临时位置移动到目标位置(异步),若文件被占用则等待一秒后重试一次 /// @@ -952,7 +952,7 @@ namespace CheckDownload return false; } } - + /// /// 为被占用文件创建批处理脚本,在程序退出后自动完成文件替换 /// @@ -985,9 +985,9 @@ namespace CheckDownload batchContent.AppendLine("del \"%~f0\" /f /q"); batchContent.AppendLine("exit"); - + File.WriteAllText(batchFilePath, batchContent.ToString(), new UTF8Encoding(false)); - + var startInfo = new ProcessStartInfo { FileName = "cmd.exe", @@ -1104,7 +1104,7 @@ namespace CheckDownload try { var ipUrl = signedUrl.Replace(signedUri.Host, ip); - + var request = new HttpRequestMessage(HttpMethod.Get, ipUrl) { Version = HttpVersion.Version11 }; request.Headers.Host = signedUri.Host; using (var response = await _httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead)) @@ -1152,10 +1152,10 @@ namespace CheckDownload var random = new Random(number); var guid = new byte[16]; random.NextBytes(guid); - + guid[7] = (byte)((guid[7] & 0x0F) | 0x40); guid[8] = (byte)((guid[8] & 0x3F) | 0x80); - + var resultGuid = new Guid(guid); return resultGuid.ToString("N").Replace("-", ""); } @@ -1186,19 +1186,19 @@ namespace CheckDownload try { long timestamp = GenerateTimestamp(OneDriveAuthTimeout); - + string rand = GenerateUUID(16); - + string pathPart = ExtractPathFromUrl(url); - + string fullUrl = $"{url}/{file}"; - + string signString = $"/{pathPart}/{file}-{timestamp}-{rand}-{OneDriveUid}-{OneDriveAuthKey}"; - + string signature = GenerateMD5(signString); - + string authUrl = $"{fullUrl}?auth_key={timestamp}-{rand}-{OneDriveUid}-{signature}"; - + return authUrl; } catch (Exception ex) @@ -1220,7 +1220,7 @@ namespace CheckDownload { var uri = new Uri(url); pathPart = uri.AbsolutePath.TrimStart('/'); - + if (string.IsNullOrEmpty(pathPart)) { string basePattern = $"{uri.Scheme}://{uri.Host}"; @@ -1260,7 +1260,7 @@ namespace CheckDownload { return true; } - + UpdateStatus("123盘下载失败,尝试阿里云OSS备用方案..."); return await DownloadFileWithFallback(fileName, localPath); } @@ -1304,9 +1304,9 @@ namespace CheckDownload try { string currentProgramName = Path.GetFileName(Application.ExecutablePath); - + string programPathInMd5 = FindFileInMd5Data(data, currentProgramName); - + if (!string.IsNullOrEmpty(programPathInMd5)) { string programDirInMd5 = Path.GetDirectoryName(programPathInMd5); @@ -1314,9 +1314,9 @@ namespace CheckDownload { programDirInMd5 = ""; } - + string currentProgramDir = Application.StartupPath; - + if (string.IsNullOrEmpty(programDirInMd5)) { _baseDirectory = currentProgramDir; @@ -1350,9 +1350,9 @@ namespace CheckDownload { string key = property.Name; JToken value = property.Value; - + string fullPath = string.IsNullOrEmpty(currentPath) ? key : Path.Combine(currentPath, key); - + if (value.Type == JTokenType.String) { if (string.Equals(key, fileName, StringComparison.OrdinalIgnoreCase)) @@ -1382,11 +1382,11 @@ namespace CheckDownload { try { - string[] expectedDirs = expectedRelativePath.Split(new char[] { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar }, + string[] expectedDirs = expectedRelativePath.Split(new char[] { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar }, StringSplitOptions.RemoveEmptyEntries); - + string checkDir = currentDir; - + for (int i = 0; i < expectedDirs.Length; i++) { string parentDir = Directory.GetParent(checkDir)?.FullName; @@ -1394,10 +1394,10 @@ namespace CheckDownload { break; } - + string currentDirName = Path.GetFileName(checkDir); string expectedDirName = expectedDirs[expectedDirs.Length - 1 - i]; - + if (string.Equals(currentDirName, expectedDirName, StringComparison.OrdinalIgnoreCase)) { if (i == expectedDirs.Length - 1) @@ -1411,7 +1411,7 @@ namespace CheckDownload break; } } - + return currentDir; } catch (Exception) @@ -1495,8 +1495,14 @@ namespace CheckDownload await Task.Run(() => { try { + string sevenZipDllPath = Extract7zDll(); + if (string.IsNullOrEmpty(sevenZipDllPath)) + { + throw new Exception("无法提取7z.dll,解压中止。"); + } + string extractionPath = Path.GetDirectoryName(sevenZipFile); - using (var archiveFile = new ArchiveFile(sevenZipFile)) + using (var archiveFile = new ArchiveFile(sevenZipFile, sevenZipDllPath)) { archiveFile.Extract(extractionPath, true); } @@ -1514,8 +1520,49 @@ namespace CheckDownload catch (Exception ex) { UpdateStatus($"处理 tim.7z 时出错: {ex.Message}"); + MessageBox.Show($"处理 tim.7z 时出错: {ex.Message}"); await Task.Delay(3000); } } + + /// + /// 从嵌入的资源中提取与当前进程体系结构匹配的7z.dll到临时目录。 + /// + /// 提取的7z.dll的路径,如果失败则返回null。 + private string Extract7zDll() + { + try + { + string dllName = Environment.Is64BitProcess ? "7z-x64.dll" : "7z-x86.dll"; + string resourceName = $"CheckDownload.{dllName}"; + string dllPath = Path.Combine(_tempDirectory, "7z.dll"); + + if (File.Exists(dllPath)) + { + // 可以选择在这里添加对现有DLL版本的校验,但为简化,我们先直接返回 + return dllPath; + } + + using (var resourceStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName)) + { + if (resourceStream == null) + { + UpdateStatus($"在嵌入资源中未找到 {dllName}。"); + return null; + } + + using (var fileStream = new FileStream(dllPath, FileMode.Create, FileAccess.Write)) + { + resourceStream.CopyTo(fileStream); + } + } + return dllPath; + } + catch (Exception ex) + { + UpdateStatus($"提取7z.dll失败: {ex.Message}"); + return null; + } + } } } \ No newline at end of file