title: Get Currently Opened Word Document from Process
body: <p>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.</p>
  
  <p><strong>Pseudocode Example:</strong></p>
  
  <pre><code>Process myWordProcess = something; // This is my process reference
  DocumentInformation docInfo = SomeNamespace.GetDocumentInformation(myWordProcess);
  string documentPath = docInfo.FullName; // "C:\User\Foo\Documents\Test.docx"
  </code></pre>
  
  <p>The starting point is a <code>Process</code> object which is executed by <code>WINWORD.exe</code>.</p>
  
  <p>I am not looking for a way that includes parsing <code>process.MainWindowTitle</code>, but rather a more, let's say, "proper" solution.</p>
  
  <p>Having done a fair bit of initial research, I believe what's required is the Windows Accessibility API.</p>
  
  <p><a href="http://www.pinvoke.net/default.aspx/oleacc.accessibleobjectfromwindow" rel="nofollow noreferrer">Pinvoke</a> mentiones the <code>AccessibleObjectFromWindow</code> signature.  That being said, the resulting <code>accessible</code> object does not provide me with much more information than the <code>process</code> already does.</p>
  
  <p>Here's what I tried from Pinvoke:</p>
  
  <pre><code>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
      }
  }
  </code></pre>
  
  <p>Perhaps the solution is to somehow get a <code>Document</code> interface (Office COM Interop, <a href="https://msdn.microsoft.com/en-us/library/microsoft.office.interop.word.document(v=office.14).aspx" rel="nofollow noreferrer">see here for the interface</a>) from the process or window handle?  Or, perhaps, first getting a <a href="https://msdn.microsoft.com/en-us/library/microsoft.office.interop.word.window(v=office.14).aspx" rel="nofollow noreferrer">Window</a> and then the <code>Document</code>?</p>
  
  <p>Then, equipped with that information from Office Interop, one could read the <code>Path</code> property.</p>
  
  <p>I am open to any solutions for this.</p>
  
  <p>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).</p>