Tutorial :Get PID from MS-Word ApplicationClass?



Question:

Consider this code:

using Microsoft.Office.Interop.Word;    ApplicationClass _application = new ApplicationClass();  

Can I get the PID from the Winword.exe process that was launched by the _application?

I need the PID because with corrupted files, I just can't quit the ApplicationClass, even using this code:

_application.Quit(ref saveFile, ref missing, ref missing);  System.Runtime.InteropServices.Marshal.ReleaseComObject(_application);  GC.Collect();  GC.WaitForPendingFinalizers();  

I can't search for the winword.exe process and kill it, because I will have several, and I don't know which one to kill. If I can get a PID for each ApplicationClass, I could just kill the correct winword.exe process that is giving me troubles to quit.


Solution:1

Here is how to do it.

//Set the AppId  string AppId = ""+DateTime.Now.Ticks(); //A random title    //Create an identity for the app    this.oWordApp = new Microsoft.Office.Interop.Word.ApplicationClass();  this.oWordApp.Application.Caption = AppId;  this.oWordApp.Application.Visible = true;    ///Get the pid by for word application  this.WordPid = StaticMethods.GetProcessIdByWindowTitle(AppId);    while ( StaticMethods.GetProcessIdByWindowTitle(AppId) == Int32.MaxValue) //Loop till u get  {      Thread.Sleep(5);  }    this.WordPid = StaticMethods.GetProcessIdByWindowTitle(AppId);      ///You canh hide the application afterward              this.oWordApp.Application.Visible = false;    string this.oWordApp = new Microsoft.Office.Interop.Word.ApplicationClass();  this.oWordApp.Application.Caption = AppId;  this.oWordApp.Application.Visible = true;  ///Get the pid by   this.WordPid = StaticMethods.GetProcessIdByWindowTitle(AppId);    while ( StaticMethods.GetProcessIdByWindowTitle(AppId) == Int32.MaxValue)  {      Thread.Sleep(5);  }    this.WordPid = StaticMethods.GetProcessIdByWindowTitle(AppId);    this.oWordApp.Application.Visible = false; //You Can hide the application now    /// <summary>  /// Returns the name of that process given by that title  /// </summary>  /// <param name="AppId">Int32MaxValue returned if it cant be found.</param>  /// <returns></returns>  public static int GetProcessIdByWindowTitle(string AppId)  {     Process[] P_CESSES = Process.GetProcesses();     for (int p_count = 0; p_count < P_CESSES.Length; p_count++)     {          if (P_CESSES[p_count].MainWindowTitle.Equals(AppId))          {                      return P_CESSES[p_count].Id;          }     }        return Int32.MaxValue;  }  


Solution:2

The usual way to get it is to change Word's title to something unique and hop through the top-level window list until you find it (EnumWindows).


Solution:3

http://www.codekeep.net/snippets/7835116d-b254-466e-ae66-666e4fa3ea5e.aspx

///Return Type: DWORD->unsigned int  ///hWnd: HWND->HWND__*  ///lpdwProcessId: LPDWORD->DWORD*  [System.Runtime.InteropServices.DllImportAttribute( "user32.dll", EntryPoint = "GetWindowThreadProcessId" )]  public static extern int GetWindowThreadProcessId ( [System.Runtime.InteropServices.InAttribute()] System.IntPtr hWnd, out int lpdwProcessId );      private int _ExcelPID = 0;  Process _ExcelProcess;    private Application _ExcelApp = new ApplicationClass();  GetWindowThreadProcessId( new IntPtr(_ExcelApp.Hwnd), out _ExcelPID );  _ExcelProcess = System.Diagnostics.Process.GetProcessById( _ExcelPID );    ...    _ExcelProcess.Kill();  


Solution:4

There may be some error in the Word file. As a result, when you open the file with the method Word.ApplicationClass.Documents.Open(), there will be a dialog shown and the process will hang.

Use Word.ApplicationClass.Documents.OpenNoRepairDialog() instead. I found it fixed the problem.


Solution:5

No, unfortunately there is no way to associate an instance of ApplicationClass with a running process of Word.

Why do you need to kill the instance of Word? Couldn't you just ask it to close all of its documents and then simply stop using that instance? If you remove all references to the class eventually the GC will kick in and take down the COM server.


Solution:6

Before you start your application, list all running Word processes, start your application, and list running Word processes again. The process found in the second list and not found in the first one is the right one:

var oPL1 = from proc in Process.GetProcessesByName("WINWORD") select proc.Id;  var app = new Word.Application();    var oPL2 = from proc in Process.GetProcessesByName("WINWORD") select proc.Id;  var pid = (from p in oPL2 where !oPL1.Contains(p) select p).ToList()[0];  

The method has obvious timing issues, but it is the only one I've found which works reliably most of the time.


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »