【问题标题】:Infopath COM object that has been separated from its underlying RCW cannot be used无法使用已与其底层 RCW 分离的 Infopath COM 对象
【发布时间】:2012-08-30 15:56:11
【问题描述】:

我遇到了一个问题,我似乎无法在互联网上的任何地方找到答案。我有一个在 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 或任何 dispose 方法。我还在 FormControl 对象上执行了 GC.SuppressFinalize,并在更新视图的代码周围添加了一个 SyncLock,以防出现线程问题。作为最后的努力,我什至手动添加了数百个对 COM 对象的引用,因为 COM 对象应该只有在最后一个引用被删除后才被释放。这些事情都没有任何影响。总是在第四次视图更改之后,它会出现该错误,并且遵循每一行代码让我无处可去。它总是在设置第四个视图和点击上述事件之间的某个时间丢失 COM 对象。据我所知,在此期间没有执行任何代码,所以我陷入了这个问题。

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

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

【问题讨论】:

    标签: vb.net interop com-interop infopath infragistics


    【解决方案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 包装器对象仍然存在,因此它通过了这些“什么都没有”测试,然后只有在您实际尝试使用时才会失败它。

    【讨论】:

    • 抱歉,我对 InfoPath 还是很陌生,但请您澄清一下在这种情况下“代码隐藏”是什么意思。您指的是 InfoPath 表单本身的代码吗?
    • 我们有相当多的表单,并且由于我们可以选择在我们的 Windows 7 构建中包含 InfoPath 2007(这对我们来说非常适合),我们将采用这条路线,而不是花更多的时间在所有形式中挖掘一些过时的代码,无论如何我们可能会或可能不会在一年后使用这些代码。感谢您的所有见解!
    猜你喜欢
    • 2011-11-21
    • 2012-04-27
    • 2011-07-03
    • 1970-01-01
    • 2022-08-09
    • 1970-01-01
    • 1970-01-01
    • 2012-09-17
    • 2011-07-15
    相关资源
    最近更新 更多