Practical Standards for Microsoft Visual Basic .NET (Pro-Developer)

[Previous] [ Next ]

14.1 Increment the version number each time you compile a program.

When you compile a program or ActiveX component, a version number is included in the compiled file. This version number is used by installation programs to ensure that files aren't overwritten with older versions. You can view the version number of a file by using Windows Explorer ”see Figure 14-1 ”which makes troubleshooting faulty installations easier.

The version number of a compiled program is not arbitrary. The number is determined by the settings on the Make tab of the Project Properties dialog box, as shown in Figure 14-2. When the Auto Increment check box is selected, Visual Basic automatically increments the version number stored in the project whenever you compile a new distributable file. You should select this check box in every one of your projects.

Figure 14-1. Right-clicking a file in Windows Explorer allows you to view the file's properties, which include the file's version number.

Figure 14-2. The version numbers you specify in the Project Properties dialog box are part of the distributable file.

Even if you're only compiling a component for a quick internal test, increment the version number. It's tempting to "not waste" a version number, but this is silly ”you can maintain hundreds of minor revision numbers, and it's simply far too risky to have two versions of a compiled program with the same version number.

NOTE


If your installation program supports versioning, maintain incremental versions and a separate version information document for each new version of the installation program that you create.

14.2 Display a program's version number in the About dialog box.

Version numbers greatly aid the customer support process. When a user calls about a problem and you believe the problem is fixed, you need to know what version of the program the user is running to compare it against your internal revision document. It's best to make things easy for the user. Asking a user to open Windows Explorer, find a file, right-click the file, and select Properties (to view the file's properties) ”all so that you can determine the file's version ”isn't wise.

All professional programs should include an About dialog box. This dialog box usually contains licensing information such as the registered user of the software and a serial number. In addition, most About dialog boxes include the version number of the program. (See Figure 14-3.)

Version numbers are shown in the following format:

Major.Minor.Revision

When displaying version information, keep in mind that the minor revision number is usually shown as four digits right-justified. To display the 28 th revision of version 8.1, for example, you'd display

8.1.0028

Figure 14-3. Include the version of your program in its About dialog box.

The major, minor, and revision numbers of the program are available as properties of the App object. Since these properties are always accurate, use them instead of hard-coding version numbers for display. The following statement can be used to display the version number of a program in a label control:

'*Displaythefullversioninformationforthisprogram. lblVersion.Caption=Trim(Str$(App.Major))&"."&_ Trim(Str$(App.Minor))&"."&_ Format(App.Revision,"0000")

14.3 Maintain backward compatibility in ActiveX components .

Distributing ActiveX components created in Visual Basic requires that you give careful consideration to code changes prior to distribution and at the time you compile a file. You no longer have the "luxury" of worrying only about breaking sections of your code. You must also make sure not to break other programs that use the component.

Simply providing unique version numbers in each compile of an update does not in itself ensure that applications using the component won't have any problems. The relationship between the new version of a component and an older one, and the extent to which they are interchangeable, is called version compatibility . When you distribute an update to a component, make sure that the new component is backward compatible with previous versions of the component so that existing applications won't be broken.

You might distribute an updated component for many reasons. Perhaps you've fixed bugs or added new features. Sometimes the changes to a component are minor and only occur within existing functions. Programs that use the updated component are blind to the changes and are able to use the component without any problems. When a new version of a component is created so that it doesn't break applications that use a previous version, it's said to have backward compatibility .

Suppose that you've created the following procedure in a distributed DLL. (This function takes two numbers, multiplies them, and returns the result ”of course you would never use such a cumbersome technique to multiply two numbers, but it serves well to illustrate a point.)

PublicFunction Multiply(intNumber1 AsInteger ,intNumber2_ AsInteger ) AsLong '*Purpose:Multiplytwonumbers. '*Accepts:intNumber1andintNumber2-thenumbers '*tomultiply. '*Returns:Theresultofmultiplyingthenumbers. OnErrorGoTo PROC_ERR Dim intCount AsInteger Dim lngResult AsLong lngResult=0 '*Addthesecondnumbertoitself.Dothisasmanytimesas '*specifiedbythefirstparameter. For intCount=1 To intNumber1 lngResult=lngResult+intNumber2 Next intCount Multiply=lngResult PROC_EXIT: ExitFunction PROC_ERR: Call ShowError(Me.Name,"Multiply",Err.Number,Err.Description) GoTo PROC_EXIT EndFunction

