improve:PPT墨迹保存
This commit is contained in:
@@ -26,6 +26,11 @@ namespace Ink_Canvas.Helpers
|
|||||||
private readonly object _lockObject = new object();
|
private readonly object _lockObject = new object();
|
||||||
private bool _disposed;
|
private bool _disposed;
|
||||||
private string _currentActivePresentationId = "";
|
private string _currentActivePresentationId = "";
|
||||||
|
|
||||||
|
// 墨迹备份机制
|
||||||
|
private readonly Dictionary<string, Dictionary<int, StrokeCollection>> _strokeBackups;
|
||||||
|
private DateTime _lastBackupTime = DateTime.MinValue;
|
||||||
|
private const int BackupIntervalMinutes = 2; // 每2分钟备份一次
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Constructor
|
#region Constructor
|
||||||
@@ -33,6 +38,7 @@ namespace Ink_Canvas.Helpers
|
|||||||
{
|
{
|
||||||
_presentationManagers = new Dictionary<string, PPTInkManager>();
|
_presentationManagers = new Dictionary<string, PPTInkManager>();
|
||||||
_presentationInfos = new Dictionary<string, PresentationInfo>();
|
_presentationInfos = new Dictionary<string, PresentationInfo>();
|
||||||
|
_strokeBackups = new Dictionary<string, Dictionary<int, StrokeCollection>>();
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@@ -112,8 +118,15 @@ namespace Ink_Canvas.Helpers
|
|||||||
var currentPresentation = GetCurrentActivePresentation();
|
var currentPresentation = GetCurrentActivePresentation();
|
||||||
if (currentPresentation != null)
|
if (currentPresentation != null)
|
||||||
{
|
{
|
||||||
currentManager.SaveAllStrokesToFile(currentPresentation);
|
try
|
||||||
LogHelper.WriteLogToFile($"已保存当前演示文稿墨迹: {currentPresentation.Name}", LogHelper.LogType.Trace);
|
{
|
||||||
|
currentManager.SaveAllStrokesToFile(currentPresentation);
|
||||||
|
LogHelper.WriteLogToFile($"已保存当前演示文稿墨迹: {currentPresentation.Name}", LogHelper.LogType.Trace);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogHelper.WriteLogToFile($"保存当前演示文稿墨迹失败: {ex}", LogHelper.LogType.Error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -126,10 +139,10 @@ namespace Ink_Canvas.Helpers
|
|||||||
_presentationInfos[presentationId].LastAccessTime = DateTime.Now;
|
_presentationInfos[presentationId].LastAccessTime = DateTime.Now;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_currentActivePresentationId != presentationId)
|
if (_currentActivePresentationId != presentationId)
|
||||||
{
|
{
|
||||||
LogHelper.WriteLogToFile($"已切换到演示文稿: {presentation.Name}", LogHelper.LogType.Trace);
|
LogHelper.WriteLogToFile($"已切换到演示文稿: {presentation.Name}", LogHelper.LogType.Trace);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -161,7 +174,17 @@ namespace Ink_Canvas.Helpers
|
|||||||
var manager = GetCurrentManager();
|
var manager = GetCurrentManager();
|
||||||
if (manager != null)
|
if (manager != null)
|
||||||
{
|
{
|
||||||
|
// 先创建备份
|
||||||
|
if (!string.IsNullOrEmpty(_currentActivePresentationId))
|
||||||
|
{
|
||||||
|
CreateStrokeBackup(_currentActivePresentationId, slideIndex, strokes);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 保存到管理器
|
||||||
manager.SaveCurrentSlideStrokes(slideIndex, strokes);
|
manager.SaveCurrentSlideStrokes(slideIndex, strokes);
|
||||||
|
|
||||||
|
// 检查是否需要执行定期备份
|
||||||
|
CheckAndPerformBackup();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@@ -209,12 +232,29 @@ namespace Ink_Canvas.Helpers
|
|||||||
var manager = GetCurrentManager();
|
var manager = GetCurrentManager();
|
||||||
if (manager != null)
|
if (manager != null)
|
||||||
{
|
{
|
||||||
return manager.LoadSlideStrokes(slideIndex);
|
var strokes = manager.LoadSlideStrokes(slideIndex);
|
||||||
|
|
||||||
|
// 如果从管理器加载失败,尝试从备份恢复
|
||||||
|
if (strokes == null || strokes.Count == 0)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(_currentActivePresentationId))
|
||||||
|
{
|
||||||
|
strokes = RestoreStrokeFromBackup(_currentActivePresentationId, slideIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return strokes ?? new StrokeCollection();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
LogHelper.WriteLogToFile($"加载页面墨迹失败: {ex}", LogHelper.LogType.Error);
|
LogHelper.WriteLogToFile($"加载页面墨迹失败: {ex}", LogHelper.LogType.Error);
|
||||||
|
|
||||||
|
// 尝试从备份恢复
|
||||||
|
if (!string.IsNullOrEmpty(_currentActivePresentationId))
|
||||||
|
{
|
||||||
|
return RestoreStrokeFromBackup(_currentActivePresentationId, slideIndex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -511,6 +551,12 @@ namespace Ink_Canvas.Helpers
|
|||||||
}
|
}
|
||||||
_presentationInfos.Remove(id);
|
_presentationInfos.Remove(id);
|
||||||
|
|
||||||
|
// 清理备份数据
|
||||||
|
if (_strokeBackups.ContainsKey(id))
|
||||||
|
{
|
||||||
|
_strokeBackups.Remove(id);
|
||||||
|
}
|
||||||
|
|
||||||
LogHelper.WriteLogToFile($"已清理非活跃演示文稿: {id}", LogHelper.LogType.Trace);
|
LogHelper.WriteLogToFile($"已清理非活跃演示文稿: {id}", LogHelper.LogType.Trace);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -520,6 +566,98 @@ namespace Ink_Canvas.Helpers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建墨迹备份
|
||||||
|
/// </summary>
|
||||||
|
private void CreateStrokeBackup(string presentationId, int slideIndex, StrokeCollection strokes)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (strokes == null || strokes.Count == 0) return;
|
||||||
|
|
||||||
|
if (!_strokeBackups.ContainsKey(presentationId))
|
||||||
|
{
|
||||||
|
_strokeBackups[presentationId] = new Dictionary<int, StrokeCollection>();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 释放旧的备份
|
||||||
|
if (_strokeBackups[presentationId].ContainsKey(slideIndex))
|
||||||
|
{
|
||||||
|
_strokeBackups[presentationId][slideIndex] = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建新的备份
|
||||||
|
_strokeBackups[presentationId][slideIndex] = strokes.Clone();
|
||||||
|
|
||||||
|
LogHelper.WriteLogToFile($"已创建第{slideIndex}页墨迹备份", LogHelper.LogType.Trace);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogHelper.WriteLogToFile($"创建墨迹备份失败: {ex}", LogHelper.LogType.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 从备份恢复墨迹
|
||||||
|
/// </summary>
|
||||||
|
private StrokeCollection RestoreStrokeFromBackup(string presentationId, int slideIndex)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (_strokeBackups.ContainsKey(presentationId) &&
|
||||||
|
_strokeBackups[presentationId].ContainsKey(slideIndex))
|
||||||
|
{
|
||||||
|
var backup = _strokeBackups[presentationId][slideIndex];
|
||||||
|
if (backup != null)
|
||||||
|
{
|
||||||
|
LogHelper.WriteLogToFile($"从备份恢复第{slideIndex}页墨迹", LogHelper.LogType.Trace);
|
||||||
|
return backup.Clone();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogHelper.WriteLogToFile($"从备份恢复墨迹失败: {ex}", LogHelper.LogType.Error);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new StrokeCollection();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 检查并执行定期备份
|
||||||
|
/// </summary>
|
||||||
|
private void CheckAndPerformBackup()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var now = DateTime.Now;
|
||||||
|
|
||||||
|
// 检查是否需要执行备份
|
||||||
|
if (now - _lastBackupTime < TimeSpan.FromMinutes(BackupIntervalMinutes))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 备份当前活跃演示文稿的所有墨迹
|
||||||
|
if (!string.IsNullOrEmpty(_currentActivePresentationId) &&
|
||||||
|
_presentationManagers.ContainsKey(_currentActivePresentationId))
|
||||||
|
{
|
||||||
|
var manager = _presentationManagers[_currentActivePresentationId];
|
||||||
|
if (manager != null)
|
||||||
|
{
|
||||||
|
// 这里可以添加更详细的备份逻辑
|
||||||
|
LogHelper.WriteLogToFile($"执行定期墨迹备份: {_currentActivePresentationId}", LogHelper.LogType.Trace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_lastBackupTime = now;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogHelper.WriteLogToFile($"定期备份检查失败: {ex}", LogHelper.LogType.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Private Methods
|
#region Private Methods
|
||||||
@@ -637,12 +775,24 @@ namespace Ink_Canvas.Helpers
|
|||||||
{
|
{
|
||||||
lock (_lockObject)
|
lock (_lockObject)
|
||||||
{
|
{
|
||||||
|
// 释放所有管理器
|
||||||
foreach (var manager in _presentationManagers.Values)
|
foreach (var manager in _presentationManagers.Values)
|
||||||
{
|
{
|
||||||
manager?.Dispose();
|
manager?.Dispose();
|
||||||
}
|
}
|
||||||
_presentationManagers.Clear();
|
_presentationManagers.Clear();
|
||||||
_presentationInfos.Clear();
|
_presentationInfos.Clear();
|
||||||
|
|
||||||
|
// 清理备份数据
|
||||||
|
foreach (var backupDict in _strokeBackups.Values)
|
||||||
|
{
|
||||||
|
foreach (var backup in backupDict.Values)
|
||||||
|
{
|
||||||
|
backup?.Clear();
|
||||||
|
}
|
||||||
|
backupDict.Clear();
|
||||||
|
}
|
||||||
|
_strokeBackups.Clear();
|
||||||
}
|
}
|
||||||
_disposed = true;
|
_disposed = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,6 +35,12 @@ namespace Ink_Canvas.Helpers
|
|||||||
private DateTime _lastSwitchTime = DateTime.MinValue;
|
private DateTime _lastSwitchTime = DateTime.MinValue;
|
||||||
private int _lastSwitchSlideIndex = -1;
|
private int _lastSwitchSlideIndex = -1;
|
||||||
private const int MinSwitchIntervalMs = 100; // 最小切换间隔100毫秒
|
private const int MinSwitchIntervalMs = 100; // 最小切换间隔100毫秒
|
||||||
|
|
||||||
|
// 内存管理相关字段
|
||||||
|
private long _totalMemoryUsage = 0;
|
||||||
|
private const long MaxMemoryUsageBytes = 100 * 1024 * 1024; // 100MB限制
|
||||||
|
private DateTime _lastMemoryCleanup = DateTime.MinValue;
|
||||||
|
private const int MemoryCleanupIntervalMinutes = 5; // 5分钟清理一次
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Constructor
|
#region Constructor
|
||||||
@@ -125,17 +131,29 @@ namespace Ink_Canvas.Helpers
|
|||||||
|
|
||||||
if (slideIndex < _memoryStreams.Length)
|
if (slideIndex < _memoryStreams.Length)
|
||||||
{
|
{
|
||||||
|
// 先释放旧的内存流,防止内存泄漏
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_memoryStreams[slideIndex]?.Dispose();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogHelper.WriteLogToFile($"释放旧内存流失败: {ex}", LogHelper.LogType.Warning);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建新的内存流
|
||||||
var ms = new MemoryStream();
|
var ms = new MemoryStream();
|
||||||
strokes.Save(ms);
|
strokes.Save(ms);
|
||||||
ms.Position = 0;
|
ms.Position = 0;
|
||||||
|
|
||||||
// 释放旧的内存流
|
|
||||||
_memoryStreams[slideIndex]?.Dispose();
|
|
||||||
_memoryStreams[slideIndex] = ms;
|
_memoryStreams[slideIndex] = ms;
|
||||||
|
|
||||||
if (ms.Length > 0)
|
if (ms.Length > 0)
|
||||||
{
|
{
|
||||||
|
LogHelper.WriteLogToFile($"已保存第{slideIndex}页墨迹,大小: {ms.Length} bytes", LogHelper.LogType.Trace);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 检查内存使用情况
|
||||||
|
CheckAndPerformMemoryCleanup();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@@ -158,12 +176,20 @@ namespace Ink_Canvas.Helpers
|
|||||||
{
|
{
|
||||||
if (slideIndex < _memoryStreams.Length)
|
if (slideIndex < _memoryStreams.Length)
|
||||||
{
|
{
|
||||||
|
// 先释放旧的内存流,防止内存泄漏
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_memoryStreams[slideIndex]?.Dispose();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogHelper.WriteLogToFile($"释放旧内存流失败: {ex}", LogHelper.LogType.Warning);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建新的内存流
|
||||||
var ms = new MemoryStream();
|
var ms = new MemoryStream();
|
||||||
strokes.Save(ms);
|
strokes.Save(ms);
|
||||||
ms.Position = 0;
|
ms.Position = 0;
|
||||||
|
|
||||||
// 释放旧的内存流
|
|
||||||
_memoryStreams[slideIndex]?.Dispose();
|
|
||||||
_memoryStreams[slideIndex] = ms;
|
_memoryStreams[slideIndex] = ms;
|
||||||
|
|
||||||
LogHelper.WriteLogToFile($"已强制保存第{slideIndex}页墨迹,大小: {ms.Length} bytes", LogHelper.LogType.Trace);
|
LogHelper.WriteLogToFile($"已强制保存第{slideIndex}页墨迹,大小: {ms.Length} bytes", LogHelper.LogType.Trace);
|
||||||
@@ -388,13 +414,30 @@ namespace Ink_Canvas.Helpers
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
for (int i = 0; i < _memoryStreams.Length; i++)
|
// 安全释放所有内存流
|
||||||
|
if (_memoryStreams != null)
|
||||||
{
|
{
|
||||||
_memoryStreams[i]?.Dispose();
|
for (int i = 0; i < _memoryStreams.Length; i++)
|
||||||
_memoryStreams[i] = null;
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_memoryStreams[i]?.Dispose();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogHelper.WriteLogToFile($"释放内存流{i}失败: {ex}", LogHelper.LogType.Warning);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_memoryStreams[i] = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重新初始化数组
|
||||||
|
_memoryStreams = new MemoryStream[_maxSlides + 2];
|
||||||
}
|
}
|
||||||
|
|
||||||
CurrentStrokes.Clear();
|
CurrentStrokes?.Clear();
|
||||||
LogHelper.WriteLogToFile("已清除所有墨迹", LogHelper.LogType.Trace);
|
LogHelper.WriteLogToFile("已清除所有墨迹", LogHelper.LogType.Trace);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@@ -447,6 +490,110 @@ namespace Ink_Canvas.Helpers
|
|||||||
_lastSwitchSlideIndex = -1;
|
_lastSwitchSlideIndex = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 检查并执行内存清理
|
||||||
|
/// </summary>
|
||||||
|
private void CheckAndPerformMemoryCleanup()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var now = DateTime.Now;
|
||||||
|
|
||||||
|
// 检查是否需要执行内存清理
|
||||||
|
if (now - _lastMemoryCleanup < TimeSpan.FromMinutes(MemoryCleanupIntervalMinutes))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算当前内存使用量
|
||||||
|
long currentMemoryUsage = 0;
|
||||||
|
if (_memoryStreams != null)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < _memoryStreams.Length; i++)
|
||||||
|
{
|
||||||
|
if (_memoryStreams[i] != null)
|
||||||
|
{
|
||||||
|
currentMemoryUsage += _memoryStreams[i].Length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_totalMemoryUsage = currentMemoryUsage;
|
||||||
|
|
||||||
|
// 如果内存使用量超过限制,执行清理
|
||||||
|
if (currentMemoryUsage > MaxMemoryUsageBytes)
|
||||||
|
{
|
||||||
|
LogHelper.WriteLogToFile($"内存使用量超限 ({currentMemoryUsage / 1024 / 1024}MB),开始清理", LogHelper.LogType.Warning);
|
||||||
|
|
||||||
|
// 清理非当前页面的墨迹
|
||||||
|
CleanupInactiveSlideStrokes();
|
||||||
|
|
||||||
|
_lastMemoryCleanup = now;
|
||||||
|
LogHelper.WriteLogToFile($"内存清理完成,当前使用量: {_totalMemoryUsage / 1024 / 1024}MB", LogHelper.LogType.Trace);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_lastMemoryCleanup = now;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogHelper.WriteLogToFile($"内存清理检查失败: {ex}", LogHelper.LogType.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 清理非活跃页面的墨迹
|
||||||
|
/// </summary>
|
||||||
|
private void CleanupInactiveSlideStrokes()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (_memoryStreams == null) return;
|
||||||
|
|
||||||
|
int cleanedCount = 0;
|
||||||
|
long freedMemory = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < _memoryStreams.Length; i++)
|
||||||
|
{
|
||||||
|
// 保留当前锁定页面和最近访问的页面
|
||||||
|
if (i == _lockedSlideIndex || i == _lastSwitchSlideIndex)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_memoryStreams[i] != null)
|
||||||
|
{
|
||||||
|
long memorySize = _memoryStreams[i].Length;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_memoryStreams[i].Dispose();
|
||||||
|
freedMemory += memorySize;
|
||||||
|
cleanedCount++;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogHelper.WriteLogToFile($"清理页面{i}墨迹失败: {ex}", LogHelper.LogType.Warning);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_memoryStreams[i] = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cleanedCount > 0)
|
||||||
|
{
|
||||||
|
LogHelper.WriteLogToFile($"已清理{cleanedCount}个页面的墨迹,释放内存: {freedMemory / 1024}KB", LogHelper.LogType.Trace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogHelper.WriteLogToFile($"清理非活跃页面墨迹失败: {ex}", LogHelper.LogType.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Private Methods
|
#region Private Methods
|
||||||
|
|||||||
@@ -411,63 +411,30 @@ namespace Ink_Canvas.Helpers
|
|||||||
catch (COMException comEx)
|
catch (COMException comEx)
|
||||||
{
|
{
|
||||||
var hr = (uint)comEx.HResult;
|
var hr = (uint)comEx.HResult;
|
||||||
|
LogHelper.WriteLogToFile($"取消PPT事件注册时COM异常: {comEx.Message} (HR: 0x{hr:X8})", LogHelper.LogType.Warning);
|
||||||
}
|
}
|
||||||
catch (InvalidCastException)
|
catch (InvalidCastException)
|
||||||
{
|
{
|
||||||
// COM对象类型转换失败,通常是因为对象已经被释放
|
// COM对象类型转换失败,通常是因为对象已经被释放
|
||||||
LogHelper.WriteLogToFile("PPT COM对象已被释放,跳过事件注册取消", LogHelper.LogType.Trace);
|
LogHelper.WriteLogToFile("PPT COM对象已被释放,跳过事件注册取消", LogHelper.LogType.Trace);
|
||||||
}
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogHelper.WriteLogToFile($"取消PPT事件注册时发生异常: {ex}", LogHelper.LogType.Warning);
|
||||||
|
}
|
||||||
}, DispatcherPriority.Normal, CancellationToken.None, TimeSpan.FromSeconds(1));
|
}, DispatcherPriority.Normal, CancellationToken.None, TimeSpan.FromSeconds(1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
LogHelper.WriteLogToFile($"取消PPT事件注册失败: {ex}", LogHelper.LogType.Warning);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 释放COM对象
|
// 安全释放COM对象
|
||||||
try
|
SafeReleaseComObject(CurrentSlide, "CurrentSlide");
|
||||||
{
|
SafeReleaseComObject(CurrentSlides, "CurrentSlides");
|
||||||
if (Marshal.IsComObject(CurrentSlide))
|
SafeReleaseComObject(CurrentPresentation, "CurrentPresentation");
|
||||||
{
|
SafeReleaseComObject(PPTApplication, "PPTApplication");
|
||||||
Marshal.ReleaseComObject(CurrentSlide);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (Marshal.IsComObject(CurrentSlides))
|
|
||||||
{
|
|
||||||
Marshal.ReleaseComObject(CurrentSlides);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (Marshal.IsComObject(CurrentPresentation))
|
|
||||||
{
|
|
||||||
Marshal.ReleaseComObject(CurrentPresentation);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (Marshal.IsComObject(PPTApplication))
|
|
||||||
{
|
|
||||||
Marshal.ReleaseComObject(PPTApplication);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// 清理引用
|
// 清理引用
|
||||||
PPTApplication = null;
|
PPTApplication = null;
|
||||||
@@ -491,6 +458,30 @@ namespace Ink_Canvas.Helpers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 安全释放COM对象
|
||||||
|
/// </summary>
|
||||||
|
private void SafeReleaseComObject(object comObject, string objectName)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (comObject != null && Marshal.IsComObject(comObject))
|
||||||
|
{
|
||||||
|
int refCount = Marshal.ReleaseComObject(comObject);
|
||||||
|
LogHelper.WriteLogToFile($"已释放COM对象 {objectName},引用计数: {refCount}", LogHelper.LogType.Trace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (COMException comEx)
|
||||||
|
{
|
||||||
|
var hr = (uint)comEx.HResult;
|
||||||
|
LogHelper.WriteLogToFile($"释放COM对象 {objectName} 时COM异常: {comEx.Message} (HR: 0x{hr:X8})", LogHelper.LogType.Warning);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogHelper.WriteLogToFile($"释放COM对象 {objectName} 时发生异常: {ex}", LogHelper.LogType.Warning);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void UpdateCurrentPresentationInfo()
|
private void UpdateCurrentPresentationInfo()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|||||||
Reference in New Issue
Block a user