目标是获取在我有过程参考的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 Accessibility 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 Interop,see here for the interface)?或者,也许首先获得Window然后获得Document
?
然后,配备来自Office Interop的信息,可以阅读Path
属性。
我愿意接受任何解决方案。
如果你知道如何在Excel或PowerPoint上执行此操作 - 那么这也没关系,因为我假设可以对Word应用相同的过程(在更改几个接口和GUID之后)。
答案 0 :(得分:3)
借用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);
}
}
}
}
如果需要,您仍然可以参考正在运行的进程。
如果需要,迭代Documents
集合是一件简单的事情。
foreach (Word.Document doc in word.Documents)
{
Console.WriteLine("{0}", doc.FullName);
}
答案 1 :(得分:0)
您可以使用以下代码获取所有单词打开文档的列表
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;