代码之家  ›  专栏  ›  技术社区  ›  JDR Jake Ginnivan

从进程获取当前打开的Word文档

  •  2
  • JDR Jake Ginnivan  · 技术社区  · 7 年前

    目标是获取在我有流程参考的Microsoft Word实例中打开的文档的完整路径。

    伪代码示例:

    Process myWordProcess = something; // This is my process reference
    DocumentInformation docInfo = SomeNamespace.GetDocumentInformation(myWordProcess);
    string documentPath = docInfo.FullName; // "C:\User\Foo\Documents\Test.docx"
    

    起点是 Process 由执行的对象 WINWORD.exe .

    我不是在寻找一种包括解析的方法 process.MainWindowTitle ,但更确切地说,这是一个“适当”的解决方案。

    在做了相当多的初步研究之后,我认为需要的是Windows辅助功能API。

    Pinvoke 提到 AccessibleObjectFromWindow 签名话虽如此,结果 accessible 对象没有为我提供比 process 已经有了。

    以下是我从Pinvoke尝试的内容:

    internal enum OBJID : uint
    {
        WINDOW = 0x00000000,
        SYSMENU = 0xFFFFFFFF,
        TITLEBAR = 0xFFFFFFFE,
        MENU = 0xFFFFFFFD,
        CLIENT = 0xFFFFFFFC,
        VSCROLL = 0xFFFFFFFB,
        HSCROLL = 0xFFFFFFFA,
        SIZEGRIP = 0xFFFFFFF9,
        CARET = 0xFFFFFFF8,
        CURSOR = 0xFFFFFFF7,
        ALERT = 0xFFFFFFF6,
        SOUND = 0xFFFFFFF5,
    }
    
    public class DocumentLocator
    {
        [DllImport("oleacc.dll")]
        internal static extern int AccessibleObjectFromWindow(IntPtr hwnd, uint id, ref Guid iid, [In] [Out] [MarshalAs(UnmanagedType.IUnknown)] ref object ppvObject);
    
        public static void GetWordInfo(Process process)
        {
            var mainWindowHandle = process.MainWindowHandle;
            var guid = new Guid("{618736E0-3C3D-11CF-810C-00AA00389B71}");
    
            object obj = null;
            var retVal = AccessibleObjectFromWindow(mainWindowHandle, (uint)OBJID.WINDOW, ref guid, ref obj);
            var accessible = (IAccessible) obj; // Not much information is contained in this object
        }
    }
    

    也许解决办法是 Document 接口(Office COM互操作, see here for the interface )从进程或窗口句柄?或者,也许是第一次 Window 然后 文件 ?

    然后,利用Office Interop提供的信息,可以阅读 Path 所有物

    我愿意接受任何解决方案。

    如果您知道如何对Excel或PowerPoint执行此操作,那么也可以,因为我假设相同的过程可以应用于Word(在更改了几个界面和GUI之后)。

    2 回复  |  直到 7 年前
        1
  •  3
  •   Andy G    7 年前

    从中借用一些代码 Microsoft ,其关键方法是 GetActiveObject :

    using System;
    using System.Runtime.InteropServices;
    using Word = Microsoft.Office.Interop.Word;
    
    namespace ConsoleApp2
    {
        class Program
        {
            static void Main(string[] args)
            {
                object wordAsObject;
                Word.Application word;
    
                try
                {
                    wordAsObject = System.Runtime.InteropServices.Marshal.GetActiveObject("Word.Application");
                    //If there is a running Word instance, it gets saved into the word variable
                    word = (Word.Application)wordAsObject;
    
                    Console.WriteLine("{0}", word.ActiveDocument.FullName);
    
                    Console.ReadKey();
                }
                catch (COMException)
                {
                    //If there is no running instance, it creates a new one
                    //Type type = Type.GetTypeFromProgID("Word.Application");
                    //wordAsObject = System.Activator.CreateInstance(type);
                }
            }
        }
    }
    

    您仍然有一个对running的引用 过程 如果你需要的话。

    迭代 Documents 如果需要,收集。

    foreach (Word.Document doc in word.Documents)
    {
        Console.WriteLine("{0}", doc.FullName);
    }
    
        2
  •  0
  •   Kalpesh Bhadra    7 年前

    您可以使用以下代码获取所有word打开文档的列表

    Microsoft.Office.Interop.Word.Application WordObj;
    WordObj = (Microsoft.Office.Interop.Word.Application)System.Runtime.InteropServices.Marshal.GetActiveObject("Word.Application");
    for (int i = 0; i < WordObj.Windows.Count; i++)
    {
        object idx = i + 1;
        Window WinObj = WordObj.Windows.get_Item(ref idx);
        doc_list.Add(WinObj.Document.FullName);
    }
    

    使用以下代码获取活动文档的完整路径

        Microsoft.Office.Interop.Word.Application WordObj;
        WordObj =
     (Microsoft.Office.Interop.Word.Application)System.Runtime.InteropServices.Marshal.GetActiveObject("Word.Application");
        var word = (Word.Application)WordObj;
        string docPath=word.ActiveDocument.FullName;