質問

このコードを検討してください:

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プロセスを強制終了できます。

役に立ちましたか?

解決

その方法を次に示します。

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

他のヒント

Wordファイルにエラーがある可能性があります。その結果、メソッド Word.ApplicationClass.Documents.Open()でファイルを開くと、ダイアログが表示され、プロセスがハングします。

代わりに Word.ApplicationClass.Documents.OpenNoRepairDialog()を使用します。問題が解決したことがわかりました。

それを取得する通常の方法は、Wordのタイトルをユニークなものに変更し、それが見つかるまでトップレベルのウィンドウリストをたどることです(EnumWindows)。

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

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

なぜWordのインスタンスを殺す必要があるのですか?すべてのドキュメントを閉じて、そのインスタンスの使用を停止するように依頼することはできませんか?最終的にクラスへのすべての参照を削除すると、 GC が起動して取得します COM サーバーにアクセスします。

アプリケーションを開始する前に、実行中のすべてのWordプロセスをリストし、アプリケーションを開始して、実行中のWordプロセスを再度リストします。 2番目のリストにあり、最初のリストにはないプロセスが正しいものです。

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

この方法には明らかなタイミングの問題がありますが、ほとんどの場合に確実に機能するのは私が見つけた唯一の方法です。

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;
        }
    }
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top