无法使用已与其基础RCW分离的Infopath COM对象



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

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

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或任何dispose方法。我还做了GC。在FormControl对象上SuppressFinalize,并在更新视图的代码周围添加SyncLock,以防出现线程问题。作为最后的努力,我甚至手动添加了数百个对COM对象的引用,因为COM对象应该只有在删除最后一个引用后才能释放。这些事情都没有产生任何影响。总是在第四次视图更改后,它会出现错误,而遵循每一行代码都会让我一无所获。它总是在设置第四个视图和命中上述事件之间的某个时间丢失COM对象。据我所知,在这段时间里没有任何代码在执行,所以我陷入了这个问题。

编辑:我还应该补充一点,这是一个正在升级的应用程序。净2至。Net4,这在以前使用InfoPath2007时运行得很好。目前,它使用的是InfoPath 2010 x64(我没有选择office版本),我认为64位版本的InfoPath可能存在一些问题,可能会导致这种情况。

第2版:这不是64位版本的问题。我换掉了我的Office版本,用Office2010x86重新编译,但仍然会出现和以前一样的错误。

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

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

"始终"表示应用程序对象已退出,通常是因为它在宿主VBA引擎中引发了未处理的错误。

AFAIK,您无法使用阻止应用程序对象退出。网络代码/调用。如果你有代码的话,我会查一下你的代码。


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

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包装器对象持续存在,因此它通过了这些"什么都不是"测试,然后只有当您实际尝试使用它时才会失败。

最新更新