Although this function works, it is by no means efficient. Now, assume you realize that you can perform this task by using the multiplication operator (*), so you change the procedure:

PublicFunction Multiply(intNumber1 AsInteger ,intNumber2_ AsInteger ) AsLong '*Purpose:Multiplytwonumbers. '*Accepts:intNumber1andintNumber2-thenumbers '*tomultiply. '*Returns:Theresultofmultiplyingthenumbers. OnErrorGoTo PROC_ERR Multiply=intNumber1*intNumber2 PROC_EXIT: ExitFunction PROC_ERR: Call ShowError(Me.Name,"Multiply",Err.Number,Err.Description) GoTo PROC_EXIT EndFunction

Because you changed only the internals of the function ”not the way the function is called or what it returns ”the programs using the existing version of the DLL can use the new version without modifications. The new component is backward compatible with the previous version of the component.

Some changes to ActiveX components aren't so benign . Say you developed an ActiveX DLL that provides the following method:

PublicSub AddRecord(strFirstName AsString ,strLastName AsString ) EndSub

Now, because of users' requests , you decide that you want the function to also accept a phone number. You change the definition to

PublicSub AddRecord(strFirstName AsString ,strLastName AsString ,_ strPhoneNumber AsString ) EndSub

When you compile the new DLL and distribute it to users, existing applications can no longer use the component! This happens because the heading of the method (procedure) has changed, making the new DLL incompatible with the older version. For existing applications to be able to use the function in the new DLL, the existing applications would need to be modified, recompiled, and redistributed.

NOTE


The text in this section refers to Class IDs (CLSIDs), globally unique identifiers (GUIDs), and other terms related to ActiveX components and the system Registry. It's beyond the scope of this book to teach you these concepts. Instead, this book shows you how to use your existing knowledge of these topics to ensure component compatibility across revisions.

For a component to be fully backward compatible, all the conditions listed below need to be met. The new version must

Visual Basic lets you create a component with one of three levels of compatibility:

You set the level of compatibility for a project on the Component tab of the Project Properties dialog box, as shown in Figure 14-4.

Figure 14-4. The Version Compatibility setting is used at compile time to make new versions remain compatible with previous versions.

Relinquishing Compatibility

To relinquish backward compatibility, select No Compatibility. Each time a project is compiled with the No Compatibility option selected, Visual Basic assigns a new CLSID to the component as well as new procedure identifiers. This is usually the least desirable option of the three levels of compatibility.

No Compatibility is useful for creating a new version of a component that won't replace an older version. This allows both versions of the component to exist peacefully on the same machine. When you use the No Compatibility option to produce a new version of a component, you should change the Project Name property of the project and compile the project with a filename different than that of the previous version. That way you'll create a completely unique component that won't overwrite the previous version or clash with it in any way. All existing programs continue to use the older component. For a program to use the new component, its source code will have to be modified and then recompiled.

Maintaining Project Compatibility

When you compile a project that uses the Project Compatibility setting, Visual Basic keeps the type library identifier of the previous component, and all class IDs from the previous version are maintained as well. Procedure IDs are retained only if binary compatibility can be maintained . This setting allows you to open projects that use previous versions of the component, but it doesn't ensure that they will run without modifications. If the type library CLSID were changed, the project couldn't load the component at all because it would be referencing an identifier that was no longer valid.

NOTE


The Visual Basic documentation states that for the purpose of releasing compatible versions of a component, Project Compatibility is the same as No Compatibility.

Perhaps you've experienced Visual Basic being unable to load an ActiveX control because it was no longer available on the development computer. Visual Basic doesn't know what to do in this situation, so it replaces all instances of the component with picture box controls.

When Project Compatibility is selected, the text box at the bottom of the Project Properties dialog box is enabled. In this text box, you enter the name of the component with which to maintain compatibility ”this file should be a previous version of the compiled component.

NOTE


Always keep a copy of each compiled version of a component somewhere safe. If you lose a compiled component file, you lose the ability to create new components that are backward compatible with the file.

Remember that selecting the Project Compatibility option does not ensure that a project using the component will run without modifications, only that projects will still have a valid reference to the component's library.

