2

Microsoft Office Interop を利用する C# プログラムを使用して、Microsoft Word、Excel、および PowerPoint を基本的にプログラムで使用できるようにしています。

私が遭遇した不幸な側面の 1 つは、プログラムがコードを一時停止するダイアログ ボックスを表示することがあるということです。これは、たとえば、保存できるはずの場所に突然コードを保存できなくなった場合に発生する可能性があります。つまり、問題が後で修正されたとしても、プログラム全体が一時停止する可能性があります。

追加のダイアログ ボックスが表示される状況は他にもたくさんあります。

したがって、私の意図は、これにある種のタイムアウト メカニズムを実装することです。これにより、プログラム全体を拘束するのではなく、Interop インスタンスを強制終了できます。誰でもこれを行う方法を提案できますか? 現時点では、相互運用呼び出しを a でラップしSystem.Action、一定時間後にそのスレッドを中止しますが、もっと良い方法があるのではないかと思います。

4

2 に答える 2

1

多くの人は、プロセスを強制終了することをお勧めしません。「 Excel 相互運用オブジェクトを適切にクリーンアップする方法」「.net のガベージ コレクションについて」を参照 してください。

作成した Excel インスタンスを強制終了するために使用するコードを次に示します。ニーズを満たすには、少しリファクタリングする必要があります。Excel が提供するウィンドウ ハンドルを使用してプロセス ID を取得する方法を説明します。Word や Powerpoint でも同様のプロセスになると思います。

'http://msdn.microsoft.com/en-us/library/ms633522%28v=vs.85%29.aspx
<System.Runtime.InteropServices.DllImport("user32.dll", SetLastError:=True)> _
    Private Shared Function GetWindowThreadProcessId(ByVal hWnd As IntPtr, _
    ByRef lpdwProcessId As Integer) As Integer
End Function

Sub Work()

    'declare process; will be used later to attach the Excel process
    Dim XLProc As Process

    'start the application using late binding
    Dim xlApp As Object = CreateObject("Excel.Application")

    'or use early binding
    'Dim xlApp As Microsoft.Office.Interop.Excel

    'get the window handle
    Dim xlHWND As Integer = xlApp.hwnd

    'this will have the process ID after call to GetWindowThreadProcessId
    Dim ProcIdXL As Integer = 0

    'get the process ID
    GetWindowThreadProcessId(xlHWND, ProcIdXL)

    'get the process
    XLProc = Process.GetProcessById(ProcIdXL)


    'do some work with Excel here using xlApp

    'be sure to save and close all workbooks when done

    'release all objects used (except xlApp) using NAR(x)


    'Quit Excel 
    xlApp.quit()

    'Release
    NAR(xlApp)

    'Do garbage collection to release the COM pointers
    'http://support.microsoft.com/kb/317109
    GC.Collect()
    GC.WaitForPendingFinalizers()

    'I prefer to have two parachutes when dealing with the Excel process
    'this is the last answer if garbage collection were to fail
    If Not XLProc Is Nothing AndAlso Not XLProc.HasExited Then
        XLProc.Kill()
    End If
End Sub

Private Sub NAR(ByVal o As Object)
    'http://support.microsoft.com/kb/317109
    Try
        While (System.Runtime.InteropServices.Marshal.ReleaseComObject(o) > 0)
        End While
    Catch
    Finally
        o = Nothing
    End Try
End Sub
于 2013-07-23T04:07:14.433 に答える