VB IDE and ObjectContext

A myth that is still being spread in various VB and MTS/COM+ related newsgroups, is that an application can not obtain a reference to the MTS or COM+ ObjectContext in the Visual Basic Integrated Development Environment (VB IDE).

Ever since VB 5 a VB ActiveX DLL project in the IDE can obtain a reference to the MTS ObjectContext object.

This article explains a little bit about how to use this capability, some things to check if it doesn’t seem to be working for your project and detailed instructions for creating a VB application that demonstrates the capability.

This article applies equally to Windows NT (Server or Workstation) with MTS 2.0 installed and Windows 2000 Professional or Server. For easier reading, I’ll refer to both situations as MTS.

Hyperlinks to documentation mentioned in this article can be found at the end of this article

Background – the MTS context object

When code in client application instantiates an object of an MTS component, MTS provides a context object that the code in the component can interact with. Code in an MTS component is not required to interact with the context object, but it normally does, at least to the extent of calling the SetAbort or SetComplete methods. Application code acquires a reference to the MTS context object by calling the GetObjectContext function.

A call to GetObjectContext will terminate normally whether the code making the call is in a component configured as an MTS component or not. If the code is not in configured as an MTS component, GetObjectContext returns the value Nothing.

An MTS component is always a COM DLL (ActiveX DLL in VB parlance). Each MTS Server Package (applications in Windows 2000 Component Services terminology) gets a process of its own and all components in that package execute in the same process. MTS Library packages run in the process of the client.

The VB Integrated Development Environment (VB IDE)

The VB IDE is a normal Windows executable and runs in it own process. So, how can code executing in the VB IDE be part of an MTS component?

For VB version 5 and 6, Microsoft provides a behind the scenes mechanism to overcome this technical difficulty. Without attempting to explain exactly how this works (I don’t understand all the details myself), this mechanism allows ActiveX DLL VB projects executing in the VB IDE to obtain a reference to the MTS context object. The mechanism is available automatically when MTS 2.0 (from the NT Option Pack) and VB 5 or 6 are installed. It is also available automatically when VB is installed under Windows 2000.

The VB Version differences:

VB 5:

Support for debugging MTS components with Version 5 of VB is somewhat primitive. VB 5 uses a special version of GetObjectContext and the associated context object which allows code executing in the VB IDE to obtain a reference to a simulated context object. This simulated object allows calls to SetAbort, SetComplete etc. to execute without error, but the calls have no affect on anything. To get this to work, you have to add the registry entry:

HKEY_LOCAL_MACHINESOFTWAREMicrosoftTransaction ServerDebugRunWithoutContext

This, and limitations that apply in this environment, are explained in the Microsoft Knowledge Base Article Q188919.

VB 6

Support for debugging MTS components with Version 6 of VB is far superior to that for VB Version 5. VB 6 MTS connects the component executing in the VB IDE with the real (not simulated) MTS run-time. There are a few limitations imposed by the debugging environment, such as only one thread of execution and thus only one client at a time can use the component executing in the VB IDE. The Microsoft Transaction Server (MTS) Issues section of the VB Readme file that accompanies Visual Studio 6 (READMEVB.HTM) explains the limitations fairly well and is the first place too look for additional information. This Readme is installed in the root of the Visual Studio folder (typically c:Program FilesMicrosoft Visual Studio). It’s also available as Microsoft Knowledge Base Article Q170156.

The registry key that is required for VB 5 is ignored by and therefor not required for VB 6.

Gotcha’s:

Here are a few of the main points from the VB 6 Readme mentioned above.

  • To avoid certain kinds of problems, it is recommended that components being debugged in the VB IDE not be configured under MTS. If your component is already registered as an MTS component on the development computer, you might want to delete it from MTS before opening it in the VB IDE. In my experience, this is good advice, despite many suggestions to the contrary in newsgroup posts.
  • You can not execute a component in the VB IDE while it is active in MTS. If you choose to ignore the advice above, you must make sure the component is Shut Down in MTS before starting it in the VB IDE.
  • Components in the VB IDE always run in an MTS Library package. Under NT 4.0 and MTS 2.0, this means that testing of code that interrogates security related information in the MTS context object may behave differently in the VB IDE from when the component is configured in a Server package. This is especially the case if the component implements programmatic security (e.g. the IsSecurityEnabled method will always return False). Under Windows 2000 with COM+, Library application security behaves differently; testing security related code may be less of problem. However, there still may be differences when the application is configured as a Server application (for example, see MS KB article Q243437).
  • If you try to “watch” a property of the context object or any associated objects, you may get an unexpected result or a failure in the VB IDE.

