improve:PPT联动

This commit is contained in:
2025-09-06 12:09:06 +08:00
parent d8825f0a73
commit 28109a0c97
6 changed files with 311 additions and 2 deletions
+1 -1
View File
@@ -868,7 +868,7 @@ namespace Ink_Canvas.Helpers
decryptedData[i] = (byte)(data[i] ^ keyBytes[i % keyBytes.Length]);
}
// 验证校验
// 验证校验
byte[] computedChecksum = sha256.ComputeHash(decryptedData);
if (!checksum.SequenceEqual(computedChecksum))
{
+10 -1
View File
@@ -538,7 +538,7 @@
</GroupBox.Header>
<ui:SimpleStackPanel Spacing="6" Margin="0,10,0,0">
<TextBlock TextWrapping="Wrap" Margin="0,0,0,10" Foreground="#fafafa">
打开新的设置窗口,提供更丰富的设置选项和更好的用户体验。
打开新的设置窗口,提供更丰富的设置选项和更好的用户体验。(开发中)
</TextBlock>
<Button x:Name="BtnOpenNewSettings" Content="打开新设置窗口"
HorizontalAlignment="Left" Click="BtnOpenNewSettings_Click"
@@ -1340,6 +1340,15 @@
FontFamily="Microsoft YaHei UI" FontWeight="Bold"
Toggled="ToggleSwitchSupportPowerPoint_Toggled" />
</ui:SimpleStackPanel>
<ui:SimpleStackPanel Orientation="Horizontal" HorizontalAlignment="Left">
<Image Source="/Resources/Icons-png/Powerpoint.png" Margin="0,0,6,0" Width="28"
Height="28" VerticalAlignment="Center" />
<TextBlock Foreground="#fafafa" Text="PowerPoint 联动增强" VerticalAlignment="Center"
FontSize="14" Margin="0,0,16,0" />
<ui:ToggleSwitch OnContent="" OffContent="" Name="ToggleSwitchPowerPointEnhancement"
IsOn="False" FontFamily="Microsoft YaHei UI" FontWeight="Bold"
Toggled="ToggleSwitchPowerPointEnhancement_Toggled" />
</ui:SimpleStackPanel>
<ui:SimpleStackPanel Orientation="Horizontal" HorizontalAlignment="Left">
<Image Source="/Resources/Icons-png/WPS.png" Margin="0,0,6,0" Width="28"
Height="28" VerticalAlignment="Center" />
+6
View File
@@ -438,6 +438,12 @@ namespace Ink_Canvas
StartPPTMonitoring();
}
// 如果启用PowerPoint联动增强功能,启动进程守护
if (Settings.PowerPointSettings.EnablePowerPointEnhancement)
{
StartPowerPointProcessMonitoring();
}
// HasNewUpdateWindow hasNewUpdateWindow = new HasNewUpdateWindow();
if (Environment.Is64BitProcess) GroupBoxInkRecognition.Visibility = Visibility.Collapsed;
+290
View File
@@ -3,6 +3,7 @@ using iNKORE.UI.WPF.Modern;
using Microsoft.Office.Core;
using Microsoft.Office.Interop.PowerPoint;
using System;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
@@ -84,6 +85,10 @@ namespace Ink_Canvas
private bool _isLongPressNext = true; // true为下一页,false为上一页
private const int LongPressDelay = 500; // 长按延迟时间(毫秒)
private const int LongPressInterval = 15; // 长按翻页间隔(毫秒)
// PowerPoint应用程序守护相关字段
private DispatcherTimer _powerPointProcessMonitorTimer;
private const int ProcessMonitorInterval = 5000; // 应用程序监控间隔(毫秒)
#endregion
#region PPT Managers
@@ -159,6 +164,246 @@ namespace Ink_Canvas
LogHelper.WriteLogToFile("PPT监控已停止", LogHelper.LogType.Event);
}
#region PowerPoint Application Management
/// <summary>
/// 启动PowerPoint应用程序守护
/// </summary>
private void StartPowerPointProcessMonitoring()
{
try
{
if (!Settings.PowerPointSettings.EnablePowerPointEnhancement) return;
// 创建PowerPoint应用程序实例
CreatePowerPointApplication();
// 启动应用程序监控定时器
if (_powerPointProcessMonitorTimer == null)
{
_powerPointProcessMonitorTimer = new DispatcherTimer();
_powerPointProcessMonitorTimer.Interval = TimeSpan.FromMilliseconds(ProcessMonitorInterval);
_powerPointProcessMonitorTimer.Tick += OnPowerPointApplicationMonitorTick;
}
_powerPointProcessMonitorTimer.Start();
LogHelper.WriteLogToFile("PowerPoint应用程序守护已启动", LogHelper.LogType.Event);
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"启动PowerPoint应用程序守护失败: {ex}", LogHelper.LogType.Error);
}
}
/// <summary>
/// 停止PowerPoint应用程序守护
/// </summary>
private void StopPowerPointProcessMonitoring()
{
try
{
// 停止应用程序监控定时器
_powerPointProcessMonitorTimer?.Stop();
// 关闭PowerPoint应用程序
ClosePowerPointApplication();
LogHelper.WriteLogToFile("PowerPoint应用程序守护已停止", LogHelper.LogType.Event);
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"停止PowerPoint应用程序守护失败: {ex}", LogHelper.LogType.Error);
}
}
/// <summary>
/// 创建PowerPoint应用程序实例
/// </summary>
private void CreatePowerPointApplication()
{
try
{
// 如果应用程序已存在且有效,则不重复创建
if (pptApplication != null && IsPowerPointApplicationValid())
{
return;
}
// 创建新的PowerPoint应用程序实例
pptApplication = new Microsoft.Office.Interop.PowerPoint.Application();
// 设置为不可见,作为后台进程
pptApplication.Visible = Microsoft.Office.Core.MsoTriState.msoFalse;
// 设置应用程序属性
pptApplication.WindowState = Microsoft.Office.Interop.PowerPoint.PpWindowState.ppWindowMinimized;
// 直接设置PPTManager的PPTApplication属性,绕过COM注册问题
Task.Delay(1000).ContinueWith(_ =>
{
Dispatcher.Invoke(() =>
{
try
{
// 直接设置PPTManager的PowerPoint应用程序实例
if (_pptManager != null)
{
// 使用反射或直接访问来设置PPTManager的PPTApplication
SetPPTManagerApplication(pptApplication);
LogHelper.WriteLogToFile("已直接设置PPTManager的PowerPoint应用程序实例", LogHelper.LogType.Event);
}
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"设置PPTManager的PowerPoint应用程序实例失败: {ex}", LogHelper.LogType.Error);
}
});
});
LogHelper.WriteLogToFile("PowerPoint应用程序实例已创建", LogHelper.LogType.Event);
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"创建PowerPoint应用程序实例失败: {ex}", LogHelper.LogType.Error);
}
}
/// <summary>
/// 设置PPTManager的PowerPoint应用程序实例
/// </summary>
private void SetPPTManagerApplication(Microsoft.Office.Interop.PowerPoint.Application app)
{
try
{
if (_pptManager == null) return;
// 使用反射调用PPTManager的ConnectToPPT方法
var pptManagerType = _pptManager.GetType();
var connectMethod = pptManagerType.GetMethod("ConnectToPPT",
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
if (connectMethod != null)
{
connectMethod.Invoke(_pptManager, new object[] { app });
LogHelper.WriteLogToFile("通过ConnectToPPT方法设置PowerPoint应用程序实例", LogHelper.LogType.Event);
}
else
{
// 如果无法通过反射调用,尝试直接设置属性
var pptApplicationProperty = pptManagerType.GetProperty("PPTApplication",
System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
if (pptApplicationProperty != null && pptApplicationProperty.CanWrite)
{
pptApplicationProperty.SetValue(_pptManager, app);
LogHelper.WriteLogToFile("通过属性设置PPTManager的PowerPoint应用程序实例", LogHelper.LogType.Event);
}
else
{
LogHelper.WriteLogToFile("无法设置PPTManager的PowerPoint应用程序实例", LogHelper.LogType.Warning);
}
}
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"设置PPTManager的PowerPoint应用程序实例失败: {ex}", LogHelper.LogType.Error);
}
}
/// <summary>
/// 检查PowerPoint应用程序是否有效
/// </summary>
private bool IsPowerPointApplicationValid()
{
try
{
if (pptApplication == null) return false;
if (!Marshal.IsComObject(pptApplication)) return false;
// 尝试访问一个简单的属性来验证连接是否有效
var _ = pptApplication.Name;
return true;
}
catch (COMException comEx)
{
var hr = (uint)comEx.HResult;
// 如果COM对象已失效,返回false
if (hr == 0x8001010E || hr == 0x80004005 || hr == 0x800706B5)
{
return false;
}
return false;
}
catch
{
return false;
}
}
/// <summary>
/// 关闭PowerPoint应用程序
/// </summary>
private void ClosePowerPointApplication()
{
try
{
if (pptApplication != null)
{
// 关闭所有打开的演示文稿
if (pptApplication.Presentations.Count > 0)
{
for (int i = pptApplication.Presentations.Count; i >= 1; i--)
{
try
{
pptApplication.Presentations[i].Close();
}
catch { }
}
}
// 退出PowerPoint应用程序
pptApplication.Quit();
// 释放COM对象
Marshal.ReleaseComObject(pptApplication);
pptApplication = null;
}
LogHelper.WriteLogToFile("PowerPoint应用程序已关闭", LogHelper.LogType.Event);
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"关闭PowerPoint应用程序失败: {ex}", LogHelper.LogType.Error);
}
}
/// <summary>
/// PowerPoint应用程序监控定时器事件
/// </summary>
private void OnPowerPointApplicationMonitorTick(object sender, EventArgs e)
{
try
{
if (!Settings.PowerPointSettings.EnablePowerPointEnhancement)
{
StopPowerPointProcessMonitoring();
return;
}
// 检查应用程序是否还在运行
if (!IsPowerPointApplicationValid())
{
LogHelper.WriteLogToFile("检测到PowerPoint应用程序已失效,重新创建", LogHelper.LogType.Event);
CreatePowerPointApplication();
}
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"PowerPoint应用程序监控异常: {ex}", LogHelper.LogType.Error);
}
}
#endregion
private void DisposePPTManagers()
{
try
@@ -170,6 +415,11 @@ namespace Ink_Canvas
_pptManager = null;
_pptInkManager = null;
_pptUIManager = null;
// 清理PowerPoint进程守护
StopPowerPointProcessMonitoring();
_powerPointProcessMonitorTimer = null;
LogHelper.WriteLogToFile("PPT管理器已释放", LogHelper.LogType.Event);
}
catch (Exception ex)
@@ -795,11 +1045,51 @@ namespace Ink_Canvas
}
}
private void ToggleSwitchPowerPointEnhancement_Toggled(object sender, RoutedEventArgs e)
{
if (!isLoaded) return;
Settings.PowerPointSettings.EnablePowerPointEnhancement = ToggleSwitchPowerPointEnhancement.IsOn;
// 与WPS支持互斥
if (Settings.PowerPointSettings.EnablePowerPointEnhancement)
{
Settings.PowerPointSettings.IsSupportWPS = false;
ToggleSwitchSupportWPS.IsOn = false;
// 更新PPT管理器的WPS支持设置
if (_pptManager != null)
{
_pptManager.IsSupportWPS = false;
}
}
SaveSettingsToFile();
// 启动或停止PowerPoint进程守护
if (Settings.PowerPointSettings.EnablePowerPointEnhancement)
{
StartPowerPointProcessMonitoring();
}
else
{
StopPowerPointProcessMonitoring();
}
}
private void ToggleSwitchSupportWPS_Toggled(object sender, RoutedEventArgs e)
{
if (!isLoaded) return;
Settings.PowerPointSettings.IsSupportWPS = ToggleSwitchSupportWPS.IsOn;
// 与PowerPoint联动增强互斥
if (Settings.PowerPointSettings.IsSupportWPS)
{
Settings.PowerPointSettings.EnablePowerPointEnhancement = false;
ToggleSwitchPowerPointEnhancement.IsOn = false;
StopPowerPointProcessMonitoring();
}
// 更新PPT管理器的WPS支持设置
if (_pptManager != null)
@@ -459,6 +459,8 @@ namespace Ink_Canvas
ToggleSwitchSupportWPS.IsOn = Settings.PowerPointSettings.IsSupportWPS;
ToggleSwitchPowerPointEnhancement.IsOn = Settings.PowerPointSettings.EnablePowerPointEnhancement;
ToggleSwitchAutoSaveScreenShotInPowerPoint.IsOn =
Settings.PowerPointSettings.IsAutoSaveScreenShotInPowerPoint;
ToggleSwitchEnableWppProcessKill.IsOn = Settings.PowerPointSettings.EnableWppProcessKill;
+2
View File
@@ -304,6 +304,8 @@ namespace Ink_Canvas
public bool EnableWppProcessKill { get; set; } = true;
[JsonProperty("isAlwaysGoToFirstPageOnReenter")]
public bool IsAlwaysGoToFirstPageOnReenter { get; set; }
[JsonProperty("enablePowerPointEnhancement")]
public bool EnablePowerPointEnhancement { get; set; } = false;
}
public class Automation