Microsoft Office Interop Timing Out

时间:2013-07-04 10:23:14

标签: c# ms-office office-interop

我正在使用一个使用Microsoft Office Interop的C#程序,允许您以编程方式使用Microsoft Word,Excel和PowerPoint。

我遇到的一个不幸的方面是,程序有时会引发一个暂停代码的对话框。例如,如果突然代码无法保存在您期望的位置,这可能会发生,这意味着即使稍后修复了该问题,您的整个程序也可能会暂停。

在很多其他情况下,可能会引发额外的对话框。

所以我的意图是为此实现某种超时机制,我可以杀死Interop实例,而不是将我的整个程序绑定。有谁能建议这样做的方法?目前它将Interop调用包装在System.Action中并在给定时间后中止该线程,但我想知道是否有更好的方法。

2 个答案:

答案 0 :(得分:1)

您可以通过实现OLE邮件筛选器来完成此操作。有关详细信息,请参阅this answer

答案 1 :(得分:1)

许多人不建议杀死这个过程;看到 How to properly clean up Excel interop objectsUnderstanding Garbage Collection in .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