Frage

Betrachten Sie diesen Code ein:

using Microsoft.Office.Interop.Word;

ApplicationClass _application = new ApplicationClass();

Kann ich die PID aus dem Winword.exe Prozess, der durch die _application ins Leben gerufen wurde?

Ich brauche die PID, weil mit beschädigten Dateien, kann ich einfach nicht die ApplicationClass verlassen, auch mit diesem Code:

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

Ich kann nicht für den Prozess Winword.exe suchen und sie töten, weil ich mehrere haben, und ich weiß nicht, was man zu töten. Wenn ich eine PID für jeden ApplicationClass bekommen kann, konnte ich nur den richtigen winword.exe Prozess beenden, die mir Probleme geben wird, zu beenden.

War es hilfreich?

Lösung

Hier ist, wie es zu tun.

//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;

while (GetProcessIdByWindowTitle(AppId) == Int32.MaxValue) //Loop till u get
{
    Thread.Sleep(5);
}

///Get the pid by for word application
this.WordPid = GetProcessIdByWindowTitle(AppId);

///You canh hide the application afterward            
this.oWordApp.Application.Visible = false;

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

Andere Tipps

Es kann einige Fehler in der Word-Datei sein. Als Ergebnis, wenn Sie die Datei mit der Word.ApplicationClass.Documents.Open() Methode öffnen, wird ein Dialog angezeigt und der Prozess hängen.

Verwenden Word.ApplicationClass.Documents.OpenNoRepairDialog() statt. Ich fand es das Problem behoben.

Der üblicher Weg, um es ist Word-Titel zu etwas Einzigartiges und hüpfen durch die Fenster der oberste Ebene Liste zu ändern, bis Sie es (EnumWindows) finden.

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

Nein, leider gibt es keine Möglichkeit, eine Instanz von ApplicationClass mit einem laufenden Prozess von Word zu verknüpfen.

Warum wollen Sie die Instanz von Word töten müssen? Könnten Sie nicht fragen sie nur alle seine Dokumente zu schließen und dann einfach aufhören diese Instanz mit? Wenn Sie alle Verweise auf die Klasse entfernen schließlich die GC in kicken und nehmen auf der COM Server.

Bevor Sie Ihre Anwendung starten, führen Sie alle laufenden Prozesse Wort, starten Sie Ihre Anwendung, und die Liste wieder zum Laufen Wort Prozesse. Der Prozess in der zweiten Liste gefunden und nicht in dem ersten ist die richtige gefunden:

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];

Das Verfahren hat offensichtlich Timing-Probleme, aber es ist die einzige, die ich gefunden habe, die zuverlässig die meiste Zeit funktioniert.

enter code here  public void OpenWord(string Path, bool IsVisible)
    {

        MessageFilter.Register();
        object oMissing = Missing.Value;
        GUIDCaption = Guid.NewGuid().ToString();
        wordApp = new Microsoft.Office.Interop.Word.ApplicationClass();
        wordApp.Visible = IsVisible;
        wordApp.Caption = GUIDCaption;
        object oPath = Path;
        wordDoc = wordApp.Documents.Open(ref  oPath, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing);

    }
    /// <summary>
    /// 关闭文件
    /// </summary>
    public void CloseWord()
    {
        object oMissing = Missing.Value;
        GUIDCaption = "";
        if (null != wordDoc)
        {
            wordDoc.Close(ref oMissing, ref oMissing, ref oMissing);
        }
        if (null != wordApp)
        {
            wordApp.Quit(ref oMissing, ref oMissing, ref oMissing);
        }
        MessageFilter.Revoke();
        GC.Collect();
        KillwordProcess();

    }
    /// <summary>
    /// 结束word进程
    /// </summary>
    public void KillwordProcess()
    {
        try
        {
            Process[] myProcesses;
            //DateTime startTime;
            myProcesses = Process.GetProcessesByName("WINWORD");

            //通过进程窗口标题判断
            foreach (Process myProcess in myProcesses)
            {
                if (null != GUIDCaption && GUIDCaption.Length > 0 && myProcess.MainWindowTitle.Equals(GUIDCaption))
                {
                    myProcess.Kill();
                }
            }
            MessageFilter.Revoke();
        }
        catch (Exception e)
        {
            throw e;
        }
    }
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top