2009-05-02 5 views
13

は、このコードを考えてみましょう:MS-Word ApplicationClassからPIDを取得しますか?

using Microsoft.Office.Interop.Word; 

ApplicationClass _application = new ApplicationClass(); 

は私が_applicationによって立ち上げられたのWinword.exeプロセスからPIDを取得することはできますか?

破損したファイルを、私はしても、このコードを使用して、ApplicationClassを終了することはできませんので、私はPIDが必要になります。

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

私はWINWORD.EXEプロセスを検索し、それを殺すことができない、ので、私にはいくつかのものがあり、どちらを殺すかわからない。各ApplicationClassに対してPIDを取得できれば、私は問題を終了させる正しいwinword.exeプロセスを強制終了することができます。

答えて

5

ここでその方法を説明します。

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

@Mmyikkaあなたは 'StaticMethods'クラスを投稿できますか? – BrunoLM

+3

私はこれを試しましたが、私の言葉のすべての処理MainWindowTitleは空であり、キャプションを文字列に設定しても効果がないようですが、何か不足していますか? – Arvand

1

残念ながら、ApplicationClassのインスタンスをWordの実行中のプロセスに関連付ける方法はありません。

なぜWordのインスタンスを強制終了する必要がありますか?すべての文書を閉じて、単にそのインスタンスの使用を停止するように求めることはできませんでしたか?クラスへの参照をすべて削除すると、最終的にGCCOMサーバーを起動して停止します。

+3

まだ開いていないため、文書を閉じることができません。 文書が破損しているため、人間の介入を待っているウィンドウダイアログが表示されます。しかし、私はこのコードをサービスで使用しており、何千もの文書を開き、人の介入は不可能です。 私はもう少し調べ、Excel ApplicationClassにはHwndがあります。以下を使用します。 [DllImport( "user32.dll")] static extern int GetWindowThreadProcessId(int hWnd、out int lpdwProcessId); 私はPIDを得ることができます。 しかし、Word ApplicationClassにはHwndがありません...どうも... – Ricardo

2

これを得るための一般的な方法は、Wordのタイトルを何か一意に変更し、見つかるまでトップレベルウィンドウリストをホップすることです(EnumWindows)。

2

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

excel.ApplicationClassクラスだけがHwndプロパティであり、質問に関係するword.ApplicationClassクラスではありません。 –

2

Wordファイルにいくつかの誤りがあるかもしれません。その結果、メソッドWord.ApplicationClass.Documents.Open()でファイルを開くと、ダイアログが表示され、プロセスがハングします。

代わりにWord.ApplicationClass.Documents.OpenNoRepairDialog()を使用してください。私はそれが問題を解決したことを発見した。

1

実行中のWordプロセスをすべて一覧表示し、アプリケーションを起動して、実行中のWordプロセスを再度一覧表示します。第二のリストに存在し、最初の1で見つかっていないプロセスが正しいものである:

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

方法明白なタイミングの問題を持っていますが、それは確実にほとんどの時間を働く私が見つけた唯一のものです。

+0

あなたのアプリケーションだけがwinwordプロセスを開くという保証はないので、これは答えにはなりません! – Arvand

関連する問題