我正在使用一个使用Microsoft Office Interop的C#程序,允许您以编程方式使用Microsoft Word,Excel和PowerPoint。
我遇到的一个不幸的方面是,程序有时会引发一个暂停代码的对话框。例如,如果突然代码无法保存在您期望的位置,这可能会发生,这意味着即使稍后修复了该问题,您的整个程序也可能会暂停。
在很多其他情况下,可能会引发额外的对话框。
所以我的意图是为此实现某种超时机制,我可以杀死Interop实例,而不是将我的整个程序绑定。有谁能建议这样做的方法?目前它将Interop调用包装在System.Action
中并在给定时间后中止该线程,但我想知道是否有更好的方法。
答案 0 :(得分:1)
您可以通过实现OLE邮件筛选器来完成此操作。有关详细信息,请参阅this answer。
答案 1 :(得分:1)
许多人不建议杀死这个过程;看到 How to properly clean up Excel interop objects 和Understanding 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