Some other things to keep in mind (not in the VB ReadMe):

  • Although VB allows you to have multiple VB Projects active in a single instance of the VB IDE, it’s a really good idea to start your client and components each in separate instances of VB. If you don’t, the VB IDE may crash if you terminate execution of the MTS component (e.g. by clicking on the “End” button on the Debugging toolbar).
  • When debugging a VB component invoked by IIS, the security environment for IIS and the VB IDE must be the same (see MS KB Article Q244807). Disable anonymous access to the asp page, so that IIS must validate the user through integrated security, thus getting the same identity as the component.

If the call to GetObjectContext returns Nothing in the VB IDE

Here are a few things to check if your code can’t obtain a reference to an ObjectContext object in the VB IDE:

  • Is your VB Project an ActiveX DLL? In the VB IDE click Project, Properties and make sure the Project Type: is ActiveX DLL. Other types of VB Projects can not be MTS components.
  • Is the Class Module’s Instancing Property 5-MultiUse and is its MTSTransactionMode property something other than 0-NotAnMTSObject? An MTS component has to have at least one Multi-Use Class Module with its MTSTransactionMode other than 0. When MTSTransactionMode is set to 0-NotAnMTSObject, the VB IDE will not be connected to the MTS run-time and GetObjectContext will always return Nothing.
  • Is the Distributed Transaction Co-ordinator (DTC) service running? Unless this service is running, your MTS component will not be able to obtain a reference to a context object if the class’s MTSTransactionMode is other than 1 NoTransactions. Usually, the first time you attempt to start an MTS component that may use transactions in the VB IDE, you get a warning if DTC is not running. However, you may not get this warning. Check in the Services dialog to make sure DTC is running (see step 9 for additional information).
  • Perhaps the VB6debug.dll file is missing or damaged. This dll implements the interaction between the VB IDE and MTS. The original VB6 version is in the VB98 folder of CD #1 for Visual Studio 6. An updated version is in SP3 and SP4 for Visual Studio (VS6sp3_3.cab and VS6sp43.cab respectively). This file lives in the VB98 folder of the Visual Studio installation folder (e.g. Program FilesMicrosoft Visual StudioVB98).

Instructions for building and testing a VB MTS component and client

