Change is inevitable. Creating computer software is more like growing a garden than manufacturing a widget. Although a distributed program file is a static entity, the program itself usually changes ”even adapts ”over the course of its life. For example, developers usually change a program to correct problems or improve usability. When developers stop enhancing a product, it's often
Projects in Microsoft Visual Basic are complex entities, often
Goals of Version Control
The goals of version control include
- Compiling the most current and stable
- Versioning all compiled programs
- Maintaining a history list of changes in versions
- Backing up project and other source files to prevent loss of work and time
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
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.
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.
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.
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
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:
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
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")
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
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
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
PublicSub AddRecord(strFirstName AsString ,strLastName AsString ) EndSub
Now, because of users'
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.
The text in this section refers to Class IDs (CLSIDs), globally unique identifiers (GUIDs), and other terms
relatedto 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.
The Version Compatibility setting is used at compile time to make new versions
To relinquish backward compatibility, select No Compatibility. Each time a project is compiled with the No Compatibility option selected, Visual Basic
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
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
The Visual Basic documentation states that for the purpose of releasing compatible versions of a component, Project Compatibility is the same as No Compatibility.
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.
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.
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.
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.
Product development often occurs at a rapid rate, yet it can span months or
Most users are familiar with Readme files. A Readme file is a document that usually
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
As you make changes or enhancements to your product, document them in the Readme file in a clear and
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
Of course, your particular situation should
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
happenedto 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 backedup. 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.
Keeping backup files of all revisions of all project files is next to