问题
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.
Pseudocode Example:
Process myWordProcess = something; // This is my process reference
DocumentInformation docInfo = SomeNamespace.GetDocumentInformation(myWordProcess);
string documentPath = docInfo.FullName; // "C:\User\Foo\Documents\Test.docx"
The starting point is a Process
object which is executed by WINWORD.exe
.
I am not looking for a way that includes parsing process.MainWindowTitle
, but rather a more, let's say, "proper" solution.
Having done a fair bit of initial research, I believe what's required is the Windows Accessibility API.
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.
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
}
}
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
?
Then, equipped with that information from Office Interop, one could read the Path
property.
I am open to any solutions for this.
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).
回答1:
Borrowing some code from Microsoft, the key method for which is 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.
It is a simple matter to iterate the Documents
collection if needed.
foreach (Word.Document doc in word.Documents)
{
Console.WriteLine("{0}", doc.FullName);
}
回答2:
You can get list of all word opened document using following code
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);
}
Use following code to get active document full path
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;
来源:https://stackoverflow.com/questions/48321167/get-currently-opened-word-document-from-process