The application built using the instructions below consists of two parts: an MTS component and a client EXE. The function implemented is trivial (return a Boolean variable indicating whether the MTS component is in an MTS Transaction or not), but it demonstrates obtaining a reference to an MTS context object and getting properties from that object in the VB IDE.

  1. Start VB 6 (I’m using SP4, but this also should work with no or earlier SPs).
  2. If you get the New Project dialog box, select ActiveX DLL on the New tab, then click Open. If you don’t get that dialog, select File, New Project, ActiveX DLL then click OK.
  3. In the Class Properties box for Class1, set Instancing to 5 – MultiUse and MTSTransactionMode to 2 – Requires Transaction.
  4. From the menu, select Project, References, scroll down, put a check mark beside Microsoft Transaction Server Type Library (if you are running under Windows 2000, choose COM+ Services Type Library instead) and click OK.
  5. In the Project content sub-window, click on Class1 to make sure it is selected.
  6. Paste the following code into the code window. This code returns True if the component is in a transaction and False if not.
  7. Public Function GetTransactionStatus() As Boolean
    Dim CSContext As ObjectContext
    Set CSContext = GetObjectContext()
    GetTransactionStatus = CSContext.IsInTransaction
    Set CSContext = Nothing
    End Function

  8. In the menu, click Project, Project1 Properties, select the Debugging tab and make sure that the Wait for components to be created radio button is selected; click OK.
  9. Click File, Save Project As and save the class module and the project in a suitable folder.
  10. From the Debug Toolbar (or Debug menu), click Step into. You get a warning about using Binary Compatibility Mode, building a DLL etc. Click Yes to continue anyway. You may also get a warning that the Microsoft Distributed Transaction Co-ordinator is not running. Your code can not get a reference to an MTS context object unless DTC is running, so, cancel the warning, open the Services dialog (NT Control Panel, Services; Windows 2000 Start, Programs, Administrative Tools, Services) and start the Distributed Transaction Co-ordinator service, then click Step into again.
    At this point, your component has been compiled, temporarily registered with MTS and is ready to be instantiated by a client.
  11. Open a new instance of VB and create a new Standard EXE project.
  12. In the Project content sub-window, select Project1, then in the Properties window, change the name to Project1Client.
  13. In the Project content sub-window, right click on Form1 and select View Code.
  14. From the menu, select Project, References. Scroll down to Project1 and put a check mark in its box. When you click on Project1, you will see the path to its VBP file in the bottom part of the dialog box. Click OK.
  15. From the drop down list boxes at the top of the code window, in the left side, select Form.
  16. In the Form_Load procedure, paste the following code
  17. Dim TransStatus As Boolean
    Dim obj As Project1.Class1

    Set obj = New Project1.Class1
    TransStatus = obj.GetTransactionStatus()
    Set obj = Nothing

    If TransStatus Then
    MsgBox ("Project1 is in a transaction")
    Else
    MsgBox ("Project1 is not in a transaction")
    End If

  18. From the Debug Toolbar, click Step into.
  19. Step through the code in both the client and Project1 and when you get to the statement:
  20. GetTransactionStatus = CSContext.IsInTransaction

    observe that CSContext has a reference to the MTS context object (it is not Nothing).

  21. Click Step Into again and observe that GetTransactionStatus is assigned True.
  22. Keep stepping through the code and you get the message box that says Project1 is in a transaction.

Web Site References – Documentation:

Microsoft:

Visual Studio/Visual Basic Version 6 Readme: Transaction Server (MTS) Issues

http://support.microsoft.com/support/kb/articles/Q170/1/56.ASP

MS KB article Q188919: HOWTO: Avoid “Error 91” when Debugging MTS Components with Visual Basic. This article applies to VB Version 5 only (not Version 6).

http://support.microsoft.com/support/kb/articles/Q188/9/19.ASP

MS KB article Q244807: PRB: Object Required Error for ObjectContext Under Windows 2000 in Visual Basic IDE and Active Server Pages. This article applies to VB Version 6 and Windows 2000.

http://support.microsoft.com/support/kb/articles/Q244/8/07.ASP

MS KB article Q243437: PRB: Identity Different in MTS and COM+ Library Package by Default. This article describes differences in how security is implemented between MTS under NT 4.0 and COM+ under Windows 2000.

http://support.microsoft.com/support/kb/articles/Q243/4/37.ASP

Share the Post:
Share on facebook
Share on twitter
Share on linkedin

Overview

The Latest

homes in the real estate industry

Exploring the Latest Tech Trends Impacting the Real Estate Industry

The real estate industry is changing thanks to the newest technological advancements. These new developments — from blockchain and AI to virtual reality and 3D printing — are poised to change how we buy and sell homes. Real estate brokers, buyers, sellers, wholesale real estate professionals, fix and flippers, and beyond may

man on floor with data

DevX Quick Guide to Data Ingestion

One of the biggest trends of the 21st century is the massive surge in internet usage. With major innovations such as smart technology, social media, and online shopping sites, the internet has become an essential part of everyday life for a large portion of the population. Due to this internet

payment via phone

7 Ways Technology Has Changed Traditional Payments

In today’s digital world, technology has changed how we make payments. From contactless cards to mobile wallets, it’s now easier to pay for goods and services without carrying cash or using a checkbook. This article will look at seven of the most significant ways technology has transformed traditional payment methods.