×

Loading...
Ad by
  • 推荐 OXIO 加拿大高速网络,最低月费仅$40. 使用推荐码 RCR37MB 可获得一个月的免费服务
Ad by
  • 推荐 OXIO 加拿大高速网络,最低月费仅$40. 使用推荐码 RCR37MB 可获得一个月的免费服务

Microsoft has confirmed this BUG

本文发表在 rolia.net 枫下论坛SYMPTOMS

If the Terminate event of a GlobalMultiUse class calls a procedure in another DLL, and if the same GlobalMultiUse class had previously called the same DLL, then you receive an error and the IDE may crash.

With Visual Basic 5.0, you may receive one of the following errors:

Exception: privileged instruction (0xc0000096), Address: 0x00186a3a
-or-
VB5 caused an invalid page fault (or general page fault)

With Visual Basic 6.0, the IDE does not crash, but you may receive the following error:

Run-time error '-2147418105 (80010007)':
Automation error

This error translates to:

"The callee (server [not server application]) is not available and
disappeared; all connections are invalid. The call may have executed."


CAUSE
This problem can occur when the ActiveX components are not shut down in the necessary order when your client application ends. For example, suppose your client application uses two ActiveX DLLs (DLL1 and DLL2). If the Terminate event of a class in DLL2 calls a procedure in DLL1, but DLL1 has been shut down before DLL2, you can experience this problem because the procedure in DLL1 is unavailable. The "Steps to Reproduce Behavior" section of this article demonstrates this scenario and shows how to work around the problem by controlling the order in which the two DLLs shut down.



STATUS
Microsoft has confirmed this to be a bug in the Microsoft products listed at the beginning of this article. We are researching this bug and will post new information here in the Microsoft Knowledge Base as it becomes available.



MORE INFORMATION

Steps to Reproduce Behavior
Start a new ActiveX DLL project and name the project P_DLL1.


Name its default module C_DLL1Globals and change its Instancing property to GlobalMultiUse.


Add the following code to C_DLL1Globals:

Public Function DLL1_Function() As String
DLL1_Function = "Func1"
End Function




Add a second new ActiveX DLL project and name the project P_DLL2.


Name its default module C_DLL2Globals and change it's Instancing property to GlobalMultiUse.


Add the following code to C_DLL2Globals:

Public Sub DLL2_FunctionWhichCallsDLL1_Function()
Dim s As String
s = DLL1_Function

End Sub

Public Property Get PublicObject() As C_PublicObject
Set PublicObject = M_Globals.PublicObject
End Property




Add a second Class Module to P_DLL2. Change the name to C_PublicObject and change its Instancing property to PublicNotCreatable.


Add the following code to C_PublicObject:

Private m_Something As Integer

Private Sub Class_Terminate()
Dim s As String
s = DLL1_Function
End Sub

Public Property Let Something(ByVal vData As Integer)
m_Something = vData
End Property




Add a Standard Module to P_DLL2 and name it M_Globals.


To create a reference to P_DLL1, click References on the Project menu and check P_DLL1.


Add the following code to M_Globals:

Private m_PublicObject As C_PublicObject

Public Property Get PublicObject() As C_PublicObject
If m_PublicObject Is Nothing Then
Set m_PublicObject = New C_PublicObject
End If
Set PublicObject = m_PublicObject
End Property




Add a Standard EXE project, and name the project GroupExe.


Name the default form frmGroupExe, and add a CommandButton to it.


Add the following code to frmGroupExe:

Private Sub Command1_Click()
DLL2_FunctionWhichCallsDLL1_Function
End Sub

Private Sub Form_Load()
PublicObject.Something = 1
End Sub




Save the project files.


Compile P_DLL1.dll and remove the P_DLL1 project from the project group by choosing Remove Project from the File menu.


Compile P_DLL2.dll and remove the P_DLL2 project from the project group by choosing Remove Project from the File menu.


In GroupExe, create a reference to P_DLL2.


Save your work.

NOTE: The next step will crash the IDE and you may lose your work if you do not save it at this time.


Run GroupExe, click the CommandButton, and then exit GroupExe. Note that the IDE crashes with one of the errors mentioned previously.


This problem occurs during the shut down process. If you were to trace the order in which the classes in the two DLLs shut down, you would see the following order of events:

C_DLL2Globals Terminate
C_DLL1Globals Terminate
C_PublicObject Terminate

The problem occurs when the Terminate event of C_PublicObject tries to call the DLL1_Function, which is in the C_DLL1Globals object. Because the C_DLL1Globals object has closed, the DLL1_Function cannot be called.

