2

我正在使用一个 C# 程序,该程序利用 Microsoft Office 互操作,允许您基本上以编程方式使用 Microsoft Word、Excel 和 PowerPoint。

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

在许多其他情况下,可能会出现一个额外的对话框。

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

4

2 回答 2

1

您可以通过实现 OLE 消息筛选器来做到这一点。有关更多详细信息,请参阅此答案

于 2013-07-04T12:26:51.473 回答
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 回答