Visual Modeler Reference

Microsoft Visual Modeler is a tool for designing three-tier distributed applications, using class and component diagrams. With Visual Modeler you can visually design models of the classes and components your application needs, then convert these models to Visual Basic or Visual C++ code. With Visual Basic, you can also import your application's code, and convert it to Visual Modeler diagrams. This makes it possible to switch back and forth between a model and working code, for optimum flexibility and efficiency. You can also publish the visual models you create in Microsoft's Visual Component Manager, so they can be shared and reused by other developers in your organization. Visual Modeler is based on a subset of the Unified Modeling Language (UML).

The primary documentation for Visual Modeler is contained in the Windows Help system that is installed with Visual Modeler. To view the documentation, open Visual Modeler, click the Help Menu, then click Visual Modeler Help Topics.

In addition, a collection of "Quick Start" topics and samples are provided here. The following sections provide information to acquaint you with the basic concepts, procedures and commands of Visual Modeler.

Section | Description
Visual Modeler Quick Start With Visual Basic | Provides a brief tutorial on using Visual Modeler with Visual Basic. It shows how to create visual models, how to convert visual models to Visual Basic code, and how to update a visual model after changes have been made to the code.
Visual Modeler Quick Start With Visual C++ | Provides a brief tutorial on using Visual Modeler with Visual C++. It shows how to create visual models, how to use a model to visualize the MFC class hierarchy of an application, and how to convert visual models to C++ code. It also introduces the Enroll Visual Modeler sample application.
Other Visual Modeler Samples | Provides a way to install and use a variety of complete Visual Modeler samples. These samples can be used as a starting point for your own applications.


Visual Modeler Quick Start with Visual Basic

Use this tutorial to become quickly acquainted with Microsoft Visual Modeler 2.0. You will be introduced to some basic features in Visual Modeler, and learn how to:

  • Understand an application by browsing existing design diagrams and specifications.

  • Modify an application by modeling the changes.

  • Implement changes to an application by generating and evolving the code and updating the design.

  • Understand how the design model is mapped to Visual Basic code.

It takes no more than an hour to complete the tutorial. It is a well-spent hour, since it will save you a lot of time later on.

Prerequisites

These are the prerequisites to be able to complete the tutorial:

  • To use this tutorial effectively, you should be comfortable with basic Microsoft Windows techniques, including using a mouse and choosing from menus. You should also be familiar with the Microsoft Visual Basic programming environment.

  • The example used is a design model of an order system and the corresponding Visual Basic code.

  • To run the example, you need to have Microsoft Visual Basic installed on your system.

  • To browse the model in the example, you need Visual Modeler installed on your system.

Reading Instructions

It is best to complete the parts of the tutorial sequentially. If you choose to do only a part of the tutorial, you should start with the first topic in one of the chapters. For example, you can skip chapter Introduction to the Order System Example and start with Opening the Order System Design Model in chapter Browsing the Order System Design Model, but you cannot jump directly into the middle of a chapter.

To install the sample files for the Visual Modeler Quick Start with Visual Basic tutorial, see ORDERSYS: Demonstrates Round-Trip Engineering of a Visual Basic Application.


Introduction to the Order System Example

Imagine yourself as the newest member of the MIS department in a small fish and seafood distributing company. Your first assignment is to make changes to the company’s sales order support application. After meeting with your boss, you understand that:

  • An order has a purchaser

  • An order consists of one or more order rows, each of a given article in a given quantity

  • Orders are registered and handed to shipping

  • Customers, orders, and articles need to be persistently stored by the order system

Before making any decisions on how to change the order system, you wisely decide to run the current implementation and to use Visual Modeler for studying the current architecture.

Starting the Order System

To start the order system application:

  1. Start your Microsoft Visual Basic development environment by double clicking on the ordersys.vbp project file, which you can find in the folder where the Order System sample is installed.

  2. Run the program by choosing Start With Full Compile from the Run menu.

If you have problems running the order system, make sure that:

  • The database files ordersys.mbd and ordersys.ldb are located in the same folder as the project file, and that the files are writable (not read only)

  • The correct DAO Object Library is loaded. Choose References on the Project menu and check the appropriate library

  • None of the references in the References dialog box are marked as "MISSING:"

Entering a New Order

After having successfully started the order system application you are now ready to enter a new order. An Order Id has already been allocated in the Order dialog box.

To enter a new order:

  1. Start by assigning a customer to the new order. By default the first customer found has been chosen, which is "101", "Baron's Inne", at "499 N. Gulp Rd, King of Prussia". Click the Name box to view all other customers and select one of them.

  2. Continue by adding new rows to the order: Click New to open the Order Row dialog box.

  3. Select an article from the Article Name list and see how the information in the dialog box changes.

  4. To populate the Article Name list with seafood articles with a higher article identifier, type "2*" in the Article Id box and press ENTER.

  5. Select any article, enter a number in the Quantity field, and click OK.

  6. The Order dialog box now presents the new order row and recalculates the total order sum after each new order row has been created.

  7. Click OK to accept and register the new order.

  8. Click OK to exit the order system.


Browsing the Order System Design Model

In this exercise, you'll use Visual Modeler to get acquainted with the design model of the order system. Visual Modeler provides you with several mechanisms for browsing the model.

Opening the Order System Design Model

To open the order system design model:

  1. Start the Visual Modeler application.

  2. Click Open on the File menu.

  3. In the dialog box, open the folder where the order system sample has been installed.

  4. Double-click on the ordersys.mdl file. Visual Modeler now opens the sample model and displays a diagram called the Three-Tiered Service Model.

This diagram shows the architecture of the order system application, that is, it shows the classes of the design model and the relations between them. Defining and maintaining the architecture and relationships within the system are among the most important aspects of large-scale iterative development.

The Three-Tiered Service Model diagram supports the three-tiered architectural approach used when building Microsoft Visual Basic applications. It separates the contents of the system into three conceptual tiers of services: user services (left pane), business services (middle pane), and data services (right pane). It is a special kind of class diagram, called a three-tiered diagram.

To the left in the application window, a browser window lists the contents of the order system design model in a hierarchical order. (If you cannot see the browser in your Visual Modeler application window, select Browser on the View menu.)

The diagram notation used in this tutorial is a subset of the Unified Modeling Language (UML). Please refer to the online help for descriptions of the different modeling constructs.

Browsing the Model

As you can see in the browser, a system can be described from three different views: a logical view, a component view, and a deployment view. The logical view is the actual design model of the system, which you will examine and change during this tutorial.

The component view describes the physical structure of the system and the mapping between the classes in the model and software components. The deployment view, which is empty in this example, is used to show the different processes of the running system and how they are related.

To browse the order system model:

  1. To view the logical view in the browser, expand the Logical View package by clicking on the "+" sign.

  2. Then expand the three services in the same way. The different symbols in the browser mean:

    = Package (a set of closely related classes)

    = Class

    = Interface

    = Class diagram

    Note that:

    • The "<<xxx>>" in front of the name of each model element indicates the stereotype of the element. Stereotypes can be used to further specify the type of a model element. Visual Modeler uses the stereotype of a model element during code generation to decide what kind of Visual Basic item to generate from it.

    • Below the browser there is a documentation field. This field contains a textual description of the currently selected model element or diagram. (If the documentation field is not displayed, select Documentation on the View menu.).

    • If you are not familiar with a three-tiered architecture yet, select each one of the service layers user services, business services, and data services, and take a look at their descriptions in the documentation field.
  3. Expand the Component View and take a look at its contents. The different symbols in the browser mean:

    = Component diagram

    = Component

    • The order system is implemented as one single component, an executable called OrderSystem, which corresponds to the ordersys.vbp project. All classes in the model are assigned to, and thereby implemented by, the OrderSystem component.

    • The other two components, VB and DAO, are existing DLLs that have been reverse engineered into the model because they are used by several of the classes in the model. Note that, in the Logical View, there is a package for each such component containing the interface classes provided by the component.
  4. Open the Main diagram of the Component View. Note, for example, that the VB and DAO interfaces that the order system is dependent on are shown as interface classes in the diagram.

  5. Close the Main component diagram.

Browsing the Class Diagrams

As you can see in the browser, the design model is illustrated in several diagrams, each one with its own purpose. The Three-Tiered Service Model diagram, located on the top level in the Logical View, is the main diagram of the order system design model. There are other diagrams that illustrate interesting details about parts of the model.

For example, to look at details about the Order class:

  1. Double-click on the Order Details diagram in the Business Services package. This diagram shows details about the Order class, such as: its methods, its properties and its relations with other classes.

  2. Note that the Orderrows relationship is marked with a "*" sign. This indicates that the Order class may reference a collection of OrderRow objects. Also, note that property procedures are assigned the stereotypes <<Get>>, <<Set>>, and <<Let>> in the model.

  3. Close the diagram.

Browsing the Business Objects

Each class is defined by a specification.

To view the specification of one of the classes in the Business Services package:

  1. Double-click on the Order class to open its specification.

  2. Examine the information behind the different tabs. For example, on the Components tab, note that the class is assigned to the OrderSystem component, which means that the OrderSystem component implements this class. Then close the specification dialog box.

  3. As important as understanding the detailed specification of a class is to know who is using the class. Therefore, select Order in the Three-Tiered Service Model diagram, and click Show Usage on the Report menu.

  4. Select one of the diagrams in which this class is used and click Browse. Look at the diagram and the relationships between the classes. (Move the Show Usage dialog box if it covers the opened diagram.)

  5. Close the diagram and the Show Usage dialog box.


Stereotypes and Model Properties

The next step is to study how the model is prepared for code generation. Most of the implementation details of the Visual Basic code are specified in the class, relationship, and method dialogs, but some detailed implementation decisions, specific to the Visual Basic programming language, must be entered as stereotypes or model properties of the model elements.

Note Other words for "model properties" are "code generation properties" or "code generation options".

Examining Class Stereotypes

The stereotype of a class is used to indicate a mapping to which type of Visual Basic project item the class corresponds. When generating code for a class, Visual Modeler creates a Visual Basic item of the specified type.

To examine the stereotype of a class:

  1. In the browser, expand User Services, and double-click on the dlg_Order class. The specification for the class then opens with the General tab displayed.

  2. As you can see, the stereotype is set to "Form". Thus, the dlg_Order class represents a form in the corresponding Visual Basic project. To get a list of other class stereotypes, click the arrow in the Stereotype field.

  3. Now, close the specification for dlg_Order.

Note Visual Modeler can reverse engineer most types of Visual Basic items, but the application cannot generate code for all types. For example, Visual Modeler can reverse engineer forms but not generate them.

Examining Naming Conventions

To examine the naming convention for a relationship:

  1. Open the specification of the Order class by double clicking on the class.

  2. Select the Relations tab.

  3. Double-click on pOrderrows to open the specification of that relationship. Note that relationships have two code generation tabs, Visual Basic A and Visual Basic B, one for each role.

  4. Select the Visual Basic A tab to view the model properties for role A.

  5. Take a look at the value of DataMemberName, which is "$relationship". This value means that the generated Visual Basic property will get the same name as the relationship, that is Orderrows.

  6. Also, note that NameIfUnlabeled is set to "the$supplier". This setting instructs the code generator to generate the variable name theOrderRow if the role is unnamed. In this particular case, role A is named Orderrows, so this option is not activated.

  7. To reuse specific model property settings between classes, Visual Modeler lets you define model property sets and attach a whole set to a class. In the Set field you can see that the "default" model property set is currently attached to this role. Also, in the Source field you can see that the values of all model properties, except NameIfUnlabeled, override the attached set, but the value of NameIfUnlabeled is the default value.

  8. Close the specifications.

  9. Close the Visual Modeler application by choosing Exit from the File menu.


Round-Trip Engineering with Visual Modeler

Round-trip engineering, or code-to-model and model-to-code generation, takes two forms in Visual Modeler:

  • If you have a Visual Basic project but not a design model of your system, you reverse engineer a new model from the project (which you are going to do in the next exercise).

  • Having a model that is synchronized with your existing Visual Basic code, you round-trip engineer your model. Information entered into the code is generated into the model using the Reverse Engineering Wizard. Information entered into the model is generated into the code using the Code Generation Wizard.

Reverse Engineering a New Design Model

You will now generate a new design model from the Visual Basic source code of the order system.

To generate a model from the Visual Basic project:

  1. Open the ordersys.vbp project in Microsoft Visual Basic (if it is not already open).

  2. In Microsoft Visual Basic, choose Visual Modeler from the Add-Ins menu, and then click Reverse Engineering Wizard.

  3. In the displayed Selection of Model dialog box, click New.

  4. Visual Modeler is then started with a new model opened. Also, a Welcome dialog box for the Reverse Engineering Wizard is displayed. Click Next> after you have finished reading the text.

  5. The Selection of Project Items dialog box is displayed.

  6. Deselect Save model and project before reverse engineering. (By selecting this option, you can use the Revert to Last Saved command on the Tools menu to revert to the current version of the model and code after the reverse engineering process.)

  7. Open the project items by clicking on the "+" signs, and take a look at their contents. Select the project items you want to reverse engineer:
    • Class modules — all of them

    • Module — Db

    • Form — dlg_Order

    • ActiveX Reference — DAO

    Note that some of the Visual Basic project items listed in the picture of the Selection of Project Items dialog box may not be available in your Visual Basic environment. The project in the picture is from Microsoft Visual Basic Enterprise Edition.

  8. Click Next>. A new dialog box is displayed, where you can assign the selected project items to packages in the new design model. (You can also create new packages in this dialog box, but that is not part of this exercise.)

  9. Assign dlg_Order to the User Services package by dragging and dropping it onto the User Services in the Logical packages list.

  10. Assign Article, Articles, Db, Persistence and DAO to the Data Services package and the rest of the project items to the Business Services package. Take a look at the Assigned To field to make sure that all project items are assigned. A project item that is not assigned will be assigned by default to a package named Unassigned.

  11. Click Next> to get a summary of what will be generated and estimation on how long it will take.

  12. Click Finish to build the new model from the chosen code. When the generation is finished, take a look at the result on the Summary and Log tabs in the Summary dialog box. Then click Close. (You can access and save the log later, by choosing Log from the Window menu in Visual Modeler.)

Examining the Generated Model

Now you have reverse engineered the Visual Basic project for the order system, and you have a design model of the system.

To view the generated model:

  1. Activate Visual Modeler.

  2. In the Component View, a component with the stereotype EXE, and with the same name as the corresponding project, has been created. On the Visual Basic tab of the component specification, you can see that the ProjectFile model property holds the name and location of the ordersys.vbp file. Also, the Realizes tab shows that all the reverse engineered classes have automatically been assigned to this component.

  3. In the Logical View, note that for each selected project item, the corresponding classes have been generated into the correct service package.

  4. Also note that each generated class has been inserted into the Package Overview diagram of the package where it belongs, as well as into its service tier in the Three-Tiered Service Model diagram.

  5. Moreover, all relationships between the class modules in Visual Basic have become relationships between the corresponding classes in the design model. To avoid crossed association lines in the Three-Tiered Service Model diagram, you may have to move the classes in the diagram.

  6. For the selected ActiveX component DAO, a package called DAO has been created. If you expand that package, you can see that interface classes have been generated for each of its interface elements. Note that the interfaces of a component belong to the logical view, but the actual component belongs to the component view. Thus, in the Component View, notice that a DAO component has been created.

Note If the generated relationships are not displayed in the diagram, click Filter Relationships on the Query menu. Then select all relationship types (which should already be done by default) and click OK.

Creating Classes and Associations in the Model

Now, you can practice the round-trip possibilities by creating a new business service class and an association in Visual Modeler and then updating the code with those changes.

To create and generate new model elements:

  1. On the Tools menu, click Class Wizard.

  2. Give the new class a name by typing "Invoice" in the name field. Click Next>. The Documentation dialog box opens.

  3. Write a brief description of the new class. Click Next>. The Service Type dialog box opens.

  4. Assign the new business class the appropriate tier, by selecting Business Services. Click Next>. The Inheritance dialog box opens.

  5. Because no other class implements this class, make sure that No is selected. Click Next>. The Methods dialog box opens.

  6. In the Methods list, click the right mouse button and select Insert. A new method is added to the new class. Give the new method a name by writing "Calculate" in the Name field on the General tab.

  7. Make sure that Visual Basic is selected in the Fundamental Types Language field. If so, the methods, arguments, and properties of the class will get Visual Basic data types. Then define the method's return type by selecting Integer from the Return type combo box.

  8. Click Next>. The Properties dialog box opens. In the Properties list, click the right mouse button and select Insert. Give the new property a name by writing "Number" in the Name field on the General tab. Define the return type by selecting Integer in the Type field.

  9. Click Next>. A summary of the new class is displayed. Click Finish to create the class.

  10. Activate the Three-Tiered Service Model diagram. As you can see, the new class has automatically been inserted into the appropriate tier.

  11. Create a relationship between Invoice and Order by clicking the association symbol in the toolbox. The cursor turns into a plain arrow. Place the cursor on the Invoice class in the diagram. Press the mouse button and drag the association to Order. Release the button.

  12. Name the new role of the Order class by right clicking on the Order side of the association and selecting Role Name from the menu. By default, the name of the new role becomes "theOrder". (You can also give the role a name in the specification dialog box for the relationship.)

Now you have created a new class with a property, a method, and a relationship. When you become familiar with the tool, you may choose to create classes, properties and methods directly in a diagram. To do that, place the cursor in the name field of the class and press the right mouse button. A pop-up menu appears, which contains the New Property and New Method commands. Here you can use inline editing to specify each new property and method, but you have to be familiar with the syntax.

Updating the Code from Changes in the Model

When you are satisfied with the changes in the model you are ready to generate code from the new Invoice class.

To generate code from a class:

  1. First, you have to assign the new class to the component that implements this class. (Note that a class can be assigned to and implemented by several components.) Visual Modeler needs that information to know which Visual Basic project the class belongs to. To assign the new class to the OrderSystem component, drag OrderSystem from the component view in the browser and drop it on the Invoice class in the Three-Tiered Service Model diagram.

  2. Open the specification of the Invoice class. On the Components tab, the check mark next to the OrderSystem component means that the class is assigned to that component. Close the specification.

  3. In the Three-Tiered Service Model diagram, right-click on Invoice and choose Generate Code. (Click Next> if the Welcome dialog box is shown.)

  4. The Select Classes dialog box is displayed, where you select the classes for which you want to generate code. Note that Invoice is already selected because you selected it before starting the Code Generation Wizard. Click Next>.

  5. The Preview Classes dialog box is shown. Here you can ask for a code preview of each selected class. Because Invoice is a new class, you probably have to change the code generator's default mapping to Visual Basic code. Therefore, select Invoice and click Preview.

  6. Get acquainted with the different preview dialog boxes in the Code Generation Wizard by clicking Next> and <Back. The Wizard shows the current model property settings for the class. These are stored in the specification of each class and shown on the Visual Basic tab in the specification dialog box. (Remember that you examined model properties in a previous exercise.) You are now going to change one of these settings from the Code Generation Wizard.

  7. Go to the Role Options dialog box and select the association you previously created between Invoice and Order. In the text box at the bottom of the dialog box you can see the code that should be generated with the current setting.

  8. Change the setting by, for example, selecting Property Get, which generates a Property Get procedure for the association. Note how the name of the generated variable is changed according to the naming conventions defined by the default values of the DataMemberName and NameIfUnlabeled model properties.

  9. When you are satisfied with your preview and settings, click Finish and then click Next>.

  10. The General Options dialog box is shown. Here you can instruct the code generator to insert debugging code and comments, among other things. Clear all options and click Next>.

  11. The Finish dialog box is shown where you can see a summary of what will be generated. Now, click Finish to start the code generation.

  12. Because you choose to synchronize manually, and because the code contains some project items that were not reverse engineered into the model, a Delete dialog box is shown. To keep the listed project items in the project, select <<All, and click OK.

  13. When the code generation is completed a Summary dialog box is shown. Take a look at the result on the Summary and Log tabs, and then click Close.

  14. Select the Invoice class. Press the right mouse button and choose Browse Code from the menu.

A Visual Basic class module called Invoice has now been created as you can see in the Microsoft Visual Basic window. Note how the property, method, and relationship were mapped to Visual Basic code.

Note For each generated project item, member, and method, Visual Modeler adds an identifier as a code annotation (for example "ModelID=3237F8CE0053"), which identifies the corresponding class, property, role, or method in the model. Those are not displayed in the code examples here.

Updating the Model from Changes in the Code

In the previous exercise, you practiced code generation from changes in the design model. Now, suppose that you have just created a new code class called dlg_OrderRow, and want to update the design model with the new class.

To reverse engineer a new project item:

  1. In Visual Modeler, start reverse engineering by clicking Visual Basic on the Tools menu, and then select Reverse Engineering Wizard. If a Selection of Project dialog box is displayed, select the ordersys.vbp project and click OK. (Click Next> if a Welcome dialog box is shown.)

  2. In the Selection of Project Items dialog box, select the dlg_OrderRow Visual Basic form. Deselect Save model and project before reverse engineering.

  3. Click Next> and assign dlg_OrderRow to the User Services package.

  4. Click Next> and take a look at the summary of what will be reverse engineered. Click Finish to update the new model with the new class.

  5. When the Wizard is finished, the result is shown in a Summary dialog box. The Summary tab shows the effects of the reverse engineering, and the Log tab lists any warnings or errors.

  6. Click Close and look for the new class in the browser and the Three-Tiered Service Model diagram. As you can see, a dlg_OrderRow class has been created and assigned to the OrderSystem component.

Browsing the Code and the Model

The Visual Modeler and Microsoft Visual Basic applications are tightly integrated-and not only with respect to code and class generation. You can also use each application to browse corresponding code or classes in the other tool.

To view the class module that corresponds to a selected design class:

  1. Select the Order class in the Three-Tiered Service Model diagram.

  2. Select Source Code on the Browse menu. Microsoft Visual Basic is then activated and a window with the Order class module source code is opened.

To open a diagram where the design class that corresponds to the selected project item occurs:

  1. Select the dlg_OrderRow form in Microsoft Visual Basic.

  2. Click Visual Modeler on the Add-Ins menu, and then click Browse Class Diagram. If the project is related to none or several models, select one of the models in the displayed dialog box.

  3. A dialog box with a list of the diagrams where the corresponding design class occurs is displayed. The corresponding design class is currently part of two diagrams: the Package Overview class diagram in the User Services package and the Three-Tiered Service Model diagram. To open and activate one of them, simply double-click on its name.

You have now completed the basic steps in using Visual Modeler. For complete information about the tool and round-trip engineering, please refer to the Visual Modeler online help.


Visual Modeler Quick Start with Visual C++

Use this tutorial to quickly become acquainted with C++ code generation using Microsoft Visual Modeler 2.0. You will be adding one additional step to the Visual C++ ENROLL tutorial that will show you how to:

  • Use a design model to visualize the MFC class hierarchy of an application.

  • Generate Visual C++ code from a model.

Prerequisites

These are the prerequisites for the tutorial:

  • Understand the design of a Microsoft Foundation Class Library (MFC) database application and the corresponding Visual C++ code.

  • Have Microsoft Visual C++ 6.0 and Microsoft Visual Modeler 2.0 installed on your computer.

Reading and Installation Instructions

It is best to complete the tutorial sequentially. If you haven't already done so, complete the ENROLL: Database Application tutorial. The Visual Modeler Quick Start with Visual C++ tutorial adds one additional step, STEP5, to the ENROLL tutorial. If you want, you can start directly with the Visual Modeler Quick Start with Visual C++ tutorial, as it contains all the files from the ENROLL sample at the end of STEP4.

To install the sample files for the Visual Modeler Quick Start with Visual C++ tutorial, see ENROLLVM: Demonstrates Modeling of a Visual C++ Application.


Introduction to the ENROLLVM Example

Imagine yourself as the newest member of the MIS department for a university registrar's office. Your first assignment is to make changes to the school's course administration system. After meeting with your boss, you understand that:

  • A course record in the application should now include the number of credits received upon completion of the course.

Before making any decisions on how to change the source administration system, you wisely decide to run the current implementation and to use Visual Modeler for studying the current architecture.

Starting the Enroll System

To start the enroll system application

  1. Start Microsoft Visual C++ by double-clicking the Enroll.dsw project file, which you can find in the folder where the ENROLLVM sample is installed.

  2. Build the sample by clicking Build enroll.exe from the Build menu.

  3. Run the sample by clicking Execute enroll.exe from the Build menu.

Note To run the sample, you need to register the database file StdReg32.mdb with an ODBC DSN named Student Registration. This step is outlined at the beginning of the ENROLL tutorial, under Setting Up the Student Registration Data Source.


Browsing the Enroll System Design Model

In this exercise, you'll use Visual Modeler to get acquainted with the design model of the course administration system.

Opening the Enroll System Design Model

To open the course administration system design model

  1. Start Visual Modeler. Click Start, then Programs, Microsoft Visual C++ 6.0, Microsoft Visual C++ 6.0 Tools, Microsoft Visual Modeler 6.0.

  2. Click Open on the File menu.

  3. In the Load Model from dialog box, open the folder where the ENROLLVM sample has been installed.

  4. Double-click the Enroll.mdl file. Visual Modeler opens the sample model and displays a diagram called the Three-Tiered Service Model.

When you open the model, you'll see the architecture of the course administration application; that is, you'll see the classes of the design model and the relations between them. Defining and maintaining the architecture and relationships within the system are among the most important aspects of large-scale iterative development.

The Three-Tiered Service Model diagram supports the three-tiered architectural approach used when building Microsoft Visual C++ applications. It separates the contents of the system into three conceptual tiers of services: user services (left pane), business services (middle pane), and data services (right pane). It is a special kind of class diagram, called a three-tiered diagram.

To the left in the application window, a browser window lists the contents of the course system design model in a hierarchical order. (If you cannot see the browser in your Visual Modeler application window, click Browser on the View menu.)

The diagram notation used in this tutorial is a subset of the Unified Modeling Language (UML). Please refer to the Visual Modeler online help for descriptions of the different modeling constructs. To open this help, click Help, then Visual Modeler Help Topics in the Visual Modeler.

Browsing the Class Diagrams

The User Services diagram, located on the left pane of the Three-Tiered Service Model, is the diagram of the MFC document/view structure for the course administration system's user interface. The Business Services pane in the middle separates out the Course and Section objects of the application.

In the visual representation that the User Services diagram provides, the general structure of the application can be understood without browsing the source code. As an example, examine the details of the ECourse class.

To look at the details of the ECourse class

  1. Double-click the ESection class in the Business Services pane. This displays the Class Specification for ESection (double-click below the title of the class if a drop-down list is displayed instead). This specification enumerates the methods, properties, and other aspects of the ESection class. Click the Properties tab to view the member variables of the class.

  2. Close the specification.


Changing the Sample Visually

Updating the Model

In the previous exercise, you browsed the specification of the ECourse class. Now, suppose that you want to add a new integer property to the ECourse class, named m_Credits, to represents the number of credits each course grants upon completion.

To change the properties of the ECourse class

  1. As in the previous exercise, double-click the ECourse class in the Business Services pane. This displays the Class Specification for ECourse. Click the Properties tab to view the member variables of the class.

  2. Use the right mouse button to click inside the list of properties. Click Insert from the popup menu. Type m_Credits for the property name and press Enter.

  3. Double-click with the left mouse button in the Type column of m_Credits. The Property Specification for m_Credits appears. Assign a type of int and an Initial value of 0.

  4. Click OK on the Property Specification and Class Specification to save your changes.

Generating C++ Code

Up to this point in the tutorial, no C++ code has been generated from the Visual Modeler.

To generate code for the changed ECourse class

  1. In Visual Modeler, open the Browser window by clicking Browser on the View menu.

  2. Expand the Component View by clicking the + icon to the left of the Component View folder icon.

  3. Right-click the <<EXE>> Enroll node and click Generate Code from the popup menu.

  4. In the Open Microsoft Visual C++ Project dialog box, navigate to and select the Enroll.dsw project.

  5. The Code Generation - Summary dialog box appears. Examine the Summary and Log tabs for information regarding the code generation.

  6. Open ECourse.h in the Visual C++ project window to view the C++ class declaration for ECourse with the new m_Credits integer member variable.

  7. (Optional) To add the credit field to the form, edit the IDD_COURSE_FORM resource in the Enroll.rc resource file. To persist the new m_Credits variable in the database, add a column for that variable in the Course table of StdReg32.mdb.

  8. Build the sample by clicking Build enroll.exe from the Build menu.

  9. Run the sample by clicking Execute enroll.exe from the Build menu.


Other Visual Modeler Samples

Through several samples included with Visual Studio, you can learn more about Visual Modeler by using it in conjunction with tools or technologies you may already be familiar with.

The topics listed in the following table introduce sample applications that demonstrate Visual Modeler features.

Section | Description
ADO: Models the Microsoft ActiveX Data Objects 2.0 Library | Introduces a sample that shows how a client application uses ADO objects (represented by interface classes in the model) to access a database.
ENROLLVM: Demonstrates Modeling of a Visual C++ Application | Introduces a sample that shows how to model and generate code for a Visual C++ application.
MTS: Models the Microsoft Transaction Server Application | Introduces a sample that shows the design model of the Microsoft Transaction Server application. The sample's model shows how the application is divided into three tiers of services.
ORDERSYS: Demonstrates Round-Trip Engineering of a Visual Basic Application | Introduces a sample that shows how to model and round-trip engineer a Visual Basic application.
RDO: Models the Remote Data Objects Framework | Introduces a sample that shows how a client/server application uses RDO objects to access a database.


ADO: Models the Microsoft ActiveX Data Objects 2.0 Library

Click to open or copy the ADO model and project files.

The ADO sample shows you a model of the Microsoft ActiveX(tm) Data Objects (ADO) 2.0 library. This library provides code to create and manipulate data in a database server via a provider.

By reverse engineering the ADO library into the model of the client application you are developing, you can show, in the model, how the application uses the ADO objects (represented by interface classes in the model) to access the database.

For the latest information on ADO, visit the Microsoft ADO web page.

The ADO model was built with Microsoft Visual Modeler, version 2.0, by reverse engineering the ADO ActiveX component.


ENROLLVM: Demonstrates Modeling of a Visual C++ Application

Click to open or copy the ENROLLVM model and project files.

The ENROLLVM sample shows you how to model and generate code for a Visual C++ application using Microsoft Visual Modeler 2.0. It is based on the ENROLL tutorial, which is a typical Microsoft Foundation Class Library (MFC) database application. The sample consists of the Visual C++ project files from the ENROLL tutorial and the corresponding design model.

The ENROLLVM sample is used in the Visual Modeler Quick Start with Visual C++ for Microsoft Visual Modeler 2.0. By following the Quick Start with Visual Modeler, you will quickly become acquainted with the Visual C++ integration feature of Microsoft Visual Modeler 2.0. The tutorial shows how to:

  • Use a design model to visualize the MFC class hierarchy of an application.

  • Generate Visual C++ code from a model.

The Quick Start with Visual Modeler tutorial adds one additional step to the ENROLL tutorial. Thus, before starting the Quick Start, complete the ENROLL: Database Application tutorial.

If you want to browse the design model of the ENROLLVM sample without following the Quick Start, start Microsoft Visual Modeler and open Enroll.mdl. A diagram called the Three-Tiered Service Model is displayed. This diagram shows the architecture of the ENROLL application, that is, the classes of the design model and the relations between them. This diagram, together with the high-level specification of each class, makes it easier to understand how the system is structured. Defining and maintaining the architecture and relationships within the system are among the most important aspects of large-scale iterative development.

To run the ENROLLVM application, open Enroll.dsw in Visual C++. On the Build menu, click Build enroll.exe. Then, on the same menu, click Execute enroll.exe. If you have problems running the application, make sure that the database file StdReg32.mdb is registered with an ODBC DSN named Student Registration. This step is outlined at the beginning of the ENROLL tutorial, under Setting Up the Student Registration Data Source.

The ENROLLVM model was built with Microsoft Visual Modeler, version 2.0, and the project was implemented with Microsoft Visual C++, version 6.0.


MTS: Models the Microsoft Transaction Server Application

Click to open or copy the MTS model and project files.

The MTS sample is a model of the Microsoft Transaction Server, which combines the features of a TP monitor and an object-request broker in an easy-to-use package. Software developers use Microsoft Transaction Server to deploy scalable server applications built from ActiveX components, focusing on solving business problems instead of programming application infrastructure. Microsoft Transaction Server delivers the "plumbing" including transactions, scalability services, connection management, and point-and-click administration providing developers with the easiest way to build and deploy scalable server applications for business and the Internet.

The MTS sample shows you the design model of the Microsoft Transaction Server application. The model shows how the application is divided into three tiers of services:

  • User Services - which format the information, and present it to the user. By separating the user services from other services, the presentation can be changed without impacting the rest of the application.

  • Business Services - which implement the system's business rules.

  • Data Services - which maintain the Customer and Catalog Data of the application.

Also, the Remote Data Objects (RDO) has been reverse engineered into the model to provide a framework for using code to create and manipulate components of a remote ODBC database system.

The MTS model was built with Microsoft Visual Modeler, version 2.0.


ORDERSYS: Demonstrates Round-Trip Engineering of a Visual Basic Application

Click to open or copy the ORDERSYS model and project files.

The ORDERSYS sample shows you how to model and round-trip engineer a Visual Basic application with Microsoft Visual Modeler 2.0. The sample consists of an order system application developed for a small seafood distributing company, the corresponding Visual Basic project, and a model of the application created in Visual Modeler 2.0. The application opens an order dialog, to which you can assign a customer and add new order rows based on the customer and article information stored in the application’s database.

The model of the ORDERSYS application makes it easier to understand how the system is structured by providing diagrams and high-level specifications of the classes. The ORDERSYS Visual Basic project has been generated from the model. By starting with a model of the application, the developers could focus on what the system was supposed to do and not how it was going to be implemented. At an early stage, two DLLs, DAO and VB, was reverse engineered into the model, to be used by other classes in the model. When the requirements and the model became stable, skeleton Visual Basic code was generated for all class modules, data members, and method specifications. Then the generated source code was refined into an executable system. During the refinement phase, the project and model was automatically kept consistent with each other by use of the round-trip engineering features (code generation and reverse engineering) of Microsoft Visual Modeler 2.0.

The ORDERSYS sample is used in the Visual Modeler Quick Start with Visual Basic tutorial for Microsoft Visual Modeler 2.0. To run the tutorial, choose Visual Modeler Help Topics from the Help menu in Visual Modeler. Expand the Quick Start with Visual Modeler book, open the first topic and follow the instructions. You can also open the Quick Start by double clicking on the qstart.hlp help file, which is located in the Microsoft Visual Modeler 2.0 installation folder.

You should use the tutorial in Quick Start with Visual Modeler to become quickly acquainted with Microsoft Visual Modeler 2.0. You will be introduced to some basic features in the tool, and learn how to:

  • Understand an application by browsing existing design diagrams and specifications

  • Modify an application by modeling the changes

  • Implement changes to an application by generating and evolving the code and updating the design

  • Understand how the design model is mapped to Visual Basic code

If you only want to browse the design model of the ORDERSYS sample, without following the Quick Start, start Microsoft Visual Modeler and open ordersys.mdl. A diagram called the Three-Tiered Service Model is displayed. This diagram shows the architecture of the order system application, that is, the classes of the design model and the relations between them. Defining and maintaining the architecture and relationships within the system is one of the most important aspects of large-scale iterative development. To run the ORDERSYS application, open ordersys.vbp in Microsoft Visual Basic. On the Run menu, click Start With Full Compile.

The ORDERSYS model was built with Microsoft Visual Modeler, version 2.0, and the project was built with Microsoft Visual Basic, Professional Edition version 6.0.


RDO: Models the Remote Data Objects Framework

Click to open or copy the RDO model and project files.

The RDO sample shows you a model of the Remote Data Objects (RDO) framework. This framework provides code to create and manipulate components of a remote database system. By reverse engineering the RDO framework into the model of the client/server application you are developing, you can show, in the model, how the application uses the RDO objects to access the database.

For ease of reading, the RDO model has been separated into two logical packages, one containing only constants, and the other containing the RDO objects.

See http://www.microsoft.com/vbasic/techinfo for more information on RDO.

The RDO model was built with Microsoft Visual Modeler, version 2.0.


Visual Studio Analyzer Reference

Visual Studio Analyzer is a tool to help you analyze performance, isolate faults, and understand the structure of your distributed applications. You can use Visual Studio Analyzer with applications and systems built with any of the Visual Studio tools.

Several Microsoft technologies, such as COM, ADO, and MTS are shipped with the ability to provide information to Visual Studio Analyzer. If your applications use any of these technologies, you can get detailed information about this use from Visual Studio Analyzer. In addition, you can customize your own applications to provide information to Visual Studio Analyzer.

The following sections provide information to acquaint you with the concepts, procedures, and commands of Visual Studio Analyzer.

Section | Description
Visual Studio Analyzer Concepts | Provides an overview of Visual Studio Analyzer and its features, as well as information on what you can accomplish using Visual Studio Analyzer.
Visual Studio Analyzer Common Tasks | Provides step-by-step procedures describing how to accomplish common tasks using Visual Studio Analyzer.
Visual Studio Analyzer Language Reference | Provides reference information on the Visual Studio Analyzer programming interfaces, which you can use to extend your own applications.
Visual Studio Analyzer User Interface Reference | Describes Visual Studio Analyzer's windows, dialog boxes, and wizards.
Visual Studio Analyzer Error Messages | Provides links to topics explaining error messages you may encounter, along with workarounds.


Visual Studio Analyzer Concepts

Microsoft® Visual Studio™ Analyzer gives you an overall view of your distributed application. You can evaluate, analyze, and debug the structure, performance, and interactions of a distributed application from an application perspective, rather than a component or code perspective.

Distributed applications can be complex, exploiting multiple languages and spanning multiple processes and systems. To aid in understanding this complexity, Visual Studio Analyzer focuses on the interactions between components. In this way, it helps you understand, debug, and analyze performance in new ways; ways not supported by traditional, lower-level debugging and evaluation tools.

The following sections provide information to acquaint you with Visual Studio Analyzer.

Section | Description
What is Visual Studio Analyzer? | Provides an overview of Visual Studio Analyzer and its features, as well as detailed information on what you can accomplish with it.
Understanding Application Structure | Describes using Visual Studio Analyzer to see all of the components in a distributed application and how they interact by plotting them in a diagram and annotating the diagram with the events each component generates.
Analyzing Performance | Describes using Visual Studio Analyzer for a high-level look at performance analysis by focusing on the interactions between the components of an application and allowing traditional profiling tools to provide performance analysis within those components.
Isolating Faults | Describes using Visual Studio Analyzer as a high-level tool that helps you understand which component within a distributed application is failing, so that you can use your low-level debugging tool strategically, thus reducing the overall cost of debugging.
Using the Visual Studio Analyzer Tools | Describes Visual Studio Analyzer tools that focus your analyses.
How Visual Studio Analyzer Works | Describes how Visual Studio Analyzer creates the views of your application.


What Is Visual Studio Analyzer?

Visual Studio Analyzer is a tool that you can use for debugging and analyzing distributed applications. With Visual Studio Analyzer, you can understand:

  • What a distributed application is doing.

  • What the performance of a distributed application is.

  • Where problems are occurring in a distributed application.

Visual Studio Analyzer helps you understand these things by providing several different views of your application. Visual Studio Analyzer constructs these views from information gathered as your application runs. These views are integrated into the Microsoft development environment, but you can use Visual Studio Analyzer with applications and systems built with any of the Visual Studio tools.

Understanding Application Structure

Understanding what a distributed application is doing means understanding the application's structure and flow. Visual Studio Analyzer can show you all the components and communications in your application, plot them in a diagram, and annotate the diagram with detailed information. You or your development team can use Visual Studio Analyzer this way to help new team members understand the application you are building.

Analyzing Application Performance

As a performance analysis tool, Visual Studio Analyzer focuses on a much higher level than a traditional profiling tool. The high-level focus is a result of the fact that Visual Studio Analyzer can provide a complete view, at a central location, of all the components and communications in your application. Furthermore, you can combine this view with environment and timing information from the Microsoft® Windows NT® Performance Monitor. The combination of Visual Studio Analyzer information with the Windows NT Performance Monitor information makes it easier for you to identify the slow spots, which you can then target with a profiling tool.

Isolating Faults

As a debugging tool, Visual Studio Analyzer helps you locate which component is causing problems. Visual Studio Analyzer provides a complete view, at a central location, of all the components and communications in your application. With this complete view, displayed in Visual Studio Analyzer, you can watch your application execute in real time, or you can record a session of your application and play it back. At any point you can request detailed information on a specific component. Using Visual Studio Analyzer in this way makes it easier for you to identify a problem component, and for you to use your debugging resources in the most cost-effective way.

For More Information Understanding application structure, analyzing performance, and isolating faults are the main tasks for which Visual Studio Analyzer was intended. For more information on when and how you might use Visual Studio Analyzer to accomplish these tasks, see:

  • Understanding Application Structure

  • Analyzing Performance

  • Isolating Faults

When to Use Visual Studio Analyzer

You can use the Visual Studio Analyzer views at two different points in the application life cycle:

  • In real time, as the application executes.

  • After the application finishes, for post-mortem analysis, as long as you have collected data while the application executed.

Isolating faults typically involves both real time and post-mortem analysis. You run the application, browse through the Visual Studio Analyzer views to understand what happened, and set breakpoints on individual lines of code with a traditional debugging tool. When your application reaches a breakpoint, it suspends execution. You then switch to Visual Studio Analyzer and play back what has happened so far. When you locate a possible problem within a single component, you switch to your traditional debugging tool to identify the problem.

Performance analysis almost always happens after an application is finished. Several Visual Studio Analyzer views analyze how much time each piece of an application required to execute. Visual Studio Analyzer identifies time usage as it can, and shows where time was spent using a line chart, Gantt chart, and timeline view.

Although knowing where time was spent is useful, you might be interested in other information as well. For example, did a particular SQL query take a long time because it was complex and time-consuming, or because the machine that runs it was very busy handling many requests? To address these types of questions, you can collect information from Windows NT Performance Monitor counters while your application is executing. You could, for example, collect the current load on the database machine every few seconds. By looking at the Performance Monitor information at the time the application was executing, you can get additional information about performance bottlenecks.

Getting Started with Visual Studio Analyzer

Visual Studio Analyzer is part of the Visual Studio 6.0 Enterprise Edition. It is integrated into the Microsoft development environment.

To use Visual Studio Analyzer, you need to create a Visual Studio Analyzer project. You also need to create an event log and a filter, and you need to connect to the machines running the application you want to monitor. The easiest way to accomplish all of these tasks is to use the Visual Studio Analyzer Project Wizard, but you can also create each of these items manually if you prefer. Another quick way to experiment with Visual Studio Analyzer is to create a Visual Studio Analyzer project and then open the sample event log, sample1.val.

For More Information This section mentioned Visual Studio Analyzer projects, event logs, and filters. These items are tools that Visual Studio Analyzer provides to help you in your analyses. For more information about these tools, see:

  • Understanding Visual Studio Analyzer Projects

  • Understanding Visual Studio Analyzer Event Logs

  • Understanding Visual Studio Analyzer Filters


Understanding Application Structure

Visual Studio Analyzer makes it easier to understand the structure and behavior of distributed, multi-tier applications by:

  • Showing all the components that interact.

  • Plotting them in a diagram.

  • Annotating the diagram with the Visual Studio Analyzer events that each component generates.

Your team can use Visual Studio Analyzer to record typical sessions of an application and save the resulting event logs; new members of your team can then replay these logs to learn about the application.

Helping a New Developer Understand an Application

You can take advantage of Visual Studio Analyzer's ability to log event interactions to help new team members understand your team's applications. For example, suppose a new developer has joined your project team to work on a distributed application. You are the project lead. You can use Visual Studio Analyzer to capture a typical run of your team's application and then sit down with your new team member to review the run's event log within Visual Studio Analyzer. You might proceed as follows:

  1. Start Visual Studio and open the Visual Studio Analyzer project that contains the event log.

  2. Select the event log and open the Component Diagram view, which shows a graphical representation of all the components in the application, and then replay events and watch as the events are presented.

  3. As playback progresses, you might note a confusing interaction. Stop playback, step backward event by event, and then step forward through the confusing sequence.

  4. When you are satisfied that you understand the interactions, resume playback.

Investigating Change Impact

You can use Visual Studio Analyzer to investigate the impact of changes before you make the changes final by checking in the affected code. For example, suppose you are working on a component that is part of a distributed application. You are familiar with your component, but not with the rest of the application. You have made some performance optimizations to your component, but you want to evaluate the possible impact to the rest of the application before you check in your changes to the master source code control system.

Here is how you could use Visual Studio Analyzer to investigate the impact of your changes:

  1. Start by creating a Visual Studio Analyzer project, connecting to your development machine, and creating a filter and event log.

  2. Edit the filter to collect all interactions between your component and the other components in the application, and then set the filter as the recording filter and start recording events into the event log.

  3. Start your application and switch back to Visual Studio Analyzer when the application finishes. Stop recording events into the event log.

  4. Open the Component Diagram view and replay the event log. You might notice that although usually your component is called from the same system, sometimes it is called from a remote system, so you might decide to optimize your component in a different way. You can use this method to perform a "what if" analysis of your changes as often as you would like. Investigating the impact of changes before check-in can save you time because you can spot potential problems at a time when it is easy to fix them. See Analyzing Performance for more information on using Visual Studio Analyzer to analyze various aspects of application performance.

For More Information This section mentions Visual Studio Analyzer events, event logs, projects, and filters. All of these items are tools that Visual Studio Analyzer provides to help you in your analyses. For more information about these tools, see:

  • Understanding Visual Studio Analyzer Events.

  • Understanding Visual Studio Analyzer Event Logs.

  • Understanding Visual Studio Analyzer Projects.

  • Understanding Visual Studio Analyzer Filters.


Analyzing Performance

Visual Studio Analyzer makes it easier to analyze the performance of your application by gathering data from all the components and systems automatically and presenting it to you. You can:

  • Choose how you want to view the data (see Understanding Visual Studio Analyzer Views for more information).

  • Focus on what happened and when.

  • Optionally collect and record Windows NT Performance Monitor data. If you choose to save an event log containing Performance Monitor data, you can have a snapshot of Performance Monitor data at a particular point in time, correlated with events in your application.

Comparing Visual Studio Analyzer to Code Profiling Tools

Visual Studio Analyzer provides information similar to that of profiling tools but at a very different scope. Code profiling tools, such as the Microsoft Source Profiler, are normally used to understand exactly where a component or single-process application is spending its execution time. These tools usually produce reports identifying the percentage of time spent in specific functions or at specific lines in the source code. Visual Studio Analyzer performance analysis is designed to show you a coarse-grained report of where time was spent based on the information flow of the application. You see performance information at the Visual Studio Analyzer event level rather than at the function or source code line level; time is reported for Visual Studio Analyzer event pairings, such as function call and return, rather than for individual components.

Using Visual Studio Analyzer for the Right Purpose

Visual Studio Analyzer's strength is in providing a high-level look at performance analysis, across all tiers and systems, by focusing on the interactions between the components of an application and allowing traditional profiling tools to provide performance analysis within those components.

Although you can use Visual Studio Analyzer to manually instrument your code and analyze the results, thus performing functions similar to a traditional profiling tool, Visual Studio Analyzer is not intended for this use. Using it this way has two important drawbacks:

  • You must instrument your code manually. Profiling tools instrument your code automatically.

  • Visual Studio Analyzer's network and disk usage are likely to overwhelm that of the application or system being analyzed.

Using Visual Studio Analyzer to Isolate a Performance Bottleneck

You can use Visual Studio Analyzer to identify and analyze slow parts of your application. For example, suppose your COM-based, data-driven application appears to have a performance problem. You notice that it seems to be running slower than you expect. Here's how you could use Visual Studio Analyzer to help you locate the problem:

  1. Begin by creating a new Visual Studio Analyzer project and connecting to the machines running the application. Create a new filter and open the filter in the Filter Editor.

    For more information about projects and filters, see Understanding Visual Studio Analyzer Projects and Understanding Visual Studio Analyzer Filters.

  2. For the filter, select the machines where the application is running, COM and ADO (or whatever data access technology your application uses) as the components, and basic COM and database-related events, such as object creation, function call, and query. The exact choices would of course depend on your application architecture and what the performance currently looks like. You might also use a predefined filter; the idea is to collect some useful data that might shed light on the problem.

  3. After defining your filter, set it as the recording filter and create a new event log, and then start recording events into the event log. You could open the Event List view because it provides the most comprehensive information, and watch as the collected events are displayed.

    For more information about event logs and views, see Understanding Visual Studio Analyzer Event Logs and Understanding Visual Studio Analyzer Views.

  4. When your application is finished, stop recording events and open the Chart view to see timing information for the collected events. By selecting different nodes in the event tree and watching the Gantt chart, you could see which events are taking the most time. You might notice that COM events are taking a long time relative to other events and determine they are taking so long because the database queries are running slowly. The Gantt chart will show the amount of time spent in the database query. If that percentage seems high, it indicates a potential problem.

Advanced Performance Analysis Using Data from Performance Monitor

In step 4 of the previous example, you might have determined that database queries were running slowly. Here's how you could use Visual Studio Analyzer and Performance Monitor data together to find out why:

  1. Begin by creating a new event log and by opening up the filter you created previously in the Filter Editor. Select the dynamic events category to add performance counters from the machines running the COM and database servers. These counters would include CPU utilization, paging activity, and SQL statistics.

  2. Set the revised filter as the recording filter and start recording events into the new event log. Run your application as before and stop recording events when the application finishes.

  3. Open the Chart view again to see the performance problems, but this time you might also overlay a line graph on the viewer and add the CPU events to it. The line graph would then show you the CPU events over time.

  4. You might select one of the events that shows poor database performance and notice how the line graph highlights the time sequence associated with that event. You see that the CPU load for the system at that point in time is quite high compared to the CPU load at other times.

  5. Next you might add a line graph showing paging activity data, which might show you heavy paging activity. Then add a line graph showing the SQL data, which could reveal that the complexity of the query is causing significant database activity. Knowing this, you could return to the source code and look for ways to optimize the query.


Isolating Faults

You can use Visual Studio Analyzer to isolate faults by taking advantage of the many Visual Studio Analyzer events that components can generate and that Visual Studio Analyzer can record. Visual Studio Analyzer provides many predefined events, including:

  • Component start and shutdown.

  • Function call and return.

  • Query start and completion.

You only have to write code for your own custom events. The events you collect are stored in an event log, which you can view in many different ways and at different levels to help you understand which component is at fault.

You use the events that Visual Studio Analyzer generates as the keys to understand where the failure might be. For example, if your application sends queries to a database and receives results back, you can add code to generate Visual Studio Analyzer events when these activities occur. You can then examine the Event List view to ensure that the queries do, in fact, occur as expected.

Comparing Visual Studio Analyzer and Debugging Tools

Traditional debugging tools work at a low level to determine the exact fault in a software component. Visual Studio Analyzer is not designed as a low-level debugger. Instead, Visual Studio Analyzer is a high-level tool that helps you understand which component or set of components is failing, so that you can use your low-level debugger strategically, thus reducing the overall cost of debugging.

Locating Faults

Suppose you are trying to locate a fault in a multi-tier application. Let's suppose further that you've already run Visual Studio Analyzer against a session of your application. (It can be useful to run Visual Studio Analyzer against each application as part of your final quality assurance passes, and then save the Visual Studio Analyzer project as a baseline.) The following steps illustrate how you can use Visual Studio Analyzer to assist you.

  1. Open the saved Visual Studio Analyzer project and create a new event log. Select a saved filter, set the filter as the recording filter, and start recording events into the new event log. Then open the Component Diagram view, switch to your application, set a breakpoint in your code, and begin execution.

    For more information on Visual Studio Analyzer projects, event logs, filters, and views, see Understanding Visual Studio Analyzer Projects, Understanding Visual Studio Analyzer Event Logs, Understanding Visual Studio Analyzer Filters, and Understanding Visual Studio Analyzer Views.

  2. As your application executes, the Component Diagram view displays a diagram of the application as well as the various Visual Studio Analyzer events generated by the components in your application. When the breakpoint in your code is reached, your application suspends.

  3. At this point you can reset the event log to the beginning and open an Event view, where you can view all the information about a single event. You can then step through the event log using the playback controls on the Analyzer toolbar, reviewing the details of each event in the Event view as you go along.

  4. Suppose that on this first pass you saw no problems, but you suspect your application of being corrupted in another place. You switch to your application and set a breakpoint in that place, and then resume execution. Additional events are generated and the Component Diagram view and Event view are updated. When the second breakpoint is reached, your application suspends again.

  5. You use the Event view to review the events between the two breakpoints and see an event with incorrect data, such as an incorrect call, an expected call that didn't appear, or a reported error return. This event tells you which component of your application to debug further.

Extending Visual Studio Analyzer for Custom Fault Isolation

You can use Visual Studio Analyzer to identify more complex faults, such as miscommunication between components. You accomplish this by adding Visual Studio Analyzer event generation code to your application.

For example, suppose your development team has created a large two-tier application that consists of multiple objects within a single executable. Many of these objects update a database using ODBC. A problem exists in the application that you cannot detect using normal Visual Studio Analyzer events, because it involves a bug between objects within the executable, as opposed to between separate components within the application. Your team wants to add code to your application so you can use Visual Studio Analyzer to trace the activity across the different logical components. You might use the following steps to accomplish this.

  1. Begin by implementing a setup program that registers your application with Visual Studio Analyzer, and then add event generation code to your application in any location where you want to generate an event. (See Extending Visual Studio Analyzer for more information on customizing your application for Visual Studio Analyzer.)

  2. After you have added Visual Studio Analyzer code to your application, create a Visual Studio Analyzer project, connect to the current machine (probably the development machine), create a filter, and create an event log. Edit the filter to select the current machine, your application and ODBC as event sources, and all events associated with both your application and ODBC. Activate the filter and begin collecting events, run your application, and then stop collecting events.

  3. Open the Component Diagram view and review the application and ODBC events. Trace the flow between components and view all the data associated with each event using the Event view. With this approach, you can locate the miscommunication between components.


Using the Visual Studio Analyzer Tools

Understanding application structure, analyzing performance, and isolating faults all require you to undergo an analysis process. This process is basically the same in all cases. Projects, filters, event logs, and views are the tools you use within Visual Studio Analyzer during the analysis process. The following figure illustrates the basic steps in the process.

Each step is summarized in the following list. Use the links to learn more about how to complete each step.

  1. Create or open a Visual Studio Analyzer project.

    Projects organize event logs, filters, and references to the machines where your application runs. See Understanding Visual Studio Analyzer Projects for information on what projects are and how to create them, and Starting Visual Studio Analyzer for the steps to create or open a project.

  2. Connect to the machine or machines where your application is or will be running.

See Connecting to Machines for Monitoring with Visual Studio Analyzer for the steps to connect to a machine.

  3. Define a filter that identifies the events you want to collect.

    Filters define which events to collect while your application is running and which events in an event log to include in a Visual Studio Analyzer view. See Understanding Visual Studio Analyzer Filters for information on what filters are, the sample filters supplied with Visual Studio Analyzer, creating filters, and applying filters to views.

    Events are the data of Visual Studio Analyzer. The event log contains the events that are collected from your application. Filters determine which events are collected when you run your application and which events are displayed when you view the event log. See Understanding Visual Studio Analyzer Events for information on what events are, system-defined events, what events tell you, and event security.

    If you want a filter you have defined to take effect when you start collecting events, you must set the filter as the recording filter by clicking Set Record Filter on the filter's shortcut menu.

  4. Create an event log to contain the events you collect, and start collecting events.

    Event logs provide a place for collected events. All the events generated by a particular run of your application are stored in a single event log. An event log is what you open in a Visual Studio Analyzer view, and what you see of the contents of an event log is determined by a Visual Studio Analyzer filter. See Understanding Visual Studio Analyzer Event Logs for information on what event logs are, creating event logs, and how event logs and views work together.

    To start collecting events, click Record Events on the event log's shortcut menu.

  5. Start your application. When your application finishes, you can stop recording by clicking Record Events on the shortcut menu, but this is optional.

  6. After the application finishes, open the event log in a Visual Studio Analyzer view.

    Views are ways of looking at an event log, which contains the Visual Studio Analyzer events generated by your application. See Understanding Visual Studio Analyzer Views for a list of the different views available, as well as information on opening, combining, and linking views.

  7. Refine the event collection filter to identify the events on which you want to focus.

    See Creating and Refining Event Filters for the steps to refine a filter.


Understanding Visual Studio Analyzer Projects

To use Visual Studio Analyzer services, you must create or open a Visual Studio Analyzer project within the Microsoft development environment. A Visual Studio Analyzer project consists of:

  • One or more event logs (only one recording event log per project).

  • One or more filters, including at most one recording filter.

  • One or more references to machines, which might or might not be connected.

Organizing these items within a project makes it easier for you to share Visual Studio Analyzer data among team members.

For more information on event logs and filters, see Understanding Visual Studio Analyzer Event Logs and Understanding Visual Studio Analyzer Filters.

Visual Studio Analyzer projects are displayed as a node in the Project Explorer pane within the Microsoft development environment. Under the node for your Visual Studio Analyzer project are separate nodes for event logs, filters, and machines. You can add a Visual Studio Analyzer project to a solution or combine more than one Visual Studio Analyzer project within a single solution. The total number of Visual Studio Analyzer projects you can combine depends on your system resources.

You can copy event logs and filters from one project to another, or use a single event log or filter in more than one project. The number of event logs and filters you can include in a single Visual Studio Analyzer project also depends on your system resources.

Creating a Visual Studio Analyzer Project

You can create a Visual Studio Analyzer project with or without using the Visual Studio Analyzer Wizard. The Analyzer Wizard is the fastest way to create a Visual Studio Analyzer project because it steps you through the process of connecting to machines, creating a collection filter (including offering you the choice of several predefined sample filters), and creating an event log. If you do not use the Analyzer Wizard, you need to connect to machines, create a collection filter, and create an event log manually after you create the project. See Creating and Opening Visual Studio Analyzer Projects for step-by-step procedures.


Understanding Visual Studio Analyzer Filters

Visual Studio Analyzer has the potential to generate more events than you want or need. Too many events can put stress on the network and obscure the events that are important for analysis. To avoid this kind of event overload, Visual Studio Analyzer provides a filtering mechanism. This filtering mechanism is used at two points in the analysis process:

  • During event collection, to identify or select the events you are interested in gathering.

  • During analysis, to restrict the events presented in the Visual Studio Analyzer views.

The filtering mechanism consists of one or more filters. Filters are normal Boolean expressions. They describe a combination of machines, processes, components, event categories, events, and other fields using Boolean operators such as AND and OR.

Types of Filters

Visual Studio Analyzer recognizes both file-based and transient filters. The AutoFilter command works differently with file-based and transient filters. When you create a filter in Visual Studio Analyzer, or include one of the predefined filters in your project, you are using a file-based filter — a filter that resides in a file. A transient filter is a temporary filter that resides in memory only. When you select the Edit Filter command on an unfiltered view, Visual Studio Analyzer creates a transient filter.

Predefined Filters

Some predefined filters are available for filtering standard types of events. These filters are installed when you run the Visual Studio Analyzer Wizard to create a project. You can add any predefined filter to your project by selecting the Filters node in the Project Explorer, right-clicking to display the shortcut menu, and clicking Add Predefined Filter. Once added, you can modify a predefined filter as required.

Blank Filters

When you add a blank filter, it is a filter with nothing selected. If your Visual Studio Analyzer project does not contain any other filters, this filter is the recording filter, and no Visual Studio Analyzer events are collected when you run your application. Visual Studio Analyzer is intentionally set up this way because the opposite case, a generic filter that selects all events from all event sources on all machines, would generate too much data and might cripple the network.

Creating Filters

You create a filter by right-clicking the Filters node in the Project Explorer pane of the Microsoft development environment and clicking Add Item on the shortcut menu. Then you use the Filter Editor to define the filter. See Creating and Refining Visual Studio Analyzer Filters for step-by-step procedures.

Filters During Collection and Analysis

You can set a filter as the recording filter, to determine what events are collected from your application. When you open an event log in a view, you can apply a filter to a view to refine the amount of data you see.

There is a difference between setting a filter as the recording filter and applying a filter to a view. The recording filter determines what events are collected from your application; a filter applied to a view refines the existing data displayed in that view.

The important difference is how Visual Studio Analyzer treats machines and components. During event recording, only events generated by the machines and components identified in the recording filter are recorded. When viewing data, only records with the machines and components identified in the applied filter are displayed. Although it might seem that these two actions are identical, such is not always the case.

For example, imagine that components A and B make up an application. Suppose the applied filter specifies Component=B and you are viewing events. In this case, an event that A generated, indicating communication from A to B would be displayed. However, if the recording filter specifies Component=B and you are recording events, an event that A generated, indicating communication from A to B, would not be recorded because Component=A is not explicitly specified in the filter.

This difference between event recording and event viewing allows Visual Studio Analyzer to limit the amount of data collected and subsequently passed over the network. What this means to you is that when you are recording events, you must be careful to explicitly select all participating components in your recording filter. When you are viewing events, you can be more liberal in your filter selections.

Avoiding Too Much Data

You need to construct filters thoughtfully, keeping network performance in mind. Each item you specify narrows the focus. For example, if you suspect a performance problem between machines, but you don't know which machines, you might try selecting subsets of your machines and running your application repeatedly.

Note Be careful when defining Performance Monitor events in your initial filter. Visual Studio Analyzer will warn you if you try to specify all Performance Monitor events in a filter because the overhead is prohibitive: each Performance Monitor counter will be fired at very frequent intervals, such as every half-second. The resulting events would overload the network and severely compromise Visual Studio Analyzer performance.

Applying a Filter to a Visual Studio Analyzer View

When you open one of Visual Studio Analyzer's views, the view is auto filtered — that is, the filter that is applied to the view is the same filter applied to any other open views. If no filter is applied to any other open view, or if there are no other views open, the view is unfiltered and all data is displayed.

You can apply the recording filter to the view. You can apply a different filter — or modify the applied filter — to change the events shown in the view. To apply filters to views, you use the Apply Filter command on the shortcut menu. If you have more than one view open, you can:

  • Apply the same filter to all views.

    If you apply the same filter to multiple views, any changes you make to the filter are reflected immediately in each view.

  • Apply a different filter to each view.

  • Edit a view-specific filter.

    If you choose the View Filter Editor command from a view's shortcut menu, you will edit the filter for that view (and for any other views that are linked to that filter).

Refining Filters to Target Specific Information

You can edit the filter applied to a view at any time to narrow down the events shown in the view. As soon as you finish editing the filter, the view updates to reflect your changes. Other open views that have the same filter applied also change. Normally your initial filter will be quite broad, encompassing many components and events. Once you gather your initial set of data, part of your analysis process consists of refining what you collected to eliminate components or events that do not show evidence of a problem. If you open another view after editing the active filter, the view reflects the changes you made.

Filter Files

You can share filters among Visual Studio Analyzer projects. A Visual Studio Analyzer filter is stored as a text file with the .vaf extension. You can save a filter and then copy the filter to other Visual Studio Analyzer projects. You can open a saved filter and include it with your Visual Studio Analyzer project. The name of the current filter is displayed on the viewer title bar.

When you change a saved filter, all open views to which that filter is applied will refresh their data, unless they are explicitly unlinked from the filter. See Creating and Refining Visual Studio Analyzer Filters for the steps to unlink views from the active filter.


Understanding Visual Studio Analyzer Events

All the tasks you can accomplish using Visual Studio Analyzer — understanding application structure, analyzing performance, and isolating faults — are based on identifying, generating, and collecting application events. In Visual Studio Analyzer, an event is an interaction between two components of an application. For example, in a Visual Basic application that invokes a remote COM object and sends SQL statements to a database server, the interactions between the application, the database server, and the remote COM object are all events.

Using System-Defined Events

Visual Studio Analyzer ships with many system-defined events. These events can provide you with information about:

  • Function calls and returns.

  • Measurements of system environment information, such as CPU usage.

  • Start and completion of database queries.

  • Start and shutdown of components.

  • Start, commit, and rollback of transactions.

The system-defined events cover a wide range of application activity. In addition to system-defined events, several Microsoft technologies, such as COM, ADO, and MTS are shipped with the ability to generate Visual Studio Analyzer events. If your application uses any of these technologies, you can run Visual Studio Analyzer against your application after you install Visual Studio. You will see events immediately; it is not necessary to add any code to your application.

If the system-defined events do not provide enough information, you can register your application with Visual Studio Analyzer and generate your own events; see Extending Visual Studio Analyzer for more information.

What Events Tell You

The basic information for an event includes timestamps, identifiers, source and target information (thread, component, and machine), global session identification, local session identification, and security identifications. Additional information includes sequence numbers for correlating related events (for example, requests with responses), descriptions, and user fields.

Visual Studio Analyzer can show you both sides of an interaction, such as the call into a function and the return from that function. The call to and return from the function, although related by the function, are separate events; together, they create a request-response pair.

For example, suppose that function A calls function B. Separate Visual Studio Analyzer events can show you:

  • When function A makes the call to function B.

  • When function B receives the call and begins processing.

  • When function B finishes processing and sends the result back to function A.

  • When function A receives the result.

This information makes it possible for you to measure time spent on the network, as well as time spent in actual processing.

Viewing Events in Visual Studio Analyzer

Briefly, in order to view events in Visual Studio Analyzer, you need to create three items:

  • A Visual Studio Analyzer project.

  • A Visual Studio Analyzer filter.

  • A Visual Studio Analyzer event log.

See Visual Studio Analyzer Common Tasks for step-by-step procedures to create each of these items.

After creating these items, start your application. As your application runs, it generates events. The Visual Studio Analyzer event reporting mechanism collects those events into an event log. When your application finishes, you can open the event log in one of the Visual Studio Analyzer views.

Event Security

When you are collecting events, you might be gathering data from applications that process sensitive data. You can take steps to ensure that data is protected while using Visual Studio Analyzer.

Security Assumptions

First of all, you need to guard against certain events and conditions that can make any otherwise secure system insecure. These events and conditions include:

  • Physical intrusion into a network; for example, by network packet sniffers.

  • Failure to restrict physical access to a machine.

  • Failure to keep a machine secure with proper, non-obvious passwords.

  • Failure to keep administrative functions limited to trusted individuals with the need to administer machines and the network.

Visual Studio Analyzer's security option is valuable only in the case where none of these conditions exist.

Security on Windows NT

Microsoft recommends you install and run Visual Studio Analyzer on Windows NT if you are concerned about security or will be collecting sensitive data. Windows NT has more comprehensive security support than Windows 95 does.

Any machine where the Visual Studio Analyzer server components run (and each machine you want to monitor with Visual Studio Analyzer requires the server components) must have the following security options set under Windows NT:

  • The Windows NT account under which the Visual Studio Analyzer server runs should have the Password Never Expires check box selected.

  • The Change Password at Next Logon check box should be cleared.

Also, if you want Visual Studio Analyzer to be able to collect information from the Windows NT Performance Monitor, make sure the account under which the Visual Studio Analyzer server runs belongs to a group that has the user right to profile system performance selected. You cannot set this user right on an individual Visual Studio Analyzer client basis in this release.

See Configuring Security for Visual Studio Analyzer on Windows NT for step-by-step procedures on setting up security.

Security on Windows 95

If you need to run Visual Studio Analyzer on a Windows 95 machine, you should understand the security implications of doing so. In order to connect to a remote Windows 95 machine running Visual Studio Analyzer, you must run Dcomcnfg.exe on the remote machine to change your DCOM settings to allow remote connections. Before you can run Dcomcnfg.exe on any machine, you must set the machine's access control to user-level (Dcomcnfg.exe requires user-level access control in order to run).

Important Changing access control to user level on a Windows 95 machine can have far-reaching consequences. For example, it will reset all of your current share permissions and you will need to restore those permissions manually. However, you cannot run Visual Studio Analyzer on a remote Windows 95 machine without changing access control to user level. Make sure you check with your system administrator before you change access control.

See Configuring Security for Visual Studio Analyzer on Windows 95 for step-by-step procedures on setting up security.


Understanding Visual Studio Analyzer Event Logs

Visual Studio Analyzer stores the events it collects in an event log. Once created and used for recording events, event logs never change. You use event logs in conjunction with filters and views to analyze your application with Visual Studio Analyzer. A filter defines the contents of an event log; that is, which events are collected. You open views on event logs so you can see the contents of the log. As you refine the filter, you exclude from the view the components and events that do not show evidence of a problem.

Comparing Visual Studio Analyzer Event Logs and Standard Log Files

A Visual Studio Analyzer event log provides you with more control over data than a standard log file. Through it you can:

  • Filter events in the log, both when you collect them and when you analyze them. Filtering keeps the log from getting too large. See Understanding Visual Studio Analyzer Filters for more information on filters.

  • Use predefined categories for events, gaining an extra level of structure in the log.

Creating Event Logs

If you use the Visual Studio Analyzer Wizard to create your Visual Studio Analyzer project, one event log is created for you. If you don't use the Analyzer Wizard, you need to create an event log manually before you can collect any events. You can create as many event logs as you like; the amount is limited only by available system resources, but you can have only one active event log at a time. Visual Studio Analyzer stores event logs uncompressed and accesses them directly from disk, for the highest performance. Event logs can become very large. Therefore, each time you stop recording on an event log, the event log closes and you need to create a new event log if you want to run your application again and collect data from it.

See Defining an Event Log for the steps to create an event log.

Filters and Event Logs

You can reduce the set of events displayed in a Visual Studio Analyzer view by applying a filter to the view. When you open an event log in one of Visual Studio Analyzer's views, the view is autofiltered — that is, the filter applied to any other open view is also applied to the view in which you open the event log. If there are no other open views, or if none of the other open views have filters applied, the view is unfiltered, which means that you see all the events in the event log.

You can apply any filter you want to the view or you can edit the existing filter. Remember that if the view is autofiltered, changes you make to the filter will be reflected in all views. A filter changes what you see of an event log. It does not affect the actual contents of the event log.

You need both a recording filter and an event log in order to collect events from your application. The order in which you specify these items does not matter, as long as you set a recording filter and then start recording on the event log you want. Once you have started recording on an event log, you can run your application. Visual Studio Analyzer will collect the events that your application generates into that event log. You can then pause, resume, or stop recording on that event log.

Event Logs and Views

The events in the selected event log populate the Visual Studio Analyzer view you choose; you can also open views on multiple event logs, as long as only one log is active. The active log can be recording events from your application at the same time you are looking at it in a view; you can also have views open on more than one event log at any time. For example, you might have log 1, which is active, open in a Block Diagram view and, at the same time, have log 2 open in another Event List view. The logs are independent of each other. You can open as many views on a log as you wish.

Exporting and Importing Event Logs

You can export a Visual Studio Analyzer event log to a standard comma-separated variable (.csv) file, which you can then open in Microsoft® Access or Microsoft® Excel for further analysis and manipulation. You can also import an exported event log back into Visual Studio Analyzer. You must create a new empty event log to hold the imported log.

Note: Some programs, such as Microsoft Excel, might treat exported Visual Studio Analyzer data as numeric, even when the data is enclosed in quotes. This can cause data to be translated incorrectly; for example, the hex value "1e8" might be incorrectly translated into the exponential value 1.0 E+8 = 100000000. If you run into this conversion problem with your data, then you might want to explicitly import your data into these programs as text. For Excel, this means renaming the .csv file to an alternate extension. Once you rename the file extension, Excel will prompt you for the data type of each field.

Event Log Files

A Visual Studio Analyzer event log is stored as a file with the .val extension. You can save an event log and then copy the event log to other Visual Studio Analyzer projects. You can open a saved event log and include it with your Visual Studio Analyzer project. This makes it easier to share event logs among team members.

Event Overflow

If your application is generating a lot of events, it's possible for Visual Studio Analyzer to get behind on data collection. When this happens, Visual Studio Analyzer generates an Overflow event that signals possible data loss. Visual Studio Analyzer contains a setting in the Options dialog that lets you control whether you want to pause your application so Visual Studio Analyzer can catch up or just continue to generate events without pausing your application.

There is a trade-off between pausing the application if it is generating a lot of events and continuing to collect data. If you don't want to pause the application, you risk missing events — the Overflow event indicates this condition. As a result, events have been lost, and you should be aware of that. Some Visual Studio Analyzer views might not look correct as the result of the Overflow event; for example, you might miss the return event of a call.


Understanding Visual Studio Analyzer Views

Visual Studio Analyzer presents its data in several different views, each emphasizing different aspects of your application. Through these views, you can interpret the data that Visual Studio Analyzer collects. The following table describes the Visual Studio Analyzer views and their uses. Use the links to see topics with more detailed information on each.

Viewer | Description | Recommended Use
Event List View | Shows a tabular list of all the events in the active Visual Studio Analyzer event log. | See a spreadsheet-like view of events and their parameters.
Chart View | Shows the events in the event log in a tree view, along with a Gantt chart showing the timing of the events. You can add one or more line charts showing performance data (from the Windows NT Performance Monitor) on top of the Gantt chart. | Understand how your application is performing, isolate hot spots, or understand relative timing information.
Block Diagram Views | Shows your application graphically. | Understand the structure of your application.
Event View | Shows all the parameters for a single event in the active Visual Studio Analyzer event log. | Get detailed information about a selected event.
Summary View | Shows details about the currently selected event or time range. | Get (in conjunction with the Chart view) more information about an unusual occurrence, such as a performance spike.
Timeline View | Shows the time sequence of events in the event log and includes markers that indicate the boundaries of the current selection. | Get a quick visual summary of the event log.

Combining Views

You can combine more than one Visual Studio Analyzer view on your desktop; for example, you might want to display the Event List and one of the Block Diagram views simultaneously. Each view opens in its own window. All you need to do is open the views you want and use the commands on the Window menu to arrange the views to your liking.

You can also dock the Visual Studio Analyzer views the same way you dock other windows in the development environment. See Window Management for information on docking windows, linking windows, and customizing your window preferences.

Linking and Unlinking Views

By default, all open Visual Studio Analyzer views are automatically linked to other open views and to the currently applied filter. This linking affects open views as follows:

  • If you select an event in an open view, all the other views change to reflect the selection.

  • If you change the currently applied filter, the updates are reflected immediately in all open views.

  • If you are watching the events your application generates in real time, the views you have open will update automatically.

You can unlink the view from other views and from the currently applied filter by selecting AutoSelect or AutoFilter, respectively, from the shortcut menu.

Replaying Events in Views

All Visual Studio Analyzer views are capable of replaying the events in the event log. Even the Event view updates to show the detailed information for the currently selected view. The replay commands are located on both the Analyzer menu and on the Analyzer toolbar.


How Visual Studio Analyzer Works

Visual Studio Analyzer helps you understand application structure, analyze performance, and isolate faults by providing several different views of your application. Visual Studio Analyzer constructs these views by monitoring your application as it runs, gathering information generated by COM, MTS, ADO, and other Microsoft technologies as your application runs, and then presenting that information to you.

The information that Visual Studio Analyzer gathers is in the form of events. An event, in the context of Visual Studio Analyzer, represents some kind of interaction or communication between two components in a distributed application. Function calls and returns from functions are Visual Studio Analyzer events, as are database queries, components starting and shutting down, and the like.

This section describes first how Visual Studio Analyzer sees your application, and then describes the reporting mechanism on which Visual Studio Analyzer relies to gather the events generated by the technologies your application uses.

How Visual Studio Analyzer Sees an Application

Visual Studio Analyzer consists of a set of views on your application. The views are integrated into the Microsoft development environment (with Microsoft® Visual InterDev™ and Visual J++™).

Visual Studio Analyzer treats the components of a distributed application as a series of connected black boxes and focuses on the interactions between the components. For example, a Microsoft® Visual Basic® application might invoke a remote DCOM object and send some SQL statements to a database server. The application, the DCOM object, and the server would all be components that Visual Studio Analyzer displays graphically. Where two components interact (for example, the DCOM object and the database server), the interactions are events that Visual Studio Analyzer captures, saves in an event log, and presents to you in a view.

Some of the main views that Visual Studio Analyzer provides are the Block Diagram views, which are graphical representations of the distributed application that can play back the events that occur as the application executes.

You can use the Block Diagram views as high-level views of the application, giving you a place to start from. From the Block Diagram views you can open other views that provide detailed information about individual components and events.

Event Reporting in Visual Studio Analyzer

Visual Studio Analyzer uses a set of event reporting interfaces to provide notification of the events between components. Each component in an application can use these event reporting interfaces. Many Microsoft technologies, such as ADO, COM, and MTS, are able to use these event reporting interfaces and will report Visual Studio Analyzer events without your needing to modify the components that invoke these technologies. In addition, the event reporting interfaces are available to you if you need to extend your application to report events of your own choosing.

When an event is reported, the event reporting mechanism notifies any Visual Studio Analyzer views that are currently active. The event reporting mechanism also records the event and a timestamp in the active Visual Studio Analyzer event log. The following diagram shows how events are handled.


Extending Visual Studio Analyzer

You can customize your components to generate your own Visual Studio Analyzer events. Several Microsoft-supplied technologies, including Component Object Model (COM) and ActiveX™ Data Objects (ADO), are shipped with the ability to generate Visual Studio Analyzer events, and if your components use any of these technologies, you can access a wide range of Visual Studio Analyzer information without having to modify your components. However, if the Microsoft-supplied technologies and events do not provide enough information for your needs, you can define your own events for your components.

Although in most cases you do not need to modify your components to take advantage of the Visual Studio Analyzer events that the Microsoft-supplied technologies generate, you do need to add code to your components if you want to define your own events. This code must register the component with Visual Studio Analyzer, identify the events the component will generate, and generate the events themselves.

To find out more about extending components to interact with Visual Studio Analyzer, see the following sections:

Section | Description
Understanding How Visual Studio Analyzer Works | Provides information on the parts of Visual Studio Analyzer and how they work together.
Guidelines for Customizing Your Application | Provides generic and language-specific information for customizing your applications for Visual Studio Analyzer.
Microsoft Components That Generate Visual Studio Analyzer Events | Describes the Microsoft-supplied technologies that are capable of generating Visual Studio Analyzer events.


Understanding How Visual Studio Analyzer Works

In order to customize your component for Visual Studio Analyzer, you need to understand the parts of Visual Studio Analyzer and how they work together.

The following figure illustrates the basic parts of Visual Studio Analyzer.

Visual Studio Analyzer consists of several parts: the framework, the event monitor, the event log, and the views. All of Visual Studio Analyzer is hosted in the Visual Studio environment. All Visual Studio Analyzer parts can exist on the same machine, as well as on multiple machines.

Part | Purpose
Visual Studio Analyzer Event Monitor | The Visual Studio Analyzer Event Monitor knows about the components on a particular machine and collects the events generated by each component, then evaluates the events against the active filter. Events that do not pass the active filter are ignored; events that fit the active filter criteria are passed on to the Visual Studio Analyzer Framework.
Visual Studio Analyzer Framework | The Visual Studio Analyzer Framework collects the events passed from each Visual Studio Analyzer Event Monitor and populates the current Visual Studio Analyzer Event Log and Visual Studio Analyzer Displays.
Visual Studio Analyzer Event Log | The Visual Studio Analyzer Event Log contains all the events collected by the Visual Studio Analyzer Framework for a given session. A Visual Studio Analyzer session consists of all Visual Studio Analyzer activity taking place between the creating or opening of a Visual Studio Analyzer project and the closing of that project.
Visual Studio Analyzer Views | The Visual Studio Analyzer Views present the collected events to the Visual Studio Analyzer user. Only events in the event log are displayed. Filtered events might be temporarily removed from view.

Registration Process

Before you can generate events from your component, your component must be registered. The registration process identifies your component to the Event Monitor, as well as identifying the events you plan to generate. The registration process is shown in the following illustration:

Your components interact with Visual Studio Analyzer throughout their lifecycles through code you write. The registration process and the parts you have to perform are summarized in the following list — please see the related topics for more information on how you can enable your components to perform each step.

  1. Create a unique instance of the Visual Studio Analyzer Event Source Installer object.

    The Visual Studio Analyzer Event Source Installer object is a COM object that provides methods for registering your component with the Visual Studio Analyzer framework.

  2. Register your component with the Visual Studio Analyzer framework.

    Visual Studio Analyzer components are registered on the machine or machines where they are running. Doing so allows the Visual Studio Analyzer user to view not only the events generated by your component but the machine on which the events were generated. Knowing the identity of the machine can be useful when trying to analyze performance or isolate faults.

    Components are either normal or dynamic. Dynamic components generate events at defined intervals. Performance Monitor is a good example, as is a network traffic monitor. Both of these components provide information about the status of measurable items at a particular point in time. The danger is that dynamic components can generate large amounts of data, which will most likely affect system performance, so you need to use them carefully.

    Normally you register your component with the Visual Studio Analyzer framework at the time your component is installed or at the time your component starts up. See Registering New Components with Visual Studio Analyzer for information on how to register your component with the Visual Studio Analyzer framework.

  3. Register any new Visual Studio Analyzer event categories your component will use (optional).

    Event categories allow you to group the events your component generates in a logical fashion. You are not required to use categories, but if your component generates many events, event categories can help the Visual Studio Analyzer user find the events of interest. Visual Studio Analyzer ships with several predefined event categories, or you can define custom event categories. See Registering New Event Categories with Visual Studio Analyzer for a list of the predefined event categories and for information on how to register event categories for your application.

  4. Register the Visual Studio Analyzer events your component will generate.

    A Visual Studio Analyzer event is an occurrence in the life cycle of a component, such as starting, stopping, calling a function, or querying a database. Visual Studio Analyzer ships with several predefined events, or you can define custom events. See System-defined Visual Studio Analyzer Events for a list of the predefined events, and Registering New Events with Visual Studio Analyzer for information on how to register events for your component.

After you complete the registration process, you can continue with the event generation process.

Event Generation Process

The Visual Studio Analyzer event generation process is illustrated in the following figure:

The event generation process and the parts your component must perform are summarized in the following list.

  1. Create a unique instance of the Visual Studio Analyzer Inprocess Event Creator object.

    The Inprocess Event Creator object is a COM object that provides methods for uniquely identifying a given instance of your component and for actually generating events. Make sure you create this object after any calls to DllMain.

  2. Uniquely identify this session of your component to the Visual Studio Analyzer event monitor.

    The unique identifier is important because your component might be running on several machines at the same time. If each component is generating Visual Studio Analyzer events, a unique identifier is necessary to distinguish between events generated by each instance of the component.

  3. Generate events.

    You can generate events at any point in your code. The FireEvent method allows you to pass the event name and any relevant event data. You can generate as many events as you need; keep in mind, however, that generating very large numbers of events will impact the performance of your system.

  4. Notify Visual Studio Analyzer that this instance of your component is finished generating events.

  5. Destroy the unique instance of the Visual Studio Analyzer Inprocess Event Creator object.

Visual Studio Analyzer includes one pre-registered component for generating events, DEBUG_EVENT_SOURCE_USER. You can use this component to fire unregistered events. For production applications, it is better to register one of the actual components and the events it generates, but the pre-registered component does allow for quick high-level debugging and may be useful during development or testing of an application.

For More Information For more detailed information on language-specific code to generate events, see Generating Visual Studio Analyzer Events.


Registering New Components with Visual Studio Analyzer

If you want your component to generate Visual Studio Analyzer events, the first thing you must do is add code that will register the component with Visual Studio Analyzer. Add this code to your component's installation or startup code, depending on when you want to register your component. You can register your component with Visual Studio Analyzer at one of three times:

  • When your component is installed.

  • Every time your component starts.

  • Every time your component starts, after verifying that the component isn’t already registered.

The following lists the steps you must take with code in your component in order to register that component with Visual Studio Analyzer:

  1. Create an instance of the event source installer object.

    The event source installer object is a COM object that provides methods for registering your component with the Visual Studio Analyzer Event Monitor. How you create this object depends on the language in which your component is written, as shown in the following table:

    Language Code to Create an Event Source Installer Instance
    Visual Basic
    dim mESI As MSVSAEventSourceInstaller
    Set mESI = New MSVSAEventSourceInstaller

— or —

    dim mESI As new MSVSAEventSourceInstaller
    Visual C++
    HRESULT hr = CoCreateInstance(CLSID_VSA_ESI, NULL, CLSCTX_INPROC_SERVER, IID_ISystemDebugEventInstall,
 (void **)&m_pInstall);
    Visual J++
    static ISystemDebugEventInstallAuto m_ESA = null;
    private static void SampleCreateESA()
   {
      m_ESA = new MSVSAEventSourceInstaller();
   }

  2. Call the RegisterSource or RegisterDynamicSource methods of the event source installer object, so that your component is registered.

    The RegisterSource method registers your component as a normal component. Most components fall into this category. Use the RegisterDynamicSource method to register your component as a dynamic component, which generates events at defined intervals.

    The interface exposed by the event source installer object is not a dual interface; therefore, the version of the interface you use depends on the language in which your component is written:

    Language | Event Installer Interface
    Visual Basic, Visual J++ | IsystemDebugEventInstallAuto
    Visual C++ | ISystemDebugEventInstall

    If your component is not COM-enabled, use the Visual Studio Analyzer standard RPC interface, VsaRpcl.

  3. Register any custom event categories you plan to use (optional).

    See Registering New Event Categories with Visual Studio Analyzer for information on how to do this.

  4. Register the events you plan to generate.

    See Registering New Events with Visual Studio Analyzer for information on how to do this.


Registering New Event Categories with Visual Studio Analyzer

You can use event categories to group related events, partly to make it easier to locate the events within the event log, and partly to provide context for the kinds of interaction events represent. A typical Visual Studio Analyzer event log can contain thousands of events; categories provide a way to locate particular events more quickly. The Visual Studio Analyzer user can see categories listed within the Filter Editor.

If you choose to use event categories, you can use those that Visual Studio Analyzer provides, or you can define your own. The following table lists those that Visual Studio Analyzer provides:

Predefined Event Category | Description
DEBUG_EVENT_CATEGORY_STARTSTOP | Events generated by components starting or shutting down.
DEBUG_EVENT_CATEGORY_CALLRETURN | Events generated by the function calls and returns.
DEBUG_EVENT_CATEGORY_QUERYRESULT | Events generated by the starting and completing of database queries.
DEBUG_EVENT_CATEGORY_TRANSACTION | Events generated by transactions, including start, commit, and rollback.
DEBUG_EVENT_CATEGORY_ALL | All events.
DEBUG_EVENT_CATEGORY_MEASURED_ALL | All measured events. A measured event is generated by a dynamic event source and signifies a measurement of an item, such as CPU usage.

Add the code for registering event categories to your component installation or startup code after the code for registering your component with Visual Studio Analyzer.

Defining Custom Event Categories

You must take the following steps with code in your component in order to register your custom event categories.

  1. Register your component with Visual Studio Analyzer.

    If you want your component to generate Visual Studio Analyzer events, you must add code that will register the component with Visual Studio Analyzer. See Registering New Components with Visual Studio Analyzer for information on how to do this.

  2. Call the RegisterEventCategory method of the event source installer object for each category you want to define.

    The RegisterEventCategory method registers the name and ID of each event category.

    You can arrange categories in a hierarchy with the guidParentID parameter. A hierarchy allows you to define additional levels of categorization. For example, consider the Visual Studio Analyzer events that Performance Monitor generates. These events are categorized to represent the different objects and instances that are providing performance data.

    If you register categories without specifying the guidParentID parameter, your categories will be displayed in the Filter Editor at the same level (top) as the All Events category. If you want your categories to appear subordinate to the All Events category, specify DEBUG_EVENT_CATEGORY_ALL for guidParentID.

    The interface exposed by the event source installer object is not a dual interface; therefore, the version of the interface you use depends on the language in which your component is written.

    Language | Event Installer Interface
    Visual Basic, Visual J++ | IsystemDebugEventInstallAuto
    Visual C++ | ISystemDebugEventInstall

    If your component is not COM-enabled, use the Visual Studio Analyzer standard RPC interface, VsaRpcl.

  3. Register the events you plan to generate.

    You can use any of the Visual Studio Analyzer system-defined events with your component, but you must register each event that you plan to generate. See Registering New Events with Visual Studio Analyzer for information on how to do this.


Registering New Events with Visual Studio Analyzer

You can use any of the Visual Studio Analyzer system-defined events with your component, but you must register each event that you plan to generate. The Visual Studio Analyzer system-defined events provide information about components starting or stopping, function calls and returns, database queries, and transactions. See System-Defined Visual Studio Analyzer Events for a complete list of events.

If the system-defined events do not suit your purposes, you can register custom events. Custom events are registered the same way as system-defined events. You must register each custom event you plan to generate.

Add the code for registering events to your component installation or startup code — after the code for registering your component with Visual Studio Analyzer and after the code for registering any event categories.

Registering an Event

You must take the following steps with code in your component in order to register the events you want to generate.

  1. Register your component with Visual Studio Analyzer.

    If you want your component to generate Visual Studio Analyzer events, you must add code that will register the component with Visual Studio Analyzer. See Registering New Components with Visual Studio Analyzer for information on how to do this.

  2. Register any event categories you plan to use.

    You can use event categories to group related events. See Registering New Event Categories with Visual Studio Analyzer for information on how to do this.

  3. Call the RegisterStockEvent or RegisterCustomEvent methods of the event source installer object for each event you plan to generate.

    Use RegisterStockEvent for each system-defined event you plan to generate, and RegisterCustomEvent for each custom event. Both of these methods register the name and ID of the event.

    The interface exposed by the event source installer object is not a dual interface; therefore, the version of the interface you use depends on the language in which your application is written.

    Language | Event Installer Interface
    Visual Basic, Visual J++ | IsystemDebugEventInstallAuto
    Visual C++ | ISystemDebugEventInstall

    If your component is not COM-enabled, use the Visual Studio Analyzer standard RPC interface, VsaRpcl.

  4. Destroy the event source installer object.


System-defined Visual Studio Analyzer Events

Your component can generate any of the Visual Studio Analyzer system-defined events as long as you register them for your component and then add the code to generate them at the appropriate points.

System-defined events are grouped by type. Event types provide more information about the kind of interaction the event represents. An event can be any of the following types:

Type | Description
Generic | Events that describe components starting or stopping.
Inbound | Events that describe the returning of a value or result set from a function or database query.
Measured | Events that describe a measurement of an item such as CPU usage, which is taken at intervals. Measured events are not listed in the table below because the list of available measured events is generated at runtime from the dynamic event source. In the case of NT Performance Monitor, any valid Performance Monitor counter can be a measured event.
Outbound | Events that describe the calling of a function or starting of a database query.

The following table lists the system-defined events.

Event Name | Type | Category | Description
DEBUG_EVENT_CALL | Outbound | CALLRETURN | Generated on function call
DEBUG_EVENT_CALL_DATA | Outbound | CALLRETURN | Generated if additional data is sent to support a function call
DEBUG_EVENT_COMPONENT_ START | Generic | STARTSTOP | Generated when a component loads an event source
DEBUG_EVENT_COMPONENT_ STOP | Generic | STARTSTOP | Generated when a component unloads an event source
DEBUG_EVENT_ENTER | Outbound | CALLRETURN | Generated on function enter (after any time spent on the network)
DEBUG_EVENT_ENTER_DATA | Outbound | CALLRETURN | Generated if additional data is sent to support a function enter (after any time spent on the network)
DEBUG_EVENT_LEAVE_DATA | Inbound | CALLRETURN | Generated if additional data is sent before control flow returns (before any time spent on the network)
DEBUG_EVENT_LEAVE_ EXCEPTION | Inbound | CALLRETURN | Generated if an exception is thrown (before any time spent on the network)
DEBUG_EVENT_LEAVE_ NORMAL | Inbound | CALLRETURN | Generated on a normal return of control (before any time spent on the network)
DEBUG_EVENT_QUERY_ENTER | Outbound | QUERYRESULT | Generated on the server side when a query is received from a client (after any time spent on the network)
DEBUG_EVENT_QUERY_LEAVE | Inbound | QUERYRESULT | Generated on the server side when a query is returned to a client (before any time spent on the network)
DEBUG_EVENT_QUERY_ RESULT | Inbound | QUERYRESULT | Generated on the client side when the result of a query is returned from the server
DEBUG_EVENT_QUERY_SEND | Outbound | QUERYRESULT | Generated on the client side when a query is sent to the server
DEBUG_EVENT_RETURN_DATA | Inbound | CALLRETURN | Generated if additional data is sent before control flow returns
DEBUG_EVENT_RETURN_ EXCEPTION | Inbound | CALLRETURN | Generated if an exception occurs
DEBUG_EVENT_RETURN_ NORMAL | Inbound | CALLRETURN | Generated on a normal return of control
DEBUG_EVENT_TRANSACTION_COMMIT | Generic | TRANSACTION | Generated when a transaction is committed
DEBUG_EVENT_TRANSACTION_ROLLBACK | Generic | TRANSACTION | Generated when a transaction is cancelled
DEBUG_EVENT_TRANSACTION_START | Generic | TRANSACTION | Generated when a transaction begins


Generating Visual Studio Analyzer Events

You can generate either system-defined or custom events from any place in your code. You must register any event you plan to generate. If you generate an unregistered event, or an event from an unregistered source, the event will be correctly passed and recorded. However, there is no guarantee that users will be able to create or edit filters based on an unregistered event or event source. Make sure all events and event sources are registered. (For more information on how to use filters, see Understanding Filters.)

The following lists the steps you must take with code in your component in order to generate events:

  1. Create an instance of the in-process event creator object.

    How you do this depends on the language in which your event source is written, as shown in the following table:

    Language Code to Create an Inprocess Event Creator Instance
    Visual Basic, Visual J++
    Dim MyIEC As _ MSVSAInprocEventCreator
    Set MyIEC = New _ MSVSAInprocEventCreator
    Visual C++
    HRESULT hr = CoCreateInstance(CLSID_VSA_IEC, NULL, CLSCTX_INPROC_SERVER, IID_ISystemDebugEventFire,
 (void **)&pEvent);

  2. Call the BeginSession method of the in-process event creator object.

    The BeginSession method allows you to uniquely identify this particular session of your component. The unique identifier is important because your component might be running on several machines at the same time. If each component is generating Visual Studio Analyzer events, a unique identifier is necessary to distinguish between events generated by each instance of the component.

  3. Call the FireEvent method of the in-process event creator object each time you want to generate an event.

    The FireEvent method allows you to pass the name of the event and the corresponding event data.

  4. Call the EndSession method of the in-process event creator object and then destroy the in-process event creator instance.

Passing Event Data

You can pass event data in an array with the FireEvent method. This data provides detailed information to the Visual Studio Analyzer user, helping them understand a distributed application, determine performance problems, and isolate faults. See VSAStandardParameter for a list of the parameters you can pass for event data.

Among the many possible event parameters, some of the most important are the machine, process, process name, thread, component, session, and handle for both the source and the target component. The source component is the component that generates the event; the target component is the called function, database, or transaction. You can pass default values for these parameters; see Determining Source and Target Values for Events for more information on when to pass default values and when it is better to explicitly provide source and target values.

It is also important to show how events relate to one another. The CorrelationID and CausalityID event parameters provide a way for you to ensure that related events, such as the call to and return from a function, appear related to the Visual Studio Analyzer user. See Determining the Relationships Between Events for more information on showing client and server interaction with these relationships.


Determining Source and Target Values for Events

When you generate an event you can include detailed information about the event by passing event parameters. The more details you provide about an event, the more useful the event is likely to be for the Visual Studio Analyzer user who is trying to analyze performance or isolate faults.

Among the most important parameters you can provide are the identities of the source machine (where the event originated) and the target machine (where the event ended up). In a distributed application — where business logic, a database, or a transaction server are on different machines from the application client — events such as function call or return, database query send and return, and transaction start and commit will provide more useful information if the source and target machine identities are provided.

The event parameters that describe the event source and target (machine, process, process name, thread, component, session, and handle) are individually optional, but at least one of the group is required. The Block Diagram view depends on these values to properly connect the parts of the diagram. If you cannot provide any of these values for your application, synthesize unique values for SourceHandle and TargetHandle. They represent your application's view of unique identifiers for the event source and event target. These synthesized values must be constant for all calls to FireEvent for the same source or target.

You can choose to provide default values for either the source parameters or the target parameters; however, the default values are unlikely to be correct for both source and target, because you will normally know the identity of only one. Thus the VSAEventFlags parameter of FireEvent allows you to specify default values separately for the source and target parameters.

You must try to provide as much information as possible about the source and the target. This increases the chance that the Visual Studio Analyzer user will be able to correlate calls to the same object that arrive by different channels. At a minimum, you must maintain the integrity of SourceHandle and TargetHandle, so it is clear that multiple calls are from the same source to the same target. If you cannot preserve this integrity, the number of entities in the block diagram will increase to an unacceptable level, affecting performance.

Example: SQL Server

As an example, consider calls to FireEvent from SQL Server. When SQL Server receives a query, it can generate an event. SQL Server would probably know its machine, process, and possibly thread, so it could supply values for TargetMachine, TargetProcess, and possibly TargetThread. However, SQL Server probably does not know where the query came from, unless ODBC provides this information, so this call would specify the ODBC connection handle as a value for the SourceHandle parameter (if provided by ODBC) and specify default values for the target event parameters.


Determining the Relationships Between Events

Events such as function call and return, database query send and result, and transaction start and commit are related to each other because they show both the client and server interaction. Showing these relationships to the Visual Studio Analyzer user assists in analyzing performance and isolating faults. The CorrelationID and CausalityID event parameters contain strings that you can match so that the Visual Studio Analyzer user will see related events properly.

A typical function call and return scenario generates four events in the sequence shown in the following illustrated:

  1. The first event contains the event parameters and is generated just before a call to a function actually occurs.

  2. The second event, identical to the first except for the timestamp, is generated when the call arrives at the called function (this is the Enter event).

  3. The third event (Leave) is generated as the call leaves the called function.

  4. The fourth event is generated when the call returns, and contains the ReturnValue parameter.

Often you will have only the Call and Return events, not the Call, Enter, Leave, and Return events. If you do have all four events, you should provide the same CorrelationID value for all four of these events so that they can be matched. The Source and Target event parameters should be the same for both the call and return events: that is, if A calls B, and then B returns to A, the Source parameter is A in both cases, and the Target parameter is B.

If it is not feasible to provide identical CorrelationID values for all four events, then at a minimum you should provide the same CorrelationID value for the Enter/Leave event pair and for the Call/Return pair. If it is not feasible to provide identical CorrelationID values for even the Enter/Leave or Call/Return pairs, at minimum you should provide the events with identical CausalityID values.


Guidelines for Customizing Your Application

This section provides general information on implementing the Microsoft® Visual Studio™ Analyzer programming interfaces in Visual Basic®, Visual C++®, and Visual J++™. For information and guidelines on implementing the Visual Studio Analyzer programming interfaces with each of the supported visual languages, refer to the following topics:

Language | Topic for Guidelines on Implementing Interfaces
Visual Basic | Information and Guidelines for Visual Basic Programmers
Visual C++ | Information and Guidelines for Visual C++ Programmers
Visual J++ | Information and Guidelines for Visual J++ Programmers

For details about the methods available in each interface, and for sample code in each of the three languages, consult the individual interface reference topics in the following list:

  • ISystemDebugEventFireAuto, ISystemDebugEventFire

  • ISystemDebugEventInstallAuto, ISystemDebugEventInstall

  • VsaRpcl


Information and Guidelines for Visual Basic Programmers

To access the Visual Studio Analyzer programming interfaces from within Visual Basic, you need to add two type library references to your Visual Basic project. Once you add the type library references, you can access the methods within the programming interfaces using the Object Browser.

To add the Visual Studio Analyzer type library references

  1. Click the Project menu, and then click References.

  2. In the Available references box, select the check box for the following two type libraries:
    • MSVSA Automatable Event Source Installer

    • MSVSA Automatable Inproc Event Creator
  3. Click OK.

These libraries give you access to the event source installer and in-process event creator classes. You can use the Object Browser to access the methods for each class.

Constants for Visual Studio Analyzer Predefined Events

Visual Studio Analyzer ships with a number of predefined events. These events are identified by global unique identifiers (GUIDs) and must be referred to by their GUID each time you use them in code. However, you can make using these predefined events a little easier for yourself by creating constants for these events and saving them in a global file. You can then include that file in your projects that contain code for customizing Visual Studio Analyzer.

The predefined events and their GUIDs are listed in file vaids.h. This file contains C++ declarations. You can use this file as a source to create your file of Visual Basic constants.

For example, the DEBUG_EVENT_CALL predefined event appears in vaids.h as follows:

DECLARE_GUID(DEBUG_EVENT_CALL, 6c736d61, bcbf, 11d0, 8a, 23, 00, aa, 00, b5, 8e, 10);

In your file, use the following format:

Public Const DEBUG_EVENT_CALL = "{6c736d6-bcbf-11d0-8a23-00aa00b58e10}"


Information and Guidelines for Visual C++ Programmers

Programs you write that use the Visual Studio Analyzer programming interfaces must include the following files.

File name | Description
vaevt.h | Definitions for the Visual Studio Analyzer programming interfaces.
vaids.h | Constants for the Visual Studio Analyzer predefined events, event categories, and user component.
vaevt_i.c | Definitions of the IDs and CLSIDs for the Visual Studio Analyzer programming interfaces.

Include vaevt.h and vaids.h in any file where you will register components for generating Visual Studio Analyzer events or where you will generate those events. In one file in your project, you should generate the Visual Studio Analyzer global unique identifiers (GUIDs). To do so, include initguid.h, followed by vaevt_i.c and vaids.h.

All required include files are located in C:\Program Files\Microsoft Visual Studio\Common\Tools\VS-Ent98\Vanalyzr\vaprog if you use the default installation location.


Information and Guidelines for Visual J++ Programmers

To access the Visual Studio Analyzer programming interfaces from within Visual J++, you need to add COM wrappers for the libraries in which they reside to your Visual J++ project. Once you add the COM wrappers, Visual J++ creates Java classes for each programming interface.

To add the Visual Studio Analyzer libraries

  1. Click the Project menu, and then click Add COM Wrapper.

  2. In the Installed COM Components box, select the check box for the following two libraries:
    • MSVSA Automatable Event Source Installer

    • MSVSA Automatable Inproc Event Creator
  3. Click OK.

These libraries give you access to the event source installer and in-process event creator classes.

If the Visual Studio Analyzer libraries are not listed in the COM Wrappers dialog box, make sure that Visual Studio Analyzer is installed on your machine. If Visual Studio Analyzer is installed but the libraries are not listed in the COM Wrappers dialog box, you can browse for the two DLLs you need, vaesa.dll and vaiea.dll. These DLLs are located in C:\Program Files\Microsoft Visual Studio\Common\Tools\VS-Ent98\Vanalyzr if you use the default installation location.

Constants for Visual Studio Analyzer Predefined Events

Visual Studio Analyzer ships with a number of predefined events. These events are identified by global unique identifiers (GUIDs) and must be referred to by their GUID each time you use them in code. However, you can make using these predefined events a little easier for yourself by creating constants for these events and saving them in a global file. You can then include that file in your projects that contain code for customizing Visual Studio Analyzer.

The predefined events and their GUIDs are listed in file vaids.h. This file contains C++ declarations. You can use this file as a source to create your file of Java constants.

For example, the DEBUG_EVENT_CALL predefined event appears in vaids.h as follows:

DECLARE_GUID(DEBUG_EVENT_CALL, 6c736d61, bcbf, 11d0, 8a, 23, 00, aa, 00, b5, 8e, 10);

In your file, use the following format:

static String DEBUG_EVENT_CALL = "{6c736d61-BCBF-11D0-8A23-00AA00B58E10}";


Microsoft Components That Generate Visual Studio Analyzer Events

Several Microsoft-supplied technologies support Microsoft® Visual Studio™ Analyzer. The latest versions of these technologies are able to generate Visual Studio Analyzer events.

If your distributed applications rely on any of these technologies, you can use Visual Studio Analyzer to see the interactions between these technologies and your application, in most cases without changing any of your application code.

The following sections provide more information about each of these Microsoft-supplied technologies and the specific Visual Studio Analyzer events they generate.

Section | Description
ADO | Contains information about what Visual Studio Analyzer can tell you about ADO use within your application, as well as a list of the Visual Studio Analyzer events that ADO generates.
COM Transaction Integrator (COMTI) | Contains information about what Visual Studio Analyzer can tell you about COMTI use within your application, as well as a list of the Visual Studio Analyzer events that COMTI generates.
COM | Contains information about what Visual Studio Analyzer can tell you about COM use within your application, as well as a list of the Visual Studio Analyzer events that COM generates.
IIS | Contains information about what Visual Studio Analyzer can tell you about IIS use within your application, as well as a list of the Visual Studio Analyzer events that IIS generates.
JScript | Contains information about what Visual Studio Analyzer can tell you about Microsoft® JScript™ use within your application, as well as a list of the Visual Studio Analyzer events that the JScript engine generates.
MTS | Contains information about what Visual Studio Analyzer can tell you about MTS use within your application, as well as a list of the Visual Studio Analyzer events that MTS generates.
ODBC Driver Manager | Contains information about what Visual Studio Analyzer can tell you about ODBC Driver Manager use within your application, as well as a list of the Visual Studio Analyzer events that ODBC Driver Manager generates.
SQL OLE DB Provider | Contains information about what Visual Studio Analyzer can tell you about SQL OLE DB Provider use within your application, as well as a list of the Visual Studio Analyzer events that the SQL OLE DB Provider generates.
VBScript | Contains information about what Visual Studio Analyzer can tell you about Visual Basic Script use within your application, as well as a list of the Visual Studio Analyzer events that the VBScript engine generates.
Visual Studio Analyzer User Component | Contains information about the Visual Studio Analyzer user component, a preregistered component you can use to generate system-defined events.


ADO Events for Visual Studio Analyzer

ADO version 2.0 is capable of generating Visual Studio Analyzer events. You can use these events to trace ADO interactions in your distributed applications.

Other Microsoft-supplied technologies are also capable of generating Visual Studio Analyzer events; see Microsoft Components That Generate Visual Studio Analyzer Events for a complete list.

Visual Studio Analyzer Events Generated by ADO

Event | Event description | Event data
ConnectionClose | Indicates that ADO is disconnecting from an OLE DB data source. | None.
ConnectionOpen | Indicates that ADO is connecting to an OLE DB data source. | The connection string used to connect to the data source, if the client provides it.
Find | Indicates that an ADO client has called the ADO Recordset.Find function. | Criteria for the Find operation; records are matched against this criteria.
GetRows | Indicates that an ADO client has called the ADO Recordset.GetRows function. | Number of rows being fetched.
QueryResult | Indicates that the database has returned a resultset in response to a query. | None.
QuerySend | Indicates that ADO is executing a command. This event can be triggered by the following functions: Connection.Execute Command.Execute Connection.stored procedure name Recordset.Open | The SQL statements that comprise the query.
RecordsetOpen | Indicates that ADO is opening a recordset on a remote server. Applies to three-tier scenarios only. | The source (typically the row-returning command text) with which the recordset is opened.
Sort | Indicates that ADO is prepared to filter or sort the data. | Sort or filter criteria being applied to the recordset data.
Transaction Rollback | Indicates that ADO is aborting the current local transaction. | Returns true or false. If true, the abort is retaining, meaning that another transaction will be started right after this one aborts. If false, the abort is not retaining.
TransactionCommit | Indicates that ADO is committing a local transaction on the OLE DB provider. | Returns true or false. If true, the commit is retaining, meaning that another transaction will be started right after this one commits. If false, the commit is not retaining.
TransactionStart | Indicates that ADO is beginning a local transaction on the OLE DB provider. | Isolation level at which ADO is starting the transaction. The isolation level indicates which level of changes made by other transactions can be seen.
UpdateBatch | Indicates that ADO is sending an update batch to the provider. Applies to three-tier scenarios only. | The name of the remote server, if any, to which ADO is sending the updates.


COM Transaction Integrator (COMTI) Events for Visual Studio Analyzer

COM Transaction Integrator (COMTI) version 1.0, a feature of Microsoft® SNA Server 4.0, is capable of generating Visual Studio Analyzer events. You can use these events to determine when and where a COM request has been forwarded to the mainframe for processing. Although COMTI components look like regular COM components, COMTI events indicate when the actual request has been sent to a mainframe CICS or Information Management System (IMS) program for processing and will indicate when that request comes back to the Microsoft® Windows NT® Server. If the return event does not occur, it indicates a problem on the remote mainframe.

Other Microsoft-supplied technologies are also capable of generating Visual Studio Analyzer events; see Microsoft Components That Generate Visual Studio Analyzer Events for a complete list.

Visual Studio Analyzer Events Generated by COMTI

Event | Event description | Event data
Call | Indicates that a COMTI method has been sent to the host. | Sequence number to correlate this Visual Studio Analyzer event with a COMTI invocation. COMTI Remote Environment name.
Return | Indicates that the reply to a COMTI method has been received from the host with no errors. | Sequence number to correlate this Visual Studio Analyzer event with a COMTI invocation. COMTI Remote Environment name.
ReturnException | Indicates that an error occurred in receiving the reply to a COMTI method. | Sequence number to correlate this Visual Studio Analyzer event with a COMTI invocation. COMTI Remote Environment name.


COM Events for Visual Studio Analyzer

The Component Object Model (COM) is capable of generating Visual Studio Analyzer events. You can use these events to trace how COM executes within your applications. You can see the following occurrences.

  • Creation and release of COM objects.

  • Communication between client and server (marshaling).

  • Calling, execution, and return of COM methods.

Other Microsoft-supplied technologies are also capable of generating Visual Studio Analyzer events; see Microsoft Components That Generate Visual Studio Analyzer Events for a complete list.

Note On Windows 95 machines, only processes started after the Visual Studio Analyzer server starts will report COM events. This means that you might need to add the Visual Studio Analyzer Server program, vales.exe, to your startup group. vales.exe starts the Visual Studio Analyzer server. You can find vales.exe in Program Files\Microsoft Visual Studio\Common\ide\ide98.

Visual Studio Analyzer Events Generated by COM

Event | Event description | Event data
COM Class Registration | Indicates that a COM component registered itself. COM generates this event when a COM object is created. Under normal circumstances, you can match this event with a ClassRevocation event to confirm that the COM object was created and released without errors. | Handle to the source component, in the form of a class identifier (CLSID). Correlation ID, for use in matching with ClassRevocation events. Default Visual Studio Analyzer values for the source component.
COM Class Revokation | Indicates that a COM component has been released. COM generates this event when processing is complete and the object is no longer needed. Under normal circumstances, you can match this event with a ClassRegistration event to confirm that the COM object was created and released without errors. | Handle to the source component, in the form of a class identifier (CLSID). Correlation ID, for use in matching with ClassRegistration events. Default Visual Studio Analyzer values for the source component.
COM Client Call | Indicates that a COM object has called an interface method. You can match this event with a Return event to confirm that the method received the call and returned a value. The timestamps on the Call and Return events tell you how long it took for the call to execute, including network travel time. You can also examine the values for the Enter and Leave events, which can tell you how long it took for the call to execute, without including the time it took for the call to arrive or the time it took for the results to return. | Handle to the target component, in the form of an interface pointer identifier (IPID). Apartment ID, which helps to uniquely identify the object that called the interface method. Correlation ID, for use in matching with ClientReturn events. ID of the interface being called. Number of the method being called. Default Visual Studio Analyzer values for the source component.
COM Client Return | Indicates that an interface method returned the results of a call to the object that called it. You can match this event with a Call event to confirm that the method received the call and returned a value. The timestamps on the Call and Return events tell you how long it took for the call to execute, including network travel time. You can also examine the values for the Enter and Leave events, which can tell you how long it took for the call to execute, without including the time it took for the call to arrive or the time it took for the results to return. | Handle to the target component, in the form of an interface pointer identifier (IPID). Apartment ID, which helps to uniquely identify the object that called the interface method. Correlation ID, for use in matching with ClientCall events. ID of the interface being called. Number of the method being called. Default Visual Studio Analyzer values for the source component.
COM Log Session | Indicates that COM is present and ready to start logging events for a particular session. | None.
COM Stub Enter | Indicates that an interface method received a call and started processing. You can match this event with the StubLeave and StubException events, which tell you whether the method completed without errors. You can also compare the timestamps on the StubEnter and StubLeave events to determine how long the method took to complete its processing. | Handle to the target component, in the form of an interface pointer identifier (IPID). Apartment ID, which helps to uniquely identify the object doing the processing. Correlation ID, for use in matching with StubLeave and StubException events. ID of the interface being called. Number of the method being called. Default Visual Studio Analyzer values for the target component.
COM Stub Leave | Indicates that an interface method completed processing. You can match this event with the StubEnter event to determine how long the processing took to complete. | Handle to the target component, in the form of an interface pointer identifier (IPID). Apartment ID, which helps to uniquely identify the object doing the processing. Correlation ID, for use in matching with StubEnter events. ID of the interface being called. Number of the method being called. Default Visual Studio Analyzer values for the target component.
COM Stub Exception | Indicates that an interface method encountered an error during processing. You can match this event with a StubEnter event. | Handle to the target component, in the form of an interface pointer identifier (IPID). Apartment ID, which helps to uniquely identify the object doing the processing. Correlation ID, for use in matching with StubEnter events. ID of the interface being called. Number of the method being called. Win32 exception code. Default Visual Studio Analyzer values for the target component.
COM Marshall | Indicates that the server created a stub to handle communication from a proxy on the client. You can match this event with an Unmarshal event to confirm whether client (proxy) and stub (server) communication was established. | Handle to the source component, in the form of an interface pointer identifier (IPID). Apartment ID, which helps to uniquely identify the server object. Correlation ID, for use in matching Unmarshal events. ID of the interface being called. Default Visual Studio Analyzer values for the target component.
COM Disconnect Marshall | Indicates that the server released a stub, because communication with a proxy is no longer necessary. You can match this event with a DisconnectUnmarshal event to determine whether the client released the proxy. | Correlation ID, for use in matching DisconnectUnmarshal events. Default Visual Studio Analyzer values for the target component.
COM Unmarshall | Indicates that the client created a proxy to handle communication from a stub on the server. You can match this event with a Marshal event to confirm whether client (proxy) and stub (server) communication was established. | Handle to the source component, in the form of an interface pointer identifier (IPID). Apartment ID, which helps to uniquely identify the client object. Correlation ID, for use in matching Marshal events. ID of the interface being called. Default Visual Studio Analyzer values for the source component.
COM Disconnect Unmarshall | Indicates that the client released a proxy because communication with a stub on the server is no longer necessary. You can match this event with a DisconnectMarshal event to determine whether the server has released the stub. | Correlation ID, for use in matching DisconnectMarshal events.


IIS Events for Visual Studio Analyzer

Internet Information Server (IIS) versions 3 and 4 are capable of generating Visual Studio Analyzer events. You can use these events to trace requests for Web-based applications and to correlate HTTP Get and Post calls.

Other Microsoft-supplied technologies are also capable of generating Visual Studio Analyzer events; see Microsoft Components That Generate Visual Studio Analyzer Events for a complete list.

You must configure IIS before you can view Visual Studio Analyzer events from it. How you configure IIS depends on the release you have. If you have a release of IIS prior to IIS 4, follow the procedure in "To configure releases of IIS prior to version 4." If you have IIS 4, follow the procedure in "To configure IIS version 4."

To configure releases of IIS prior to version 4

  1. Run Regedit.

  2. Select the HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W3Svc\Parameters\Filter Dlls entry.

  3. Double-click the Filter Dlls entry. The Edit Strings dialog box appears.

  4. In the Value data box, add the full path and file name of the Visual Studio Analyzer filter DLL to the beginning of the entry. Separate it from the other paths with a comma. If you accepted the setup defaults, the path is:

    Program Files\Microsoft Visual Studio\Common\Tools\VS-98Ent\Vanalyzr\Vahtp.dll

  5. Reboot your machine.

To configure IIS version 4

  1. Run the Internet Service Manager, which starts the Microsoft Management Console.

  2. Select the Web you want to enable.

  3. Right-click to display the shortcut menu, and then click Properties.

  4. Click the ISAPI Filters tab.

  5. Click Add. The Filter Properties dialog box appears.

  6. In the Filter Name box, type a filter name; for example, Visual Studio Analyzer.

  7. In the Executable box, type the full path and file name for the Visual Studio Analyzer filter DLL. If you accepted the setup defaults, the path is:

    Program Files\Microsoft Visual Studio\Common\Tools\VS-98Ent\Vanalyzr\Vahtp.dll

Visual Studio Analyzer Events Generated by IIS

Event | Description
HTTP Get | Indicates that an HTTP Get call occurred.
HTTP Post | Indicates that an HTTP Post call occurred.


JScript Engine Events for Visual Studio Analyzer

The JScript Engine version 3.0 is capable of generating Visual Studio Analyzer events. You can use these events to trace JScript code within your application.

Other Microsoft-supplied technologies are also capable of generating Visual Studio Analyzer events; see Microsoft Components That Generate Visual Studio Analyzer Events for a complete list.

Visual Studio Analyzer Events Generated by the JScript Engine

Event | Event description | Event data
ScriptAdviseCallInStart ScriptAdviseCallInStop | This event set marks the amount of time the script engine spent executing an external call to an event handler defined in the script; that is, a call into the engine through a previously set up IConnectionPoint::Advise method. | None.
ScriptDispatchCallInStart ScriptDispatchCallInStop | This event set marks the amount of time the script engine spent executing an external call to an event handler defined in the script; that is, a call into the engine through IDispatch. | None.
ScriptGlobalStart ScriptGlobalStop | This event set marks the amount of time spent by the script engine executing the script's global code. Global code is defined as those statements of code in the script that are not contained within a function or subroutine declaration, although the code can contain calls to declared functions and subroutines. Global code is executed only once, upon the initial load of the script into the script engine. | None.


MTS Events for Visual Studio Analyzer

Microsoft Transaction Server (MTS) version 1.5 is capable of generating Visual Studio Analyzer events. You can use these events to trace transaction interactions within your application.

Other Microsoft-supplied technologies are also capable of generating Visual Studio Analyzer events; see Microsoft Components That Generate Visual Studio Analyzer Events for a complete list.

Visual Studio Analyzer Events Generated by MTS

Event | Event description | Event data
Begin Session | Indicates that MTS is present and ready to start generating events for a particular session. | Session name, where the name is the current process ID.
MTS Disable Commit | Indicates that DisableCommit has been called on an object. | Source machine, process, thread, component, and session. Handle to the component in the form of the MTS object identity. Correlation ID.
MTS Enable Commit | Indicates that EnableCommit has been called on an object. | Source machine, process, thread, component, and session. Handle to the component in the form of the MTS object identity. Correlation ID.
MTS Set Complete | Indicates that SetComplete has been called on an object, and the object is now ready to be deactivated by MTS. | Source machine, process, thread, component, and session. Handle to the component in the form of the MTS object identity. Correlation ID.
MTS Transaction Aborted | Indicates that a transaction has aborted. | Source machine, process, thread, component, and session. Handle to the component in the form of the transaction GUID. Correlation ID.
MTS Transaction Prepared | Indicates that a transaction is preparing to commit, but has not actually committed yet. The MTS event system tracks only phase-one notifications of the two-phase commit protocol, so there is no notification for transaction commit. | Source machine, process, thread, component, and session. Handle to the component in the form of the transaction GUID. Correlation ID.
MTS Transaction Start | Indicates that a transactional component has been created. This event occurs only once, when the "root" object of the transaction is created. Objects that inherit transaction context from the root object do not generate this event. | Source machine, process, thread, component, and session. Handle to the component in the form of the transaction GUID. Correlation ID. Transaction stream ID.
Object Activate | Indicates that the object has been activated by MTS. This event occurs only if the object implements the IObjectControl interface. | Source machine, process, thread, component, and session. Handle to the component in the form of the MTS object identity. Correlation ID.
Object Create | Indicates that an object has been created. This event will be generated only for objects with context. This means that the component must be registered as an MTS component and the object must be created using the MTS CreateInstance method. | Source machine, process, thread, component, and session. Handle to the component in the form of the MTS object identity. Correlation ID.
Object Deactivate | Indicates that the object has been deactivated by MTS. This event occurs only if the object implements the IObjectControl interface. | Source machine, process, thread, component, and session. Handle to the component in the form of the MTS object identity. Correlation ID.
Object Release | Indicates that an object has been released by MTS. | Source machine, process, thread, component, and session. Handle to the component in the form of the MTS object identity. Correlation ID.
Package Activation | Indicates that an MTS package has been activated. | Source machine, process, thread, component, and session. Handle to the component in the form of the MTS package globally unique identifier (GUID). Correlation ID, for matching with Package Shutdown events.
Package Shutdown | Indicates that an MTS package has shut down. | Source machine, process, thread, component, and session. Handle to the component in the form of the MTS package globally unique identifier (GUID). Correlation ID, for matching with Package Activation events.
Resource Allocate | Indicates that a new resource managed by a resource dispenser has been assigned from the pool. | Source machine, process, thread, component, and session. Handle to the component in the form of the MTS resource ID. Correlation ID. Resource type.
Resource Create | Indicates that a new resource managed by a resource dispenser has been created. | Source machine, process, thread, component, and session. Handle to the component in the form of the MTS resource ID. Correlation ID. Resource type.
Resource Destroy | Indicates that a resource managed by a resource dispenser has been destroyed. | Source machine, process, thread, component, and session. Handle to the component in the form of the MTS resource ID. Correlation ID. Resource type.
Resource Recycle | Indicates that a resource managed by a resource dispenser has been placed into the pool. | Source machine, process, thread, component, and session. Handle to the component in the form of the MTS resource ID. Correlation ID. Resource type.


ODBC Driver Manager Events for Visual Studio Analyzer

The ODBC Driver Manager is capable of generating Visual Studio Analyzer events. You can use these events to trace Open Database Connectivity (ODBC) activity within your application.

Other Microsoft-supplied technologies are also capable of generating Visual Studio Analyzer events; see Microsoft Components That Generate Visual Studio Analyzer Events for a complete list.

You must configure ODBC to generate Visual Studio Analyzer events before you can view any of the events it generates.

To configure ODBC to generate Visual Studio Analyzer events

  1. Click Start.

  2. Point to Settings, and then click Control Panel.

  3. Start the ODBC applet.

  4. Click the Tracing tab.

  5. Click Start Visual Studio Analyzer Tracing.

  6. Click OK.

Visual Studio Analyzer Events Generated by the ODBC Driver Manager

Event | Description
Call | Generated on every ODBC API entry.
ReturnException | Generated on every ODBC API return if the return code is SQL_ERROR.
ReturnNormal | Generated on every ODBC API return if the return code is not SQL_ERROR.
Connection Start | Indicates that a connection started; generated when the ODBC Driver Manager calls the driver's connection APIs.
Connection Complete | Indicates that a connection completed; generated when the driver's connection APIs return to the ODBC Driver Manager.
Disconnect Start | Generated when the ODBC Driver Manager calls the driver's SQLDisconnect function.
Disconnect Complete | Generated when the driver's SQLDisconnect function returns to the ODBC Driver Manager.
QuerySend | Generated when the ODBC Driver Manager calls the driver's SQLPrepare, SQLExecute, SQLExecDirect, and catalog functions such as SQLTables and SQLColumns.
QueryResult | Generated when the driver returns a resultset to the ODBC Driver Manager for functions involving queries.
TransactionStart | Generated when an application sets the value of SQL_ATTR_AUTOCOMMIT to SQL_AUTOCOMMIT_OFF, or after an application successfully calls SQLEndTran.
TransactionCommit | Generated when an application calls SQLEndTran to commit a local transaction.
TransactionRollback | Generated when an application calls SQLEndTran to roll back a local transaction.
JoinDTC | Generated when an application joins the Distributed Transaction Coordinator (DTC).
LeaveDTC | Generated when an application leaves the Distributed Transaction Coordinator (DTC).


SQL OLEDB Provider Events for Visual Studio Analyzer

The SQL OLE DB Provider version 7.0 is capable of generating Visual Studio Analyzer events. You can use these events to:

  • Capture the interactions between the SQL OLE DB Provider and Microsoft® SQL Server™.

  • Isolate the problems of failing applications by viewing event records.

  • Isolate potential performance hotspots and tune performance of the SQL OLE DB Provider.

Other Microsoft-supplied technologies are also capable of generating Visual Studio Analyzer events; see Microsoft Components That Generate Visual Studio Analyzer Events for a complete list.

Visual Studio Analyzer Events Generated by the SQL OLE DB Provider

Event | Event description | Event data
ComponentStart | Indicates the start of a component that is a source of Visual Studio Analyzer events. You can match this event with a ComponentStop event to measure the time a component was active or to make sure that components start and stop as expected. | Unique identifier for the component in the form of a GUID.
ComponentStop | Indicates the stop of a component that is a source of Visual Studio Analyzer events. You can match this event with a ComponentStart event to measure the time a component was active or to make sure that components start and stop as expected. | Unique identifier for the component in the form of a GUID.
TransactionStart Indicates the start of a transaction. You can match this event with a TransactionCommit or TransactionRollback event to measure how long the transaction took to complete or the success or failure of the transaction. Source machine, process, and thread to uniquely identify the machine where the transaction is taking place.

Unique identifier for the event in the form of a GUID.

Correlation ID, for use in matching with TransactionCommit or TransactionRollback events.

IsolationLevel, for indicating which level of changes made by other transactions can be seen.
TransactionCommit Indicates the recording of a transaction. A transaction is recorded, or committed, only if all parts of it complete successfully. You can match this event with a TransactionStart event to measure how long the transaction took. Source machine, process, and thread to uniquely identify the machine where the transaction is taking place.

Unique identifier for the event in the form of a GUID.

Correlation ID, for use in matching with TransactionStart events.

Retain value, for indicating whether a new transaction will be started as soon as this transaction is committed.

Return code, the return value for the Commit event. The return value can be any of the following:

SQL_SUCCESS
SQL_SUCCESS_WITH_INFO
SQL_STILL_EXECUTING
SQL_NEED_DATA
SQL_NO_DATA_FOUND
SQL_ERROR
SQL_INVALID_HANDLE
TransactionRollback Indicates the rolling back of a transaction. A transaction is rolled back (undone) if one or more of its parts fails. You can match this event with a TransactionStart event to discover which transaction is failing. Source machine, process, and thread to uniquely identify the machine where the transaction failed.

Unique identifier for the event in the form of a GUID

Correlation ID, for use in matching with TransactionStart events.

Retain value, for indicating whether a new transaction will be started as soon as this transaction is undone.

Return code, the return value for the Rollback event. The return value can be any of the following:

SQL_SUCCESS
SQL_SUCCESS_WITH_INFO
SQL_STILL_EXECUTING
SQL_NEED_DATA
SQL_NO_DATA_FOUND
SQL_ERROR
SQL_INVALID_HANDLE
QuerySend Indicates that a component sent a query to the database. You can match this event with the QueryResult event to see how long the query took to process and to ensure the query completed without errors. Source machine, process, and thread to uniquely identify the machine that sent the query.

Unique identifier for the event, in the form of a GUID.

Correlation ID, for use in matching with QueryResult events.

SQLText, the SQL statements that comprise the query.
QueryResult Indicates that the database returned a resultset in response to a query. You can match this event with the QuerySend event to see how long the query took to process and to ensure the query completed without errors. Source machine, process, and thread IDs, used to uniquely identify the machine that sent the query.

Unique identifier for the event, in the form of a GUID.

Correlation ID, for use in matching with QuerySend events.

SQLText, the SQL statements that comprise the query.

Return code, the return value for the Query event. The return value can be any of the following:

SQL_SUCCESS
SQL_SUCCESS_WITH_INFO
SQL_STILL_EXECUTING
SQL_NEED_DATA
SQL_NO_DATA_FOUND
SQL_ERROR
SQL_INVALID_HANDLE
Connection Start Indicates that the SQL OLE DB Provider requested a connection to a SQL Server. Machine, process, and thread IDs, used to uniquely identify the machine where the connection request was made.

Unique identifier for the event in the form of a GUID.

Correlation ID, for use in matching with ConnectionComplete events.

SQLServerDatabaseUserID, which uniquely identifies the SQL Server name, the name of the database to which to connect, and the user ID with which to log in.
Connection Complete Generated when SQL Server replies to the connection request of the SQL OLE DB Provider. Source machine, process, and thread IDs, used to uniquely identify the machine that acknowledged the connection request.

Unique identifier for the event in the form of a GUID.

Correlation ID, for use in matching with ConnectionStart events.

SQLServerDatabaseUserID, which uniquely identifies the SQL Server name, the name of the database to which to connect, and the user ID with which to log in.

Return code, the return value for the Connection event. The return value can be any of the following:

SQL_SUCCESS
SQL_SUCCESS_WITH_INFO
SQL_STILL_EXECUTING
SQL_NEED_DATA
SQL_NO_DATA_FOUND
SQL_ERROR
SQL_INVALID_HANDLE
Disconnect Start Generated when the SQL OLE DB Provider requests to disconnect from the SQL Server. Source machine, process, and thread IDs, for uniquely identifying the machine that made the disconnect request.

Unique identifier for the event in the form of a GUID.

Correlation ID, for use in matching with DisconnectComplete events.

SQLServerDatabaseUserID, which uniquely identifies the SQL Server name, the name of the database to which to connect, and the user ID with which to log in.
Disconnect Complete Generated when SQL Server replies to a disconnect request from the SQL OLE DB Provider. Source machine, process, and thread IDs, to uniquely identify the machine that replied to the disconnect request.

Unique identifier for the event, in the form of a GUID.

Correlation ID, for use in matching DisconnectStart events.

SQLServerDatabaseUserId, which uniquely identifies the SQL Server name, the name of the database to which to connect, and the user ID with which to log in.

Return code, the return value for the Disconnect event. The return value can be one of the following:

SQL_SUCCESS
SQL_SUCCESS_WITH_INFO
SQL_STILL_EXECUTING
SQL_NEED_DATA
SQL_NO_DATA_FOUND
SQL_ERROR
SQL_INVALID_HANDLE
JoinDTC Generated when the SQL OLE DB Provider joins the Distributed Transaction Coordinator (DTC). Source machine, process, and thread IDs, to uniquely identify the machine that joins DTC.

Unique identifier for the event, in the form of a GUID.

Correlation ID, for use in matching with LeaveDTC events.

Return code, the return value for the JoinDTC event. The return value can be one of the following:

SQL_SUCCESS
SQL_SUCCESS_WITH_INFO
SQL_STILL_EXECUTING
SQL_NEED_DATA
SQL_NO_DATA_FOUND
SQL_ERROR
SQL_INVALID_HANDLE
LeaveDTC Generated when the SQL OLE DB Provider leaves the Distributed Transaction Coordinator (DTC). Source machine, process, and thread IDs, for uniquely identifying the machine that leaves DTC.

Unique identifier for this event in the form of a GUID.

Correlation ID, for use in matching JoinDTC events.

Return code, the return value for the LeaveDTC event. The return value can be one of the following:

SQL_SUCCESS
SQL_SUCCESS_WITH_INFO
SQL_STILL_EXECUTING
SQL_NEED_DATA
SQL_NO_DATA_FOUND
SQL_ERROR
SQL_INVALID_HANDLE


VBScript Engine Events for Visual Studio Analyzer

The VBScript Engine version 3.0 is capable of generating Visual Studio Analyzer events. You can use these events to trace script code within your application.

Other Microsoft-supplied technologies are also capable of generating Visual Studio Analyzer events; see Microsoft Components That Generate Visual Studio Analyzer Events for a complete list.

Visual Studio Analyzer Events Generated by the VBScript Engine

Event | Event description | Event data
ScriptAdviseCallInStart ScriptAdviseCallInStop | This event set marks the amount of time the script engine spent executing an external call to an event handler defined in the script; that is, a call into the engine through a previously set up IConnectionPoint::Advise method. | None.
ScriptDispatchCallInStart ScriptDispatchCallInStop | This event set marks the amount of time the script engine spent executing an external call to an event handler defined in the script; that is, a call into the engine through IDispatch. | None.
ScriptGlobalStart ScriptGlobalStop | This event set marks the amount of time spent by the script engine executing the script's global code. Global code is defined as those statements of code in the script that are not contained within a function or subroutine declaration, although the code can contain calls to declared functions and subroutines. Global code is executed only once, upon the initial load of the script into the script engine. | None.


Visual Studio Analyzer User Component

Visual Studio Analyzer includes a preregistered user component called DEBUG_EVENT_SOURCE_USER. If you want to trace some code quickly, without a lot of overhead, such as in a simple console application, you can generate system-defined events from your code using this component.


Visual Studio Analyzer Common Tasks

This section contains step-by-step instructions for the most common Microsoft® Visual Studio™ Analyzer tasks. These tasks include:

Adding an Event Log

Adding and Removing Line Graphs in the Chart View

Adding or Removing Columns in the Event List View

Combining Visual Studio Analyzer Views

Configuring Security for Visual Studio Analyzer on Windows 95

Configuring Security for Visual Studio Analyzer on Windows NT

Connecting to Machines for Monitoring with Visual Studio Analyzer

Creating and Opening Visual Studio Analyzer Projects

Creating and Refining Visual Studio Analyzer Filters

Exporting and Importing Visual Studio Analyzer Data

Installing the Visual Studio Analyzer Server Components

Opening Visual Studio Analyzer Views

Playing Back an Event Log

Starting and Stopping Event Recording

Starting the Visual Studio Analyzer RPC Listener Service

Starting the Visual Studio Analyzer Server on Windows 95


Adding an Event Log

You must add an event log to contain the events that Visual Studio Analyzer collects from your application. You can do any of the following actions with an event log:

  • Start recording. You must explicitly start recording with an event log or no events are collected when you run your application.

  • Pause recording.

  • Resume recording.

  • Stop recording. Once you stop recording into an event log, the event log is closed and you must create another event log if you want to record your application again.

You view the event log with Visual Studio Analyzer — either while recording or after recording has been paused or stopped — to understand your application's scope, analyze performance, or isolate faults.

To add an event log

  1. In the Project Explorer, select the Event Logs node.

  2. Right-click to display the shortcut menu, and then click Add Event Log.

    The new event log is added to the Project Explorer under Event Logs.

    You can also click Add Item on the shortcut menu. The difference between the two menu items is that Add Event Log adds an event log with a default name in a default location. With Add Item, you can specify the path and file name for the event log you add.

    Warning Event logs are large files that can grow very quickly. Make sure there is enough disk space for your event log.


Adding and Removing Line Graphs in the Chart View

You can overlay Performance Monitor information (from Microsoft® Windows NT™) or custom dynamic events you have created yourself on the Gantt chart in the Chart view. Overlaying this information makes it easier to spot correlations between your application activity and your system's overall health. Performance Monitor information is shown as a line graph. In order to overlay Performance Monitor information, you must have collected data from one or more Performance Monitor counters during a previous run of your application. To collect data from a Performance Monitor counter, you specify the counters in which you are interested in your Visual Studio Analyzer filter; counters are listed under "Measured Events."

To add a line graph

  1. In the Project Explorer, right-click an event log that contains Performance Monitor data.

  2. Click Chart to display the Chart view.

  3. Click Analyzer, then click Add Graph. The Add Graph dialog box appears.

  4. Select the machine and components reflected in the event log, and then select one of the Performance Monitor counters from which you collected data. Click OK.

To remove a line graph

  1. Select the line graph you want to remove.

  2. Right-click on the legend to display the shortcut menu, and then click Remove Graph.


Adding or Removing Columns in the Event List View

You can customize the columns that are displayed in the Event List view. Each column contains a piece of information about an event, such as the time the event occurred, the event name, the machine where the event was generated, and so on.

To add or remove columns in the Event List view

  1. Right-click in the Event List view to display the shortcut menu, and then click Columns.

    • To add one column, double-click the column name in the Available Columns box. You can add multiple columns by selecting all the columns you want in the Available Columns box and clicking Add.

    • To remove one column, double-click the column name in the Selected Columns box. You can remove multiple columns by selecting all the columns you do not want in the Selected Columns box and clicking Remove.

    • To reset the columns in the view to the default, click Reset.

    • To add all the available columns to the Event List view, click Add All.

    • To remove all the columns from the Event List view, click Remove All.

    • To reorder the columns, select the column you want to move in the Selected Columns box and click the Move Up and Move Down buttons.
  2. When you are satisfied with the arrangement of the columns, click OK.


Combining Visual Studio Analyzer Views

You can open more than one Visual Studio Analyzer view on your desktop at the same time. Views are synchronized to each other by default. If you select an event in the Event List view, all other open views will synchronize to that same event. If you select a time range in the Chart view, all other open views will synchronize to that time range. You can disable the synchronization.

You can also open multiple views on multiple Visual Studio Analyzer event logs. Only one event log can be recording at a time, but you can certainly look at more than one event log at the same time.

To combine Visual Studio Analyzer views on the same event log

  1. In the Project Explorer, select the event log you want to view.

  2. Click the View menu, click Analyzer, and then click the view you want, or right-click on the event log.

  3. Repeat step 2 to open another view on the event log.

  4. Use the Cascade and Tile options on the Window menu to arrange the views, or use the Window menu to convert document windows to docking windows. See Window Management for information on window types, docking windows, and other window management issues.

To open Visual Studio Analyzer views on different event logs

  1. In the Project Explorer, select the first event log you want to view.

  2. Click the View menu, click Analyzer, and then click the view you want.

  3. In the Project Explorer, select the next event log you want to view.

  4. Repeat step 2 to open the view you want on that log.

  5. Use the Cascade and Tile options on the Window menu to arrange the views.

To disable synchronization for a view

  1. Right-click to display the shortcut menu inside the view for which you want to disable synchronization.

  2. Click AutoSelect.

    You can also use the AutoSelect button on the Analyzer Windows toolbar.

    Note To re-enable synchronization, click AutoSelect on the view's shortcut menu again.


Configuring Security for Visual Studio Analyzer on Windows 95

Visual Studio Analyzer ships with security open. You can increase the security settings to reflect your site's needs. To increase the security settings, you need to complete the following steps:

  1. Restrict access to the Visual Studio Analyzer server to specific users.

  2. Restrict access to the Visual Studio Analyzer client.

  3. Edit the registry on the Visual Studio Analyzer server to enable security checking.

  4. Edit the registry on the Visual Studio Analyzer client to enable security checking.

These steps are described in the following procedures.

Note: You need to configure security on a per-machine basis for any machine on which you are running the Visual Studio Analyzer server or client.

The procedures for restricting access all use DCOMCNFG, a configuration utility intended for configuring DCOM-specific settings in the registry. DCOMCNFG is shipped with the Windows 95 DCOM Refresh but is not added to the Start menu or to any groups. You must start DCOMCNFG using the Run command on the Start menu.

For more information on using DCOMCNFG to configure access and launch permissions, search for "DCOMCNFG" in MSDN Library Visual Studio 6.0.

To restrict access to the Visual Studio Analyzer server to specific users

  1. Start DCOMCNFG, if necessary.

  2. On the Applications tab, select MSVSA Local Event Concentrator Class (scroll down if necessary).

  3. Click Properties.

  4. Click the Security tab.

  5. Select Use custom access permissions and click Edit.

    The Access Permissions dialog box appears. This dialog box lists the known users who currently have (or are denied) access to the machine. Click Add to add users to the list; click Remove to remove users.

  6. Click Add to add the specific users to whom you want to allow access to the Visual Studio Analyzer server on this machine.

    The Add Access Permissions dialog box appears.

  7. Select a user ID in the Name box, then click Grant Access to allow access or Deny Access to deny access to that user. The user you selected is added to the corresponding list. When you are satisfied with the access list, click OK.

  8. Click OK.

To restrict access to the Visual Studio Analyzer client

You need to perform this procedure on any machine where you are running the Visual Studio Analyzer client. This procedure ensures that the machine will connect to legitimate Visual Studio Analyzer servers only.

  1. Start DCOMCNFG, if necessary.

  2. On the Applications tab, select Microsoft Development Environment (scroll down if necessary).

  3. Click Properties.

  4. Click the Security tab.

  5. Select Use custom access permissions and click Edit.

  6. Make sure that the user ID you specified for the Visual Studio Analyzer server to run under is included in the list of users. If it is not, click Add to add it, and then add any other user IDs for machines to which you plan to connect.

  7. Click OK, then click OK twice more to stop DCOMCNFG.

To edit the registry to enable security checking on the Visual Studio Analyzer server

  1. Navigate to HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\6.0.

  2. Click Edit, point to New, and click Key.

  3. Replace the supplied name of the key with Analyzer and press Enter.

  4. Select Analyzer.

  5. Click Edit, point to New, and click Key.

  6. Replace the supplied name of the key with Security and press Enter.

  7. Click Edit, point to New, and click DWORD Value.

  8. Replace the supplied name of the value with Enable.

  9. Double-click Enable to display the Edit DWORD Value dialog box.

  10. Type 1 in the Value data box and click OK.

To edit the registry to enable security checking on the Visual Studio Analyzer client

  1. Start regedit.

  2. Navigate to HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\6.0 and select 6.0.

  3. Click Edit, point to New, and click DWORD Value.

  4. Replace the supplied name of the value with EnableSecurity and press Enter.

  5. Double-click EnableSecurity to display the Edit DWORD Value dialog box.

  6. Type 1 in the Value data box and click OK.

Connecting to Microsoft® Windows® 95 Machines Running Visual Studio Analyzer

If you want to connect to a remote Microsoft® Windows® 95 machine running Visual Studio Analyzer, you must run DCOMCNFG on the remote machine to change your DCOM settings to allow remote connections. Before you can run DCOMCNFG on any machine, you must set the machine's access control to user level (DCOMCNFG requires user-level access control in order to run). You should need to run DCOMCNFG one time only to change these settings.

Important Changing access control to user level on a Windows 95 machine can have far-reaching consequences. For example, it will reset all of your current share permissions and you will need to restore those permissions manually. However, you cannot run Visual Studio Analyzer on a remote Windows 95 machine without changing access control to user level. Make sure you check with your system administrator before you change access control.

To set access control to user level

  1. Click Start, point to Settings, and then click Control Panel.

  2. Double-click the Network icon.

  3. Click the Access Control tab.

  4. Click User-level access control and enter your domain name in the box beneath.

  5. Click OK.

To allow remote connections

  1. Click Start, then click Run.

  2. In the Open box, type Dcomcnfg and click OK.

  3. Click the Default Security tab.

  4. Select the Enable Remote Connection check box.

  5. Click OK.

To allow access to your Windows 95 machine, you must also run the Visual Studio Analyzer Server each time you want to allow remote connections. See Starting the Visual Studio Analyzer Server on Windows 95 for steps on how to start the Visual Studio Analyzer Server.

Visual Studio Analyzer ships with security open. In this way, you can adjust the security settings to reflect your site's needs.

On Windows 95, you might find a situation where no components that generate Visual Studio Analyzer events are listed for the machine to which you are connected, even though those components exist and are registered. To work around this problem, you need to install the Remote Registry Service on that machine. To use the Remote Registry Service, you must be using user-level security and you must have the Remote Administration option enabled.

To enable the Remote Administration option

  1. Click Start, point to Settings, and then click Control Panel.

  2. Double-click the Network icon.

  3. Click File And Print Sharing.

  4. Select both check boxes on the File and Print Sharing dialog box, then click OK.

  5. Double-click the Passwords icon.

  6. Click the Remote Administration tab.

  7. Select the Enable remote administration of this server check box.

  8. Set a password for Remote Administration, then click OK.

    Note If you are using user-level security, you do not receive a password dialog box. Instead, add users to the list by clicking Add.

To install the Remote Registry Service

  1. Click Start, point to Settings, and then click Control Panel.

  2. Double-click the Network icon.

  3. Click Add, click Service, click Add, and then click Have Disk.

  4. In the Copy Manufacturer's Files From box, type the path to the Admin\Nettools\RemoteReg folder on your Windows 95 CD-ROM, then click OK.

  5. When the Microsoft Remote Registry service has been added to the list of installed components, click OK. Restart your computer when you are prompted to do so.


Configuring Security for Visual Studio Analyzer on Windows NT

Visual Studio Analyzer ships with security open. You can increase the security settings to reflect your site's needs. To increase the security settings, you need to complete the following steps:

  1. Set the Visual Studio Analyzer server to run as a domain user.

  2. Restrict access to the Visual Studio Analyzer server to specific users.

  3. Restrict access to the Visual Studio Analyzer client.

  4. Edit the registry on the Visual Studio Analyzer server to enable security checking.

  5. Edit the registry on the Visual Studio Analyzer client to enable security checking.

These steps are described in the following procedures.

Note: You need to configure security on a per-machine basis for any machine on which you are running the Visual Studio Analyzer server or client.

Before You Begin

Before you begin configuring security, make sure you have a user account on your domain under which the Visual Studio Analyzer server can run. This user account can be your own user ID, a user ID shared by your group, or even a user ID you create specficially for Visual Studio Analyzer. In order to configure security, you will need to know the password for this user account as well as the user ID.

The procedure for setting the Visual Studio Analyzer server to run as a domain user and the procedures for restricting access all use DCOMCNFG, a configuration utility intended for configuring DCOM-specific settings in the registry. DCOMCNFG is shipped with Windows NT but is not added to the Start menu or to any groups. You must start DCOMCNFG using the Run command on the Start menu.

For more information on using DCOMCNFG to configure access and launch permissions, search for "DCOMCNFG" in MSDN Library Visual Studio 6.0.

To set the Visual Studio Analyzer server to run as a domain user

  1. Start DCOMCNFG.

  2. On the Applications tab, select MSVSA Local Event Concentrator Class (scroll down if necessary).

  3. Click Properties.

  4. Click the Identity tab.

  5. Select This user and complete the User, Password, and Confirm Password boxes. In the User box, specify the user ID for the account on your domain under which you want the Visual Studio Analyzer server to run. Use the form domain name\user ID.

  6. Click Apply.

To restrict access to the Visual Studio Analyzer server to specific users

  1. Start DCOMCNFG, if necessary.

  2. On the Applications tab, select MSVSA Local Event Concentrator Class (scroll down if necessary).

  3. Click Properties.

  4. Click the Security tab.

  5. Select Use custom access permissions and click Edit.

    The Registry Value Permissions dialog box appears. This dialog box lists the known users who currently have (or are denied) access to the machine.

  6. Add the specific users to whom you want to allow access to the Visual Studio Analyzer server on this machine, and remove any users to whom you want to deny access.
    • Click Add to add users, one at a time. Make sure you add the SYSTEM account as a user. This is required in order to connect to the machine. Make sure you also add the user ID under which the Visual Studio Analyzer Server is running. This is required in order to see measured events from this machine.

      To add users, you can either select a name from the Names box, or type a specific name (in the form domain name\user ID) in the Add Names box. Use the Type of Access box to allow or deny access. Click OK to add the user to the list.

    • Click Remove to remove users, one at a time. In the list, select the user you want to remove, then click Remove.
  7. When you are satisfied with the list of users in the Registry Value Permissions dialog box, click OK.

To restrict access to the Visual Studio Analyzer client

  1. Start DCOMCNFG, if necessary.

  2. On the Applications tab, select Microsoft Development Environment (scroll down if necessary).

  3. Click Properties.

  4. Click the Security tab.

  5. Select Use custom access permissions and click Edit.

  6. Make sure that the user ID you specified for the Visual Studio Analyzer server to run under is included in the list of users, as well as the SYSTEM account and any users you want to be able to run Visual Studio Analyzer. To add a user ID, click Add and then add the user ID. Repeat until all user IDs are added.

  7. Click OK, then click OK twice more to stop Dcomcnfg.exe.

To edit the registry to enable security checking on the Visual Studio Analyzer server

  1. Navigate to HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\6.0\Analyzer and select Analyzer.

  2. Click Edit, point to New, and click Key.

  3. Replace the supplied name of the key with Security and press Enter.

  4. Click Edit, point to New, and click DWORD Value.

  5. Replace the supplied name of the value with Enable.

  6. Double-click Enable to display the Edit DWORD Value dialog box.

  7. Type 1 in the Value data box and click OK.

To edit the registry to enable security checking on the Visual Studio Analyzer client

  1. Start regedit.

  2. Navigate to HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\6.0 and select the 6.0 key.

  3. Click Edit, point to New, and click DWORD Value.

  4. Replace the supplied name of the value with EnableSecurity and press Enter.

  5. Double-click EnableSecurity to display the Edit DWORD Value dialog box.

  6. Type 1 in the Value data box and click OK.

Troubleshooting Security Problems

If you are having problems seeing particular measured events in the Filter Editor, the user ID under which the Visual Studio Analyzer Server is running might not have the necessary permissions. These permissions vary depending on the type of measured event.


Connecting to Machines for Monitoring with Visual Studio Analyzer

You can identify the machines you want to monitor with Visual Studio Analyzer. References to these machines are saved as part of your Visual Studio Analyzer project. Make sure the Visual Studio Analyzer Server components are installed on any machine you plan to monitor. Installing the Visual Studio Analyzer Server components is part of the Visual Studio setup. On Windows 95 you need to start the server components manually on any remote machine from which you plan to collect data. See Starting the Visual Studio Analyzer Server on Windows 95 for instructions on how to start and stop the Visual Studio Analyzer Server components.

To add machines to a Visual Studio Analyzer project

  1. In the Project Explorer, select the Visual Studio Analyzer project.

  2. Right-click to display the shortcut menu, and then click Connect to Machine.

    You can also click the Connect to Machine button on the Visual Studio Analyzer toolbar.

  3. Type the name of the machine you want to connect to, or click Browse to navigate to a list of available machines and select the machine you want.

    Note You can type or omit the two backslashes (\\) from computer names. You can also use IP addresses (123.4.56.7) to refer to machines on your network if appropriate. However, you cannot select the My Computer node to refer to your local machine.

  4. Click Connect.


Creating and Opening Visual Studio Analyzer Projects

In order to start Visual Studio Analyzer, you must create or open a Visual Studio Analyzer project. A Visual Studio Analyzer project stores the filters and event logs associated with a particular Visual Studio Analyzer session.

The quickest way to create a new Visual Studio Analyzer project is to run the Visual Studio Analyzer Project Wizard. The Visual Studio Analyzer Project Wizard is a series of dialog boxes that prompt you for the information needed to create the project. Help is available for each dialog box.

To create a Visual Studio Analyzer project using the Visual Studio Analyzer Project Wizard

  1. Click the File menu, and then click New Project.

  2. Click Analyzer Wizard.

  3. In the Name box, type a name for your project.

  4. In the Location box, type a path for your project.

  5. Click Open.

  6. Complete the Wizard steps by choosing options that are appropriate for the kind of Visual Studio Analyzer project you are creating. You can move forward and backward through the steps of the Wizard and make changes to the options you select; the Wizard does not create any files until you click Finish. See Visual Studio Analyzer Project Wizard for detailed information about each of the Wizard's dialog boxes, as well as a summary of what files the Wizard creates.

To create a Visual Studio Analyzer project without using the Visual Studio Analyzer Project Wizard

  1. Click the File menu, and then click New Project.

  2. Click Analyzer Project.

  3. In the Name box, type a name for your project.

  4. In the Location box, type a path for your project.

  5. Click Open.

    The Project Explorer displays your project. Continue with the steps in the procedures from the following list (the Task List will show the steps you need to complete before you can use your project):

    • Selecting Machines to Monitor

    • Defining an Event Log

    • Creating and Refining Visual Studio Analyzer Filters

To open a Visual Studio Analyzer project

  1. Click the File menu, and then click Open Project.

  2. Navigate to the Visual Studio Analyzer project you want to open, select the project, and then click Open.

    Visual Studio Analyzer reconnects to the machines listed in the project and the Project Explorer displays your project.


Creating and Refining Visual Studio Analyzer Filters

With Visual Studio Analyzer filters, you can focus the data you use in your application analysis. Through filters, you determine which Visual Studio Analyzer events to collect and to include in an event log. You define a filter before you start collecting events. After you have collected events, you refine the filter to help you focus on the events that are most important to your analysis. You can have multiple filters to help you view the data in different ways.

To work with filters, you use the Filter Editor dialog box, which contains both a graphical and a textual interface. You can build most filters using the graphical interface. However, some complex filters, such as those that use comparison operators, cannot be represented using the graphical interface; you must build those filters using the textual interface, which you can access by clicking Edit Text. You can resize the Filter Editor dialog box to a size that suits you, and the dialog box will remember its size between sessions.

Visual Studio Analyzer also includes sample filters you can use to get started, or you can open an existing filter. Visual Studio Analyzer filters are saved as text files with the extension .vaf.

To create a filter

  1. In the Project Explorer, select Filters.

  2. Right-click to display the shortcut menu, and then click Add Item.

  3. Click Filter.

    A path and file name are proposed for you in the Name box.

  4. In the Name box, change the path or file name if you want.

  5. Click Open.

    The Filter Editor dialog box opens so you can define your filter.

To define a filter

  1. Click the View menu, and then click Designer.

    The Filter Editor dialog box displays, enabling you to construct a filter graphically. To edit a filter's text directly instead, click Edit Text. You can also open the filter text editor by clicking the View menu, and then clicking Code.

    The Filter Editor uses standard Boolean syntax for filter expressions. For guidelines on defining filters using the filter text editor, see Filter Syntax Reference.

    The Filter Editor dialog box is displayed in the following illustration. It is a resizable dialog box that you can resize by dragging, and it will remember its size for subsequent uses.

  2. Select the machines or processes, components, categories, and events that you want monitored.

    As you make selections, the text version of your filter is shown below the check boxes. Each selection you make within a single column is joined to the next using a logical OR. Each selection you make across columns is joined to the next using a logical AND.

    If you cannot express your filter the way you want on the first tab, click the rightmost OR tab at the top of the box, or press the INSERT key followed by the SPACE key. Another OR tab is added and the choices you make on that tab will be added to the filter using a logical OR. You can add as many additional tabs as you need.

  3. Click OK.

    Changes you make to a filter take effect as soon as you click OK. To save changes to a filter, click Save All on the File menu.

To use a predefined filter

  1. Right-click the Filters node in the Project Explorer, and then click Add Predefined Filter.

  2. Click the name of the filter you want.

    The filter is added to the Filters node in the Project Explorer. You can open it in the Filter Editor and modify it to reflect your needs.

Note You can also add a predefined filter with the Add Item command.

To save a filter

  • Click File, and then click Save All.

    This saves the filter as part of the project.

To open an existing filter

  1. Right-click the Filters node in the Project Explorer, and then click Add Item.

  2. Click the Existing tab.

  3. Navigate to the project that contains the filter you want and select the filter.

  4. Click Open.

To set a filter as the recording filter

In order for a filter to take effect when you collect events, you must mark the filter as the recording filter.

  1. Right-click the filter to display the shortcut menu.

  2. Click Set Record Filter.

To apply a filter to a Visual Studio Analyzer view

You can change the filter that is applied to a Visual Studio Analyzer view. If you have more than one view open, you can apply the same filter to all views (one at a time; there is no command to apply a filter to all views at once) or apply a different filter to each view. If you apply the same filter to multiple views, any changes you make to the filter are reflected immediately in each view, unless you disable automatic updates by turning off AutoFilter for that view and clearing the filter applied to that view.

  1. Click in the view to which you want to apply the filter.

  2. In the Project Explorer, select the filter you want to apply.

  3. Right-click to display the shortcut menu, and then click Apply Filter to View.

To clear a filter from a view

  1. Click in the view from which you want to clear the filter.

  2. Click Analyzer, and then click Clear View Filter. You can also right-click in the view to display the shortcut menu, and then click Clear View Filter.

To disable automatic view updates when filters change

If a view has AutoFilter turned on, it shares its filter settings with other windows. For example, if you clear a filter from one view, all other views with AutoFilter turned on are also cleared of that filter. You can disable updates by turning AutoFilter off. However, if you have applied a filter to a view, any modifications you make to the applied filter will always affect the view, independent of the AutoFilter setting.

  1. Click in the view for which you want to disable updates.

  2. Right-click to display the shortcut menu, and then click AutoFilter.

    Note To re-enable automatic updates to views, click AutoFilter on the view's shortcut menu again.


Filter Syntax Reference

This topic describes the syntax to use when constructing filters using the filter text editor. You access the filter text editor by clicking Edit Text on the Filter Editor dialog box.

When you click Edit Text, you will see a message warning you that some of the filters you can create using the filter text editor cannot be represented in the graphical filter editor. You can click Yes to confirm you want to use the filter text editor, or No to move back to the graphical filter editor.

The filter text editor is shown in the following illustration.

To use the filter text editor, type your expression in the box and click OK when you are satisfied. When you click OK, Visual Studio Analyzer evaluates your expression and displays a message if there are errors.

Syntax for Visual Studio Analyzer Filters

A valid statement in the filter text editor consists of three parts:

  • Operand

  • Operator

  • Comparison value

For example, the following is a valid statement:

Machine = "MyMachine"

You can combine statements with logical tokens, such as AND and OR, to create expressions. Enclose the entire filter expression in parentheses, and use parentheses inside the expression as needed for grouping. The following table lists valid operands, operators, and logical tokens.

Operands | Operators | Logical Tokens
Category Component Event Machine Process Source SourceComponent SourceMachine SourceProcess TargetComponent TargetMachine TargetProcess | != <> = == Contains "string" DoesNotContain "string" Equal IsOneOf ("Value1", "Value2", ... "ValueN" ). Make sure the final value in the list is followed by a space. or IsOneOf ({guid1}, {guid2}, ...{guidN} ). Make sure the final value in the list is followed by a space. NotEqual | !(Logical NOT — C/C++ style) &&(Logical AND — C/C++ style) ((Open parenthesis) )(Close parenthesis) ,(Comma — only used in value lists for the IsOneOf operator) ||(Logical OR — C/C++ style) AND NOT OR

Note: You can use the Contains and DoesNotContain operators to match the presence or absence of a certain string from a field. However, because of the way Visual Studio Analyzer optimizes certain fields internally, some fields cannot have these operators applied to them in this release. These fields are the component fields (SourceComponent, TargetComponent, Component) and the events and category fields. Thus, it is not possible to collect all call-type events by specifying Event Contains "Call".

Comparison Values

Comparison values must be enclosed in single or double quotation marks if they are strings. You can use a backslash (\) as an escape character to denote single or double quotation marks that are part of a string. Enclose comparison values that are GUIDs in curly braces ({}).


Exporting and Importing Visual Studio Analyzer Data

You can export Visual Studio Analyzer event logs to a standard, comma-separated variable (.csv) file, which you can then open in Microsoft® Access, Microsoft® Excel, or similar programs. You can also import exported Visual Studio Analyzer event logs back into Visual Studio Analyzer.

Note: Some programs, such as Microsoft Excel, might treat exported Visual Studio Analyzer data as numeric, even when the data is enclosed in quotes. This can cause data to be translated incorrectly; for example, the hex value "1e8" might be incorrectly translated into the exponential value 1.0 E+8 = 100000000. If you run into this conversion problem with your data, then you might want to explicitly import your data into these programs as text. For Excel, this means renaming the .csv file to an alternate extension. Once you rename the file extension, Excel will prompt you for the data type of each field.

To export Visual Studio Analyzer log data

  1. In the Project Explorer, select the event log you want to export.

  2. Click the Analyzer menu, and then click Export Events.

  3. In the File Name box, type a name for the data file.

  4. Change the location of the saved file (optional).

  5. Click Save.

To import exported Visual Studio Analyzer log data

  1. In the Project Explorer, select an event log.

    Important You cannot import into the active event log.

  2. Click the Analyzer menu, and then click Import Events.

  3. Select the exported data file you want to import.

  4. Click Open.


Installing the Visual Studio Analyzer Server Components

You must install the Visual Studio Analyzer Server components on each Windows NT and Windows 95 machine in your network that you plan to monitor using Visual Studio Analyzer. If you install the Visual Studio Enterprise Edition on those machines the server components are installed automatically.

If you do not want to install all of Visual Studio on a machine, you can choose to install only the Visual Studio Analyzer Server components.

To install the Visual Studio Analyzer Server components

  1. Run the Visual Studio setup program.

  2. Step through the Installation Wizard screens until you reach the screen with Client - Server Setup Options.

  3. Select Server Setup.

  4. Click Next.

  5. Select Server Component Setup, and then click Install.

  6. Select Custom, and then click Next.

  7. Click Visual Studio Analyzer, and then click Next.

  8. Step through the rest of the Installation Wizard by clicking Next until you get to the point where the setup program installs the components you selected.


Opening Visual Studio Analyzer Views

You can open any view by clicking Analyzer on the View menu, by displaying the shortcut menu in the Project Explorer, or by clicking a button on the Analyzer Windows toolbar. You need to select an event log to view before you open a view. The following table summarizes how to open each view.

View How to Open
Event List view On the View menu, click Analyzer, and then click Event List.

–or–

Right-click on the event log in the Project Explorer, and then click Event List on the shortcut menu.

–or–

Click the New Event List button on the Analyzer Windows toolbar.
Chart view On the View menu, click Analyzer, and then click Chart.

–or–

Right-click the event log in the Project Explorer, and then click Chart on the shortcut menu.

–or–

Click the New Chart button on the Analyzer Windows toolbar.
Block Diagram views On the View menu, click Analyzer, and then click Machine Diagram, Process Diagram, or Component Diagram.

–or–

Right-click the event log in the Project Explorer, and then click Machine Diagram, Process Diagram, or Component Diagram on the shortcut menu.

–or–

Click the New Machine Diagram, New Process Diagram, or New Component Diagram button on the Analyzer Windows toolbar.
Event view On the View menu, click Analyzer, then click Event.

–or–

Right-click the event log in the Project Explorer, and then click Event on the shortcut menu.

–or–

Click the New Event Viewer button on the Analyzer Windows toolbar.

–or–

Double-click on the event you want.
Summary view On the View menu, click Analyzer, and then click Summary.

–or–

Right-click the event log in the Project Explorer, and then click Summary on the shortcut menu.

–or–

Click the View Summary button on the Analyzer Windows toolbar.
Timeline view On the View menu, click Analyzer, and then click Timeline

–or–

Right-click the event log in the Project Explorer, and then click Timeline on the shortcut menu.

–or–

Click the View Time Line button on the Analyzer Windows toolbar.


Playing Back an Event Log

You can play back an event log to see the sequence in which events occurred and the interactions between components. Playback works on all Visual Studio Analyzer views. Using playback in the Block Diagram highlights the interactions between components.

To play back an event log

  1. Display the event log in the Visual Studio Analyzer view you choose, such as the Block Diagram.

    Note You can also combine views. A combination of views you might find useful is the Block Diagram and the Event List, which shows you both the sequence of events as they occur and the interactions between the components that generate the events.

  2. Click the Analyzer menu, and then click Replay Events.

Through other commands on the Analyzer menu, you can control the playback. You can pause or stop playback, move to the first or last event in the event log, single-step from event to event, and increase or decrease the playback speed. You can also find these commands on the Analyzer toolbar.


Starting and Stopping Event Recording

You start, pause, and stop event recording on a specific event log. The Record Events button is a two-state button. That means it is turned on until you explicitly turn it off by clicking it. Pausing is not the same thing as stopping and does not affect the Record Events button.

To start recording into an event log

  1. Select the event log into which you want to record events.

  2. Click Analyzer, and then click Record Events.

    You can also click the Record Events button on the Visual Studio Analyzer toolbar, or right-click the event log to display the shortcut menu and then click Record Events.

To pause recording into an event log

  1. Select the event log into which you are recording events.

  2. Click Analyzer, and then click Pause Event Recording. You can also click the Pause Event Recording button on the Visual Studio Analyzer toolbar, or right-click the event log to display the shortcut menu and then click Pause Event Recording.

To resume recording into an event log

  1. Select the event log into which you want to record events.

  2. Click Analyzer, and then click Pause Event Recording.

    You can also click the Pause Event Recording button on the Visual Studio Analyzer toolbar, or right-click the event log to display the shortcut menu and then click Pause Event Recording.

To stop recording into an event log

  1. Select the event log into which you want to stop recording events.

  2. Click Analyzer, and then click Record Events.

    You can also click the Record Events button on the Visual Studio Analyzer toolbar, or right-click the event log to display the shortcut menu and then click Record Events.


Starting the Visual Studio Analyzer RPC Listener Service

If you want to monitor Visual Studio Analyzer events from an application that generates events using the RPC interface, you must first start the RPC listener service on the server machine (the machine that is generating the events). This will work only on NT, because services are NT-specific. Follow these steps, which are the usual steps for starting any service under NT:

To start the Visual Studio Analyzer RPC Listener Service

  1. Click Start.

  2. Click Settings.

  3. Click Control Panel.

  4. Double-click Services.

  5. Select Visual Studio Analyzer RPC bridge.

  6. Click Start.

If you always want to run this service on this machine after a reboot, click Startup and select Automatic Startup Type.


Starting the Visual Studio Analyzer Server on Windows 95

Every time you want to connect remotely to a Windows 95 machine while using Visual Studio Analyzer, you must either start the Visual Studio Analyzer Server or make sure that the Visual Studio Analyzer Server is running on that machine. Once you start the Visual Studio Analyzer Server, it continues to run unless you explicitly stop it or exit from it. You must exit the Visual Studio Analyzer Server before you shut down the Windows 95 machine or you will experience problems during shutdown.

To start the Visual Studio Analyzer Server

  1. Click Start.

  2. Click Programs.

  3. Click Microsoft Visual Studio 6.0.

  4. Click Enterprise Features.

  5. Click Visual Studio Analyzer Server.

    The Visual Studio Analyzer Server starts and places an icon on the right side of the taskbar.

To stop or exit the Visual Studio Analyzer Server

  1. Right-click the Visual Studio Analyzer Server icon on the right side of the taskbar.

  2. Click Stop Service to stop the Visual Studio Analyzer Server (you can restart it later using the Start Service command).

  3. Click Exit to exit the Visual Studio Analyzer Server (required before shutting down your machine). Clicking Exit will also stop the service if it is currently running.

Instead of starting the Visual Studio Analyzer Server manually, you can add it to your Windows 95 Startup Folder so that it starts automatically. See your Windows 95 online help for information on how to do this; search for "startup folder." The executable name you want to add is vales.exe and it is located in C:\Program Files\Microsoft Visual Studio\Common\ide\ide98\vales.exe if you installed into the default location.

Note In the unlikely event that your Visual Studio Analyzer Server hangs, you can stop it manually using the killlec.exe program, located in C:\Program Files\Microsoft Visual Studio\Common\Tools\Vs-Ent98\Vanalyzr. To use the killlec program, open a Command Prompt window and type the following:

killlec


Language Reference

You can use the Visual Studio Analyzer programming interfaces to register a component or application as an event source and to generate Visual Studio Analyzer events from that component or application. You can use the programming interfaces provided whether programming in Microsoft Visual C++, Microsoft Visual Basic, Microsoft Visual J++, or event sources based on the remote procedure call (RPC) mechanism.

For More Information For guidelines on using these interfaces together in your components, see Extending Visual Studio Analyzer.

For reference information describing each of the Visual Studio Analyzer interfaces, see the following sections:

Section | Description
ISystemDebugEventInstallAuto, ISystemDebugEventInstall | Provides reference for these interfaces, which are for installing event sources. ISystemDebugEventInstallAuto is best used in components written in Visual Basic and Visual J++; ISystemDebugEventInstall is best used in Visual C++ components.
ISystemDebugEventFireAuto, ISystemDebugEventFire | Provides reference for these interfaces, which are for firing events. ISystemDebugEventFireAuto is best used in Visual Basic and Visual J++ components; ISystemDebugEventFire is best used in Visual C++ components.
VsaRpcl | Provides reference for this interface, which is for installing event sources and firing events. Best used in components that are not COM-based.


ISystemDebugEventFireAuto, ISystemDebugEventFire

Generates Visual Studio Analyzer events for the calling component.

Use ISystemDebugEventFireAuto if your component is written in Microsoft® Visual Basic or Microsoft® Visual J++™. Use ISystemDebugEventFire if your component is written in Microsoft® Visual C++.

ISystemDebugEventFireAuto and ISystemDebugEventFire Methods

BeginSession | Starts a Visual Studio Analyzer session with the calling component.
EndSession | Ends a Visual Studio Analyzer session with the calling component.
FireEvent | Generates a specific event.
IsActive | Reports whether a Visual Studio Analyzer client is interested in events from the calling component.


ISystemDebugEventFire Example (Visual Basic)

The following code shows the use of all methods in ISystemDebugEventFire. In order to modify this code for your own use, you need to add error handling. Each method can raise errors, which you should make sure to trap. You can use the Windows® application Guidgen.exe to generate globally unique IDs (GUIDs) where required.

Before you can generate events from a component, you must register the component and the events you want it to generate with Visual Studio Analyzer. ISystemDebugEventInstall provides methods for accomplishing this registration.

' Declare an event creator object like this;
' this variable is module-level.
Private mIEC As MSVSAAutomatableInprocEventCreator

' Instantiate the event creator object.
Private Sub Sample_InstantiateIEC()
   Set mIEC = New MSVSAAutomatableEventSourceInstaller
End Sub

' Begin a session with the event creator object.
Private Sub Sample_BeginSession(ByVal sSourceGUID As String)
   Dim sSessionName As String
   ' sSourceGUID identifies the component that will be monitored
   ' sSessionName uniquely identifies the session to
   ' Visual Studio Analyzer.
   sSessionName = "MyEventSourceFiringSession1"
   ' Begin the session.
   mIEC.BeginSession sSourceGUID, sSessionName
End Sub

' Verify that the event creator object is ready to generate events.
Private Sub Sample_IsActive()
   Dim bIsActive As Boolean
   ' bIsActive is passed by reference and gets the answer.
   ' Run method.
   mIEC.IsActive bIsActive
End Sub

' Generate an event.
Private Sub Sample_FireEvent(ByVal sEventGUID As String)
   Dim Keys(1 To 3) As Variant, Values(1 To 3) As Variant
   Dim lCount As Long
   Dim lFlags As Long
   ' The event creator object must be active (as indicated
   ' by IsActive method). sEventGUID is the GUID of the event
   ' to generate and should be the GUID of a registered event.

   ' The FireEvent method takes an array of parameter
   ' names and their values.
   ' These parameters contain descriptive information about the event.
   ' The parameter names are strings.
   ' The parameter values can be strings or numerical.
   ' See VSAStandardParameter for a complete list of the system-defined
   ' event parameter names and descriptions.
   ' Create arrays of keys and values for passing the event parameters.
   ' Fixed-count arrays of variants are used here, but you can also use
   ' dynamic arrays and arrays of strings.
   Keys(1) = PARAM_CausalityID   ' A system-defined parameter
   Values(1) = "SomeIDString"
   Keys(2) = "MyCustomParam1"      ' A custom parameter (text)
   Values(2) = "SomeString"
   Keys(3) = "MyCustomParam2"      ' A custom parameter (number)
   Values(3) = 7
   ' lCount is the total count of event parameters in the array
   lCount = 3
   ' lFlags can contain zero or more Visual Studio Analyzer constants,
   ' which you can combine with a logical OR. See VSAEventFlags for a
   ' complete list of the constants you can use.
   lFlags = cVSAEventStandard
   Generate the event
   mIEC.FireEvent sEventGUID, Keys, Values, lCount, lFlags
End Sub

' End the session with the event creator object when you are
' finished generating events.
Private Sub Sample_EndSession()
   mIEC.EndSession
End Sub

' Destroy the event creator object.
Private Sub Sample_DestroyIEC()
   Set mIEC = Nothing
End Sub


ISystemDebugEventFire Example (Visual C++)

The following code shows the use of all methods in ISystemDebugEventFire. In order to modify this code for your own use, you need to add error handling. Each method can raise errors, which you should make sure to trap. You can use the Windows® application Guidgen.exe to generate globally unique IDs (GUIDs) where required.

Before you can generate events from a component, you must register the component and the events you want it to generate with Visual Studio Analyzer. ISystemDebugEventInstall provides methods for accomplishing this registration.

// Include required files.

#include "vaevt.h"      // ISystemDebugEventFire
#include "vaevt_i.c"      // IID_ISystemDebugEventFire

// These files are required for generating valid GUIDs.
// Many of the VSA interface methods take a GUID as input.
#include <objbase.h>         // Required by initguid.h
#include <initguid.h>      // Ensure that GUIDs are generated by
                           // DEFINE_GUID
// This file contains constants for system-defined categories and events
#include "Vaids.h"

// Now generate GUIDs for the component that will generate VSA events, as
// well as a user-defined event,and a parameter that can hold a GUID if
// you wanted to pass a GUID as a parameter to FireEvent.
DEFINE_GUID(SAMPLE_SOURCE_GUID, 0x4ED47050, 0x64EF, 0x11D1, 0xA0, 0x6C, 0x00, 0xAA, 0x00, 0x6B, 0xBF, 0xAD);
DEFINE_GUID(SAMPLE_EVENT_GUID, 0x4ED47052, 0x64EF, 0x11D1, 0xA0, 0x6C, 0x00, 0xAA, 0x00, 0x6B, 0xBF, 0xAD);
DEFINE_GUID(SAMPLE_GUID_PARAMETER, 0x4ED47055, 0x64EF, 0x11D1, 0xA0, 0x6C, 0x00, 0xAA, 0x00, 0x6B, 0xBF, 0xAD);

// Declare a pointer to the event creator object.
ISystemDebugEventFire   *pIEC = NULL;

// Create the event creator object as an in-process server object.
void SampleCreateIEC()
{
   CoCreateInstance(CLSID_VSA_IEC, NULL, CLSCTX_INPROC_SERVER,
      IID_ISystemDebugEventFire, (void**)&pIEC );
}

// Begin a session with the component.
// SAMPLE_SOURCE_GUID identifies the component.
// Specify a name (Sample Session Name) to uniquely identify the session
// to Visual Studio Analyzer. The session name must be unique for each
// time, each component, and each run of the component.
void SampleBeginSession()
{
   pIEC->BeginSession( SAMPLE_SOURCE_GUID, L"Sample Session Name");
}

// Verify that the event creator object is ready to generate events
boolean SampleIsActive()
{
   HRESULT hr = pIEC->IsActive();
   return( S_OK == hr );
}

// Prepare to generate an event.
// Declare a byteArray to hold binary data; event data can be one of five
// different types, including binary data; all types are shown.
BYTE byteArray[] = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a";

// Event data is passed in arrays of parameter names (keys) and values.
// This array holds the parameter names. It is sized at 5 to show the
// five different types of event data you can pass.
// Standard event parameters (such as cVSAStandardParameterSourceHandle)
// are defined in vaevt.h.
#define MAXPARAMS 5
DWORD rgKeys[ MAXPARAMS ] = {
   cVSAStandardParameterCorrelationID,      // System-defined parameter
   (DWORD) L"First custom parameter",      // 3 custom parameters
   (DWORD) L"Second custom parameter",
   (DWORD) L"Third custom parameter",
   cVSAStandardParameterSourceHandle };   // Another system-defined
                                          // parameter

// This array holds the parameter values.
DWORD rgValues[ MAXPARAMS ] = {
   (DWORD) L"This is a unicode string",
   (DWORD) "This is an ANSI string",
   (DWORD) &SAMPLE_GUID_PARAMETER,
   0xFFFFFFFF,
   (DWORD) byteArray };

// Remember to specify cVSAParameterKeyString for all custom parameters
// and to specify the length for all BYTE array data.
DWORD rgTypes[ MAXPARAMS ] = {
   cVSAParameterValueUnicodeString,
   cVSAParameterKeyString | cVSAParameterValueANSIString,
   cVSAParameterKeyString | cVSAParameterValueGUID,
   cVSAParameterKeyString | cVSAParameterValueDWORD,
   cVSAParameterValueBYTEArray | ( cVSAParameterValueLengthMask &
sizeof(byteArray) ) };

// Generate the event.
// SAMPLE_EVENT_GUID is the GUID of the registered event to generate.
void SampleFireEvent()
{
   pIEC->FireEvent( SAMPLE_EVENT_GUID, MAXPARAMS, rgKeys, rgValues,
rgTypes, 0, 0,
      cVSAEventDefaultSource | cVSAEventDefaultTarget );
}

// End the session when you are finished generating events.
void SampleEndSession()
{
   pIEC->EndSession();
}

// Release the event creator object.
void SampleDestroyIEC()
{
   pIEC->Release();
   pIEC = NULL;
}


ISystemDebugEventFire Example (Visual J++)

The following code shows the use of all methods in ISystemDebugEventFire. In order to modify this code for your own use, you need to add error handling. Each method can raise errors, which you should make sure to trap. You can use the Windows® application Guidgen.exe to generate globally unique IDs (GUIDs) where required.

Before you can generate events from a component, you must register the component and the events you want it to generate with Visual Studio Analyzer. ISystemDebugEventInstall provides methods for accomplishing this registration.

// Import required class libraries.
import vaiea.*;
import com.ms.com.Variant;
import com.ms.com.SafeArray;

// Declare an event creator object.
static ISystemDebugEventFireAuto m_IEA = null;

// Now define GUIDs for the component that will generate VSA events, as
// well as a user-defined event,and a parameter that can hold a GUID if
// you wanted to pass a GUID as a parameter to FireEvent.

static String SAMPLE_SOURCE_GUID = "{E736B2E0-652D-11d1-A06D-00AA006BBFAD}";
static String SAMPLE_EVENT_GUID = "{E736B2E2-652D-11d1-A06D-00AA006BBFAD}";
static String SAMPLE_GUID_PARAMETER = "{E736B2E5-652D-11d1-A06D-00AA006BBFAD}";

// Define constants for a system-defined event and category.
static String DEBUG_EVENT_CALL = "{6c736d61-BCBF-11D0-8A23-00AA00B58E10}";
static String DEBUG_EVENT_CATEGORY_ALL = "{6c736d85-BCBF-11D0-8A23-00AA00B58E10}";

// Declare variables for event type and for a standard event parameter.
static final int DEBUG_EVENT_TYPE_GENERIC = 2;
static final int cVSAStandardParameterCorrelationID = 0x4005;

// Create an event creator object.
private static void SampleCreateIEA()
   {
      m_IEA = new MSVSAAutomatableInprocEventCreator();
   }

// Begin a session with the component.
// SAMPLE_SOURCE_GUID identifies the component.
// Specify a name (Sample Session Name) to uniquely identify the session
// to Visual Studio Analyzer. The session name must be unique for each
// time, each component, and each run of the component.
private static void SampleBeginSession()
   {
      m_IEA.BeginSession( SAMPLE_SOURCE_GUID, "Sample Session Name" );
   }

// Verify that the event creator object is ready to generate events.
private static boolean SampleIsActive()
   {
      boolean registered[] = { false, false };

      m_IEA.IsActive( registered );
      return( registered[ 0 ] );
   }

// Prepare to generate an event.
// Declare an array to hold event parameters.
private static final int MAXPARAMS = 2;

// Event data is passed in arrays of parameter names (keys) and values.
private static void SampleFireEvent()
   {
      SafeArray saKeys = new SafeArray( Variant.VariantString, MAXPARAMS
);
      saKeys.setString( 0, "CorrelationID" );         // Stock parameter
      saKeys.setString( 1, "This is a custom parameter" );
      Variant rgKeys = new Variant( saKeys, false );

      SafeArray saValues = new SafeArray( Variant.VariantString,
MAXPARAMS );
      saValues.setString( 0, "String parameter" );
      saValues.setString( 1, "Another string parameter" );
      Variant rgValues = new Variant( saValues, false );

      // Generate the event.
      // SAMPLE_EVENT_GUID is the GUID of the registered event to
      // generate.
      m_IEA.FireEvent( SAMPLE_EVENT_GUID, rgKeys, rgValues, MAXPARAMS,
         eVSAEventFlags.cVSAEventDefaultSource |
         eVSAEventFlags.cVSAEventDefaultTarget );
   }

// End the session when you are finished generating events.
private static void SampleEndSession()
   {
      m_IEA.EndSession();
   }

// Destroy the event creator object.
private static void SampleDestroyIEA()
   {
      m_IEA = null;
   }


BeginSession

Starts a Visual Studio Analyzer session with the calling component. You assign a unique identifier to the session. Events that are generated during this session are stamped with the session identifier, which helps you identify the true source of an event, particularly in cases where multiple copies of the component are running at the same time.

Syntax

Visual Basic | object.BeginSession(guidSourceID As String, strSessionName As String)
Visual C++ | HRESULT BeginSession( REFGUID guidSourceID, LPCOLESTR strSessionName);
Visual J++ | object.BeginSession(String guidSourceID, String strSessionName);

Parameters

object

A unique instance of the event creator object. The event creator object generates Visual Studio Analyzer events for the calling component. Each instance of a component has its own event creator object.

guidSourceID

A unique identifier for the calling component. Multiple sessions from this component can exist at the same time on the same machine. This ID is defined in the call to the RegisterSource method of ISystemDebugEventInstall, which registers components with the Visual Studio Analyzer framework.

Visual C++: [in]

strSessionName

A session identifier, which must be unique among all instances of this component until the machine where the component resides is restarted.

Visual C++: [in]

Remarks

Before you can call BeginSession, you must register the calling component with the Visual Studio Analyzer framework by calling the RegisterSource method of ISystemDebugEventInstall.

Each event creator object can accept only one call to BeginSession at a time. If your application supports multiple simultaneous sessions, such as a Web server running on more than one port, you can choose to create multiple in-process event creator objects.

You can make repeated calls to BeginSession on the same object, as long as you have a matching EndSession call for each BeginSession call. You cannot nest calls, as the following table illustrates:

Accepted | Not Accepted
BeginSession | BeginSession
EndSession | BeginSession
BeginSession | EndSession
EndSession | EndSession

The code does not validate whether strSessionName is unique. If the session identifier is not unique, the user might be unable to distinguish between events from multiple sessions of the same component. However, this lack of checking allows for two servers that represent one conceptual session to coexist and operate correctly.

This function will fail if guidSourceID is not properly registered.

You can use the default user component, DEBUG_EVENT_SOURCE_USER, which is already registered, if you want a quick way to generate events without a lot of overhead. The default user component is registered automatically when you install Visual Studio Analyzer.


BeginSession Example (Visual Basic)

This example demonstrates calling BeginSession so that a component can start generating Visual Studio Analyzer events. Refer to ISystemDebugEventFire Example (Visual Basic) to see this code in context.

' Begin a session with the event creator object.
Private Sub Sample_BeginSession(ByVal sSourceGUID As String)
   Dim sSessionName As String
   ' sSourceGUID identifies the component that will be monitored.
   ' sSessionName uniquely identifies the session to
   ' Visual Studio Analyzer.
   sSessionName = "MyEventSourceFiringSession1"
   ' Begin the session.
   mIEC.BeginSession sSourceGUID, sSessionName
End Sub


BeginSession Example (Visual C++)

This example shows what a call to BeginSession looks like. Refer to ISystemDebugEventFire Example (Visual C++) to see the constant declarations and object creation code, as well as to see this code in a form you can run with minor modifications.

// Begin a session with the component.
// SAMPLE_SOURCE_GUID identifies the component.
// Specify a name (Sample Session Name) to uniquely identify the session
// to Visual Studio Analyzer. The session name must be unique for each
// time, each component, and each run of the component.
void SampleBeginSession()
{
   pIEC->BeginSession( SAMPLE_SOURCE_GUID, L"Sample Session Name");
}


BeginSession Example (Visual J++)

This example shows what a call to BeginSession looks like. Refer to ISystemDebugEventFire Example (Visual J++) to see the constant declarations and object creation code, as well as to see this code in a form you can run with minor modifications.

// Begin a session with the component.
// SAMPLE_SOURCE_GUID identifies the component.
// Specify a name (Sample Session Name) to uniquely identify the session
// to Visual Studio Analyzer. The session name must be unique for each
// time, each component, and each run of the component.
private static void SampleBeginSession()
   {
      m_IEA.BeginSession( SAMPLE_SOURCE_GUID, "Sample Session Name" );
   }


EndSession

Ends a Visual Studio Analyzer session for the calling component.

Syntax

Visual Basic | object.EndSession()
Visual C++ | HRESULT EndSession();
Visual J++ | object.EndSession();

Parameters

object

A unique instance of the event creator object. The event creator object generates Visual Studio Analyzer events for the calling component. Each instance of a component has its own event creator object.

Remarks

You must call BeginSession before you call EndSession.

You can make repeated calls to EndSession on the same object, as long as you have a matching BeginSession call for each EndSession call. You cannot nest calls, as the following table illustrates:

Accepted | Not Accepted
BeginSession | BeginSession
EndSession | BeginSession
BeginSession | EndSession
EndSession | EndSession


EndSession Example (Visual Basic)

This example shows the process of calling EndSession when a component is finished generating Visual Studio Analyzer events. Refer to ISystemDebugEventFire Example (Visual Basic) to see this code in context.

' End the session with the event creator object when you are
' finished generating events.
Private Sub Sample_EndSession()
   mIEC.EndSession
End Sub


EndSession Example (Visual C++)

This example shows what a call to EndSession looks like. Refer to ISystemDebugEventFire Example (Visual C++) to see the object creation code and to see this code in a form you can run with minor modifications.

// End the session when you are finished generating events.
void SampleEndSession()
{
   pIEC->EndSession();
}


EndSession Example (Visual J++)

This example shows what a call to EndSession looks like. Refer to ISystemDebugEventFire Example (Visual J++) to see the object creation code and to see this code in a form you can run with minor modifications.

// End the session when you are finished generating events.
private static void SampleEndSession()
   {
      m_IEA.EndSession();
   }


FireEvent

Generates a registered event from the calling component.

Syntax

Visual Basic | object.FireEvent(guidEvent As String, rgKeys, rgValues, rgCount As Long, dwFlags As eVSAEventFlags)
Visual C++ | HRESULT FireEvent( REFGUID guidEvent, int nEntries, LPCDWORD rgKeys, LPCDWORD rgValues, LPCDWORD rgTypes, DWORD dwTimeLow, LONG dwTimeHigh, VSAEventFlags dwFlags);
Visual J++ | object.FireEvent(String guidEvent, Variant rgKeys, Variant rgValues, int rgCount, int dwFlags);

Parameters

object

A unique instance of the in-process event creator object.

guidEvent

The event being generated. Events have many possible parameters, which are specified in the rgKeys and rgValues arrays. In Visual C++, the parameter types are specified in the rgType array.

Visual C++: [in]

rgCount, nEntries

Number of entries in the rgKeys, rgValues, and rgTypes arrays.

Visual C++: [in]

rgKeys

Names of event fields passed for this event. See VSAStandardParameter for a list of available event fields. In Visual C++, the cVSAParameterKeyMask and cVSAParameterKeyString values in rgTypes define whether the event field names are passed as strings or as predefined indexes.

Visual C++: [in size_is(nEntries)]

Visual J++: This value must be initialized as a SafeArray or the call to FireEvent will fail.

rgValues

Values for the event fields passed for this event. In Visual C++, information in the rgTypes array defines whether the values are Unicode strings, ANSI strings, GUIDs, DWORDs, or BYTEArrays.

Visual C++: [in size_is(nEntries)]

Visual J++: This value must be initialized as a SafeArray or the call to FireEvent will fail.

rgTypes

Visual C++: [in size_is(nEntries)] Data types for values in the rgKeys and rgValues arrays. See VSAParameterType for more information.

dwTimeLow

Visual C++: [in] The local time of the event, or 0. (Low 32 bits.)

dwTimeHigh

Visual C++: [in] The local time of the event, or 0. (High 32 bits.)

dwFlags

Provides default values for a group of event parameters. See VSAEventFlags for more information.

Visual C++: [in]

Visual Basic: Possible values are cVSAEventStandard, cVSAEventDefaultSource, or cVSAEventDefaultTarget.

Remarks

Visual Basic: Use the rgKeys and rgValues arrays in the FireEvent call to pass information about the event. These arrays work together; the rgKeys array holds the names of the various fields for an event; the rgValues array holds the value for each field. You can dimension these arrays as either fixed-count or dynamic; for example:

Dim Keys (1 to 2) As String, Values (1 to 2) as String

Visual C++: Set the dwTimeLow and dwTimeHigh parameters using the return value of the QueryPerformanceCounter function. If you pass in 0 for these parameters, Visual Studio Analyzer defaults to the current time. If you know that the event happened at a different time, you should pass that time in.


VSAParameterType

Visual C++: The VSAParameterType enumeration values define characteristics of keys and values. Specify these values in the prgTypes array; one value for each value you pass in the prgValues array. Populate the prgKeys, prgTypes, and prgValues arrays before you call FireEvent.

typedef [v1_enum] enum VSAParameterType
{
   cVSAParameterKeyMask=0x80000000,
   cVSAParameterKeyString=0x80000000,
   cVSAParameterValueMask=0x0007ffff,
   cVSAParameterValueTypeMask=0x00070000,
   cVSAParameterValueUnicodeString=0x00000,
   cVSAParameterValueANSIString=0x10000,
   cVSAParameterValueGUID=0x20000,
   cVSAParameterValueDWORD=0x30000,
   cVSAParameterValueBYTEArray=0x40000,
   cVSAParameterValueLengthMask=0xffff
} VSAParameterType;

Elements

cVSAParameterKeyMask

Mask for key-related flags.

cVSAParameterKeyString

If true, the rgKeys array element contains a string, not one of the predefined indices listed in VSAStandardParameter.

cVSAParameterValueMask

Mask for all value-related flags and data.

cVSAParameterValueTypeMask

Mask for the type of item in rgValues.

cVSAParameterValueUnicodeString

rgValues contains a Unicode string.

cVSAParameterValueANSIString

rgValues contains an ANSI string.

cVSAParameterValueGUID

rgValues contains a GUID.

cVSAParameterValueDWORD

rgValues contains a DWORD.

cVSAParameterValueBYTEArray

rgValues contains a BYTEArray.

cVSAParameterValueLengthMask

Number of bytes that rgValues points to. Only used for BYTEArray. This limits the size of the byte array to a theoretical maximum of about 64 kb, but generating an event with this much data is not recommended.


VSAStandardParameter

The VSAStandardParameter values describe names of the system-defined event parameters. These parameters provide additional information about an event. Specify the parameter values you want in the sKeys or rgKeys array before you call FireEvent. You can use the VSAEventFlags parameter in your call to FireEvent to set either the Source or the Target parameters to default values.

Visual C++ Syntax:

typedef [v1_enum] enum VSAStandardParameter
{
   cVSAStandardParameterSourceMachine=0,
   cVSAStandardParameterSourceProcess=1,
   cVSAStandardParameterSourceThread=2,
   cVSAStandardParameterSourceComponent=3,
   cVSAStandardParameterSourceSession=4,
   cVSAStandardParameterTargetMachine=5,
   cVSAStandardParameterTargetProcess=6,
   cVSAStandardParameterTargetThread=7,
   cVSAStandardParameterTargetComponent=8,
   cVSAStandardParameterTargetSession=9,
   cVSAStandardParameterSecurityIdentity=10,
   cVSAStandardParameterCausalityID=11,
   cVSAStandardParameterSourceProcessName=12,
   cVSAStandardParameterTargetProcessName=13
   cVSAStandardParameterNoDefault=0x4000,
   cVSAStandardParameterSourceHandle=0x4000,
   cVSAStandardParameterTargethandle=0x4001,
   cVSAStandardParameterArguments=0x4002,
   cVSAStandardParameterReturnValues=0x4003,
   cVSAStandardParameterException=0x4004,
   cVSAStandardParameterCorrelationID=0x4005
} VSAStandardParameter;

v1_enum is an Interface Definition Language (IDL) attribute that describes how the enumerated type is transmitted. See v1_enum in the MIDL Language Reference for a complete description.

Elements

cVSAStandardParameterSourceMachine, SourceMachine

The machine name of this event's original source. The default value for this parameter is the current machine name. Although this parameter is optional, if you know that the event source machine name is different from the current machine name, you should supply it.

cVSAStandardParameterSourceProcess, SourceProcess

The process ID of this event's original source. The default value for this parameter is the current process ID. Although this parameter is optional, if you know that the event source process ID is different from the current process ID, you should supply it.

cVSAStandardParameterSourceThread, SourceThread

The thread ID of this event's original source. The default value for this parameter is the current thread ID. Although this parameter is optional, if you know that the event source thread ID is different from the current thread ID, you should supply it.

cVSAStandardParameterSourceComponent, SourceComponent

The GUID (from RegisterSource) of the component that generated this event. The default value for this parameter is the current GUID. Although this parameter is optional, if you know that the component GUID is different from the current GUID, you should supply it.

cVSAStandardParameterSourceSession, SourceSession

The session identifier (from BeginSession) that identifies this instance of the component that generated the event. The default value for this parameter is the current session identifier. Although this parameter is optional, if you know that the component session identifier is different from the current session identifier, you should supply it.

cVSAStandardParameterSourceHandle, SourceHandle

A handle to the component that generated the event that is unique for this instance of the component. There is no default value for this parameter. This parameter is optional if other information (such as machine, process, thread, component, or session) is known about the component; if other information is unknown, synthesize a unique value for this parameter. The synthesized value must remain constant for all calls to ISystemDebugFireEvent that are for the same instance of this component.

cVSAStandardParameterTargetMachine, TargetMachine

The machine name of this event's final target. The default value for this parameter is the current machine name. Although this parameter is optional, if you know that the event target machine name is different from the current machine name, you should supply it.

cVSAStandardParameterTargetProcess, TargetProcess

The process ID of this event's final target. The default value for this parameter is the current process ID. Although this parameter is optional, if you know that the event target process ID is different from the current process ID, you should supply it.

cVSAStandardParameterTargetThread, TargetThread

The thread ID of this event's final target. The default value for this parameter is the current thread ID. Although this parameter is optional, if you know that the event target thread ID is different from the current thread ID, you should supply it.

cVSAStandardParameterTargetComponent, TargetComponent

The GUID (from RegisterSource) for this event's final target. The default value for this parameter is the current GUID. Although this parameter is optional, if you know that the event target GUID is different from the current GUID, you should supply it.

cVSAStandardParameterTargetSession, TargetSession

The session identifier (from BeginSession) for this event's final target. The default value is the current session identifier. Although this parameter is optional, if you know that the event target session identifier is different from the current session identifier, you should supply it.

cVSAStandardParameterTargetHandle, TargetHandle

A handle to the final target that is unique for this instance of this source. There is no default value for this parameter. This parameter is optional if other information (such as machine, process, thread, component, or session) is known about the target; if nothing is known about the target, the component should synthesize a unique value for this parameter. The synthesized value must remain constant for all calls to ISystemDebugEventFire that are for the same target.

cVSAStandardParameterArguments, Arguments

The arguments to the function or the text of the query. This parameter has meaning during function or query start only. There is no default value for this parameter, and this parameter is optional.

cVSAStandardParameterReturnValue, ReturnValue

The return value from the function or query. This parameter has meaning on function or query end only. There is no default value for this parameter, and this parameter is optional.

cVSAStandardParameterCorrelationID, CorrelationID

An ID used to match up pairs of inbound and outbound events, such as calls and returns, or enters and leaves. There is no default value for this parameter, and this parameter is optional, but if you want events to be correlated, you should supply this parameter. See Determining the Relationships Between Events for more information on correlation.

cVSAStandardParameterCausalityID, CausalityID

A value used to match up sequences of subactions. The default value for this parameter is provided by COM and is generally applicable. Replace this value only if you are sure.

cVSAStandardParameterSourceProcessName, SourceProcessName

The process name of this event's original source. The default value for this parameter is the current process name. Although this parameter is optional, if you know that the event source process name is different from the current process name, you should supply it.

cVSAStandardParameterTargetProcessName, TargetProcessName

The process name of this event's target. The default value for this parameter is the current process name. Although this parameter is optional, if you know that the event target process name is different from the current process name, you should supply it.

cVSAStandardParameterSecurityIdentity, Security Identity

The security context in use. The default value for this parameter is the user name of the logged on user. This parameter is optional.

Remarks

The parameter keys in the preceding list are defined by the system. It is possible to define additional custom parameters. You may choose any key name you wish, as long as it is always a string and either unique or with a unique prefix.


VSAEventFlags

Specifies default values for specific groups of event parameters. Pass the values you want as part of the call to FireEvent.

Required Files

VC: vaevt.h

typedef [v1_enum] enum eVSAEventFlags
{
   cVSAEventStandard=0,
   cVSAEventDefaultSource=1,
   cVSAEventDefaultTarget=2,
} VSAEventFlags;

cVSAEventStandard

When set, no default values are set for any parameters. This is the default.

cVSAEventDefaultSource

When set, the SourceMachine, SourceProcess, SourceThread, SourceComponent, and SourceSession event fields will be set to default values. See Determining Source and Target Values for Events for more information.

cVSAEventDefaultTarget

When set, the TargetMachine, TargetProcess, TargetThread, TargetComponent, and TargetSession event fields will be set to default values. See Determining Source and Target Values for Events for more information.


FireEvent Example (Visual Basic)

This example shows how to define the data passed with a Visual Studio Analyzer event as well as the process of calling FireEvent to generate the event. Refer to ISystemDebugEventFire Example (Visual Basic) to see this code in context.

' Generate an event.
Private Sub Sample_FireEvent(ByVal sEventGUID As String)
   Dim Keys(1 To 3) As Variant, Values(1 To 3) As Variant
   Dim lCount As Long
   Dim lFlags As Long
   ' The event creator object must be active
   ' (as indicated by IsActive method).

   ' sEventGUID is the GUID of the event to generate
   ' and should be the GUID of a registered event.

   ' The FireEvent method takes an array of parameter names
   ' and their values.
   ' These parameters contain descriptive information about the event.
   ' The parameter names are strings.
   ' The parameter values can be strings or numerical.
   ' See VSAStandardParameter for a complete list of the system-defined
   ' event parameter names and descriptions.
   ' Create arrays of keys and values for passing the event parameters.
   ' Fixed-count arrays of variants are used here, but you can also use
   ' dynamic arrays and arrays of strings.
   Keys(1) = PARAM_CausalityID   ' A system-defined parameter
   Values(1) = "SomeIDString"
   Keys(2) = "MyCustomParam1"      ' A custom parameter (text)
   Values(2) = "SomeString"
   Keys(3) = "MyCustomParam2"      ' A custom parameter (number)
   Values(3) = 7
   ' lCount is the total count of event parameters in the array
   lCount = 3
   ' lFlags can contain zero or more Visual Studio Analyzer constants,
   ' which you can combine with a logical OR. See VSAEventFlags for a
   ' complete list of the constants you can use.
   lFlags = cVSAEventStandard
   Generate the event
   mIEC.FireEvent sEventGUID, Keys, Values, lCount, lFlags
End Sub


FireEvent Example (Visual C++)

This example shows what a call to FireEvent looks like. Refer to ISystemDebugEventFire Example (Visual C++) to see the constant declarations and object creation code, as well as to see this code in a form you can run with minor modifications.

// Prepare to generate an event.
// Declare a byteArray to hold binary data; event data can be one of five
// different types, including binary data; all types are shown.
BYTE byteArray[] = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a";

// Event data is passed in arrays of parameter names (keys) and values.
// This array holds the parameter names. It is sized at 5 to show the
// five different types of event data you can pass.
// Standard event parameters (such as cVSAStandardParameterSourceHandle)
// are defined in vaevt.h
#define MAXPARAMS 5
DWORD rgKeys[ MAXPARAMS ] = {
   cVSAStandardParameterCorrelationID,      // System-defined parameter
   (DWORD) L"First custom parameter",      // 3 custom parameters
   (DWORD) L"Second custom parameter",
   (DWORD) L"Third custom parameter",
   cVSAStandardParameterSourceHandle };   // Another system-defined
                                          // parameter

// This array holds the parameter values.
DWORD rgValues[ MAXPARAMS ] = {
   (DWORD) L"This is a unicode string",
   (DWORD) "This is an ANSI string",
   (DWORD) &SAMPLE_GUID_PARAMETER,
   0xFFFFFFFF,
   (DWORD) byteArray };

// Remember to specify cVSAParameterKeyString for all custom parameters
// and to specify the length for all BYTE array data.
DWORD rgTypes[ MAXPARAMS ] = {
   cVSAParameterValueUnicodeString,
   cVSAParameterKeyString | cVSAParameterValueANSIString,
   cVSAParameterKeyString | cVSAParameterValueGUID,
   cVSAParameterKeyString | cVSAParameterValueDWORD,
   cVSAParameterValueBYTEArray | ( cVSAParameterValueLengthMask &
sizeof(byteArray) ) };

// Generate the event.
// SAMPLE_EVENT_GUID is the GUID of the registered event to generate
void SampleFireEvent()
{
   pIEC->FireEvent( SAMPLE_EVENT_GUID, MAXPARAMS, rgKeys, rgValues,
rgTypes, 0, 0,
      cVSAEventDefaultSource | cVSAEventDefaultTarget );
}


FireEvent Example (Visual J++)

This example shows what a call to FireEvent looks like. Refer to ISystemDebugEventFire Example (Visual J++) to see the constant declarations and object creation code, as well as to see this code in a form you can run with minor modifications.

// Prepare to generate an event.
// Declare an array to hold event parameters
private static final int MAXPARAMS = 2;

// Event data is passed in arrays of parameter names (keys) and values.
private static void SampleFireEvent()
   {
      SafeArray saKeys = new SafeArray( Variant.VariantString, MAXPARAMS
);
      saKeys.setString( 0, "CorrelationID" );         // Stock parameter
      saKeys.setString( 1, "This is a custom parameter" );
      Variant rgKeys = new Variant( saKeys, false );

      SafeArray saValues = new SafeArray( Variant.VariantString,
MAXPARAMS );
      saValues.setString( 0, "String parameter" );
      saValues.setString( 1, "Another string parameter" );
      Variant rgValues = new Variant( saValues, false );

      // Generate the event.
      // SAMPLE_EVENT_GUID is the GUID of the registered event to
      // generate
      m_IEA.FireEvent( SAMPLE_EVENT_GUID, rgKeys, rgValues, MAXPARAMS,
         eVSAEventFlags.cVSAEventDefaultSource |
eVSAEventFlags.cVSAEventDefaultTarget );
   }


IsActive

Returns a value indicating whether there are any Visual Studio Analyzer clients interested in events generated by the calling component. This test allows for a low-cost determination of whether a Visual Studio Analyzer client is running and interested in events. Possible return values are S_OK or S_FALSE; a return value of S_FALSE means that events need not be generated.

The FireEvent method calls IsActive anyway, so if generating an event is low-impact, you might choose to omit the IsActive test.

Syntax

Visual Basic | object.IsActive(pbIsActive As Boolean)
Visual C++ | HRESULT IsActive();
Visual J++ | object.IsActive(boolean[] pbIsActive);

Parameters

object

A unique instance of the in-process event creator object.

pbIsActive

Returns a value to indicate whether a Visual Studio Analyzer client is interested in events from this component.


IsActive Example (Visual Basic)

This example shows how to ensure that the event creator object is ready to generate Visual Studio Analyzer events. Refer to ISystemDebugEventFire Example (Visual Basic) to see this code in context.

' Verify that the event creator object is ready to generate events
Private Sub Sample_IsActive()
   Dim bIsActive As Boolean
   ' bIsActive is passed by reference and gets the answer
   ' Run method.
   mIEC.IsActive bIsActive
End Sub


IsActive Example (Visual C++)

This example shows what a call to IsActive looks like. Refer to ISystemDebugEventFire Example (Visual C++) to see the object creation code and to see this code in a form you can run with minor modifications.

// Verify that the event creator object is ready to generate events
boolean SampleIsActive()
{
   HRESULT hr = pIEC->IsActive();
   return( S_OK == hr );
}


IsActive Example (Visual J++)

This example shows what a call to IsActive looks like. Refer to ISystemDebugEventFire Example (Visual J++) to see the object creation code and to see this code in a form you can run with minor modifications.

// Verify that the event creator object is ready to generate eventsprivate static boolean SampleIsActive()
   {
      boolean registered[] = { false, false };

      m_IEA.IsActive( registered );
      return( registered[ 0 ] );
   }


ISystemDebugEventInstallAuto, ISystemDebugEventInstall

Registers the calling component as a source of Visual Studio Analyzer events; also registers the event categories and events the component generates.

Use ISystemDebugEventInstallAuto if your component is written in Microsoft® Visual Basic® or Microsoft® Visual J++™. If your component is written in Microsoft® Visual C++®, use ISystemDebugEventInstall instead.

Component Methods

IsSourceRegistered | Reports whether a particular component is registered.
RegisterSource | Registers an application or component as a source of Visual Studio Analyzer events.
UnRegisterSource | Uninstalls a component.

Category Method

RegisterEventCategory Registers a user-defined category for events.

Event Methods

RegisterCustomEvent | Registers a user-defined event.
RegisterStockEvent | Registers a system-defined event.

Dynamic Component Methods

IsDynamicSourceRegistered | Reports whether a particular dynamic component is registered.
RegisterDynamicSource | Registers an application or component as a source of dynamic Visual Studio Analyzer events.
UnRegisterDynamicSource | Uninstalls a dynamic component.


ISystemDebugEventInstall Example (Visual Basic)

The following code shows the use of all methods in ISystemDebugEventInstall. In order to modify this code for your own use, you need to add error handling. Each method can raise errors, which you should make sure to trap. You can use the Windows® application Guidgen.exe to generate globally unique IDs (GUIDs) where required.

Use ISystemDebugEventInstall to register the component that will generate events and the events that component will generate. After you finish the registration process, you can generate events. ISystemDebugEventFire provides methods for generating events.

Option Explicit
' Code examples for methods in ISystemDebugEventInstall.

' Declare the installer object like this; note that
' this particular variable is module-level.
Private mESI As MSVSAAutomatableEventSourceInstaller

' Instantiate an installer object.
Private Sub Sample_InstantiateESI()
   Set mESI = New MSVSAAutomatableEventSourceInstaller
End Sub

' Check to see whether a normal component is registered.
Private Sub Sample_IsSourceRegistered(ByVal sSourceGUID As String)
   Dim bIsRegistered As Boolean
   ' sSourceGUID is the GUID for the component.
   ' bIsRegistered is passed by reference and gets the answer.
   ' Run the method.
   mESI.IsSourceRegistered sSourceGUID, bIsRegistered
   If bIsRegistered Then MsgBox "Registered" Else MsgBox "Not Registered"
End Sub

'Check to see whether a dynamic component is registered.
Private Sub Sample_IsDynamicSourceRegistered(ByVal sSourceGUID As String)
   Dim bIsRegistered As Boolean
   ' sSourceGUID is the GUID for the component.
   ' bIsRegistered is passed by reference and gets the answer.
   ' Run the method.
   mESI.IsDynamicSourceRegistered sSourceGUID, bIsRegistered
   If bIsRegistered Then MsgBox "Registered" Else MsgBox "Not Registered"
End Sub

' Register a normal component with Visual Studio Analyzer.
Private Sub Sample_RegisterEventSource()
   Dim sSourceGUID As String
   Dim sSourceName As String
   ' You need a unique GUID to assign to the component;
   ' substitute your own in the following line.
   sSourceGUID = "{B3303262-5C87-11d1-A2AD-00AA003B23FF}"
   ' Assign a name to the component.
   sSourceName = "MyEventSource1"
   ' Run the method.
   mESI.RegisterSource sSourceGUID, sSourceName
End Sub

' Register a dynamic component with Visual Studio Analyzer.
Private Sub Sample_RegisterDynamicSource()
   Dim sDynamicSourceGUID As String
   Dim sDynamicSourceName As String
   Dim sDynamicSourceDescr As String
   Dim sCLSID As String
   Dim lInProc As Long
   ' You need a unique GUID to assign to the component;
   ' substitute your own in the following line.
   sDynamicSourceGUID = "{B3303260-5C87-11d1-A2AD-00AA003B23FF}"
   ' Assign a name and description to the component.
   sDynamicSourceName = "MyDynamicEventSource1"
   sDynamicSourceDescr = "MyDynamicEventSource1 Description"
   ' If the dynamic component is a COM object that you want
   ' VSA to start automatically, you need to provide its CLSID.
   ' Substitute the correct CLSID in the following line.
   sCLSID = "{B3303261-5C87-11d1-A2AD-00AA003B23FF}"
   ' Specify whether your COM object should be started in process;
   ' use nonzero for true, zero for false.
   lInProc = 1
   ' Run the method.
   mESI.RegisterDynamicSource _
       sDynamicSourceGUID, _
       sDynamicSourceName, _
       sDynamicSourceDescr, _
       sCLSID, _
       lInProc
End Sub

' Register a system-defined (stock) event.
Private Sub Sample_RegisterStockEvents(ByVal sSourceGUID As String)
   ' sSourceGUID is the component for which to
   ' register this stock event.

   ' Run the method.
   ' This registers the stock event DEBUG_EVENT_CALL.
   mESI.RegisterStockEvent sSourceGUID, DEBUG_EVENT_CALL
End Sub

' Register a user-defined (custom) event.
Private Sub Sample_RegisterCustomEvent(ByVal sSourceGUID As String)
   Dim sCustomEventGUID As String
   Dim sCustomEventName As String
   Dim sCustomEventDescr As String
   Dim sIconFile As String, lIcon As Long
   ' sSourceGUID is the component for which to register
   ' this custom event.

   ' You need to create a unique GUID for the event; substitute your own
   ' in the following line.
   sCustomEventGUID = "{A84C4E72-1FD7-11D1-A573-00C04FD5B402}"
   ' Assign a name and description to the event.
   sCustomEventName = "MyCustomDebugEvent1"
   sCustomEventDescr = "MyCustomDebugEvent1 Description"
   ' Pass the next two parameters empty.
   sIconFile = "": lIcon = 0
   ' Run the method.
   ' This call assigns the defaults for event type and category.
   mESI.RegisterCustomEvent _
       sSourceGUID, _
       sCustomEventGUID, _
       sCustomEventName, _
       sCustomEventDescr, _
       DEBUG_EVENT_TYPE_DEFAULT, DEBUG_EVENT_CATEGORY_ALL, _
       sIconFile, _
       lIcon
End Sub

' Register a custom event category.
Private Sub Sample_RegisterEventCategory(ByVal sSourceGUID As String)
   Dim sEventCategoryGUID As String
   Dim sParentGUID As String
   Dim sEventCategoryName As String
   Dim sEventCategoryDescr As String
   Dim sIconFile As String, lIcon As Long
   ' sSourceGUID is the component for which to register
   ' this custom event category.

   ' Create a unique GUID for the custom event category;
   ' substitute your own in the following line.
   sEventCategoryGUID = "{B3303263-5C87-11d1-A2AD-00AA003B23FF}"
   ' If you want to specify a position in a hierarchy, specify a
   ' parent, such as All Events; leaving this empty will place
   ' your custom category at the top level
   ' in the Filter Editor.
   sParentGUID = ""
   ' Specify a name and description for the event category.
   sEventCategoryName = "MyCustomEventCategory1"
   sEventCategoryDescr = "MyCustomEventCategory1 Description"
   ' Pass the next two parameters empty.
   sIconFile = "": lIcon = 0
   ' Run the method.
   mESI.RegisterEventCategory sSourceGUID, _
       sEventCategoryGUID, _
       sParentGUID, _
       sEventCategoryName, _
       sEventCategoryDescr, _
       sIconFile, _
       lIcon
End Sub

' Unregister a dynamic component.
Private Sub Sample_UnregisterDynamicSource(ByVal sSourceGUID As String)
   ' sSourceGUID is the GUID for the component
   mESI.UnRegisterDynamicSource sSourceGUID
End Sub

' Unregister a normal component.
Private Sub Sample_UnregisterEventSource(ByVal sSourceGUID As String)
   ' sSourceGUID is the GUID for the component
   mESI.UnRegisterSource sSourceGUID
End Sub

' Destroy the installer object.
Private Sub Sample_DestroyESI()
   Set mESI = Nothing
End Sub


ISystemDebugEventInstall Example (Visual C++)

The following code shows the use of all methods in ISystemDebugEventInstall. In order to modify this code for your own use, you need to add error handling. Each method can raise errors, which you should make sure to trap. You can use the Windows® application Guidgen.exe to generate globally unique IDs (GUIDs) where required.

Use ISystemDebugEventInstall to register the component that will generate events and the events that component will generate. After you finish the registration process, you can generate events. ISystemDebugEventFire provides methods for generating events.

// Include required files.
#include "vaevt.h"         // ISystemDebugEventInstall #include "vaevt_i.c"      // IID_ISystemDebugEventInstall
// These files are required for generating valid GUIDs.
// Many of the VSA interface methods take a GUID as input.
#include <objbase.h>      // Required by initguid.h
#include <initguid.h>      // Ensure that GUIDs are generated by
                           // DEFINE_GUID
// Contains constants for system-defined categories and events
#include "Vaids.h"

// Now generate GUIDs for the component that will generate VSA events, as
// well as a custom event category, a user-defined event, a dynamic
// component, and the CLSID of a COM component that implements the
// dynamic event interface. The CLSID is used when you want Visual Studio
// Analyzer to start the dynamic component automatically.
DEFINE_GUID(SAMPLE_SOURCE_GUID, 0x4ED47050, 0x64EF, 0x11D1, 0xA0, 0x6C, 0x00, 0xAA, 0x00, 0x6B, 0xBF, 0xAD);
DEFINE_GUID(SAMPLE_CATEGORY_GUID, 0x4ED47051, 0x64EF, 0x11D1, 0xA0, 0x6C, 0x00, 0xAA, 0x00, 0x6B, 0xBF, 0xAD);
DEFINE_GUID(SAMPLE_EVENT_GUID, 0x4ED47052, 0x64EF, 0x11D1, 0xA0, 0x6C, 0x00, 0xAA, 0x00, 0x6B, 0xBF, 0xAD);
DEFINE_GUID(SAMPLE_DYNAMIC_SOURCE_GUID, 0x4ED47053, 0x64EF, 0x11D1, 0xA0, 0x6C, 0x00, 0xAA, 0x00, 0x6B, 0xBF, 0xAD);
DEFINE_GUID(CLSID_SAMPLE_DYNAMIC_SOURCE, 0x4ED47054, 0x64EF, 0x11D1, 0xA0, 0x6C, 0x00, 0xAA, 0x00, 0x6B, 0xBF, 0xAD);

// Declare a pointer to the event installer object.
ISystemDebugEventInstall   *pESI = NULL;

// Create the event installer object as an in-process server object.
void SampleCreateESI()
{
   CoCreateInstance( CLSID_VSA_ESI, NULL, CLSCTX_INPROC_SERVER, IID_ISystemDebugEventInstall, (void **)&pESI );
}

// Check to see whether a component is already registered.
// SAMPLE_SOURCE_GUID is the GUID for the component (defined in
// preceding code); substitute the GUID for your component.
boolean SampleIsSourceRegistered()
{
   HRESULT hr = pESI->IsSourceRegistered( SAMPLE_SOURCE_GUID );
   return( S_OK == hr );
}

// Check to see whether a dynamic component is already registered.
// SAMPLE_DYNAMIC_SOURCE_GUID is the GUID for the dynamic component
// (defined in preceding code); substitute the GUID for your dynamic
// component.
boolean SampleIsDynamicSourceRegistered()
{
   HRESULT hr = pESI->IsDynamicSourceRegistered( SAMPLE_DYNAMIC_SOURCE_GUID );
   return( S_OK == hr );
}

// Register the component we checked for in preceding code.
// SAMPLE_SOURCE_GUID is defined in preceding code; substitute the
// GUID for your component. Assign a name for the component
// (Sample Event Source) using Unicode characters.
void SampleRegisterSource()
{   pESI->RegisterSource( L"Sample Event Source", SAMPLE_SOURCE_GUID );}
// Register the dynamic component we checked for in preceding code.
// SAMPLE_DYNAMIC_SOURCE_GUID is defined in preceding code;
// substitute the GUID for your dynamic component. Assign a name
// (Sample Dynamic Source) and a description (A sample dynamic
// component) using Unicode characters.
// If the dynamic component is a COM object that you want VSA to start
// automatically, provide its CLSID (CLSID_SAMPLE_DYNAMIC_SOURCE).
// Also specify whether the COM object should be started in process (true
// or false). Note that dynamic components should usually be created
// out-of-process so that if they crash, Visual Studio Analyzer will not
// be affected.
void SampleRegisterDynamicSource()
{
   pESI->RegisterDynamicSource( L"Sample Dynamic Source", SAMPLE_DYNAMIC_SOURCE_GUID,

      L"A sample dynamic component", CLSID_SAMPLE_DYNAMIC_SOURCE, false );
}

// Register a system-defined event for the component to generate.
// SAMPLE_SOURCE_GUID is the component that will generate the event
// being registered; DEBUG_EVENT_CALL is the event.
void SampleRegisterStockEvent()
{
   pESI->RegisterStockEvent( SAMPLE_SOURCE_GUID, DEBUG_EVENT_CALL );
}

// Register a custom event category for the component.
// SAMPLE_SOURCE_GUID is the component for the category being registered.
// SAMPLE_CATEGORY_GUID is a unique GUID for the category (defined
// in preceding code); substitute the GUID for your component.

// If you want the category to appear in a hierarchy, specify a parent
// (DEBUG_EVENT_CATEGORY_ALL will be the parent of this category).
// If you do not specify a parent, your category will appear at the top
// level in the Filter Editor.
// Assign a name (Sample Event Category) and description
// (Category for all sample events) using Unicode characters.
void SampleRegisterCategory()
{
   pESI->RegisterEventCategory( SAMPLE_SOURCE_GUID, SAMPLE_CATEGORY_GUID,
      DEBUG_EVENT_CATEGORY_ALL, L"Sample Event Category",
      L"Category for all sample events", NULL, 0 );
}

// Register a user-defined event for the component to generate.
// SAMPLE_SOURCE_GUID is the component that will generate the event
// being registered.
// SAMPLE_EVENT_GUID is a unique GUID for the event (defined in
// preceding code); substitute the GUID for your component.
// Assign a Name (Sample Event) and Description (Event generated by the
// component) using Unicode characters.
void SampleRegisterCustomEvent()
{
   pESI->RegisterCustomEvent( SAMPLE_SOURCE_GUID, SAMPLE_EVENT_GUID,
      L"Sample Event", L"Event generated by the component ",
      DEBUG_EVENT_TYPE_GENERIC, SAMPLE_CATEGORY_GUID, NULL, 0 );
}
// Release the event installer object.
void SampleDestroyESI()
{
   pESI->Release();
   pESI = NULL;
}

// Normally, you would unregister your components only during uninstall.
// The following code would be placed in your component's uninstall
// code.

// Unregister the dynamic component.
void SampleUnRegisterDynamicSource()

{
   pESI->UnRegisterDynamicSource( SAMPLE_DYNAMIC_SOURCE_GUID );
}

// Unregister the component.
void SampleUnRegisterSource()

{
   pESI->UnRegisterSource( SAMPLE_SOURCE_GUID );
}


ISystemDebugEventInstall Example (Visual J++)

The following code shows the use of all methods in ISystemDebugEventInstall. In order to modify this code for your own use, you need to add error handling. Each method can raise errors, which you should make sure to trap. You can use the Windows® application Guidgen.exe to generate globally unique IDs (GUIDs) where required.

Use ISystemDebugEventInstall to register the component that will generate events and the events that component will generate. After you finish the registration process, you can generate events. ISystemDebugEventFire provides methods for generating events.

// Import required class libraries.
import vaesa.*;
import com.ms.com.Variant;
import com.ms.com.SafeArray;

// Declare an event installer object.
static ISystemDebugEventInstallAuto m_ESA = null;

// Now generate GUIDs for the component that will generate VSA events, as
// well as a custom event category, a user-defined event, a dynamic
// component, and the CLSID of a COM component that implements the
// dynamic event interface. The CLSID is used when you want Visual Studio
// Analyzer to start the dynamic component automatically.

static String SAMPLE_SOURCE_GUID = "{E736B2E0-652D-11d1-A06D-00AA006BBFAD}";
static String SAMPLE_CATEGORY_GUID = "{E736B2E1-652D-11d1-A06D-00AA006BBFAD}";
static String SAMPLE_EVENT_GUID = "{E736B2E2-652D-11d1-A06D-00AA006BBFAD}";
static String SAMPLE_DYNAMIC_SOURCE_GUID = "{E736B2E3-652D-11d1-A06D-00AA006BBFAD}";
static String CLSID_SAMPLE_DYNAMIC_SOURCE = "{E736B2E4-652D-11d1-A06D-00AA006BBFAD}";

// Define constants for a system-defined event and category
static String DEBUG_EVENT_CALL = "{6c736d61-BCBF-11D0-8A23-00AA00B58E10}";
static String DEBUG_EVENT_CATEGORY_ALL = "{6c736d85-BCBF-11D0-8A23-00AA00B58E10}";

// Declare variables for event type and for a standard event parameter
static final int DEBUG_EVENT_TYPE_GENERIC = 2;
static final int cVSAStandardParameterCorrelationID = 0x4005;

// Create an event installer object.
private static void SampleCreateESA()
   {
      m_ESA = new MSVSAAutomatableEventSourceInstaller();
   }

// Check to see whether a component is already registered.
// SAMPLE_SOURCE_GUID is the GUID for the component (defined in
// preceding code); substitute the GUID for your component.

private static boolean SampleIsSourceRegistered()
   {
      boolean registered[] = { false, false };

      m_ESA.IsSourceRegistered( SAMPLE_SOURCE_GUID, registered );
      return( registered[ 0 ] );
   }

// Register the component we checked for in preceding code.
// SAMPLE_SOURCE_GUID is defined in preceding code; substitute the
// GUID for your component.
private static void SampleRegisterSource()
   {
      m_ESA.RegisterSource( "Sample Event Source", SAMPLE_SOURCE_GUID );
   }

// Check to see whether a dynamic component is already registered.
// SAMPLE_DYNAMIC_SOURCE_GUID is the GUID for the dynamic component
// (defined in preceding code); substitute the GUID for your dynamic
// component.

private static boolean SampleIsDynamicSourceRegistered()
   {
      boolean registered[] = { false, false };

      m_ESA.IsDynamicSourceRegistered( SAMPLE_DYNAMIC_SOURCE_GUID,
         registered );
      return( registered[ 0 ] );
   }

// Register the dynamic component we checked for in preceding code.

// SAMPLE_DYNAMIC_SOURCE_GUID is defined in preceding code; substitute
// the GUID for your dynamic component.

// If the dynamic component is a COM object that you want VSA to start
// automatically, provide its CLSID (CLSID_SAMPLE_DYNAMIC_SOURCE).

// Also specify whether the COM object should be started in process (true
// or false). Note that dynamic components should usually be created
// out-of-process so that if they crash, Visual Studio Analyzer will not
// be affected.

private static void SampleRegisterDynamicSource()
   {
      m_ESA.RegisterDynamicSource( "Sample Dynamic Event Source",
         SAMPLE_DYNAMIC_SOURCE_GUID, "A sample dynamic event source",
         CLSID_SAMPLE_DYNAMIC_SOURCE, 1 );
   }

// Register a system-defined event for the component to generate.

// SAMPLE_SOURCE_GUID is the component that will generate the event
// being registered; DEBUG_EVENT_CALL is the event.

private static void SampleRegisterStockEvent()
   {
      m_ESA.RegisterStockEvent( SAMPLE_SOURCE_GUID, DEBUG_EVENT_CALL );
   }

// Register a custom event category for the component.

// SAMPLE_SOURCE_GUID is the component for the category being registered.

// SAMPLE_CATEGORY_GUID is a unique GUID for the category (defined
// in preceding code); substitute the GUID for your component.

// If you want the category to appear in a hierarchy, specify a parent
// (DEBUG_EVENT_CATEGORY_ALL will be the parent of this category).

// If you do not specify a parent, your category will appear at the top
// level in the Filter Editor.
private static void SampleRegisterCategory()
   {
      m_ESA.RegisterEventCategory( SAMPLE_SOURCE_GUID, SAMPLE_CATEGORY_GUID,
         DEBUG_EVENT_CATEGORY_ALL, "Sample Event Category",
         "Category for all sample events", null, 0 );
   }

// Register a user-defined event for the component to generate.

// SAMPLE_SOURCE_GUID is the component that will generate the event
// being registered.

// SAMPLE_EVENT_GUID is a unique GUID for the event (defined in
// preceding code); substitute the GUID for your component.

private static void SampleRegisterCustomEvent()
   {
      m_ESA.RegisterCustomEvent( SAMPLE_SOURCE_GUID, SAMPLE_EVENT_GUID,
         "Sample Event", "Event fired by the sample event source",
         DEBUG_EVENT_TYPE_GENERIC, SAMPLE_CATEGORY_GUID, null, 0 );
   }

// Destroy the event installer object.

private static void SampleDestroyESA()
   {
      m_ESA = null;
   }

// Normally, you would unregister your components only during uninstall.
// The following code would be placed in your component's uninstall
// code.

// Unregister the component.
private static void SampleUnRegisterSource()
   {
      m_ESA.UnRegisterSource( SAMPLE_SOURCE_GUID );
   }

// Unregister the dynamic component.
private static void SampleUnRegisterDynamicSource()
   {
      m_ESA.UnRegisterDynamicSource( SAMPLE_DYNAMIC_SOURCE_GUID );
   }


IsDynamicSourceRegistered

Returns a value indicating whether a particular dynamic component is already registered. A dynamic component generates events that are measured; for example, Performance Monitor is a dynamic component. Possible return values are S_OK or S_FALSE. A return value of S_FALSE means the component is not registered.

Syntax

Visual Basic | object.IsDynamicSourceRegistered(guidSourceID As String, boolRegistered As Boolean)
Visual C++ | HRESULT IsDynamicSourceRegistered([in] REFGUID guidSourceID);
Visual J++ | object.IsDynamicSourceRegistered(String guidSourceID, boolean[] boolRegistered);

Parameters

object

A unique instance of the installer object.

guidSourceID

A unique identifier for this component.

boolRegistered

Returns a value to indicate whether this dynamic component is already registered.


IsDynamicSourceRegistered Example (Visual Basic)

This example shows how to evaluate the return value from IsDynamicSourceRegistered to see whether a particular dynamic component is already registered. Refer to ISystemDebugEventInstall Example (Visual Basic) to see this code in context.

' Check to see whether a dynamic component is registered.
Private Sub Sample_IsDynamicSourceRegistered(ByVal sSourceGUID As String)
   Dim bIsRegistered As Boolean
   ' sSourceGUID is the GUID for the component.
   ' bIsRegistered is passed by reference and gets the answer.
   ' Run the method.
   mESI.IsDynamicSourceRegistered sSourceGUID, bIsRegistered
   If bIsRegistered Then MsgBox "Registered" Else MsgBox "Not Registered"
End Sub


IsDynamicSourceRegistered Example (Visual C++)

This example shows what a call to IsDynamicSourceRegistered looks like. Refer to ISystemDebugEventInstall Example (Visual C++) to see the constant declarations and object creation code, as well as to see this code in a form you can run with minor modifications.

// Check to see whether a dynamic component is already registered.

// SAMPLE_DYNAMIC_SOURCE_GUID is the GUID for the dynamic component
// (defined in preceding code); substitute the GUID for your dynamic
// component.

boolean SampleIsDynamicSourceRegistered()

{
   HRESULT hr = pESI->IsDynamicSourceRegistered( SAMPLE_DYNAMIC_SOURCE_GUID );
   return( S_OK == hr );
}


IsDynamicSourceRegistered Example (Visual J++)

This example shows what a call to IsDynamicSourceRegistered looks like. Refer to ISystemDebugEventInstall Example (Visual J++) to see the constant declarations and object creation code, as well as to see this code in a form you can run with minor modifications.

// Check to see whether a dynamic component is already registered.

// SAMPLE_DYNAMIC_SOURCE_GUID is the GUID for the dynamic component
// (defined in preceding code); substitute the GUID for your dynamic
// component.
private static boolean SampleIsDynamicSourceRegistered()
   {
      boolean registered[] = { false, false };

      m_ESA.IsDynamicSourceRegistered( SAMPLE_DYNAMIC_SOURCE_GUID, registered );
      return( registered[ 0 ] );
   }


IsSourceRegistered

Returns a value indicating whether a particular component is already registered. Possible return values are S_OK or S_FALSE. A return value of S_FALSE means the component is not registered.

Syntax

Visual Basic | object.IsSourceRegistered(guidSourceID As String, pbIsRegistered As Boolean)
Visual C++ | HRESULT IsSourceRegistered([in] REFGUID guidSourceID);
Visual J++ | object.IsSourceRegistered(String guidSourceID, boolean[] pbIsRegistered);

Parameters

object

A unique instance of the installer object.

guidSourceID

A unique identifier for this component.

pbIsRegistered

Returns a value to indicate whether this component is already registered.


IsSourceRegistered Example (Visual Basic)

This example shows how to evaluate a return value from IsSourceRegistered to see whether a particular component has already been registered. Refer to ISystemDebugEventInstall Example (Visual Basic) to see this code in context.

' Check to see whether a normal component is registered.
Private Sub Sample_IsSourceRegistered(ByVal sSourceGUID As String)
   Dim bIsRegistered As Boolean
   ' sSourceGUID is the GUID for the component.
   ' bIsRegistered is passed by reference and gets the answer.
   ' Run the method.
   mESI.IsSourceRegistered sSourceGUID, bIsRegistered
   If bIsRegistered Then MsgBox "Registered" Else MsgBox "Not Registered"
End Sub


IsSourceRegistered Example (Visual C++)

This example shows what a call to IsSourceRegistered looks like. Refer to ISystemDebugEventInstall Example (Visual C++) to see the constant declarations and object creation code, as well as to see this code in a form you can run with minor modifications.

// Check to see whether a component is already registered.

// SAMPLE_SOURCE_GUID is the GUID for the component (defined in preceding
// code); substitute the GUID for your component.
boolean SampleIsSourceRegistered()
{
   HRESULT hr = pESI->IsSourceRegistered( SAMPLE_SOURCE_GUID );
   return( S_OK == hr );
}


IsSourceRegistered Example (Visual J++)

This example shows what a call to IsSourceRegistered looks like. Refer to ISystemDebugEventInstall Example (Visual J++) to see the constant declarations and object creation code, as well as to see this code in a form you can run with minor modifications.

// Check to see whether a component is already registered.

// SAMPLE_SOURCE_GUID is the GUID for the component (defined in preceding
// code); substitute the GUID for your component.

private static boolean SampleIsSourceRegistered()
   {
      boolean registered[] = { false, false };

      m_ESA.IsSourceRegistered( SAMPLE_SOURCE_GUID, registered );
      return( registered[ 0 ] );
   }


RegisterCustomEvent

Registers each custom event the calling component might generate. A custom event is a user-defined event, usually an event that is specific to your component and that does not match any of the system-defined events included with Visual Studio Analyzer. For example, if your component is part of an order entry system, you might want one event to indicate when an order is submitted and another event to indicate when the order is shipped.

Syntax

Visual Basic | object.RegisterCustomEvent(guidSourceID As String, guidEventID As String, strVisibleName As String, strDescription As String, nEventType As Long, guidCategory As String, strIconFile As String, nIcon As Long)
Visual C++ | HRESULT RegisterCustomEvent([in] REFGUID guidSourceID, [in] REFGUID guidEventID, [in] LPCOLESTR strVisibleName, [in] LPCOLESTR strDescription, [in] long nEventType, [in] REFGUID guidCategory, [in] LPCOLESTR strIconFile, [in] long nIcon);
Visual J++ | object.RegisterCustomEvent(String guidSourceID, String guidEventID, String strVisibleName, String strDescription, int nEventType, String guidCategory, String strIconFile, int nIcon);

Parameters

object

A unique instance of the installer object.

guidSourceID

A unique identifier for this component.

guidEventID

A unique identifier for this event.

strVisibleName

The name of the event. This name is visible to the Visual Studio Analyzer user. You must use Unicode characters from the ANSI character set for the name.

strDescription

The description of the event. This description is visible to the Visual Studio Analyzer user. You must use Unicode characters from the ANSI character set for the description.

nEventType

The event type. Possible event types are OUTBOUND (the outbound, or call, part of a function or query); INBOUND (the inbound, or return, part of a function or query); GENERIC (neither outbound nor inbound); and MEASURED (caused by a periodic measurement, rather than by a specific event).

guidCategory

(Optional) The category for the event, or an empty string. Predefined event categories include STARTSTOP, CALLRETURN, QUERYRESULT, TRANSACTION, ALL, and MEASURED_ALL.

strIconFile

Not used; specify an empty string.

nIcon

Not used; specify an empty string.


RegisterCustomEvent Example (Visual Basic)

This example shows how to register a custom event. Refer to ISystemDebugEventInstall Example (Visual Basic) to see this code in context.

' Register a user-defined (custom) event.
Private Sub Sample_RegisterCustomEvent(ByVal sSourceGUID As String)
   Dim sCustomEventGUID As String
   Dim sCustomEventName As String
   Dim sCustomEventDescr As String
   Dim sIconFile As String, lIcon As Long

   ' sSourceGUID is the component for which to
   ' register this custom event.
   ' You need to create a unique GUID for the event; substitute your own
   ' in the following line
   sCustomEventGUID = "{A84C4E72-1FD7-11D1-A573-00C04FD5B402}"
   ' Assign a name and description to the event
   sCustomEventName = "MyCustomDebugEvent1"
   sCustomEventDescr = "MyCustomDebugEvent1 Description"
   ' Pass the next two parameters empty
   sIconFile = "": lIcon = 0

   ' Run the method.
   ' This call assigns the defaults for event type and category.
   mESI.RegisterCustomEvent _
      sSourceGUID, _
      sCustomEventGUID, _
      sCustomEventName, _
      sCustomEventDescr, _
      DEBUG_EVENT_TYPE_DEFAULT, DEBUG_EVENT_CATEGORY_ALL, _
      sIconFile, _
      lIcon
End Sub


RegisterCustomEvent Example (Visual C++)

This example shows what a call to RegisterCustomEvent looks like. Refer to ISystemDebugEventInstall Example (Visual C++) to see the constant declarations and object creation code, as well as to see this code in a form you can run with minor modifications.

// Register a user-defined event for the component to generate.

// SAMPLE_SOURCE_GUID is the component that will generate the event
// being registered.

// SAMPLE_EVENT_GUID is a unique GUID for the event (defined in preceding
// code); substitute the GUID for your component.
// Assign a Name (Sample Event) and Description (Event generated by the
// component) using Unicode characters.
void SampleRegisterCustomEvent()
{
   pESI->RegisterCustomEvent( SAMPLE_SOURCE_GUID, SAMPLE_EVENT_GUID,
      L"Sample Event", L"Event generated by the component ",
      DEBUG_EVENT_TYPE_GENERIC, SAMPLE_CATEGORY_GUID, NULL, 0 );
}


RegisterCustomEvent Example (Visual J++)

This example shows what a call to RegisterCustomEvent looks like. Refer to ISystemDebugEventInstall Example (Visual J++) to see the constant declarations and object creation code, as well as to see this code in a form you can run with minor modifications.

// Register a user-defined event for the component to generate.
// SAMPLE_SOURCE_GUID is the component that will generate the event
// being registered.

// SAMPLE_EVENT_GUID is a unique GUID for the event (defined in preceding
// code); substitute the GUID for your component.

private static void SampleRegisterCustomEvent()
   {
      m_ESA.RegisterCustomEvent( SAMPLE_SOURCE_GUID, SAMPLE_EVENT_GUID,
         "Sample Event", "Event fired by the sample event source",
         DEBUG_EVENT_TYPE_GENERIC, SAMPLE_CATEGORY_GUID, null, 0 );
   }


RegisterDynamicSource

Registers the calling component as a dynamic component. A dynamic component generates events that are measured; for example, Performance Monitor is a dynamic component.

Syntax

Visual Basic | object.RegisterDynamicSource(strVisibleName As String, guidSourceID As String, strDescription As String, guidClsid As String, inproc As Long)
Visual C++ | HRESULT RegisterDynamicSource([in] LPCOLESTR strVisibleName, [in] REFGUID guidSourceID, [in] LPCOLESTR strDescription, [in] REFGUID guidClsid, [in] long inproc);
Visual J++ | object.RegisterDynamicSource(String strVisibleName, String guidSourceID, String strDescription, String guidClsid, int inproc);

Parameters

object

A unique instance of the installer object.

strVisibleName

The name of the component or system that will be firing events. This name is visible to the Visual Studio Analyzer user. You must use Unicode characters from the ANSI character set for the name.

guidSourceID

A unique identifier for this component.

strDescription

The description of the component or system that will be firing events. This name is visible to the Visual Studio Analyzer user. You must use Unicode characters from the ANSI character set for the description.

guidClsid

(Optional) A unique identifier for the class to which this component belongs. Used when the component being registered is not already running on the client machine; this parameter tells the Visual Studio Analyzer server which client process to start.

inproc

(Optional) The type of client process to start. Used when the component being registered is not already running on the client machine; this parameter tells the Visual Studio Analyzer server to start the client process as either in-process or out-of-process.


RegisterDynamicSource Example (Visual Basic)

This example shows how to register a dynamic component. Refer to ISystemDebugEventInstall Example (Visual Basic) to see this code in context.

' Register a dynamic component with Visual Studio Analyzer.
Private Sub Sample_RegisterDynamicSource()
   Dim sDynamicSourceGUID As String
   Dim sDynamicSourceName As String
   Dim sDynamicSourceDescr As String
   Dim sCLSID As String
   Dim lInProc As Long
   ' You need a unique GUID to assign to the component;
   ' substitute your own in the following line.
   sDynamicSourceGUID = "{B3303260-5C87-11d1-A2AD-00AA003B23FF}"
   ' Assign a name and description to the component.
   sDynamicSourceName = "MyDynamicEventSource1"
   sDynamicSourceDescr = "MyDynamicEventSource1 Description"
   ' If the dynamic component is a COM object that you want VSA to start
   ' automatically, you need to provide its CLSID. Substitute the correct
   ' CLSID in the following line.
   sCLSID = "{B3303261-5C87-11d1-A2AD-00AA003B23FF}"
   ' Specify whether your COM object should be started in process;
   ' use nonzero for true, zero for false.
   lInProc = 1
   ' Run the method.
   mESI.RegisterDynamicSource _
      sDynamicSourceGUID, _
      sDynamicSourceName, _
      sDynamicSourceDescr, _
      sCLSID, _
      lInProc
End Sub


RegisterDynamicSource Example (Visual C++)

This example shows what a call to RegisterDynamicSource looks like. Refer to ISystemDebugEventInstall Example (Visual C++) to see the constant declarations and object creation code, as well as to see this code in a form you can run with minor modifications.

// Register the dynamic component.
// SAMPLE_DYNAMIC_SOURCE_GUID is defined in preceding code; substitute
// the GUID for your dynamic component. Assign a name (Sample Dynamic
// Source) and a description (A sample dynamic component) using Unicode
// characters.

// If the dynamic component is a COM object that you want VSA to start
// automatically, provide its CLSID (CLSID_SAMPLE_DYNAMIC_SOURCE).

// Also specify whether the COM object should be started in process (true
// or false). Note that dynamic components should usually be created
// out-of-process so that if they crash, Visual Studio Analyzer will not
// be affected.

void SampleRegisterDynamicSource()

{
   pESI->RegisterDynamicSource( L"Sample Dynamic Source",
      SAMPLE_DYNAMIC_SOURCE_GUID,

      L"A sample dynamic component", CLSID_SAMPLE_DYNAMIC_SOURCE, false );
}


RegisterDynamicSource Example (Visual J++)

This example shows what a call to RegisterDynamicSource looks like. Refer to ISystemDebugEventInstall Example (Visual J++) to see the constant declarations and object creation code, as well as to see this code in a form you can run with minor modifications.

// Register the dynamic component we checked for above.
// SAMPLE_DYNAMIC_SOURCE_GUID is defined above; substitute the GUID for
// your dynamic component.
// If the dynamic component is a COM object that you want VSA to start
// automatically, provide its CLSID (CLSID_SAMPLE_DYNAMIC_SOURCE).
// Also specify whether the COM object should be started in process (true
// or false). Note that dynamic components should usually be created
// out-of-process so that if they crash, Visual Studio Analyzer will not
// be affected.
private static void SampleRegisterDynamicSource()
   {
      m_ESA.RegisterDynamicSource( "Sample Dynamic Event Source",
         SAMPLE_DYNAMIC_SOURCE_GUID, "A sample dynamic event source",
         CLSID_SAMPLE_DYNAMIC_SOURCE, 1 );
   }


RegisterEventCategory

Registers each custom event category the component will use. Components are not required to use custom categories, so this function is optional.

You define event categories to provide some context as to how an event is used and help the Visual Studio Analyzer user locate a particular event or group of events.

Syntax

Visual Basic | object.RegisterEventCategory(guidSourceID As String, guidCategoryID As String, guidParentID As String, strVisibleName As String, strDescription As String, strIconFile As String, nIcon As Long)
Visual C++ | HRESULT RegisterEventCategory([in] REFGUID guidSourceID, [in] REFGUID guidCategoryID, [in] REFGUID guidParentID, [in] LPCOLESTR strVisibleName, [in] LPCOLESTR strDescription, [in] LPCOLESTR strIconFile, [in] long nIcon);
Visual J++ | object.RegisterEventCategory(String guidSourceID, String guidCategoryID, String guidParentID, String strVisibleName, String strDescription, String strIconFile, int nIcon);

Parameters

object

A unique instance of the installer object.

guidSourceID

A unique identifier for this component.

guidCategoryID

A unique identifier for this event category.

guidParentID

The parent category, or a string if the category is at the top level. You can arrange event categories in a hierarchy, which allows you to define the level of categorization you need. For example, Visual Studio Analyzer uses a hierarchy of event categories for Performance Monitor data to represent different objects and instances.

strVisibleName

The name of the category. This name is visible to the Visual Studio Analyzer user. You must use Unicode characters from the ANSI character set for the name.

strDescription

The description of the event category. This name is visible to the Visual Studio Analyzer user. You must use Unicode characters from the ANSI character set for the description.

strIconFile

Not used; specify an empty string.

nIcon

Not used; specify an empty string.


RegisterEventCategory Example (Visual Basic)

This example shows how to register an event category. Refer to ISystemDebugEventInstall Example (Visual Basic) to see this code in context.

' Register a custom event category.
Private Sub Sample_RegisterEventCategory(ByVal sSourceGUID As String)
   Dim sEventCategoryGUID As String
   Dim sParentGUID As String
   Dim sEventCategoryName As String
   Dim sEventCategoryDescr As String
   Dim sIconFile As String, lIcon As Long

   ' sSourceGUID is the component for which to register
   ' this custom event category.
   ' Create a unique GUID for the custom event category;
   ' substitute your own in the following line.
   sEventCategoryGUID = "{B3303263-5C87-11d1-A2AD-00AA003B23FF}"

   ' If you want to specify a position in a hierarchy,
   ' specify a parent, such as All Events; leaving this empty
   ' will place your custom category at the top level in the
   ' Filter Editor.
   sParentGUID = ""

   ' Specify a name and description for the event category
   sEventCategoryName = "MyCustomEventCategory1"
   sEventCategoryDescr = "MyCustomEventCategory1 Description"

   ' Pass the next two parameters empty
   sIconFile = "": lIcon = 0

   ' Run the method
   mESI.RegisterEventCategory sSourceGUID, _
      sEventCategoryGUID, _
      sParentGUID, _
      sEventCategoryName, _
      sEventCategoryDescr, _
      sIconFile, _
      lIcon
End Sub


RegisterEventCategory Example (Visual C++)

This example shows what a call to RegisterEventCategory looks like. Refer to ISystemDebugEventInstall Example (Visual C++) to see the constant declarations and object creation code, as well as to see this code in a form you can run with minor modifications.

// Register a custom event category for the component.

// SAMPLE_SOURCE_GUID is the component for the category being registered.

// SAMPLE_CATEGORY_GUID is a unique GUID for the category (defined
// above); substitute the GUID for your component.

// If you want the category to appear in a hierarchy, specify a parent
// (DEBUG_EVENT_CATEGORY_ALL will be the parent of this category).

// If you do not specify a parent, your category will appear at the top
// level in the Filter Editor.
// Assign a name (Sample Event Category) and description
// (Category for all sample events) using Unicode characters.
void SampleRegisterCategory()
{
   pESI->RegisterEventCategory( SAMPLE_SOURCE_GUID, SAMPLE_CATEGORY_GUID,
      DEBUG_EVENT_CATEGORY_ALL, L"Sample Event Category",
      L"Category for all sample events", NULL, 0 );
}


RegisterEventCategory Example (Visual J++)

This example shows what a call to RegisterEventCategory looks like. Refer to ISystemDebugEventInstall Example (Visual J++) to see the constant declarations and object creation code, as well as to see this code in a form you can run with minor modifications.

// Register a custom event category for the component.
// SAMPLE_SOURCE_GUID is the component for the category being registered.
// SAMPLE_CATEGORY_GUID is a unique GUID for the category (defined
// above); substitute the GUID for your component.

// If you want the category to appear in a hierarchy, specify a parent
// (DEBUG_EVENT_CATEGORY_ALL will be the parent of this category).

// If you do not specify a parent, your category will appear at the top
// level in the Filter Editor.

private static void SampleRegisterCategory()
   {
      m_ESA.RegisterEventCategory( SAMPLE_SOURCE_GUID, SAMPLE_CATEGORY_GUID,
         DEBUG_EVENT_CATEGORY_ALL, "Sample Event Category",
         "Category for all sample events", null, 0 );
   }


RegisterSource

Registers a component with Visual Studio Analyzer.

Syntax

Visual Basic | object.RegisterSource(strVisibleName As String, guidSourceID As String)
Visual C++ | HRESULT RegisterSource([in] LPCOLESTR strVisibleName, [in] REFGUID guidSourceID);
Visual J++ | object.RegisterSource(String strVisibleName, String guidSourceID);

Parameters

object

A unique instance of the installer object.

strVisibleName

The name of the component that will be firing events. This name is visible to the Visual Studio Analyzer user. You must use Unicode characters from the ANSI character set for the name.

guidSourceID

A unique identifier for this component.


RegisterSource Example (Visual Basic)

This example shows how to register a component. Refer to ISystemDebugEventInstall Example (Visual Basic) to see this code in context.

' Register a normal component with Visual Studio Analyzer.
Private Sub Sample_RegisterEventSource()
   Dim sSourceGUID As String
   Dim sSourceName As String
   ' You need a unique GUID to assign to the component;
   ' substitute your own in the following line.
   sSourceGUID = "{B3303262-5C87-11d1-A2AD-00AA003B23FF}"
   ' Assign a name to the component.
   sSourceName = "MyEventSource1"
   ' Run the method.
   mESI.RegisterSource sSourceGUID, sSourceName
End Sub


RegisterSource Example (Visual C++)

This example shows what a call to RegisterSource looks like. Refer to ISystemDebugEventInstall Example (Visual C++) to see the constant declarations and object creation code, as well as to see this code in a form you can run with minor modifications.

// Register the component we checked for above.
// SAMPLE_SOURCE_GUID is defined above; substitute the GUID for your
// component. Assign a name for the component (Sample Event Source) using
// Unicode characters.

void SampleRegisterSource()

{
   pESI->RegisterSource( L"Sample Event Source", SAMPLE_SOURCE_GUID );
}


RegisterSource Example (Visual J++)

This example shows what a call to RegisterSource looks like. Refer to ISystemDebugEventInstall Example (Visual J++) to see the constant declarations and object creation code, as well as to see this code in a form you can run with minor modifications.

// Register the component.
// SAMPLE_SOURCE_GUID is defined above; substitute the GUID for your
// component.

private static void SampleRegisterSource()
   {
      m_ESA.RegisterSource( "Sample Event Source", SAMPLE_SOURCE_GUID );
   }


RegisterStockEvent

Registers each system-defined (stock) event a component might generate. See System-defined Events for a list of the system-defined events Visual Studio Analyzer supports. Microsoft defines stock events; you define custom events.

Syntax

Visual Basic | object.RegisterStockEvent(guidSourceID As String, guidEventID As String)
Visual C++ | HRESULT RegisterStockEvent([in] REFGUID guidSourceID, [in] REFGUID guidEventID);
Visual J++ | object.RegisterStockEvent(String guidSourceID, String guidEventID);

Parameters

object

A unique instance of the installer object.

guidSourceID

A unique identifier for this component.

guidEventID

A unique identifier for this event.


RegisterStockEvent Example (Visual Basic)

This example shows how to register a system-defined event. Refer to ISystemDebugEventInstall Example (Visual Basic) to see this code in context.

' Register a system-defined (stock) event.
Private Sub Sample_RegisterStockEvents(ByVal sSourceGUID As String)
   ' sSourceGUID is the component for which to register this stock event.

   ' Run the method.
   ' This registers the stock event DEBUG_EVENT_CALL.
   mESI.RegisterStockEvent sSourceGUID, DEBUG_EVENT_CALL
End Sub


RegisterStockEvent Example (Visual C++)

This example shows what a call to RegisterStockEvent looks like. Refer to ISystemDebugEventInstall Example (Visual C++) to see the constant declarations and object creation code, as well as to see this code in a form you can run with minor modifications.

// Register a system-defined event for the component to generate.
// SAMPLE_SOURCE_GUID is the component that will generate the event
// being registered; DEBUG_EVENT_CALL is the event.

void SampleRegisterStockEvent()
{
   pESI->RegisterStockEvent( SAMPLE_SOURCE_GUID, DEBUG_EVENT_CALL );
}


RegisterStockEvent Example (Visual J++)

This example shows what a call to RegisterStockEvent looks like. Refer to ISystemDebugEventInstall Example (Visual J++) to see the constant declarations and object creation code, as well as to see this code in a form you can run with minor modifications.

// Register a system-defined event for the component to generate.
// SAMPLE_SOURCE_GUID is the component that will generate the event
// being registered; DEBUG_EVENT_CALL is the event.

private static void SampleRegisterStockEvent()
   {
      m_ESA.RegisterStockEvent( SAMPLE_SOURCE_GUID, DEBUG_EVENT_CALL );
   }


UnRegisterDynamicSource

Unregisters the calling dynamic component from the Visual Studio Analyzer framework.

Syntax

Visual Basic | object.UnRegisterDynamicSource(guidSourceID As String)
Visual C++ | HRESULT UnRegisterDynamicSource([in] REFGUID guidSourceID);
Visual J++ | object.UnRegisterDynamicSource(String guidSourceID);

Parameters

object

A unique instance of the installer object.

guidSourceID

A unique identifier for this component.


UnRegisterDynamicSource Example (Visual Basic)

This example shows how to unregister a component. Refer to ISystemDebugEventInstall Example (Visual Basic) to see this code in context.

' Unregister a dynamic component.
Private Sub Sample_UnregisterDynamicSource(ByVal sSourceGUID As String)
   ' sSourceGUID is the GUID for the component.
   mESI.UnRegisterDynamicSource sSourceGUID
End Sub


UnRegisterDynamicSource Example (Visual C++)

This example shows what a call to UnRegisterDynamicSource looks like. Refer to ISystemDebugEventInstall Example (Visual C++) to see the constant declarations and object creation code, as well as to see this code in a form you can run with minor modifications.

// Unregister the dynamic component.
void SampleUnRegisterDynamicSource()
{
   pESI->UnRegisterDynamicSource( SAMPLE_DYNAMIC_SOURCE_GUID );
}


UnRegisterDynamicSource Example (Visual J++)

This example shows what a call to UnRegisterDynamicSource looks like. Refer to ISystemDebugEventInstall Example (Visual J++) to see the constant declarations and object creation code, as well as to see this code in a form you can run with minor modifications.

// Unregister the dynamic component.
private static void SampleUnRegisterDynamicSource()
   {
      m_ESA.UnRegisterDynamicSource( SAMPLE_DYNAMIC_SOURCE_GUID );
   }


UnRegisterSource

Unregisters the calling component with the Visual Studio Analyzer framework.

Syntax

Visual Basic | object.UnRegisterSource(guidSourceID As String)
Visual C++ | HRESULT UnRegisterSource([in] REFGUID guidSourceID);
Visual J++ | object.UnRegisterSource(String guidSourceID);

Parameters

object

A unique instance of the installer object.

guidSourceID

A unique identifier for this component.


UnRegisterSource Example (Visual Basic)

This example shows how to unregister a component. Refer to ISystemDebugEventInstall Example (Visual Basic) to see this code in context.

' Unregister a normal component.
Private Sub Sample_UnregisterEventSource(ByVal sSourceGUID As String)
   ' sSourceGUID is the GUID for the component.
   mESI.UnRegisterSource sSourceGUID
End Sub


UnRegisterSource Example (Visual C++)

This example shows what a call to UnRegisterSource looks like. Refer to ISystemDebugEventInstall Example (Visual C++) to see the constant declarations and object creation code, as well as to see this code in a form you can run with minor modifications.

// Unregister the component.
void SampleUnRegisterSource()
{
   pESI->UnRegisterSource( SAMPLE_SOURCE_GUID );
}


UnRegisterSource Example (Visual J++)

This example shows what a call to UnRegisterSource looks like. Refer to ISystemDebugEventInstall Example (Visual J++) to see the constant declarations and object creation code, as well as to see this code in a form you can run with minor modifications.

// Unregister the component.
private static void SampleUnRegisterSource()
   {
      m_ESA.UnRegisterSource( SAMPLE_SOURCE_GUID );
   }


VsaRpcl

Allows systems to interact with the Visual Studio Analyzer framework without using Component Object Model (COM); this may be particularly useful in the remote procedure call (RPC)-based components on legacy systems. The VsaRpcl interface provides procedures for generating events and registering components. These procedures mirror the COM method calls in ISystemDebugEventInstall and ISystemDebugEventFire, which provide similar functionality for COM-based components. Note that the RPC interface does not support dynamic components.

VsaRpcl Procedures

VSABeginSession | Establishes the calling component as an event reporter for a specified Visual Studio Analyzer session.
VSACloseConnection | Closes the connection from the calling component to the Visual Studio Analyzer log and destroys the log.
VSAEndSession | Removes the calling component from the Visual Studio Analyzer framework.
VSAFireEvent | Generates a registered event for a registered RPC-based component.
VSAIsActive | Returns a value indicating whether there are any Visual Studio Analyzer clients interested in events generated by the calling component.
VSAIsSourceRegistered | Returns a value indicating whether the calling component is registered.
VSAOpenConnection | Opens a connection from the calling component to a Visual Studio Analyzer log.
VSARegisterCustomEvent | Registers each new user-defined event that a component might generate.
VSARegisterEventCategory | Registers each new event category you create.
VSARegisterSource | Registers a component with the Visual Studio Analyzer framework.
VSARegisterStockEvent | Registers each system-defined (stock) event a component might generate.
VSAUnregisterSource | Unregisters a component with the Visual Studio Analyzer framework.


VsaRpcl Example

The code below is a working test application, fully equipped with the WinMain function. Note that within the WinMain function you will need to change pszNetworkAddress to point to your own IP address, as described in the code comments.

You can find the files you are required to include in Program Files\Microsoft Visual Studio\Common\Tools\VS-Ent98\Vanalyzr\VAProg, if you accepted the default file locations during installation.

// Include required files
#include "windows.h"   // Required by WinMain
#include "varpc_c.c"   // Defines RPC Interface proxy functions
#include "varpc.h"      // For the declarations of the RPC Interface
                        // functions
#include "vaids.h"      // Defines constants for system-defined
                        // categories and events

// Now define GUIDs for the component that will generate VSA events, as
// well as a GUID for a custom event category, a user-defined event and a
// GUID for a parameter that can hold a GUID if you wanted to pass a GUID
// as a parameter to FireEvent.
static wchar_t str_SAMPLE_SOURCE_GUID[]      = L"{4ED47050-FD2D-11d0-86B9-00AA006C1D08}";
static wchar_t str_SAMPLE_CATEGORY_GUID[]   = L"{4ED47051-FD2D-11d0-86B9-00AA006C1D08}";
static wchar_t str_SAMPLE_EVENT_GUID[]      = L"{4ED47052-FD2D-11d0-86B9-00AA006C1D08}";
static wchar_t str_SAMPLE_GUID_PARAMETER[]   = L"{4ED47055-FD2D-11d0-86B9-00AA006C1D08}";

// Define constants for a system-defined event and category
static wchar_t str_DEBUG_EVENT_CALL[]         = L"{6c736d61-bcbf-11d0-8a23-00aa00b58e10}";
static wchar_t str_DEBUG_EVENT_CATEGORY_ALL[]   = L"{6c736d85-bcbf-11d0-8a23-00aa00b58e10}";

// Declare and initialize a variable to hold error codes
static unsigned long LastErrorCode = 0;

// Check to see whether a component is already registered.
// str_SAMPLE_SOURCE_GUID is the GUID for the component (defined in
// preceding code); substitute the GUID for your component.
static bool RpcSampleIsSourceRegistered()
{
   HRESULT hr = S_FALSE;

   RpcTryExcept
   {
      hr = VSAIsSourceRegistered(str_SAMPLE_SOURCE_GUID);
      if( (S_OK != hr) && (S_FALSE != hr ) )
         MessageBox( NULL, "Unexpected return code", "VSAIsSourceRegistered", MB_OK );
   }
   RpcExcept(1)
   {
      LastErrorCode = RpcExceptionCode();
      MessageBox( NULL, "Exception", "VSAIsSourceRegistered", MB_OK );
   }
   RpcEndExcept;

   return( S_OK == hr );
}

// Register the component we checked for in preceding code.
// str_SAMPLE_SOURCE_GUID is defined in preceding code; substitute the
// GUID for your component. Assign a name for the component
// (Sample Event Source) using Unicode characters.
static void RpcSampleRegisterSource()
{
   HRESULT hr = S_FALSE;

   RpcTryExcept
   {
      hr = VSARegisterSource( L"Sample Event Source", str_SAMPLE_SOURCE_GUID );
      if( hr )
         MessageBox( NULL, "Non-zero return code", "VSARegisterSource", MB_OK );
   }
   RpcExcept(1)
   {
      LastErrorCode = RpcExceptionCode();
      MessageBox( NULL, "Exception", "VSARegisterSource", MB_OK );
   }
   RpcEndExcept;
}

// Register a system-defined event for the component to generate.
// str_SAMPLE_SOURCE_GUID is the component that will generate the event
// being registered; str_DEBUG_EVENT_CALL is the event.
static void RpcSampleRegisterStockEvent()
{
   HRESULT hr = S_FALSE;

   RpcTryExcept
   {
      hr = VSARegisterStockEvent(str_SAMPLE_SOURCE_GUID, str_DEBUG_EVENT_CALL);
      if( hr )
         MessageBox( NULL, "Non-zero return code", "VSARegisterStockEvent", MB_OK );
   }
   RpcExcept(1)
   {
      LastErrorCode = RpcExceptionCode();
      MessageBox( NULL, "Exception", "VSARegisterStockEvent", MB_OK );
   }
   RpcEndExcept;
}

// Register a custom event category for the component.
// str_SAMPLE_SOURCE_GUID is the component for the category being
// registered.
// str_SAMPLE_CATEGORY_GUID is a unique GUID for the category (defined
// in preceding code); substitute the GUID for your component.

// If you want the category to appear in a hierarchy, specify a parent
// (str_DEBUG_EVENT_CATEGORY_ALL will be the parent of this category).
// If you do not specify a parent, your category will appear at the top
// level in the Filter Editor.
// Assign a name (Sample Event Category) and description
// (Category for all sample events) using Unicode characters.
static void RpcSampleRegisterCategory()
{
   HRESULT hr = S_FALSE;

   RpcTryExcept
   {
      hr = VSARegisterEventCategory(
         str_SAMPLE_SOURCE_GUID,
         str_SAMPLE_CATEGORY_GUID,
         str_DEBUG_EVENT_CATEGORY_ALL,
         L"Sample Event Category",
         L"Category for all sample events"
         );
      if( hr )
         MessageBox( NULL, "Non-zero return code", "VSARegisterEventCategory", MB_OK );
   }
   RpcExcept(1)
   {
      LastErrorCode = RpcExceptionCode();
      MessageBox( NULL, "Exception", "VSARegisterEventCategory", MB_OK );
   }
   RpcEndExcept;
}

// Register a user-defined event for the component to generate.
// str_SAMPLE_SOURCE_GUID is the component that will generate the event
// being registered.
// str_SAMPLE_EVENT_GUID is a unique GUID for the event (defined in
// preceding code); substitute the GUID for your component.
// Assign a Name (Sample Event) and Description (Event generated by the
// component) using Unicode characters.
static void RpcSampleRegisterCustomEvent()
{
   HRESULT hr = 0;

   RpcTryExcept
   {
      hr = VSARegisterCustomEvent(
         str_SAMPLE_SOURCE_GUID,
         str_SAMPLE_EVENT_GUID,
         L"Sample Event",
         L"Event fired by the sample event source",
         DEBUG_EVENT_TYPE_GENERIC,
         str_SAMPLE_CATEGORY_GUID
         );
      if( hr )
         MessageBox( NULL, "Non-zero return code", "VSARegisterCustomEvent", MB_OK );
   }
   RpcExcept(1)
   {
      LastErrorCode = RpcExceptionCode();
      MessageBox( NULL, "Exception", "VSARegisterCustomEvent", MB_OK );
   }
   RpcEndExcept;
}

// Normally, you would unregister your components only during uninstall.
// The following code would be placed in your component's uninstall
// code.

//Unregister the component
static void RpcSampleUnRegisterSource()
{
   HRESULT hr = 0;

   RpcTryExcept
   {
      hr = VSAUnregisterSource(str_SAMPLE_SOURCE_GUID);
      if( hr )
         MessageBox( NULL, "Non-zero return code", "VSAUnregisterSource", MB_OK );
   }
   RpcExcept(1) {
      LastErrorCode = RpcExceptionCode();
      MessageBox( NULL, "Exception", "VSAUnregisterSource", MB_OK );
   }
   RpcEndExcept;
}

// The OpenConnection and CloseConnection functions are the equivalents
// of creating and destroying an event creator object, as in the
// COM-based interface ISystemDebugEventFire.
// The VSAOpenConnection function returns an ID that is used to uniquely
// identify this session of the component.
static long RpcSampleOpenConnection()
{
   HRESULT hr = S_FALSE;
   long VSAId = 0;

   RpcTryExcept
   {
      hr = VSAOpenConnection(&VSAId);
      if( hr )
         MessageBox( NULL, "Non-zero return code", "VSAOpenConnection", MB_OK );
      else if( 0 == VSAId )
         MessageBox( NULL, "VSAId is NULL", "VSAOpenConnection", MB_OK );
   }
   RpcExcept(1) {
      LastErrorCode = RpcExceptionCode();
      MessageBox( NULL, "Exception", "VSAOpenConnection", MB_OK );
   }
   RpcEndExcept;

   return VSAId;
}

// Begin a session with the component.
// str_SAMPLE_SOURCE_GUID identifies the component. VSAId should be the
// unique ID returned by VSAOpenConnection.
// Specify a name (Sample Session Name) to uniquely identify the session
// to Visual Studio Analyzer. The session name must be unique for each
// time, each component, and each run of the component.
static void RpcSampleBeginSession(long VSAId)
{
   HRESULT hr = 0;

   RpcTryExcept
   {
      hr = VSABeginSession(VSAId,str_SAMPLE_SOURCE_GUID,L"Sample Session Name");
      if( hr )
         MessageBox( NULL, "Non-zero return code", "VSABeginSession", MB_OK );
   }
   RpcExcept(1)
   {
      LastErrorCode = RpcExceptionCode();
      MessageBox( NULL, "Exception", "VSABeginSession", MB_OK );
   }
   RpcEndExcept;
}

// Verify whether there is any active event collector interested in the
// events fired.
static bool RpcSampleIsActive(long VSAId)
{
   HRESULT hr = S_FALSE;

   RpcTryExcept
   {
      hr = VSAIsActive(VSAId);
      if( (S_OK != hr) && (S_FALSE != hr ) )
         MessageBox( NULL, "Unexpected return code", "VSAIsActive", MB_OK );
   }
   RpcExcept(1) {
      LastErrorCode = RpcExceptionCode();
      MessageBox( NULL, "Exception", "VSAIsActive", MB_OK );
   }
   RpcEndExcept;

   return( S_OK == hr );
}

// Prepare to generate an event. Define an array to hold
// event parameters

#define MAXPARAMS 2

// Generate the event.
// str_SAMPLE_EVENT_GUID is the GUID of the registered event to generate
static void RpcSampleFireCustomEvent(long VSAId)
{
   HRESULT hr = S_FALSE;

    // Event data is passed in arrays of parameter names (keys) and
    // values.
    // This array holds the parameter names.
   wchar_t * rgKeys[MAXPARAMS];
   wchar_t * rgValues[MAXPARAMS];

   rgKeys[0] = L"Custom Field 1";
   rgKeys[1] = L"Custom Field 2";
   rgValues[0] = L"Custom Value 1";
   rgValues[1] = L"Custom Value 2";

   RpcTryExcept
   {
      hr = VSAFireEvent(VSAId,str_SAMPLE_EVENT_GUID,
         MAXPARAMS, rgKeys, rgValues, 0, 0, // dwTimeLow and dwTimeHigh
                                             // values
         cVSAEventDefaultSource | cVSAEventDefaultTarget);
      if( hr )
         MessageBox( NULL, "Non-zero return code", "VSAFireEvent (Custom)", MB_OK );
   }
   RpcExcept(1)
   {
      LastErrorCode = RpcExceptionCode();
      MessageBox( NULL, "Exception", "VSAFireEvent (Custom)", MB_OK );
   }
   RpcEndExcept;
}

static void RpcSampleFireStockEvent(long VSAId)
{
   HRESULT hr = S_FALSE;

    // Event data is passed in arrays of parameter names (keys) and
    // values.
    // This array holds the parameter names.
   wchar_t * rgKeys[MAXPARAMS];
   wchar_t * rgValues[MAXPARAMS];

   rgKeys[0] = L"Field 1";
   rgKeys[1] = L"Field 2";
   rgValues[0] = L"Value 1";
   rgValues[1] = L"Value 2";

   RpcTryExcept
   {
      hr = VSAFireEvent(VSAId,str_DEBUG_EVENT_CALL,
         MAXPARAMS, rgKeys, rgValues, 0, 0, // dwTimeLow and dwTimeHigh
                                             // values
         cVSAEventDefaultSource | cVSAEventDefaultTarget);
      if( hr )
         MessageBox( NULL, "Non-zero return code", "VSAFireEvent (Stock)", MB_OK );
   }
   RpcExcept(1)
   {
      LastErrorCode = RpcExceptionCode();
      MessageBox( NULL, "Exception", "VSAFireEvent (Stock)", MB_OK );
   }
   RpcEndExcept;
}

// End the session when you are finished generating events.
static void RpcSampleEndSession(long VSAId)
{
   HRESULT hr = S_FALSE;

   RpcTryExcept
   {
      hr = VSAEndSession(VSAId);
      if( hr )
         MessageBox( NULL, "Non-zero return code", "VSAEndSession", MB_OK );
   }
   RpcExcept(1) {
      LastErrorCode = RpcExceptionCode();
      MessageBox( NULL, "Exception", "VSAEndSession", MB_OK );
   }
   RpcEndExcept;
}

// Close the connection. After the call to this function,
// VSAId would no longer be valid.
static void RpcSampleCloseConnection(long VSAId)
{
   HRESULT hr = 0;

   RpcTryExcept
   {
      VSACloseConnection(VSAId);
      if( hr )
         MessageBox( NULL, "Non-zero return code", "VSACloseConnection", MB_OK );
   }
   RpcExcept(1)
   {
      LastErrorCode = RpcExceptionCode();
      MessageBox( NULL, "Exception", "VSACloseConnection", MB_OK );
   }
   RpcEndExcept;
}

// The code that follows creates a test application you can use to
// call the above functions. If you choose to write your own RPC test
// application, make sure to use the end point "2000" when you do the
// RPC binding. Also, make sure to use the correct IP address of the server.
// MIDL allocate and free code is also included in the
// following code just to demonstrate. You can substitute your own MIDL
// allocate and free code.

int WINAPI WinMain(HINSTANCE hInstance,
                            HINSTANCE hPrevInstance,
                            LPSTR lpszCmdLine,
                            int nCmdShow)

{
   RPC_STATUS status;
   unsigned char * pszUuid             = NULL;
   unsigned char * pszProtocolSequence = (unsigned char *)"ncacn_ip_tcp";

    // Change this address to the IP address of the machine where the
    // Visual Studio Analyzer RPC service is running.
   unsigned char * pszNetworkAddress   = (unsigned char *)"172.30.169.32";

    // 2000 is the end point used by the Visual Studio Analyzer RPC bridge
    // server
   unsigned char * pszEndpoint         = (unsigned char *)"2000";
   unsigned char * pszOptions          = NULL;
   unsigned char * pszStringBinding    = NULL;

   status = RpcStringBindingCompose(pszUuid,
      pszProtocolSequence,
      pszNetworkAddress,
      pszEndpoint,
      pszOptions,
      &pszStringBinding);

   if (status)
   {
      exit(status);
   }

   // Set the binding handle that will be used to bind to the server.
   status = RpcBindingFromStringBinding(pszStringBinding, &VsaRpcl_IfHandle);
   if (status)
   {
      exit(status);
   }

   // Call RegisterSource
   RpcSampleRegisterSource();

   // Call IsSourceRegistered
   if (RpcSampleIsSourceRegistered())
   {
      MessageBox(NULL, "Source is registered", "IsSourceRegistered", MB_OK);
   }
   else
   {
      MessageBox(NULL, "Source is not registered", "IsSourceRegistered", MB_OK);
   }

   // Call RegisterStockEvent
   RpcSampleRegisterStockEvent();

   // Call RegisterEventCategory
   RpcSampleRegisterCategory();

   // Call RegisterCustomEvent
   RpcSampleRegisterCustomEvent();

   // Call Open Connection
   long VSAId = RpcSampleOpenConnection();

   // Call BeginSession
   RpcSampleBeginSession(VSAId);

   // Call IsActive
   if (RpcSampleIsActive(VSAId))
   {
      MessageBox(NULL, "Ready to generate events", "IsActive", MB_OK);
   }
   else
   {
      MessageBox(NULL, "Not ready to generate events", "IsActive", MB_OK);
   }

   // Call FireEvent 10 times for Custom and Stock events
   for( int i = 0; i < 10; ++i )
   {
      RpcSampleFireCustomEvent(VSAId);
      RpcSampleFireStockEvent(VSAId);
   }

   // Call EndSession
   RpcSampleEndSession(VSAId);

   // Call CloseConnection
   RpcSampleCloseConnection(VSAId);

   // Call UnregisterSource
   RpcSampleUnRegisterSource();

   //  The calls to the remote procedures are complete.
   //  Free the string and the binding handle
   status = RpcStringFree(&pszStringBinding);
   if (status)
   {
      exit(status);
   }

   status = RpcBindingFree(&VsaRpcl_IfHandle);
   if (status)
   {
      exit(status);
   }

   return 0;
}

// MIDL allocate and free

void  __RPC_FAR * __RPC_USER midl_user_allocate(size_t len)
{
   return(malloc(len));
}

void __RPC_USER midl_user_free(void __RPC_FAR * ptr)
{
   free(ptr);
}


VSABeginSession

Starts a Visual Studio Analyzer session with the calling component. You assign a unique identifier to the session. Events that are generated during this session are stamped with the session identifier, which helps you identify the true source of an event, particularly in cases where multiple copies of the component are running at the same time.

Syntax

HRESULT VSABeginSession ([in] long vaaId,
[in, string] wchar_t *guidSourceID,
[in, string] wchar_t *strSessionName);

Parameters

vaaId

Unique identifier for this session of the component. This identifier is returned when you call VSAOpenConnection.

guidSourceID

A unique identifier for this component. Multiple sessions from this component can exist at the same time on the same machine. This ID is defined when you register a component with Visual Studio Analyzer.

strSessionName

A session identifier, which must be unique among all instances of this component until the machine is restarted.

Remarks

Each Visual Studio Analyzer in-process event creator object can accept only one call to BeginSession. If your object supports multiple simultaneous sessions, such as a Web server running on more than one port, you can choose to create multiple in-process event creator objects.

The code does not validate whether strSessionName is unique. If it is not unique, the user might be unable to distinguish events from the two sessions. This lack of checking allows for two servers that represent one conceptual session to coexist and operate correctly.

This function will fail if guidSourceID is not properly registered.

You can use the default user component, DEBUG_EVENT_SOURCE_USER, which is already registered, if you want a quick way to generate events without a lot of overhead. The default user component is registered automatically when you install Visual Studio Analyzer.

You can make repeated calls to BeginSession and EndSession on the same object, as long as you have a matching BeginSession call for each EndSession call. You cannot nest calls.

Accepted | Not Accepted
BeginSession | BeginSession
EndSession | BeginSession
BeginSession | EndSession
EndSession | EndSession


VSABeginSession Example

This example shows what a call to VSABeginSession looks like. Refer to VsaRpcl Example to see the constant declarations and to see this code in a form you can run with minor modifications.

// Begin a session with the component.
// str_SAMPLE_SOURCE_GUID identifies the component.
// Specify a name (Sample Session Name) to uniquely identify the session
// to Visual Studio Analyzer. The session name must be unique for each
// time, each component, and each run of the component.
static void RpcSampleBeginSession(long VSAId)
{
   RpcTryExcept
   {
      VSABeginSession(VSAId,str_SAMPLE_SOURCE_GUID,L"Sample Session Name");
   }
   RpcExcept(1)
   {
      LastErrorCode = RpcExceptionCode();
   }
   RpcEndExcept;
}


VSACloseConnection

Destroys the remote Visual Studio Analyzer server invocation for the calling RPC-based component, closing the connection to the Visual Studio Analyzer event log and destroying the log.

Syntax

HRESULT VSACloseConnection([in] long vaaID);

Parameters

vaaID

Unique identifier for this invocation of this component; maps to a remote Visual Studio Analyzer server invocation.


VSACloseConnection Example

This example shows what a call to VSACloseConnection looks like. Refer to VsaRpcl Example to see the constant declarations and to see this code in a form you can run with minor modifications.

// Close the connection
static void RpcSampleCloseConnection(long VSAId)
{
   RpcTryExcept
   {
      VSACloseConnection(VSAId);
   }
   RpcExcept(1)
   {
      LastErrorCode = RpcExceptionCode();
   }
   RpcEndExcept;
}


VSAEndSession

Removes the calling RPC-based component as a component for a specified Visual Studio Analyzer session.

Syntax

HRESULT VSAEndSession([in] long vaaID);

Parameters

vaaID

Unique identifier for this invocation of this component.

Remarks

You can make repeated calls to EndSession during the same session, as long as you have a matching BeginSession call for each EndSession call. You cannot nest calls.

Accepted | Not Accepted
BeginSession | BeginSession
EndSession | BeginSession
BeginSession | EndSession
EndSession | EndSession


VSAEndSession Example

This example shows what a call to VSAEndSession looks like. Refer to VsaRpcl Example to see the constant declarations and to see this code in a form you can run with minor modifications.

// End the session when you are finished generating events.
static void RpcSampleEndSession(long VSAId)
{
   RpcTryExcept
   {
      VSAEndSession(VSAId);
   }
   RpcExcept(1)
   {
      LastErrorCode = RpcExceptionCode();
   }
   RpcEndExcept;
}


VSAFireEvent

Generates a registered event for a registered RPC-based component.

Syntax

HRESULT VSAFireEvent([in] long vaaID,
[in, string] wchar_t *guidEvent,
[in] long prgCount,
[in, string, size_is(prgCount)] wchar_t *prgKeys[],
[in, string, size_is(prgCount)] wchar_t *prgValues,
[in] long dwTimeLow,
[in] long dwTimeHigh,
[in] VSAEventFlags dwFlags);

Parameters

vaaID

Unique identifier for this session of the component.

guidEvent

The event being generated. Events have many possible parameters, which are specified in the rgKeys and rgValues arrays; the parameter types are specified in the rgType array.

prgCount

Number of entries in the prgKeys and prgValues arrays.

prgKeys

Names of event fields passed for this event. See VSAStandardParameter for a list of the available event fields.

prgValues

Values for the event fields passed for this event.

dwTimeLow

The local time of the event, or 0. (Low 32 bits.)

dwTimeHigh

The local time of the event, or 0. (High 32 bits.)

dwFlags

Provides default values for a group of event parameters. See VSAEventFlags for a list of the possible flags.

Remarks

Pass in 0 for the dwTimeLow and dwTimeHigh parameters unless the component is running on a Windows NT® machine. If the component is running on a Windows NT machine, you can set the dwTimeLow and dwTimeHigh parameters using the return value of QueryPerformanceCounter. If you pass in 0 for these parameters, Visual Studio Analyzer defaults to the current time. If you know that the event happened at a different time, you should pass that time in.


VSAFireEvent Example

This example shows what a call to VSAFireEvent looks like. Refer to VsaRpcl Example to see the constant declarations and to see this code in a form you can run with minor modifications.

// Prepare to generate an event. Define an array to hold
// event parameters

#define MAXPARAMS 2

// Generate the event.
// str_SAMPLE_EVENT_GUID is the GUID of the registered event to generate
static void RpcSampleFireEvent(long VSAId)
{
   // Event data is passed in arrays of parameter names (keys) and
   // values.
   // This array holds the parameter names.
   wchar_t * rgKeys[MAXPARAMS];
   wchar_t * rgValues[MAXPARAMS];

   rgKeys[0] = L"Custom Field 1";
   rgKeys[1] = L"Custom Field 2";
   rgValues[0] = L"Custom value 1";
   rgValues[1] = L"Custom value 2";

   RpcTryExcept
   {
      VSAFireEvent(VSAId,str_SAMPLE_EVENT_GUID,
         MAXPARAMS,
         rgKeys, rgValues,
         0,0,                //dwTimeLow and dwTimeHigh values
         cVSAEventDefaultSource | cVSAEventDefaultTarget);
   }
   RpcExcept(1)
   {
      LastErrorCode = RpcExceptionCode();
   }
   RpcEndExcept;
}


VSAIsActive

Returns a value indicating whether there are any Visual Studio Analyzer clients interested in events generated by the calling RPC-based component. Possible return values are S_OK or S_FALSE; a return value of S_FALSE means that events need not be generated.

The VSAFireEvent method calls VSAIsActive anyway, so if generating an event is low impact, you might choose to omit the VSAIsActive test. If generating an event does impact the system, call VSAIsActive to make sure a client is interested in the event first.

Syntax

HRESULT VSAIsActive([in] long vaaId);

Parameters

vaaID

Unique identifier for this component session.


VSAIsActive Example

This example shows what a call to VSAIsActive looks like. Refer to VsaRpcl Example to see the constant declarations and to see this code in a form you can run with minor modifications.

// Verify that the component is ready to generate events
static bool RpcSampleIsActive(long VSAId)
{
   BOOL active = FALSE;

   RpcTryExcept
   {
      BOOL active = VSAIsActive(VSAId);
   }
   RpcExcept(1)
   {
      LastErrorCode = RpcExceptionCode();
   }
   RpcEndExcept;

   return( (active == TRUE) ? true:false );
}


VSAIsSourceRegistered

Returns a value indicating whether the calling RPC-based component is registered. Possible return values are S_OK or S_FALSE. A return value of S_FALSE means the component is not registered.

Syntax

HRESULT VSAIsSourceRegistered([in, string] wchar_t *guidSourceID);

Parameters

guidSourceID

A unique identifier for this component.


VSAIsSourceRegistered Example

This example shows what a call to VSAIsSourceRegistered looks like. Refer to VsaRpcl Example to see the constant declarations and to see this code in a form you can run with minor modifications.

// Check to see whether a component is already registered.
// str_SAMPLE_SOURCE_GUID is the GUID for the component (defined in
// preceding code); substitute the GUID for your component.
static bool RpcSampleIsSourceRegistered()
{
   long hr = S_FALSE;

   RpcTryExcept
   {
      hr = VSAIsSourceRegistered(str_SAMPLE_SOURCE_GUID);
   }
   RpcExcept(1)
   {
      LastErrorCode = RpcExceptionCode();
   }
   RpcEndExcept;
   return( S_OK == hr );
}


VSAOpenConnection

Opens a connection from the calling RPC-based component to a Visual Studio Analyzer log. Called by each invocation of an RPC-based component; returns a unique identifier to a remote Visual Studio Analyzer server invocation. This identifier is used in all subsequent calls until the connection is closed.

Syntax

HRESULT VSAOpenConnection([out] long vaaID);

Parameters

vaaID

Unique identifier to a remote Visual Studio Analyzer server invocation.


VSAOpenConnection Example

This example shows what a call to VSAOpenConnection looks like. Refer to VsaRpcl Example to see the constant declarations and to see this code in a form you can run with minor modifications.

// The VSAOpenConnection function returns an ID that is used to uniquely
// identify this session of the component.

static long RpcSampleOpenConnection()
{
   long VSAId = 0;

   RpcTryExcept
   {
      VSAOpenConnection(&VSAId);
   }
   RpcExcept(1)
   {
      LastErrorCode = RpcExceptionCode();
   }
   RpcEndExcept;

   return VSAId;
}


VSARegisterCustomEvent

Registers each custom event the calling component might generate. A custom event is a user-defined event, usually an event that is specific to your component and that doesn't match any of the system-defined events included with Visual Studio Analyzer. For example, if your component is part of an order entry system, you might want one event to indicate when an order is submitted and another event to indicate when the order is shipped.

Syntax

HRESULT VSARegisterCustomEvent([in, string] wchar_t *guidSourceID,
[in, string] wchar_t *guidEventID,
[in, string] wchar_t *strVisibleName,
[in, string] wchar_t *strDescription,
[in] long nEventType,
[in, string] wchar_t *guidCategory);

Parameters

guidSourceID

A unique identifier for this component.

guidEventID

A unique identifier for this event.

strVisibleName

The name of the component or system that will be firing events. This name is visible to the user. You must use ANSI characters for the name.

strDescription

The description of the component or system that will be firing events. This name is visible to the user. You must use ANSI characters for the description.

nEventType

The event type. Possible event types are OUTBOUND (the outbound, or call, part of a function or query); INBOUND (the inbound, or return, part of a function or query); GENERIC (neither outbound nor inbound); and MEASURED (caused by a periodic measurement, rather than by a specific event).

guidCategory

(Optional.) The category for the event, or an empty string. Predefined event categories include STARTSTOP, CALLRETURN, QUERYRESULT, TRANSACTION, ALL, and MEASURED_ALL.


VSARegisterCustomEvent Example

This example shows what a call to VSARegisterCustomEvent looks like. Refer to VsaRpcl Example to see the constant declarations and to see this code in a form you can run with minor modifications.

// Register a user-defined event for the component to generate.
// str_SAMPLE_SOURCE_GUID is the component that will generate the event
// being registered.
// str_SAMPLE_EVENT_GUID is a unique GUID for the event (defined in
// preceding code); substitute the GUID for your component.
// Assign a Name (Sample Event) and Description (Event generated by the
// component) using Unicode characters.
static void RpcSampleRegisterCustomEvent()
{
   RpcTryExcept
   {
      VSARegisterCustomEvent(
         str_SAMPLE_SOURCE_GUID,
         str_SAMPLE_EVENT_GUID,
         L"Sample Event",
         L"Event generated by the sample event source",
         DEBUG_EVENT_TYPE_GENERIC,
         str_SAMPLE_CATEGORY_GUID
         );
   }
   RpcExcept(1)
   {
      LastErrorCode = RpcExceptionCode();
   }
   RpcEndExcept;
}


VSARegisterEventCategory

Registers each category the component will use. Components are not required to use categories, so this function is optional.

Event categories provide some context as to how an event is used and help the Visual Studio Analyzer user locate a particular event or group of events.

Syntax

HRESULT VSARegisterEventCategory([in, string] wchar_t *guidSourceID,
[in, string] wchar_t *guidCategoryID,
[in, string] wchar_t *guidParentID,
[in, string] wchar_t *strVisibleName,
[in, string] wchar_t *strDescription);

Parameters

guidSourceID

A unique identifier for this component.

guidCategoryID

A unique identifier for this event category.

guidParentID

The parent category, or NULL if the category is at the top level.

strVisibleName

The name of the category. This name is visible to the user. You must use ANSI characters for the name.

strDescription

The description of the event category. This name is visible to the user. You must use ANSI characters for the description.


VSARegisterEventCategory Example

This example shows what a call to VSARegisterEventCategory looks like. Refer to VsaRpcl Example to see the constant declarations and to see this code in a form you can run with minor modifications.

// Register a custom event category for the component.
// str_SAMPLE_SOURCE_GUID is the component for the category being
// registered.
// str_SAMPLE_CATEGORY_GUID is a unique GUID for the category (defined
// in preceding code); substitute the GUID for your component.

// If you want the category to appear in a hierarchy, specify a parent
// (str_DEBUG_EVENT_CATEGORY_ALL will be the parent of this category).
// If you do not specify a parent, your category will appear at the top
// level in the Filter Editor.
// Assign a name (Sample Event Category) and description
// (Category for all sample events) using Unicode characters.
static void RpcSampleRegisterCategory()
{
   RpcTryExcept
   {
      VSARegisterEventCategory(
         str_SAMPLE_SOURCE_GUID,
         str_SAMPLE_CATEGORY_GUID,
         str_DEBUG_EVENT_CATEGORY_ALL,
         L"Sample Event Category",
         L"Category for all sample events"
         );
   }
   RpcExcept(1)
   {
      LastErrorCode = RpcExceptionCode();
   }
   RpcEndExcept;
}


VSARegisterSource

Registers a component with the Visual Studio Analyzer framework.

Syntax

HRESULT VSARegisterSource([in, string] wchar_t *strVisibleName,
[in, string] wchar_t *guidSourceID);

Parameters

strVisibleName

The name of the component or system that will be firing events. This name is visible to the user. You must use ANSI characters for the name.

guidSourceID

A unique identifier for this component.


VSARegisterSource Example

This example shows what a call to VSARegisterSource looks like. Refer to VsaRpcl Example to see the constant declarations and to see this code in a form you can run with minor modifications.

// Register the component we checked for in preceding code.
// str_SAMPLE_SOURCE_GUID is defined in preceding code; substitute the
// GUID for your component. Assign a name for the component
// (Sample Event Source) using Unicode characters.
static void RpcSampleRegisterSource()
{
   RpcTryExcept
   {
      VSARegisterSource( L"Sample Event Source", str_SAMPLE_SOURCE_GUID );
   }
   RpcExcept(1)
   {
      LastErrorCode = RpcExceptionCode();
   }
   RpcEndExcept;
}


VSARegisterStockEvent

Registers each system-defined (stock) event a component might generate. See System-defined Events for a list of the system-defined events Visual Studio Analyzer supports. Microsoft defines stock events; you define custom events.

Syntax

HRESULT VSARegisterStockEvent([in, string] wchar_t *guidSourceID, [in, string] wchar_t *guidEventID);

Parameters

guidSourceID

A unique identifier for this component.

guidEventID

A unique identifier for this event.


VSARegisterStockEvent Example

This example shows what a call to VSARegisterStockEvent looks like. Refer to VsaRpcl Example to see the constant declarations and to see this code in a form you can run with minor modifications.

// Register a system-defined event for the component to generate.
// str_SAMPLE_SOURCE_GUID is the component that will generate the event
// being registered; str_DEBUG_EVENT_CALL is the event.
static void RpcSampleRegisterStockEvent()
{
   RpcTryExcept
   {
      VSARegisterStockEvent(str_SAMPLE_SOURCE_GUID,
         str_DEBUG_EVENT_CALL);
   }
   RpcExcept(1)
   {
      LastErrorCode = RpcExceptionCode();
   }
   RpcEndExcept;
}


VSAUnRegisterSource

Unregisters the calling component as a component.

Syntax

HRESULT VSAUnRegisterSource([in, string] wchar_t *guidSourceID);

Parameters

guidSourceID

A unique identifier for this component.


VSAUnRegisterSource Example

This example shows what a call to VSAUnRegisterSource looks like. Refer to VsaRpcl Example to see the constant declarations and to see this code in a form you can run with minor modifications.

//Unregister the component
static void RpcSampleUnRegisterSource()
{
   RpcTryExcept
   {
      VSAUnregisterSource(str_SAMPLE_SOURCE_GUID);
   }
   RpcExcept(1)
   {
      LastErrorCode = RpcExceptionCode();
   }
   RpcEndExcept;
}


Visual Studio Analyzer User Interface Reference

This section includes reference information on items in Microsoft® Visual Studio™ Analyzer's user interface. Select any of the links below for more information on the named item.

Add Graph Dialog Box

Add Item Dialog Box

Add/Remove Columns Dialog Box

Analyzer (Options Dialog Box)

Analyzer Toolbar

Analyzer Windows Toolbar

Block Diagram Views

Chart View

Connect to Machine Dialog Box

Event List View

Event View

Filter Editor Dialog Box

Project Explorer — Visual Studio Analyzer Projects

Summary View

Timeline View

Visual Studio Analyzer Import From and Export to File Dialog Box

Visual Studio Analyzer Project Wizard


Add Graph Dialog Box

Use the Add Graph dialog box to add line graphs representing Microsoft® Windows NT® Performance Monitor counters to a Visual Studio Analyzer Chart view. Adding line graphs to the Chart view shows you environment activity, such as CPU usage, along with Visual Studio Analyzer events.

The Add Graph dialog box constructs a filter that it uses to draw the line graph on the Chart view. This filter specifies the machine, component, and Performance Monitor event of interest.

Although the Add Graph dialog box appears very similar to the Filter Editor dialog box, the Add Graph dialog box is different in the following ways:

  • You can select only one item in each column; therefore, you cannot select parent items. Performance Monitor data comes from the Perfmon Dynamic Source component listed in the Components column.

  • The Categories/Events column shows existing events in the event log in bold. You can select any event (bold or not). Selecting events that are not bold causes the event to be graphed when data arrives. This is useful for future sessions.

  • Only measured events are included in the Categories/Events column.

  • Only machines are included in the Machines/Processes column.

Options

Categories/Events

Specifies the available Performance Monitor events, organized by category. Click the plus sign next to a subcategory to display a list of events in that category. You can select only one Performance Monitor event at a time. If you want to look at more than one Performance Monitor event, you need to add a line graph for each one.

Components

Specifies the components of interest. You can select only one component at a time. If you want to look at more than one component, you need to add a line graph for each one.

Edit Text

Displays the filter in an edit box where you can type the expression representing the filter.

Warning Some filters, although you can type them in yourself, cannot be shown using the Filter Editor user interface. An example of these filters is an expression that uses inequality operators, such as <>. When you click Edit Text, a message appears that warns you about this. Click OK to confirm that you want to edit the filter text. Also, although you can enter any filter you want using Edit Text, it is possible that such a filter will not be suitable for graphing.

Machines/Processes

Specifies the machines of interest.


Add Item Dialog Box

Use the Add Item dialog box to add machines, event logs, and filters to your Visual Studio Analyzer project (the New tab) or to open an event log or filter in an existing Visual Studio Analyzer project (the Existing tab).

Options

Event Log

Creates a new empty event log to contain Visual Studio Analyzer events. By default, this new event log is set to record events next time you run your application. Make sure you activate a filter as well; the filter determines what events are collected in the event log.

Filter

Creates a new filter to identify Visual Studio Analyzer events to collect, and opens the filter in the Filter Editor. If you want to use this new filter to determine which events are collected the next time you run your application, make sure to activate the filter by clicking Set Record Filter on the shortcut menu.

The predefined filters shipped with Visual Studio Analyzer also appear in the Add Item dialog box. Click any of the predefined filters to add them to your project; you can use the Filter Editor dialog box to modify them to suit your purposes. The predefined filters are shown in the following list.

  • Advanced Events

  • Basic Events

  • Intermediate Events

  • All Events Except Performance

  • Basic Performance Events

  • Basic COM (and MTS) Events

  • Basic Database Events

  • Basic Object Events

  • Basic Web Events

Machine

Displays the Connect to Machine dialog box, where you can specify the name of a machine you want to monitor for Visual Studio Analyzer events. Make sure that the Visual Studio Analyzer Server components are installed on any Windows machine you want to monitor.

Sample

Adds the sample event log to your project. This event log is shipped with Visual Studio Analyzer to provide a way for you to familiarize yourself with Visual Studio Analyzer's features without connecting to other machines or recording any data.


Add/Remove Columns Dialog Box

Use the Add/Remove Columns dialog box to customize the information you see in the Event List view, the event tree in the Chart view, and the Summary view.

Options

Add

Moves selected columns from the list of available columns to the list of selected columns. When you close the dialog box, the Event List view will redisplay with the columns you choose.

Available Columns

Contains an alphabetical list of the columns that you can add to the Event List view. You can select a column name and click Add.

Move Up, Move Down

Reorder column names in the Selected Columns list. You can undo changes by clicking Reset. Does not work with more than one column name selected.

Remove

Moves columns from the list of selected columns to the list of available columns. When you close the dialog box, the Event List view will redisplay with the columns you choose.

Reset

Resets the columns in the Available and Selected Columns lists to the way they were when you opened the Add/Remove Columns dialog box. In addition to moving columns back to the lists where they originated, Reset undoes any ordering changes you make with the Move Up and Move Down buttons.

Selected Columns

Contains a list of the columns that will be displayed in the Event List view when you close this dialog box. To remove a column from the view, select its name and click Remove.


Analyzer (Options Dialog Box)

Use this page to set preferences for Visual Studio Analyzer. You can customize the settings for new Visual Studio Analyzer views (windows), set the interval at which measured events are generated, specify whether to hide measured events in the Event List view, and specify whether to pause the application you are monitoring if necessary to finish event processing.

Options

Pause client application if necessary to process all events

Specifies whether to pause your distributed application in order to finish moving all previously generated Visual Studio Analyzer events to the Visual Studio Analyzer event collector. When your application generates Visual Studio Analyzer events, they are gathered in a buffer and then moved in groups to the Visual Studio Analyzer event collector.

This option is off by default to ensure that your application isn't ever blocked by Visual Studio Analyzer. If your application is blocked by Visual Studio Analyzer, you can lose data necessary to your analysis. For example, you might miss a crucial request-response pair that shows the true location of a problem.

Hide measured events in Event List

Specifies whether to hide measured events in the Event List view. These events are hidden by default in the Block Diagram views and the Chart view. This option applies to unfiltered views only.

This option is off by default.

AutoFilter new windows

Specifies whether newly opened Visual Studio Analyzer views are automatically linked to the current autofilter.

This option is on by default.

AutoSelect new windows

Specifies whether newly opened Visual Studio Analyzer views are automatically linked to other open views, so that when you select an event in one view, the same event is selected in all other views.

This option is on by default.

AutoPlayTrack new windows

Specifies whether newly opened Visual Studio Analyzer views automatically change during playback.

This option is on by default.

Measured event firing period 1 event every ... millisecond

Sets a time period for generating measured events. The default value is every 1000 milliseconds.


Analyzer Toolbar

Use this toolbar for quick access to Visual Studio Analyzer commands. You can display the Analyzer toolbar by right-clicking in a blank spot on the displayed toolbar, and then clicking Analyzer. The toolbar is shown in the following picture.

Button | Function
Connect to Machine | Displays the Connect to Machine dialog box, where you can specify the name of a machine you want to monitor with Visual Studio Analyzer.
Go To Event | Moves to a selected event in the event log.
Increase Playback Speed, Decrease Playback Speed | Changes the speed of playback.
Pause Event Recording | Suspends recording events into a particular event log. Click this button again to resume recording events.
Record Events | Starts recording events into a particular event log. Click this button again to stop recording events.
Replay Events | Starts playing back the events in the event log from the currently selected event.
Show First Event | Moves back to and selects the first event in the event log.
Show Last Event | Moves to and selects the last event in the event log.
Show Previous Event, Show Next Event | Steps backward or forward one event in the event log.
Stop Replay | Stops playing back events.


Analyzer Windows Toolbar

Use the Analyzer Windows toolbar to manage the different Visual Studio Analyzer views. The Analyzer Windows toolbar is shown in the following illustration.

Button | Function
AutoSelect | Controls whether the view is linked to other open views, so that when you select an event in any open view, that event is also selected in every other open view.
AutoFilter | Controls whether the view is linked to the current autofilter, so that when you change the filter, the changes are immediately reflected in the view and in all other views that are linked to the current autofilter.
AutoPlayTrack | Controls whether the view changes during playback to highlight each event as it occurs.
New Chart | Opens a new Chart view on the selected event log.
New Component Diagram | Opens a new Component Diagram view on the selected event log.
New Event List | Opens a new Event List view on the selected event log.
New Event Viewer | Opens a new Event view on the selected event log.
New Machine Diagram | Opens a new Machine Diagram view on the selected event log.
New Process Diagram | Opens a new Process Diagram view on the selected event log.
View Summary | Opens the Summary view on the selected event log.
View Timeline | Opens the Timeline view on the selected event log.
Zoom In | Zooms in on the selected view.
Zoom Out | Zooms out on the selected view.
Zoom to Fit | Sizes the selected view to fit within the window.


Block Diagram Views

Use the three Block Diagram views — the Machine Diagram, the Process Diagram, and the Component Diagram — to understand the structure and interactions of your application. The Block Diagram views present a diagram of your application, constructed from the events in the event log; you can play back the events as they occurred. You can use standard VCR-like buttons to navigate forward or backward through events. You can also skip events until a different component is involved — this choice omits back-and-forth messages between the same two components.

The event playback is animated. You can adjust the speed of the animation, and that speed is remembered.

The following picture shows what the Component Diagram view looks like.

Options

Collapse Selection

Collapses the selected machine, process, or component to show only the parent machine, process, or component; child processes, components, and events are not shown.

Expand Selection

Expands the selected machine, process, or component to show its child processes, components, or events.

Zoom In

Zooms in on the selected view.

Zoom Out

Zooms out on the selected view.

Zoom to Fit

Sizes the selected view to fit within the window.


Chart View

Use the Chart View when you want to understand an application's performance. The Chart View presents application performance data using a tree view of request-response pairs (for example, function call and return) and an associated Gantt chart that shows each pair's timing. Use the separator to resize. Each node visible in the tree has a corresponding Gantt entry. As new data that meets the filter criteria arrives, it is added to the view.

You can play back the events shown in the view. You can use standard VCR-like buttons to navigate forward or backward through events. You can also skip events until a different component is involved — this choice omits back-and-forth messages between the same two components.

The event playback is animated. You can adjust the animation's speed, and that speed is remembered.

When you select an event, the event, its parent events, and all its child events are selected. If you want to select a group of events for a particular time range, you can click and drag the mouse in the Gantt chart portion of the view. If necessary, you can refine the display by zooming.

The following picture shows what the Chart View looks like.

Combining Views

You can augment the Chart View by adding or removing application performance data and Windows NT® Performance Monitor data. This information is overlaid on the Chart view. You can use this overlaid view to see whether lengthy times for request-response pairs correspond to high values in processor usage or other dynamic event data.

Adding Performance Monitor Data

Performance Monitor data is plotted on a line chart. To add Performance Monitor data, you add a line graph for the counter in which you are interested to the Chart View. See Adding and Removing Line Graphs in the Chart View for step-by-step procedures.

When you add a new event type, or as new data arrives, the new data is added to the graph. This means that the viewer scales data so that it can be added, because multiple data items are plotted at the same time. Within the graph, the X-axis represents time and the Y-axis represents the scaled values associated with events. Whenever a new line is added to the graph, an entry is added to the legend at the bottom of the tool window.

Understanding the Line Graphs

When you add a line graph for a particular Performance Monitor counter, the counters are graphed differently depending on the units of the data in the counter. Performance Monitor data can be in any of the following units:

  • Raw number (for example, bytes, or number of handles)

  • Rate (for example, interrupts per second)

  • Percentage (for example, CPU utilization)

Data expressed as a percentage is always graphed such that the minimum value is 0 and the maximum value is 100.

Data expressed as raw numbers or as rates is graphed such that the minimum value is mapped to the bottom of the chart (0 on the right), the maximum data value is mapped to the top of the chart (100 on the right), and values between the minimum and maximum are mapped proportionately into the 0 - 100 range. This means that the percentage a data value is between the minimum and maximum is graphed.

For example, suppose a data series consisted of the following numbers: 10, 15, 20, and 15. In the chart, a line would be graphed from the bottom (10) to the middle (first 15), to the top (20), and back to the middle (last 15). The corresponding percentages would be 0%, 50%, 100%, and 50%.

The best way to think of the lines in a line graph is that they show the relationship between the data at given times. The data value can be steady, rising, or falling. Graphing the lines this way makes it easy to see a trend.

Options

Add Graph

Adds a line chart showing dynamic event data. The line chart is overlaid on the Chart View. You can use an overlaid line chart to correlate Visual Studio Analyzer events to system information, such as processor usage.

AutoFilter

Controls whether the view is linked to the current autofilter, so that when you change the filter, the changes are immediately reflected in the view and in all other views that are linked to the current autofilter.

AutoPlayTrack

Controls whether the view changes during playback to highlight each event as it occurs.

AutoSelect

Controls whether the view is linked to other open views, so that when you select an event in any open view, that event is also selected in every other open view.

Clear View Filter

Clears the currently applied filter from the view. If the filter is linked to other open views through AutoFilter, the filter will clear from those views as well.

Zoom Out, Zoom In

Adjusts the amount of data shown in the Chart View so that a greater or lesser time range is shown.

Zoom to Fit

Sizes the selected view to fit within the window.


Connect to Machine Dialog Box

Use the Connect to Machine dialog box to identify machines that you want to monitor for Visual Studio Analyzer events. The Visual Studio Analyzer Server components must be installed on any Windows machine you want to monitor. If you are connecting to a remote machine running Windows 95, make sure that the Visual Studio Analyzer Server has been started.

Options

Browse

Displays a dialog box through which you can browse the network for machines.

Connect

Connects to the machine you specified and adds the machine to the Machines node in the Project Explorer.


Event List View

Use the Event List view when you want to see a comprehensive list of the events generated by an application and their associated event data. The Event List view shows a list of all events that match the criteria of the filter currently applied to the view. The view includes several columns that provide detailed information about each event. You can:

  • Sort each column's contents (a small arrow indicates the sort order).

  • Select an event or range of events.

  • Refine the filter applied to the view.

  • Select which columns are displayed in the view.

  • Resize and reorder the columns by dragging.

Customizations you make to the Event List view are not saved until you explicitly do so, by clicking Save Column Settings on the view's shortcut menu.

You can play back the events shown in the view. You can use standard VCR-like buttons to navigate forward or backward through events. You can also skip events until a different component is involved — this choice omits back-and-forth messages between the same two components.

The event playback is animated. You can adjust the animation's speed, and that speed is remembered.

Options

AutoFilter

Controls whether the view is linked to the current autofilter, so that when you change the filter, the changes are immediately reflected in the view and in all other views that are linked to the current autofilter.

AutoPlayTrack

Controls whether the view changes during playback to highlight each event as it occurs.

AutoSelect

Controls whether the Event List view is linked to other open views, so that when you select an event in any open view, the same event is also selected in the Event List view.

Columns

Displays the Add/Remove Columns dialog box, which you can use to select the columns you want displayed in the Event List view.

Save Column Settings

Saves the columns you have chosen and the order in which they are displayed in the Event List view.

Size Columns To Fit

Sizes the columns you have chosen for display so that they all fit within the view.


Event View

Use the Event view to see detailed information on a selected event. All information in the event log associated with a particular event is displayed as either text or binary data. You can use the Event view in conjunction with the Block Diagram, Event List, Timeline, or Chart views when you are trying to isolate a fault. Open the Event view on top of the other views and step through your application. The Event view will display details for each event you select.

Options

AutoPlay Track

Controls whether the Event view changes during playback to contain detailed event information for each event as playback progresses.

AutoSelect

Controls whether the Event view is linked to other open views, so that when you select an event in any open view, the Event view shows the details of that event.


Filter Editor Dialog Box

Use the Filter Editor to define the Visual Studio Analyzer events you want to collect from your distributed application.

The Filter Editor is available by clicking View Filter Editor on the View menu. The following picture shows what the Filter Editor looks like.

Clicking a plus sign expands a node. Clicking a check box selects an item. As you select items, the box underneath the columns shows the text form of the filter you are creating. A parent item is shaded if you select some, but not all, of the child items beneath it.

Options

Categories/Events

Specifies the event categories and events you want to monitor. Click the plus sign to display a list of subcategories. Click the plus sign next to a subcategory to display a list of events in that category.

Collect

Use to construct your filter. Within a column, each item you select is joined with a logical OR operator. Across columns, each item you select is joined with a logical AND operator. If you prefer to type in the Boolean expression representing the filter yourself, you can click Edit Text to open an edit window.

Components

Specifies the components you want to monitor. Click the check box next to each component you want to monitor.

Edit Text

Displays the filter in an edit box where you can type the expression representing the filter.

Note Some filters, although you can type them in yourself, cannot be shown using the Filter Editor user interface. An example of these filters is an expression that uses inequality operators, such as <>. When you click Edit Text, a message displays that warns you about this. Click OK to confirm that you want to edit the filter text.

Machines/Processes

Specifies machines or processes you want to monitor. Click the plus sign next to each machine name to display a list of processes on that machine.

OR

Adds another tab to the Filter Editor dialog box. Use this tab when you need to construct an expression with an OR clause, such as:

(Machine = "All Machines" AND Component = "All Components" AND (Category = "Startup and shutdown events")) OR (Machine = "All Machines" AND Component = "All Components" AND (Category = "Function call/return"))


Project Explorer -- Visual Studio Analyzer Projects

Project Explorer — Visual Studio Analyzer Projects

Use the Project Explorer to manage a Visual Studio Analyzer project. Each project contains event logs, filters, and references to connected machines. This information is presented in the Project Explorer tree view, with separate nodes for event logs, filters, and machines.

From the Project Explorer, you can manage your Visual Studio Analyzer projects in the following ways:

  • See a centralized view of a project, including the event logs in the project, the filters in the project, and the machines to which the project connects.

  • Add event logs, filters, or machines to the project.

  • Start or stop event recording.

  • Open the Event, Event List, Chart, Machine Diagram, Process Diagram, or Component Diagram views.

  • Edit, activate, or apply filters to views and event logs.

  • Disconnect from or delete connected machines.

Options

Add Event Log

Adds an event log with a predefined name to your project. Available by clicking on the Event Logs node.

Add Filter

Adds a filter with a predefined name to your project and opens the Filter Editor. Available by clicking on the Filters node.

Add Item

Displays the Add Item dialog box, where you can add machines, event logs, or filters to your project. Available by right-clicking on the Event Logs or Filters node.

Add Predefined Filter

Displays a menu where you can choose a predefined filter to add to your project. Predefined filters are shipped ready to collect certain Visual Studio Analyzer events; you can modify predefined filters to suit your purposes.

Apply Filter to View

Applies the selected filter to the foreground Visual Studio Analyzer view. Available by right-clicking on an individual filter.

Chart

Displays the Chart View. Available by right-clicking on an individual event log.

Component Diagram

Displays the Component Diagram, one of the block diagram views. The Component Diagram shows only the components included in the event log. Available by right-clicking on an individual event log.

Connect

Displays the Connect to Machine dialog box, where you can specify a machine you want to monitor with Visual Studio Analyzer. Available by right-clicking on an individual machine.

Connect to Machine

Displays the Connect to Machine dialog box, where you can specify a machine you want to monitor with Visual Studio Analyzer. Available by right-clicking on either the top-level project node or the Machines node.

Disconnect

Disconnects from a specific machine. Available by right-clicking on an individual machine.

Event

Displays the Event view. Available by right-clicking on an individual event log.

Event List

Displays the Event List view. Available by right-clicking on an individual event log.

Machine Diagram

Displays the Machine Diagram, one of the Block Diagram views. The Machine Diagram shows only the machines included in the event log. Available by right-clicking on an individual event log.

Pause Recording

Suspends event recording in the active event log. Click again to resume event recording. Available by right-clicking on an individual event log.

Process Diagram

Displays the Process Diagram, one of the Block Diagram views. The Process Diagram shows only the processes included in the event log. Available by right-clicking on an individual event log.

Record Events

Starts recording events into an event log. Click again to stop recording events. Available by right-clicking on an individual event log.

Remove

Removes a selected event log, filter, or machine from the project. Available by right-clicking on an individual event log, filter, or machine.

Set Record Filter

Marks the selected filter for event recording. Click again to clear. Available by right-clicking on an individual filter.

View Filter Editor

Displays the selected filter in the Filter Editor. Available by right-clicking on an individual filter.

View Filter Text

Displays the selected filter in text mode in the Filter Editor. Available by right-clicking on an individual filter.


Summary View

Use the Summary view to get additional information on a selection in any Visual Studio Analyzer view. For example, you can use Summary view with Chart view to see how Performance Monitor data relates to what is happening in your application. You could select the time period in which a spike in processor usage occurs and then open the Summary view for detailed information on what is happening with your application during that time.

The following picture shows what the Summary view looks like.

Options

AutoSelect

Controls whether the Summary view is linked to other open views, so that when you select an event in any open view, the same event is also selected in the Summary view.


Timeline View

Use the Timeline view to see a graphical representation of how long it took to run an application. In the Timeline view, Visual Studio Analyzer events are displayed as tick marks along a timeline. You can select one or more events in the Timeline view and see those same events highlighted in the Event List or Chart views.

The following picture shows what the Timeline view looks like.

Options

Size To Fit

Sizes the timeline display so that all of it fits within the view.

Zoom In, Zoom Out

Adjusts the amount of data shown in the Timeline view so that a greater or lesser time range is shown.


Visual Studio Analyzer Import From and Export To File Dialog Box

Use the Export To File dialog box to identify an event log that you want to export to a standard comma-separated variable (.csv) file. You can then open this .csv file in Microsoft® Access or Microsoft® Excel for further analysis.

Options

File name

Provides a name for the exported file.

Save as type

Specifies that the file is saved as a standard comma-separated variable (.csv) file. You cannot change this field.

Save in

Identifies the location where you want to save the exported file.


Visual Studio Analyzer Project Wizard

The Visual Studio Analyzer Project Wizard is the fastest way to create a Visual Studio Analyzer project. The wizard consists of four main steps:

  1. Scan the current solution for the machines you want to monitor with Visual Studio Analyzer.

  2. Identify by name any additional machines you want to monitor.

  3. Select the components from which you want to see Visual Studio Analyzer events. This step is repeated for each machine you want to monitor.

  4. Select the sample filters that you would like to include in your Visual Studio Analyzer project.

Additionally, the wizard creates and activates a default event log and filter, both of which are required to be present in a project before you can begin collecting events.

The wizard includes a standard set of buttons along the bottom. These buttons control the following actions:

Button | Description
Help | Displays online help for the Project Wizard.
< Back | Moves back one step in the process.
Next > | Moves forward one step in the process.
Finish | Creates all items and closes the wizard.
Cancel | Closes the wizard; no project is created.

Scan for Machines

This step scans the current solution for machines. If you click Yes the wizard will create a list of every machine it finds. You can then select from this list to identify the machines you want to monitor with Visual Studio Analyzer. If you click No the wizard will continue with step 2, where you can specify individual machines by name.

Specify Additional Machines

In this step you can select machines from the list that the wizard built in step 1 and identify other machines that you would like to monitor. All machines you want to monitor must have the Visual Studio Analyzer Server components installed and running; you might have to start the server components manually on remote Windows 95 machines. See Starting the Visual Studio Analyzer Server on Windows 95 for a step-by-step procedure describing how to do this.

Add Machine

Click to display the Connect to Machine dialog box, where you can specify a machine you want to monitor with Visual Studio Analyzer.

Select Components

In this step you select the components from which you would like to see Visual Studio Analyzer events. You repeat this step for each machine you specified. The components listed here are Microsoft technologies that are shipped ready to generate Visual Studio Analyzer events. See Microsoft Components That Generate Visual Studio Analyzer Events for a complete list of these technologies and information about the specific events each technology generates.

Import Filters

In this step you select any existing filters from other projects in the current solution that you want to add to your new Visual Studio Analyzer project. You apply filters to event logs to specify which events to collect, and to Visual Studio Analyzer views to determine what subset of events in the event log to display. Sample filters are predefined filters that you can modify as necessary.

Select Sample Filters

In this step you select sample filters to include in your Visual Studio Analyzer project. You apply filters to event logs to specify which events to collect, and to Visual Studio Analyzer views to determine what subset of events in the event log to display. Sample filters are predefined filters that you can modify as necessary.

Finish

This step completes the wizard. It shows a confirmation box that summarizes the options you have chosen. If you want to change any of the options shown, use the Back button to step back through the wizard and make changes. Once you click Finish, the wizard actually creates the project file and the items inside the file, including a default event log and default filter, both of which are automatically set to record events.


Visual Studio Analyzer Error Messages

This section contains reference information on Visual Studio Analyzer error messages. These error messages include:

A file with this name already exists

At least one component must be chosen

At least one machine must be chosen

Editing the filter text directly

Export failed

Import failed

The filename you have entered is already in this project

The filter contained one or more Process IDs

The filter expression you specified isn't valid

The import was aborted while incomplete

The machine you have entered is already connected to machine

The machine name you have entered is invalid

The name you have entered is either not a valid filename, or does not contain a file extension

The Visual Studio Analyzer project file cannot be understood

This filter is empty

This filter is not valid

This filter is too general

Unable to read Visual Studio Analyzer event log

Unable to remove the file, because it is currently open

Visual Studio Analyzer could not find any registered events

Visual Studio Analyzer is already connected

Visual Studio Analyzer was unable to connect to the machine. Check the security settings

Visual Studio Analyzer was unable to connect to the machine. Ensure that it is powered

Visual Studio Analyzer was unable to scan for registered events

Visual Studio Analyzer was unable to scan for registered events. Access denied


A file with this name already exists

The name you specified for an event log or filter already exists on disk.

Try specifying a different file name, or click OK to overwrite the existing file.


At least one component must be chosen

No components are selected in the Select Components step of the Visual Studio Analyzer Project Wizard. Information in this step is used to construct a Visual Studio Analyzer filter. A filter should include at least one component.

Try selecting the components from which you would like to see Visual Studio Analyzer events; to see data from everything, select all components.


At least one machine must be chosen

No machines are selected in the Specify Additional Machines step of the Visual Studio Analyzer Project Wizard. A valid Visual Studio Analyzer project must include at least one machine.

Select the names of the machines you want to monitor. If you want to monitor programs running on your own machine, specify your machine name.


Editing the filter text directly

You can create advanced filter expressions — such as those containing comparison operators — if you edit a filter directly, but doing so can result in a filter expression that cannot be displayed in the graphical, tree-based Filter Editor dialog box.

Click OK to continue with editing the filter directly, or click Cancel to return to the Filter Editor dialog box.


Export failed

Visual Studio Analyzer was unable to export the selected event log. Generally, failure to export an event log is the result of errors such as a full disk, a read-only disk, or insufficient disk access permissions.

Try the following:

  • Correct conditions such as a full disk.

  • Export the event log to a different location.


Import failed

Visual Studio Analyzer was unable to import a selected file. In addition to errors such as insufficient space in the target event log, this message can occur when the file you are trying to import is not in the correct format. Files you want to import into Visual Studio Analyzer must be standard comma-separated values (.csv) format.

Try the following:

  • Import the file into a different event log

  • Open the file using a text editor and try to determine what is wrong with it.


The filename you have entered is already in this project

A file that already exists in the Visual Studio Analyzer project has the same name as the one you entered. Although you can have more than one event log or filter in a Visual Studio Analyzer project, the path to each one must be unique.

Try the following:

  • Check to see if you have already added the file.

  • Specify a different name.


The filter contained one or more Process IDs

A filter opened in the Filter Editor contains Process IDs that cannot be found in the current environment. The Filter Editor removes the Process IDs.

Try the following:

  • To retain the Process IDs so you can use the filter with a saved event log, cancel the Filter Editor dialog box.

  • To set the filter to record events, continue editing; you do not need the removed Process IDs.


The filter expression you specified isn't valid

The Filter Editor attempted to compile the filter you created but encountered errors. If you do not correct the errors, all changes you have made to the filter will be lost.

Try the following:

  • Correct the filter.

  • Cancel the Filter Editor dialog box.


The import was aborted while incomplete

Visual Studio Analyzer has detected corruption in a file you are attempting to import. Although some events will have been added to your event log, the import will not finish. There is no workaround.


The machine name you have entered is invalid

The specified machine name is not valid for your network.

Specify a valid machine name.


The machine you have entered is already connected to machine

Your Visual Studio Analyzer project is already connected to the machine specified in the Connect to Machine dialog box.

Try specifying a different machine name.


The name you have entered is either not a valid filename, or does not contain a file extension

Either the specified file name is invalid or it includes a dot but not a file extension. If you do not place the dot, Visual Studio Analyzer fills in the extension for you. Visual Studio Analyzer file names conform to standard file name requirements.

Correct the file name, or specify one of the following extensions:

  • .vaf for a Visual Studio Analyzer filter

  • .val for a Visual Studio Analyzer event log


The Visual Studio Analyzer project file cannot be understood

The Visual Studio Analyzer project file is corrupted. There is no workaround.


This filter is empty

The filter does not specify any machines, processes, or events to monitor.

Try the following:

  • Specify machines, processes, or events to monitor.

  • Save the empty filter to edit later.


This filter is too general

The specified filter has the potential to collect a very large number of events, such as all events from all processes on all machines. Filters like this can have an adverse affect on your network.

Try the following:

  • Create a more specific filter.

  • Save the filter anyway (since this message is a warning).


This filter is not valid

The filter you are trying to set for recording is not valid. Filters can be invalid if they are empty or if they contain an invalid filter expression.

Try editing the filter to correct it.


Unable to add more events to Visual Studio Analyzer event log

The drive is full, so Visual Studio Analyzer is unable to add any more events to the event log. Event recording is paused. While event recording is paused, you will lose event data from your application.

Click OK to clear the message box, then try to clear more space on the drive. You must click Pause again to restart recording.


Unable to read Visual Studio Analyzer event log

Your event log is corrupted. There is no workaround.


Unable to remove the file, because it is currently open

The file you want to remove is open in an editor or view.

Close the editor or view, then remove the file.


Unable to save Visual Studio Analyzer event log

The drive is full, so Visual Studio Analyzer cannot save the event log as part of closing the project.

Try to clear some space on your drive, then click OK to retry the save. If you cannot clear any more space on the drive, the event log is not saved.


Visual Studio Analyzer could not find any registered events

The Visual Studio Analyzer server components are not installed on the machine you are attempting to monitor.

Try installing the Visual Studio Analyzer server components by running the Visual Studio Installation Wizard.


Visual Studio Analyzer is already connected

Visual Studio Analyzer is already connected to the specified machine. Only one Visual Studio Analyzer client can connect to a given machine for monitoring.

Try entering another machine name.


Visual Studio Analyzer was unable to connect to the machine. Check the security settings

Visual Studio Analyzer cannot connect to a machine for monitoring because of the security settings on the machine.

Try correcting the security settings.


Visual Studio Analyzer was unable to connect to the machine. Ensure that it is powered

Visual Studio Analyzer cannot connect to a machine for monitoring for reasons other than the security settings on the machine.

Try the following:

  • Confirm that the machine is powered and connected to the network, and that the Visual Studio Analyzer server-side components are installed correctly.

  • Reinstall the Visual Studio Analyzer server-side components if necessary by running the Visual Studio Installation Wizard and selecting the Server setup option.

  • Confirm that Visual Studio Analyzer server has been started.


Visual Studio Analyzer was unable to scan for registered events

The Visual Studio Analyzer Project Wizard cannot connect to a specified Windows 95 machine.

Try the following:

  • Confirm that the machine is powered and connected to the network, and that the Visual Studio Analyzer server-side components are installed correctly.

  • Reinstall the Visual Studio Analyzer server-side components if necessary by running the Visual Studio Installation Wizard and selecting the Server setup option.

  • If necessary, start the Remote Registry Service.


Visual Studio Analyzer was unable to scan for registered events. Access denied

The Visual Studio Analyzer Project Wizard cannot connect to a specified Windows 95 machine for security reasons.

Try correcting the security settings.


Topic Not Found

No matching topic was found. Some possible reasons and remedies are as follows:

  • The file (.chm) that contains the destination topic is not in the expected location.

    Remedy: Rerun the MSDN Library Setup.

  • The file (.chm) that contains the current topic or destination topic is out-of-date and the link is no longer valid.

    Remedy: Install the latest version of the MSDN Library.

  • The MSDN Library CD is not in the CD-ROM drive.

    Remedy: Insert the MSDN Library CD into the CD-ROM drive.