VB.Forms.Add错误-2147417848通过COM调用

时间:2013-02-12 15:48:15

标签: com vb6

我有一个引用VB6遗留DLL的.NET应用程序。旧版DLL有一个带有公共方法的类。在这个公共方法中,它试图按名称查找现有表单,或者如果它不存在则创建它:

Set objForm = GetForm(strFormName)

If objForm Is Nothing Then

    'Creates a new instance of the form
    Set objForm = VB.Forms.Add(strFormName)

End If

...其中GetForm是:

Private Function GetForm(ByVal strFormName As String) As Form

    Dim objForm As Form

    For Each objForm In VB.Forms
        If objForm.Name = strFormName Then
            Set GetForm = objForm
            Exit Function
        End If
    Next

    Set GetForm = Nothing

End Function

这一行引起了错误:

Set objForm = VB.Forms.Add(strFormName)

错误是:

Automation error
The object invoked has disconnected from its clients.   
Error#-2147417848(80010108)

请注意,strFormName是有效的表单名称,此公共方法调用几乎始终 。它偶尔会发生这种错误。

我想知道导致此错误的原因,或者我还能做些什么来进一步追踪它?

2 个答案:

答案 0 :(得分:6)

@Dabblernl链接的KB article与此问题非常相关。 VB.Forms集合正是这样一个不合格的引用。它就像一个全局变量,你可以在VB6代码中的任何地方使用VB.Forms而不提供对象引用。

在幕后,VB6运行时在您第一次创建表单并存储此集合对象时创建Forms集合,以便将来对VB.Forms的引用使用完全相同的集合。错误代码的含义是您在销毁之后使用该集合

目前还不是很清楚何时发生这种情况,这是VB6运行时支持库的所有内部管道。但通常情况下,VB6应用程序会在最后一个表单卸载时终止。在您的情况下有所不同的是,您的进程的生命周期不再受VB6运行时控制。 .NET现在控制它。

因此,推断,很有可能VB6运行时已经决定不再需要Forms集合并将其销毁,并且您的.NET代码可能会创建一个新表单,从而触发错误。

如果这完全准确,那么您需要采取对策来防止这种情况发生。一种可行的方法是确保始终至少有一个VB6表单以保持集合有效。它不一定是可见的。

答案 1 :(得分:1)

如果问题是间歇性的,很少像OP中提到的那样,重试可能会解决它:

Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

Public Sub SomeProcedure()
Dim attempts As Integer
On Error Goto ErrHandler

    Set objForm = GetForm(strFormName)
    If objForm Is Nothing Then

        'Creates a new instance of the form
        Set objForm = VB.Forms.Add(strFormName)

    End If

ErrHandler:
    If Err.Number = -2147417848 Then
        attempts = attempts + 1
        If attempts < 10 Then
            Err.Clear
            Sleep 55
            Debug.Print "Automation error. Retry attempt: " & attempts
            Resume
        End If
    End If
    If Err.Number <> 0 Then 'this should run after the 10th failed attempt
        MsgBox Err.Message
        Err.Clear
    End If
End Sub

它没有解决问题,但它可能会因为它而停止你的应用程序崩溃......