improve:自动更新

This commit is contained in:
2026-02-12 17:22:47 +08:00
parent 200317a0f5
commit 376790330d
7 changed files with 99 additions and 12 deletions
+1 -1
View File
@@ -1431,7 +1431,7 @@ namespace Ink_Canvas.Helpers
try
{
LogHelper.WriteLogToFile($"AutoUpdate | 开始解压ZIP文件到: {extractPath}");
ZipFile.ExtractToDirectory(zipFilePath, extractPath);
SafeZipExtractor.ExtractZipSafely(zipFilePath, extractPath, overwrite: true);
LogHelper.WriteLogToFile("AutoUpdate | ZIP文件解压完成");
}
catch (Exception ex)
@@ -186,11 +186,11 @@ namespace Ink_Canvas.Helpers
}
/// <summary>
/// 释放GPU资源
/// 释放GPU相关资源标记
/// </summary>
public void Dispose()
{
_renderTarget?.Clear();
_isInitialized = false;
}
}
-4
View File
@@ -209,9 +209,5 @@ namespace Ink_Canvas.Helpers
private readonly DrawingAttributes _drawingAttributes;
public static implicit operator Stroke(StrokeVisual v)
{
throw new NotImplementedException();
}
}
}
+75
View File
@@ -0,0 +1,75 @@
using System;
using System.IO;
using System.IO.Compression;
namespace Ink_Canvas.Helpers
{
public static class SafeZipExtractor
{
/// <param name="zipFilePath">ZIP 文件路径</param>
/// <param name="extractPath">解压目标目录</param>
/// <param name="overwrite">是否覆盖已存在文件</param>
public static void ExtractZipSafely(string zipFilePath, string extractPath, bool overwrite = true)
{
if (string.IsNullOrWhiteSpace(zipFilePath))
throw new ArgumentNullException(nameof(zipFilePath));
if (string.IsNullOrWhiteSpace(extractPath))
throw new ArgumentNullException(nameof(extractPath));
var fullExtractPath = Path.GetFullPath(extractPath);
Directory.CreateDirectory(fullExtractPath);
using (var zip = ZipFile.OpenRead(zipFilePath))
{
foreach (var entry in zip.Entries)
{
// 跳过空条目
if (string.IsNullOrEmpty(entry.FullName))
continue;
// 防止绝对路径和盘符前缀
if (Path.IsPathRooted(entry.FullName))
continue;
// 统一路径分隔符
var normalized = entry.FullName.Replace('/', Path.DirectorySeparatorChar);
// 拒绝包含 .. 的路径,防止目录穿越
if (normalized.Contains(".." + Path.DirectorySeparatorChar) ||
normalized.StartsWith(".." + Path.DirectorySeparatorChar, StringComparison.Ordinal))
{
continue;
}
var destinationPath = Path.GetFullPath(
Path.Combine(fullExtractPath, normalized));
// 再次确认仍然在目标目录下
if (!destinationPath.StartsWith(fullExtractPath, StringComparison.OrdinalIgnoreCase))
continue;
// 目录条目
if (entry.FullName.EndsWith("/", StringComparison.Ordinal) ||
entry.FullName.EndsWith("\\", StringComparison.Ordinal))
{
Directory.CreateDirectory(destinationPath);
continue;
}
Directory.CreateDirectory(Path.GetDirectoryName(destinationPath) ?? fullExtractPath);
if (!overwrite && File.Exists(destinationPath))
continue;
using (var input = entry.Open())
using (var output = File.Create(destinationPath))
{
input.CopyTo(output);
}
}
}
}
}
}
+10
View File
@@ -92,6 +92,11 @@ namespace Ink_Canvas.Helpers
public TimeMachineHistory Undo()
{
if (_currentIndex < 0 || _currentIndex >= _currentStrokeHistory.Count)
{
return null;
}
var item = _currentStrokeHistory[_currentIndex];
item.StrokeHasBeenCleared = !item.StrokeHasBeenCleared;
_currentIndex--;
@@ -102,6 +107,11 @@ namespace Ink_Canvas.Helpers
public TimeMachineHistory Redo()
{
if (_currentStrokeHistory.Count == 0 || _currentIndex >= _currentStrokeHistory.Count - 1)
{
return null;
}
var item = _currentStrokeHistory[++_currentIndex];
item.StrokeHasBeenCleared = !item.StrokeHasBeenCleared;
NotifyUndoRedoState();