0

我遇到了一个问题,我似乎无法在互联网上的任何地方找到答案。我有一个在 Windows 窗体内托管 Infopath.FormControl 的应用程序。每个 InfoPath 表单都有 5 个必须显示的视图,并且使用 Infragistics UI v11.1 控件,我们在应用程序的单独选项卡上拥有每个视图。

该应用程序能够显示您正确选择的前四个视图,无论您选择什么顺序(例如 1、5、4、2 或 1、2、3、4),但在第四个之后一,它总是会出现错误“已经与其底层RCW分离的COM对象无法使用”。

Private Sub utForm_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles utForm.Click

    lastTabClicked = Me.utForm.SelectedTab.Text
    Me.OHeader1.Focus()
    ' If Me.formIsReadOnly Then
    If Me.fcInfoPath Is Nothing Or wasPrinted Then
        If Not Me.utForm.SelectedTab Is Nothing Then
            processReadOnlyTabChange(Me.utForm.SelectedTab.Text)
            Exit Sub
        End If
    End If

    'This is the line of code that will get the exception, but by the time we get
    'here, the COM object has already been released.
    Me.fcInfoPath.XmlForm.CurrentView.ForceUpdate()

    'Failed Ideas to stop the Com object from separating from it's wrapper (RCW)
    'Dim test As IntPtr = Marshal.GetIUnknownForObject(Me.fcInfoPath)
    'Marshal.AddRef(test)
    'GC.SuppressFinalize(Me.fcInfoPath)
    'SyncLock fcInfoPath for duration of event

    If Not Me.utForm.SelectedTab Is Nothing Then
        processTabChange(Me.utForm.SelectedTab.Key)
    End If
End Sub 

我已经深入研究了代码,它从不调用 Marshal.ReleaseComObject 或任何处置方法。我还在 FormControl 对象上执行了 GC.SuppressFinalize,并在更新视图的代码周围添加了一个 SyncLock,以防出现线程问题。作为最后的努力,我什至手动添加了数百个对 COM 对象的引用,因为 COM 对象应该仅在删除最后一个引用后才被释放。这些事情都没有任何影响。总是在第四次视图更改之后,它会出现该错误,并且遵循每一行代码让我无处可去。它总是在设置第四个视图和点击上述事件之间的某个时候丢失 COM 对象。据我所知,在此期间没有执行任何代码,因此我陷入了这个问题。

编辑:我还应该补充一点,这是一个从 .Net 2 升级到 .Net 4 的应用程序,之前它使用 InfoPath 2007 时运行良好。现在,它使用的是 InfoPath 2010 x64(我没有选择办公室版本),我认为 64 位版本的 InfoPath 可能存在一些可能导致此问题的问题。

编辑 2:这不是 64 位版本的问题。我切换了我的 Office 版本并使用 Office 2010 x86 重新编译,但仍然遇到与以前相同的错误。

4

1 回答 1

1

我不熟悉 InfoPath 的 COM 接口,但在我从 .Net 使用的所有其他 COM 应用程序(Office 对象,如 Excel、Word 等)中,该错误:

"COM object that has been separated from its underlying RCW cannot be used."

始终意味着应用程序对象已退出,通常是因为它在其托管的 VBA 引擎中引发了未处理的错误。

AFAIK,您无法使用 .Net 代码/调用阻止应用程序对象退出。如果你有的话,我会检查你的代码隐藏。


实际上再次查看您的代码:

If Me.fcInfoPath Is Nothing Or wasPrinted Then
    ...
End If

'This is the line of code that will get the exception, but by the time we get
'here, the COM object has already been released.
Me.fcInfoPath.XmlForm.CurrentView.ForceUpdate()

    ...

Me.fcInforPath Is Nothing ..很可能,甚至在您进行测试之前,该应用程序就已经退出了。在处理 .net/COM 包装器时,这是一个令人讨厌的问题,即使 COM 对象早已不复存在,.Net 包装器对象仍然存在,因此它通过了这些“什么都没有”测试,然后只有在您实际尝试使用时才会失败它。

于 2012-09-10T18:49:53.673 回答