2013-07-04 42 views
2

我與它採用的Microsoft Office互操作允許你完全編程方式使用Microsoft Word,Excel和PowerPoint C#程序的工作。的Microsoft Office互操作超時

一個不幸的方面我遇到的是,有時,該計劃將提高其暫停碼的對話框。例如,如果代碼突然無法保存在您所期望的位置,這意味着您的整個程序可能會暫停,即使稍後會修復該問題也是如此。

有很多,其中一個額外的對話框可能引發的其他情形。

所以我的目的是實現某種超時機制對於這一點,因此我可以殺了互操作實例,而不是有我的整個程序捆綁起來。任何人都可以建議一種方法來做到這一點目前它在Interop呼叫中包裝System.Action,並在給定時間後中止該線程,但我想知道是否有更好的方法。

+2

我已經在過去做過這樣的東西。唯一要做的事情就是讀取你正在自動化的VBA代碼,並對其進行測試,以便知道對話框出現的時間和地點,以及爲什麼。然後你可以編程。相信我,從長遠來看,這會讓你的生活更輕鬆! – JMK

+0

此外,Office Interop並非設計爲無人值守使用,其理念是您的最終用戶可以看到這些對話框並與其進行適當的交互。如果你想要無人值守的辦公自動化,你可以看看OpenXML。 – JMK

回答

1

您可以通過實現一個OLE郵件篩選器做到這一點。有關更多詳細信息,請參閱this answer

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 
相關問題