如何用C#获取Adobe Acrobat Reader中所有已打开PDF的文件名
解决C#获取Adobe Acrobat Reader所有打开PDF文件名的问题
你遇到的问题根源在于Adobe Acrobat Reader默认采用单进程多文档架构——哪怕打开多个PDF,系统中通常只有一个Acrord32(或64位版本的AcroRd64)进程。Process.MainWindowTitle仅会返回当前激活窗口的标题,自然只能拿到一个文件名。
要获取所有打开的PDF文件名,需要通过Windows API枚举该进程下的所有窗口,再提取每个窗口的标题信息。以下是完整实现:
实现代码
首先引入必要的命名空间:
using System; using System.Collections.Generic; using System.Diagnostics; using System.Runtime.InteropServices; using System.Text;
编写窗口枚举的工具类:
public static class WindowHelper { private delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam); [DllImport("user32.dll", CharSet = CharSet.Unicode)] private static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount); [DllImport("user32.dll")] private static extern bool EnumWindows(EnumWindowsProc enumProc, IntPtr lParam); [DllImport("user32.dll")] private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId); public static List<string> GetAcrobatOpenPdfNames() { List<string> pdfNames = new List<string>(); // 先检查32位进程,再检查64位进程 Process[] acrobatProcesses = Process.GetProcessesByName("Acrord32"); if (acrobatProcesses.Length == 0) { acrobatProcesses = Process.GetProcessesByName("AcroRd64"); } foreach (Process process in acrobatProcesses) { uint targetProcessId = (uint)process.Id; // 枚举所有窗口 EnumWindows((hWnd, lParam) => { GetWindowThreadProcessId(hWnd, out uint windowProcessId); // 判断窗口是否属于目标Acrobat进程 if (windowProcessId == targetProcessId) { StringBuilder titleBuilder = new StringBuilder(256); GetWindowText(hWnd, titleBuilder, titleBuilder.Capacity); string windowTitle = titleBuilder.ToString().Trim(); // Acrobat窗口标题格式为「文件名 - Adobe Acrobat Reader」 if (!string.IsNullOrEmpty(windowTitle) && windowTitle.EndsWith(" - Adobe Acrobat Reader")) { string pdfName = windowTitle.Substring(0, windowTitle.LastIndexOf(" - Adobe Acrobat Reader")).Trim(); // 去重,避免重复添加 if (!pdfNames.Contains(pdfName)) { pdfNames.Add(pdfName); } } } return true; }, IntPtr.Zero); } return pdfNames; } }
使用示例
调用工具类获取并输出所有打开的PDF文件名:
List<string> openPdfs = WindowHelper.GetAcrobatOpenPdfNames(); foreach (string pdfName in openPdfs) { Console.WriteLine(pdfName); }
关键说明
- 同时适配32位(
Acrord32)和64位(AcroRd64)版本的Acrobat Reader - 通过
EnumWindows遍历系统所有窗口,结合GetWindowThreadProcessId筛选出属于Acrobat进程的窗口 - 解析窗口标题时,按照Acrobat的默认格式截取文件名部分
- 添加去重逻辑,避免同一文件的重复窗口被多次统计
内容的提问来源于stack exchange,提问作者suyog kotkar
相关产品推荐
相关产品推荐