To work around this problem, make sure the C_PublicObject Terminate event occurs while the C_DLL1Globals object is still available. To accomplish this task, put code in the Terminate event of C_DLL2Globals that causes the C_PublicObject to terminate. This will force the C_PublicObject Terminate event to fire before the C_DLL1Globals object is closed. Here's the code modifications for the workaround:

Put the following procedure in the M_Globals module of P_DLL2:


Public Sub ClosePublicObject
Set m_PublicObject = Nothing
End Sub

Next, add the following code to the C_DLL2Globals class:


Private Sub Class_Terminate()
ClosePublicObject
End Sub

Now, when C_DLL2Globals terminates, the ClosePublicObject procedure is run that causes the C_PublicObject object to terminate. The new order of events during shutdown is:

C_DLL2Globals Terminate
C_PublicObject Terminate
C_DLL1Globals Terminate



REFERENCES
For more information about ActiveX component shutdown guidelines, please refer to Appendix B: ActiveX Component Standards and Guidelines in the Visual Basic Components Tools Guide

Additional query words: kbDSupport kbDSD gpf ipf kernel32.dll 0137:bff858c0 kbVBp500bug kbActiveX
kbClientServer kbVBp600bug kbVBp kbdsd kbDSupport更多精彩文章及讨论,请光临枫下论坛 rolia.net
Report

