improve:PPT联动模块

This commit is contained in:
2026-02-06 21:49:11 +08:00
parent 13b24aeb7c
commit 15a6799d7b
+31 -45
View File
@@ -1284,64 +1284,62 @@ namespace Ink_Canvas.Helpers
private void DisconnectFromPPT() private void DisconnectFromPPT()
{ {
if (PPTApplication == null && _pptActivePresentation == null) if (PPTApplication == null && _pptActivePresentation == null && _pptSlideShowWindow == null &&
CurrentPresentation == null && CurrentSlides == null && CurrentSlide == null)
{ {
return; return;
} }
_isModuleUnloading = true;
try try
{ {
UnbindEvents(); UnbindEvents();
// 安全释放所有COM对象,即使它们已失效也不会抛出异常
SafeReleaseComObject(_pptSlideShowWindow, "_pptSlideShowWindow"); SafeReleaseComObject(_pptSlideShowWindow, "_pptSlideShowWindow");
SafeReleaseComObject(_pptActivePresentation, "_pptActivePresentation"); SafeReleaseComObject(_pptActivePresentation, "_pptActivePresentation");
SafeReleaseComObject(CurrentSlide, "CurrentSlide"); SafeReleaseComObject(CurrentSlide, "CurrentSlide");
SafeReleaseComObject(CurrentSlides, "CurrentSlides"); SafeReleaseComObject(CurrentSlides, "CurrentSlides");
SafeReleaseComObject(CurrentPresentation, "CurrentPresentation"); SafeReleaseComObject(CurrentPresentation, "CurrentPresentation");
// 释放PPTApplication
if (PPTApplication != null) if (PPTApplication != null)
{ {
try try
{ {
// 检查是否为有效的COM对象
if (Marshal.IsComObject(PPTApplication)) if (Marshal.IsComObject(PPTApplication))
{ {
// 检查COM对象是否仍然有效
try try
{ {
var _ = Marshal.GetIUnknownForObject(PPTApplication); var unk = Marshal.GetIUnknownForObject(PPTApplication);
Marshal.Release(_); Marshal.Release(unk);
// 对象有效,尝试释放 try
try
{
Marshal.FinalReleaseComObject(PPTApplication);
}
catch
{
try
{
int refCount = Marshal.ReleaseComObject(PPTApplication);
while (refCount > 0)
{ {
refCount = Marshal.ReleaseComObject(PPTApplication); Marshal.FinalReleaseComObject(PPTApplication);
}
catch
{
try
{
int refCount = Marshal.ReleaseComObject(PPTApplication);
while (refCount > 0)
{
refCount = Marshal.ReleaseComObject(PPTApplication);
}
}
catch
{
}
} }
}
catch { }
}
} }
catch (InvalidComObjectException) catch (InvalidComObjectException)
{ {
// COM对象已失效,直接设置为null
LogHelper.WriteLogToFile("PPTApplication COM对象已失效,跳过释放", LogHelper.LogType.Trace); LogHelper.WriteLogToFile("PPTApplication COM对象已失效,跳过释放", LogHelper.LogType.Trace);
} }
} }
} }
catch (InvalidComObjectException) catch (InvalidComObjectException)
{ {
// COM对象已失效,这是正常的
LogHelper.WriteLogToFile("PPTApplication COM对象已失效,跳过释放", LogHelper.LogType.Trace); LogHelper.WriteLogToFile("PPTApplication COM对象已失效,跳过释放", LogHelper.LogType.Trace);
} }
catch (Exception ex) catch (Exception ex)
@@ -1350,7 +1348,6 @@ namespace Ink_Canvas.Helpers
} }
} }
// 清空所有引用
PPTApplication = null; PPTApplication = null;
_pptActivePresentation = null; _pptActivePresentation = null;
_pptSlideShowWindow = null; _pptSlideShowWindow = null;
@@ -1362,33 +1359,22 @@ namespace Ink_Canvas.Helpers
_forcePolling = true; _forcePolling = true;
_bindingEvents = false; _bindingEvents = false;
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
PPTConnectionChanged?.Invoke(false); PPTConnectionChanged?.Invoke(false);
LogHelper.WriteLogToFile("已断开PPT连接,暂时卸载模块以确保COM完全释放", LogHelper.LogType.Event); LogHelper.WriteLogToFile("已断开PPT连接,并显式释放所有COM对象", LogHelper.LogType.Event);
ThreadPool.QueueUserWorkItem(_ => ThreadPool.QueueUserWorkItem(_ =>
{ {
try try
{ {
Thread.Sleep(2000); Thread.Sleep(2000);
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
Thread.Sleep(1000);
_isModuleUnloading = false; _isModuleUnloading = false;
LogHelper.WriteLogToFile("PPT联动模块已重新加载", LogHelper.LogType.Trace); LogHelper.WriteLogToFile("PPT联动模块已允许重新连接", LogHelper.LogType.Trace);
} }
catch (Exception ex) catch (Exception ex)
{ {
LogHelper.WriteLogToFile($"重新加载PPT联动模块失败: {ex}", LogHelper.LogType.Error); LogHelper.WriteLogToFile($"重新启用PPT联动模块失败: {ex}", LogHelper.LogType.Error);
_isModuleUnloading = false; _isModuleUnloading = false;
} }
}); });