Maintaining Total Compatibility

The Binary Compatibility option is the only option that truly enforces compatibility between components. When you compile a project with Binary Compatibility selected, the new component has the same CLSID and procedure identifiers as its previous version. Applications that use the previous version of the component can use the new component without having to be modified or recompiled.

Simply selecting Binary Compatibility does not force Visual Basic to prevent you from making changes to a project that would render it incompatible with a previous version. However, if you do make changes that would prohibit backward compatibility (such as changing a Procedure ID by using the Procedure Attributes dialog box), Visual Basic will warn you of that fact at compile time. (See Figure 14-5.) If you choose to ignore this warning, you sacrifice backward compatibility.

Figure 14-5. Visual Basic tells you when you are creating an incompatible component. You can then alter your approach or go ahead and break compatibility.

When creating an ActiveX component, you must be keenly aware of compatibility issues. In most situations, Binary Compatibility is the best option and No Compatibility is the worst. If you truly want no backward compatibility, create a new component by changing the project name and the name of the compiled program.

14.4 Document changes in a Readme file.

Product development often occurs at a rapid rate, yet it can span months or years . Because it's impractical to expect a person or a team to remember all the various changes that are made and in what versions those changes were made, it's important to maintain a journal of program changes. Usually, this journal is written as a Readme file.

Most users are familiar with Readme files. A Readme file is a document that usually accompanies a program during a new installation or an update. Users view the Readme file to learn about program changes that might or might not have made it into the product documentation. Use the Readme file as a vehicle to notify users of important changes and additions.

You can choose to maintain two versions of a Readme file: one for users and one for internal use. Generally, Readme file information for users is of a more general nature than that in your internal documents. Users don't need to know the specific technical implementation of a feature, just that the feature is available and how to access it. However, internal documents are used as references by developers, and therefore they need to contain specific information. You can maintain two documents, or you might choose to maintain one document and remove the items intended for internal use prior to distributing the file with the product.

You can put just about anything you want in a Readme file. Many companies choose to include a welcome letter, contact information, and marketing information. My advice is to keep the Readme file as focused as possible. If you want to distribute a lot of nontechnical information, consider putting it into other document files and including a reference to those files in the Readme document. Regardless of what other types of information you do include in the Readme file, you should always provide revision information.

As you make changes or enhancements to your product, document them in the Readme file in a clear and concise manner. It's important to associate all items in the Readme file with a specific revision of the program. When distributing a Readme file, you can choose to lump all revisions under one version number rather than showing all the various revisions numbers between releases, but do keep track of the changes in each specific revision for internal use. Sooner or later, you're going to need to know the exact version in which a change occurred.

14.5 Back up your files.

Too often I hear about a company or individual that has lost data and has no current backup. (This happens more frequently than you'd think.) Before computers became mainstream, ignorance was the most common reason for this sad state of affairs. However, even then, ignorance was a marginal excuse . Most software documentation includes information on the necessity of backing up files. Now, the need to back up files is well understood , and CD-ROM burners, tape units, and large hard drives are so common and inexpensive that it's inexcusable not to back up your files.

Of course, your particular situation should dictate the type of backup plan you employ . If few changes are made to a project, a weekly backup might be sufficient. For most development shops , nightly backups are the norm. Don't forget to rotate your media. At times, backup media can go bad, and backups can become corrupted. It's best if you keep at least five successive backups. In addition, you should archive backups of important milestones such as product releases.

NOTE


Consider this: You have a problem, and you need to go to a backup. No problem ”you always back up your files. Soon you find out that the file you need isn't there because the file or its folder wasn't specified in the backup plan. It's happened to me a few times and to others I know as well. You should periodically restore a backup just to make sure that everything you want backed up is being backed up. It's easy to forget to add a folder to your backup plan, and this mistake can be disastrous. The time to find out you're not backing up a file is not when you need it.

14.6 Use Microsoft Visual SourceSafe to maintain versions of source code.

Keeping backup files of all revisions of all project files is next to impossible . For complex projects, you should seriously consider using a program such as Visual SourceSafe to manage your projects. Visual SourceSafe keeps track of all of the revisions of all files in a project, allowing you to easily revert to a specific revision when necessary. Chapter 15, "Source Code Control," explains the implementation of Visual SourceSafe in detail.

Категории