Replies, comments and Discussions:

  • 工作学习 / IT技术讨论 / VB高手请进:
    我在一WINNT(SP3)上安装VB应用程序后,出现一下错误:
    run time error '-2147418105(80010007)'
    the callee(server[not server application] ) is not available and disappeared; all connections are invalid. the call may have executed.'
    我查找internet 后,发现可能有多种原因,不幸的是这多种原因都可能存在。而且很多没有解决的办法,或解决办法很苯,必然影响程序运行速度。
    可能原因:
    1。ado
    2。createobject(对象创建速度似乎不够快)
    3。自定义的控件
    4。ACTIVEX DLL和 ACTIVEX EXE文件调用。
    我想问诸位大虾,是否碰到过这一问题。如何解决。
    • 是不是ADO的版本不对啊?以上只是猜测而已。:)
      • 我是用光盘装的VISUAL BASIC。在NT上安装时,用的ADMINISTROR,不应有权限限制了。
        同时安装了另一软件,这个软件和有问题的软件都是用VB编写的,而且也利用了ADO,CREATEOBJECT方法。
        用INSTALL SHIELD打包后,我对比了两个软件的LOG FILE,基本相同。但这个软件能够成功的运行。
        • 刚才我看错了。现在改了。我想可能是用的ADO的版本不一样。
          • 谢谢,我快要气死了。又不能在客户的机器上调试。
    • 先能找另一台机器装,如果问题一样,没什么好办法,只好一步一步的DEBUG了,看起来想是 4。ACTIVEX DLL和 ACTIVEX EXE文件调用。
      • 我在其他WINNT4,WINME,WIN2000,WINXP(2台),WIN98都试了,除一WINXP未成功外,其他均可。
      • 那我是否要在客户机器上用VB,看看IDE环境下是否能运行?
        • up
    • 如果我来做的话, 首先把环境调好: NT的最新的SP, VS的最新的SP, 这样一来可以减少非常多的不必要的麻烦.
      • I installed SP5 for VB and SP3 for NT. And the customer tried SP5, but it still does not work.
        • Microsoft has confirmed this BUG
          本文发表在 rolia.net 枫下论坛SYMPTOMS

          If the Terminate event of a GlobalMultiUse class calls a procedure in another DLL, and if the same GlobalMultiUse class had previously called the same DLL, then you receive an error and the IDE may crash.

          With Visual Basic 5.0, you may receive one of the following errors:

          Exception: privileged instruction (0xc0000096), Address: 0x00186a3a
          -or-
          VB5 caused an invalid page fault (or general page fault)

          With Visual Basic 6.0, the IDE does not crash, but you may receive the following error:

          Run-time error '-2147418105 (80010007)':
          Automation error

          This error translates to:

          "The callee (server [not server application]) is not available and
          disappeared; all connections are invalid. The call may have executed."


          CAUSE
          This problem can occur when the ActiveX components are not shut down in the necessary order when your client application ends. For example, suppose your client application uses two ActiveX DLLs (DLL1 and DLL2). If the Terminate event of a class in DLL2 calls a procedure in DLL1, but DLL1 has been shut down before DLL2, you can experience this problem because the procedure in DLL1 is unavailable. The "Steps to Reproduce Behavior" section of this article demonstrates this scenario and shows how to work around the problem by controlling the order in which the two DLLs shut down.



          STATUS
          Microsoft has confirmed this to be a bug in the Microsoft products listed at the beginning of this article. We are researching this bug and will post new information here in the Microsoft Knowledge Base as it becomes available.



          MORE INFORMATION

          Steps to Reproduce Behavior
          Start a new ActiveX DLL project and name the project P_DLL1.


          Name its default module C_DLL1Globals and change its Instancing property to GlobalMultiUse.


          Add the following code to C_DLL1Globals:

          Public Function DLL1_Function() As String
          DLL1_Function = "Func1"
          End Function




          Add a second new ActiveX DLL project and name the project P_DLL2.


          Name its default module C_DLL2Globals and change it's Instancing property to GlobalMultiUse.


          Add the following code to C_DLL2Globals:

          Public Sub DLL2_FunctionWhichCallsDLL1_Function()
          Dim s As String
          s = DLL1_Function

          End Sub

          Public Property Get PublicObject() As C_PublicObject
          Set PublicObject = M_Globals.PublicObject
          End Property




          Add a second Class Module to P_DLL2. Change the name to C_PublicObject and change its Instancing property to PublicNotCreatable.


          Add the following code to C_PublicObject:

          Private m_Something As Integer

          Private Sub Class_Terminate()
          Dim s As String
          s = DLL1_Function
          End Sub

          Public Property Let Something(ByVal vData As Integer)
          m_Something = vData
          End Property




          Add a Standard Module to P_DLL2 and name it M_Globals.


          To create a reference to P_DLL1, click References on the Project menu and check P_DLL1.


          Add the following code to M_Globals:

          Private m_PublicObject As C_PublicObject

          Public Property Get PublicObject() As C_PublicObject
          If m_PublicObject Is Nothing Then
          Set m_PublicObject = New C_PublicObject
          End If
          Set PublicObject = m_PublicObject
          End Property




          Add a Standard EXE project, and name the project GroupExe.


          Name the default form frmGroupExe, and add a CommandButton to it.


          Add the following code to frmGroupExe:

          Private Sub Command1_Click()
          DLL2_FunctionWhichCallsDLL1_Function
          End Sub

          Private Sub Form_Load()
          PublicObject.Something = 1
          End Sub




          Save the project files.


          Compile P_DLL1.dll and remove the P_DLL1 project from the project group by choosing Remove Project from the File menu.


          Compile P_DLL2.dll and remove the P_DLL2 project from the project group by choosing Remove Project from the File menu.


          In GroupExe, create a reference to P_DLL2.


          Save your work.

          NOTE: The next step will crash the IDE and you may lose your work if you do not save it at this time.


          Run GroupExe, click the CommandButton, and then exit GroupExe. Note that the IDE crashes with one of the errors mentioned previously.


          This problem occurs during the shut down process. If you were to trace the order in which the classes in the two DLLs shut down, you would see the following order of events:

          C_DLL2Globals Terminate
          C_DLL1Globals Terminate
          C_PublicObject Terminate

          The problem occurs when the Terminate event of C_PublicObject tries to call the DLL1_Function, which is in the C_DLL1Globals object. Because the C_DLL1Globals object has closed, the DLL1_Function cannot be called.

          To work around this problem, make sure the C_PublicObject Terminate event occurs while the C_DLL1Globals object is still available. To accomplish this task, put code in the Terminate event of C_DLL2Globals that causes the C_PublicObject to terminate. This will force the C_PublicObject Terminate event to fire before the C_DLL1Globals object is closed. Here's the code modifications for the workaround:

          Put the following procedure in the M_Globals module of P_DLL2:


          Public Sub ClosePublicObject
          Set m_PublicObject = Nothing
          End Sub

          Next, add the following code to the C_DLL2Globals class:


          Private Sub Class_Terminate()
          ClosePublicObject
          End Sub

          Now, when C_DLL2Globals terminates, the ClosePublicObject procedure is run that causes the C_PublicObject object to terminate. The new order of events during shutdown is:

          C_DLL2Globals Terminate
          C_PublicObject Terminate
          C_DLL1Globals Terminate



          REFERENCES
          For more information about ActiveX component shutdown guidelines, please refer to Appendix B: ActiveX Component Standards and Guidelines in the Visual Basic Components Tools Guide

          Additional query words: kbDSupport kbDSD gpf ipf kernel32.dll 0137:bff858c0 kbVBp500bug kbActiveX
          kbClientServer kbVBp600bug kbVBp kbdsd kbDSupport更多精彩文章及讨论,请光临枫下论坛 rolia.net
          • Yes, but this occured in IDE Enviroment. Then why on other machines, the software runs well?
            • maybe should check your deployment package