You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET Core C#中Acrobat关闭文件标签页时进程未终止问题求助

.NET Core C# 监听Acrobat标签页关闭事件的问题

我在.NET Core C#开发的应用中遇到下述问题:通过代码调用Acrobat打开PDF文件,当前监听Acrobat进程退出事件,关闭Acrobat主程序时可正常终止自身应用;但关闭Acrobat内的文件标签页时,应用仍在后台运行。我不想杀死所有Acrobat进程,希望获取文件标签页关闭的事件。

原代码示例

var process = Process.Start(new ProcessStartInfo
{
    FileName = deafaultReader,
    Arguments = $"/n {filepath}",
    UseShellExecute = true
});

process.EnableRaisingEvents = true;
process.Exited += (sender, e) => 
{
    // 监听Acrobat关闭事件,在此处终止自身应用
};
return process;
// 目前关闭Acrobat主程序时能正常终止应用,但关闭PDF标签页时,应用仍在后台运行

解决方案

Acrobat采用单进程多标签的架构,你启动的进程是主程序实例,关闭标签页不会触发主进程退出,因此靠Exited事件无法实现需求。以下是几种可行的解决思路:

1. 利用Acrobat COM接口监听文档关闭事件

Acrobat提供了COM自动化接口,可直接连接到Acrobat实例并监听文档关闭事件:

  • 先在项目中添加COM引用,搜索并选择"Adobe Acrobat xx.0 Type Library"
  • 编写监听代码:
using Acrobat;

// 打开目标PDF并获取Acrobat实例
var acroApp = new CAcroApp();
var acroPDDoc = acroApp.Open(filepath, "");

// 绑定文档关闭事件
acroPDDoc.OnClose += () =>
{
    // 此处处理PDF标签页关闭逻辑,比如终止自身应用
    Environment.Exit(0);
};

// 注意:必须保持对acroApp和acroPDDoc的引用,否则会被GC回收导致监听失效

注意:该方式依赖Acrobat的COM支持,部分精简版Acrobat可能不提供此功能。

2. 轮询检查目标PDF窗口是否存在

如果无法使用COM接口,可通过Windows API枚举Acrobat窗口,轮询目标PDF的窗口标题是否存在:

using System.Runtime.InteropServices;
using System.Timers;

public class PdfWindowMonitor
{
    [DllImport("user32.dll", CharSet = CharSet.Unicode)]
    private static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count);

    [DllImport("user32.dll")]
    private static extern bool EnumWindows(EnumWindowsProc proc, IntPtr lParam);

    private delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);

    private readonly string _targetPdfName;
    private Timer _checkTimer;

    public PdfWindowMonitor(string pdfFilePath)
    {
        _targetPdfName = Path.GetFileName(pdfFilePath);
    }

    public void StartMonitoring()
    {
        _checkTimer = new Timer(1000); // 每秒检查一次
        _checkTimer.Elapsed += CheckPdfWindowStatus;
        _checkTimer.Start();
    }

    private void CheckPdfWindowStatus(object sender, ElapsedEventArgs e)
    {
        bool isPdfOpen = false;
        EnumWindows((hWnd, lParam) =>
        {
            var windowTitle = new StringBuilder(256);
            GetWindowText(hWnd, windowTitle, windowTitle.Capacity);
            string title = windowTitle.ToString();
            
            // Acrobat窗口标题格式通常为"文件名 - Adobe Acrobat"
            if (title.Contains(_targetPdfName) && title.Contains("Adobe Acrobat"))
            {
                isPdfOpen = true;
                return false; // 找到目标窗口后停止枚举
            }
            return true;
        }, IntPtr.Zero);

        if (!isPdfOpen)
        {
            _checkTimer.Stop();
            _checkTimer.Dispose();
            Environment.Exit(0); // 终止自身应用
        }
    }
}

// 使用方式
var monitor = new PdfWindowMonitor(filepath);
monitor.StartMonitoring();

注意:该方式依赖Acrobat窗口标题格式,若用户修改了Acrobat语言设置,需适配对应标题关键词。

3. 强制启动独立Acrobat实例

如果允许每个PDF打开独立的Acrobat进程,可修改启动参数,让每个PDF对应单独进程,这样关闭标签页(即进程退出)时就能触发Exited事件:

var process = Process.Start(new ProcessStartInfo
{
    FileName = deafaultReader,
    Arguments = $"/s {filepath}", // 用/s参数强制启动新实例
    UseShellExecute = true
});

process.EnableRaisingEvents = true;
process.Exited += (sender, e) => 
{
    Environment.Exit(0);
};
return process;

注意:该方式会生成多个Acrobat进程,可能不符合用户常规使用习惯,但能直接复用原有的进程监听逻辑。

内容的提问来源于stack exchange,提问作者RAM yadav

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 01:03:24