从流程中获取当前打开的Word文档 [英] Get Currently Opened Word Document from Process

查看:58
本文介绍了从流程中获取当前打开的Word文档的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

The goal is to get the full path to the document opened in an instance of Microsoft Word that I have a process reference for.

伪代码示例:

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 的方法,而是一种更多的合适的"解决方案.

I am not looking for a way that includes parsing process.MainWindowTitle, but rather a more, let's say, "proper" solution.

经过大量的初步研究,我相信需要Windows Accessibility API.

Having done a fair bit of initial research, I believe what's required is the Windows Accessibility API.

Pinvoke 提到了 AccessibleObjectFromWindow 签名.话虽这么说,与 process 相比,所得的 accessible 对象没有为我提供更多的信息.

Pinvoke mentiones the AccessibleObjectFromWindow signature. That being said, the resulting accessible object does not provide me with much more information than the process already does.

这是我从Pinvoke尝试的内容:

Here's what I tried from 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 Interop,

Perhaps the solution is to somehow get a Document interface (Office COM Interop, see here for the interface) from the process or window handle? Or, perhaps, first getting a Window and then the Document?

然后,借助Office Interop的信息,人们可以读取 Path 属性.

Then, equipped with that information from Office Interop, one could read the Path property.

我愿意为此提供任何解决方案.

I am open to any solutions for this.

如果您知道如何针对Excel或PowerPoint执行此操作-那也很好,因为我假设可以对Word应用相同的过程(在更改了两个接口和GUID之后).

If you know how to perform this regarding Excel or PowerPoint - then that would be fine, too, as I assume the same process can be applied for Word (after changing a couple of interfaces and GUIDs).

推荐答案

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);
            }
        }
    }
}

如果需要,您仍然可以参考正在运行的进程.

You still have a reference to the running process if you need it.

如果需要,迭代 Documents 集合很简单.

It is a simple matter to iterate the Documents collection if needed.

foreach (Word.Document doc in word.Documents)
{
    Console.WriteLine("{0}", doc.FullName);
}

这篇关于从流程中获取当前打开的Word文档的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