Everybody's doing components on the desktop these days, but what are the components doing to the desktop?
Robert Richardson
When it comes to software components, simplicity is everything. It's not that these items -- such as DLLs for Windows and extensions in the Mac world -- can't do fiendishly complex things. These mix-and-match software plug-ins can range from simple buttons on Web pages to full-blown chart packages that you can toss into your enterprise database. However, the environment that these parts and pieces inhabit has to be homey if a thriving marketplace for them is to emerge: It s
hould be obvious how to add these components to an existing system. After all, what's the point of having components if it takes an advanced degree and as much as a year of coding to get a few of them to communicate with each other?
The computer industry came to realize the value of no-frills practicality after the hothouse growth in third-party controls (known as VBXes) for Microsoft's Visual Basic. Since then, Microsoft has jettisoned righteous abstractions, such as inheritance and polymorphism, which are sacred to the serious object-orient
ed-programming crowd. The result has been a shower of derision from the gallery -- and a ground swell of support from the vendors and users in the trenches.
DLLs Aren't Dull
Today, the locus of Windows component development is the shared DLL. This isn't surprising; developers want to be able to share functions without having to share code. This basic functionality is something that DLLs have provided within Windows si
nce the get-go.
There is a problem, though: The wide variance in the structure and syntax of procedure calls within DLLs inhibits the broad use of disparate DLLs. So, increasingly, the Component Object Model (COM) -- Microsoft's framework for encapsulating the variations within components behind rigidly defined binary interface entry points -- has become a popular way of packaging the components stored within DLLs. COM makes component use easier through two technologies: OLE provides the standard approach to binary interfaces, and the COM "bus" hides the complexity of finding and loading components (even when those components are to be loaded on remote machines).
Much of the success of components on Windows desktops has been due to the success of DLLs. At the same time that DLL use has grown swiftly, however, a troubling pathology of system instability has emerged. In the pursuit of simplicity, Microsoft has overlooked management mechanisms needed to prevent component chaos. The flood of DLLs in a
Windows system directory (several hundred on an average Windows installation) is impossible to manage properly. Microsoft seems to be only barely aware of what action it will take to keep components safe for end-user consumption.
Extension Tension
Most component screwups today are on Windows desktops, but that's not because other systems are any cleaner. Rather, the popularity of Windows and the frenzy of shared DLL development have combined to make Windows the de facto test-bed for the desktop componentware concept.
Apple's Mac OS has a limited concept of shared components: Mac OS extensions. These extensions load extra functions into the general OS environment rather than loading and unloading them on a per-application basis. But they do not lend themselves to easy reuse by other applications and, as a result, have not been an active development area. As John Landwehr, product marketing manager for Apple's forthcoming Rhapsody OS, puts it: "There aren't many components in the Mac OS, a
nd I would not say that they're the easiest to use."
Landwehr adds that extensions are mostly for situations requiring device-driver software, and that applications generally use only the extensions in the application package. Yet Mac extensions often conflict with each other. This has spawned a market for third-party extension managers, such as Conflict Catcher (Casady & Greene, Salinas, CA), and the Extension Manager in more recent versions of the Mac OS. These utilities give users much finer control over when and in what order extensions load. If Mac applications shared extensions more often, as Windows applications do, Mac users would encounter the same array of disasters that Windows users face daily.
Jeff Foster, president of Mac software developer Vicious Fishes Software (Brea, CA;
http://w
ww.viciousfishes.com
), says that, as a way to add functionality to serial ports and other hardware, the extension mechanism is "worth the aggravation of most of the conflicts." But there are conflicts aplenty. "Since we're a development shop here, we are continually having conflicts of one sort or another," he adds. "You either find a workaround or let the machine keep crashing."
The original Apple strategy was to leave extensions as just that -- extensions to the low-level OS -- and then embrace OpenDoc, a multivendor component-software initiative, as a way to deliver componentware on the Mac. But OpenDoc never gained widespread user support, and Apple abandoned it earlier this year.
For now, extensions are the only mainstream component mechanism that the Mac OS has to offer. Since most vendors don't use extensions from third parties, relying on some other developer's extension -- the Achilles' heel of DLLs -- is not the problem. However, extensions share a common memory space, and one exten
sion's bug is often another extension's corrupted data.
Apple's Technical Information Library is full of helpful tidbits like this: "You can attempt to remedy a conflict by changing the loading order of a given extension or Control Panel by locating the file in the System Folder and adding a space or spaces to the front of the file's name." In other words, you can use the alphabetical ordering of the extension filenames to shuffle around the order in which extensions load. The goal is to mix things up enough so that whatever memory sins being committed are happening in some location where no one gets hurt.
Aspirations for a higher level of rocket science have spawned a market for the aforementioned third-party extension managers. They give users much finer control over when and in what order extensions load, generally by copying extensions in and out of the folder from which the Mac OS loads them.
This system might be OK for genuine OS extensions. But as a basis for components similar to DL
Ls (which is what Mac extensions have gradually become), it's a ludicrous approach, and Apple has done next to nothing to make the arrangement better. As of the 7.6 version of the Mac OS, you don't have to load all your extensions at the same time, but you do have to reboot every time you want to change extension sets. This is
not
one of those situations where Mac loyalists can gloat over how long it took the Windows camp to figure out how to do it right.
Apple's use of components will change radically with the introduction of its new Rhapsody OS, a heavily object-oriented, high-end, "next-generation" product scheduled to be in a developer release by the time this article sees print. Rhapsody, built from the foundations of the NextStep OS, has a highly developed object framework and at least the beginnings of a system for managing it (
see the screen
). It remains to be seen whether Rhapsody will have the same component confusion that Windows now has, but it seems possible. Si
nce the simpler Mac OS has extension-conflict problems, Rhapsody may well have even more.
DLL Dilemmas
DLL discomfort has several causes. For example:
Older DLL versions copy over the "correct" versions.
This "back-revving" happens because vendors never know whether a customer's system is going to have the necessary shared DLLs. So, DOESGOOD.DLL version 2 goes into the Windows system directory, obliterating version 3 of the same name. To be sure, vendors distribute the DLLs they've tested during development. However, newer drivers may already have superseded these by the time users load them.
In theory, a vendor's installation routine should double-check to see if a newer version of a shared DLL is already on the target system. Yet vendors have been sloppy or cautious about this, depending on how you look at it. On the sloppy side of the equation, some installation routines simply don't check for existing DLLs. In the interest of caution, though, some vendors intend to copy the
specific DLL that they've tested, which gives them some cause for confidence (in particular because they're worried about the next DLL discomfort I'll discuss). Copying older DLL versions means the newly installed application will work, but applications that rely on later versions of the DLL are now more likely to encounter problems.
Users can also get in on the fun by, for example, restoring files from backup tapes without regard for newer versions installed in the meantime.
Newer DLL versions copy over older versions.
The heartening, if perverse, optimism of the software industry makes us believe that an updated version of a component will be better than older versions. But new versions introduce new bugs or don't speak the same interface language as older versions. So when a vendor follows the rules and does not load an older DLL, it can get into trouble for adhering to Microsoft guidelines.
If you load a new copy of Microsoft's Publisher 97, for instance, the installed program ma
y fail immediately after it starts. The Microsoft Technical Support KnowledgeBase boldly states that "this error occurs if a newer version of the MSVCRT40.DLL file is already installed on your computer when you run Publisher Setup." This is your reward for keeping up with Redmond's product line.
The system deletes shared DLLs during uninstalls.
When an application installs itself according to Microsoft guidelines, it increments registry-based usage counters for all the shared DLLs it calls. When Microsoft's uninstall feature removes programs, it consults the counters to see how many other programs expect the shared DLL to be there.
If no other applications need the DLL, the system will assume it's OK to remove the DLL. But nothing forces applications to increment the counters. If one program shirks its duties, the counter is off, the DLL may well vanish prematurely, and thereafter any programs that need the DLL are bound to fail.
Windows keeps hidden copies of special DLLs that you
cannot delete.
Windows keeps copies of some particularly sensitive DLLs in the SysBckup directory within the Windows directory. At start-up, it compares the copies to the originals in the System directory and, if they don't match, the backups copy over whatever's in the System directory. Copying a new version of WINSOCK.DLL into the System directory, for example, will be magically undone at the next system start-up.
DLLs can conflict with each other.
Some DLLs are just plain badly coded, a simple fact of programming life. While we're all resigned to a certain amount of buggy code, it would be desirable to be able to separate contentious DLLs so that they never load at the same time.
This is an instance where the Mac has created advantage from adversity. Unlike DLLs, which load as needed, Mac extensions load into memory and stay there throughout a session. In earlier versions of the Mac OS, all the needed extensions had to load, meaning that they all used memory all the time. When confl
icts occurred, the only remedy was to juggle the order in which the extensions loaded. Version 7.6's Extension Manager could create different groups of extensions so that some would load together while others would not.
The DLL namespace readily allows collisions.
Vendors currently tend to throw all their DLLs into the System directory, although Microsoft suggests that only shared DLLs belong there. Further, even though Microsoft's 32-bit OSes allow DLLs to have long filenames, most vendors stick to the 8.3 convention; they must if their DLLs are also for 16-bit environments. Plus, their files may someday reside on a shared network drive that supports only short names.
There are only so many eight-character names -- fewer when you use meaningful abbreviations and short words. When two developers use a name like DISPLAY.DLL, somebody's going to get hurt.
DLLs may not load the way Microsoft says they do.
Dan Plastina, group program manager for Windows administration, says Microso
ft's 32-bit platforms load DLLs "by path name, not by filename." He says there is not a problem if they call two DLLs with the same name if they have unique full path names.
Not so, say programmers, including John McMillan, lead programmer for new product development at Great Lakes Business Solutions (Canton, MI;
http://www.glbs.com
), which makes the installation product Microsoft now uses for its System Management System product. "Once a DLL is in memory, the system will never pull in another version of that DLL again," he adds. Other programmers cite cases where Windows has mistakenly used a same-name DLL.
The issue seems to arise because there are two ways in which a DLL can load. In a normal case, it uses a link library of
stub functions
(i.e., the same process compiles the actual DLL) and calls
the DLL by its short name. Windows checks memory for currently loaded DLLs of the same name before looking elsewhere. It's possible to load a DLL by path name, but only when you make DLL function calls by linking to a library of precompiled stubs.
DLLs with the same version number may be different.
Each DLL has a version resource that includes several stock fields, including a binary version number and a string for the manufacturer. You can see the version number for a DLL by right-clicking your mouse on the file within File Explorer and then selecting Properties. But there's no standard rule for updating these numbers. It's common practice at Microsoft, for instance, to release several different builds of a DLL with the same version number.
This last problem -- different DLLs with the same version number -- has some independent software vendors (ISVs) hopping mad. Bob Denny, creator of O'Reilly and Associate's WebSite, says the root cause of "DLL hell" is what happens when you have "a com
ponent where the behavior hasn't been changed but that's been bug-fixed. Microsoft itself has in some cases released dozens of versions of a DLL that are functionally identical but that have different levels of bug fixes."
Moreover, end users are often unaware that underlying system-level components have changed. Loading something like an Internet Explorer browser update can update low-level OS components -- the lowest-level TCP/IP protocol stack DLLs, for example. There may be no direct relation; Microsoft may have used the update to slipstream a number of OS patches.
The result is that it becomes harder for vendors to support their products because it's difficult to tell exactly what set of system DLLs any given user has. "As a developer," Denny says, "I really hate working in the Microsoft environment right now, because it's just a snake pit from a support standpoint. You never know what your customers have."
How Active Can One Desktop Be?
Developers are making two separate reali
zations about desktop components. The first is that haste makes GPFs. Microsoft's rush to get activated has resulted in too many versions of system components that beg for stability. Vendors have been sloppy, too, with shared components in the System directory.
The second realization, though, has consequences that require more than tie-straightening and good manners: Applications badly need a way to protect themselves when forward compatibility with new versions of trusted components does not work out. There's a new realization that better tools are necessary for assessing component conflicts. It's sometimes more stable if developers reuse components in their products but don't try to share them with other applications on users' systems. Much more stability is necessary in widely shared components, such as the 3-D controls in Office, FrontPage, and Internet Explorer (all now shipped with slightly different versions).
The Microsoft Way
Microsoft realizes there's a problem, says Russ Madle
ner, product manager for desktop OSes. However, don't look for any real fixes to come with Windows 98 (aka Memphis). Help will come in the form of somewhat-better safeguards for DLL installation and a tool for post-mortem forensics on failed systems.
First, Microsoft intends to get tougher about granting "Designed for Windows" logos to software vendors. Madlener says there will be "enhanced restrictions" on the "whole approach of installing and uninstalling an application." To date, he says, Microsoft has offered only guidelines, which often are not well understood or followed.
Under the new program, vendors will be in "violation of logo" if they copy anything other than Microsoft-shared DLLs to the System directory (see the figure
"How to Stay Clear of the Long Arm of the Logo Police"
). Components intended to be shared by others will be copied into the Common Files directory. Every other DLL that an application uses must be in the application's own directory. Assuming vendor
compliance, this will at least reduce the risks of name collisions.
Coming with Windows 98 is the System File Checker, which performs such an obvious function that one wonders why it wasn't available before. This utility checks system-level files -- and any other files that the user wants to monitor -- to make sure they haven't been modified or corrupted since the last time the utility recorded a profile of the system (
see the screen
).
NT Promises
It's with the release of Windows NT 5.0 that component-management enhancements really get interesting, according to Madlener. For one thing, vendors will no longer control their own destiny when installing a new application. Instead, installation will pass to a system-level installation utility. Currently code-named Darwin, this setup utility will run on all 32-bit platforms.
With NT, says Microsoft's Plastina, "when you go to install an application, you ask Darwin to do the work for you. You give Darwin an instructi
on file." Darwin carries out the instructions, following the rules of DLL reference counts and replacing DLLs.
Another change in DLLs has to do with packaging system components. Says Plastina: "Today when you install an application, it puts down a good number of megabytes of data that comes with the system. Those are really OS components, though. With NT 5.0, we'll have quarterly releases of shared component service packs." These will contain "the latest versions of the DLLs that the OS group has blessed, and applications won't ship those DLLs anymore." DLLs in service packs will contain updated version numbers.
Darwin is just one part of the Zero Administration Windows (ZAW) initiative that Microsoft announced a year ago. Network administrators will also be able to lock down the Windows directory so that a user can't change it (see the figure
"Windows NT Corrals Components"
). In addition, administrators will have complete control over which programs go on a user's system.
Future Perfect?
To some degree, mismatches among components are an inevitable result of the current pace of software development and the modular approach to software that's necessary for updates in short time frames. But there's now concern among some developers that Microsoft's game plan of migrating most components from plain DLLs into the COM framework might only make matters less manageable. If the problem of DLLs is a lack of control over versioning, the problem with COM is that the whole notion of versioning is absent.
In COM, the functionality of each interface is specified and permanently fixed. Every interface is assigned a Globally Unique ID (GUID), which virtually eliminates name collisions. But individual implementations of the interface associated with any given GUID are indistinguishable within COM.
For now, Microsoft has implemented most of the widely used COM interfaces. Furthermore, until now, fixing Microsoft's COM interface bugs has entailed adding functionality; e
ach revised interface has received new function calls and new GUIDs.
Despite prior insistence that the interface is all that matters, Microsoft's Madlener says that there are "plans to add finer-grained versioning to COM." The details of versioning in the next generation of COM (called Common Object Runtime [COR]) should be out by the time you read this.
There are similar promises on the Apple front. Rhapsody gets the benefit of several years of Next's experience with objects. Unfortunately, Rhapsody objects don't have versioning, either. Apple's Landwehr says that Apple is "planning on making some changes this fall that will support better object versioning."
There's no question that careless vendors will always be able to crash systems with badly done software. At the same time, though, mainstream OSes need to provide at least a rational safety net when third-party component vendors take reasonable pains to behave.
Right now, the Windows desktop has arrived at a critical point where
things are falling apart and more control is necessary. Other OS vendors -- who haven't faced the fire that a base of 40 million users can ignite -- should examine whether their own component-management strategies will hold up under heavy use.
There are certainly steps that users and vendors alike can take to limit the depths of DLL hell. Vendors need to tighten up their installations so that only system-level DLLs (generally, those made by Microsoft) load into the System directory. DLLs for general sharing among multiple vendors should load into the Common Files subdirectory. All other DLLs go in the application's own directory. Shared DLLs should change only when a newer version of a component replaces an older one. Even then, the user should receive notice of the replacement and have the option to back up the DLL being replaced.
Users should use the Windows 98 System File Checker utility to ensure that older versions do not replace newer System files when new applications load. It would be a c
reditable gesture for Microsoft to freely distribute this utility to current Windows 95 users as well.
Meanwhile, because Windows is by far the mostly widely distributed desktop platform that employs component technology, Microsoft should embrace the long-term task of straightening up the mess. Usable componentware hangs in the balance.
illustration_link (14 Kbytes)

NT 5.0 can lock down a user's System directory, install assigned applications, and allow published applications -- but that's all.
illustration_link (14 Kbytes)

Good behavior includes steering application-specific, common, and system-level DLLs into the proper directories.
screen_link (44 Kbytes)

A report generated by Microsoft Windows 98's System File Checker, indicating that a system-level file has changed somehow.
screen_link (62 Kbytes)

Rhapsody manages objects in three folder tiers: for user and system on each system and, here, for the system object folder on the server.
Robert Richardson (Swarthmore, PA) is a frequent contributor to Network Magazine, Web Review, Web Techniques, and ZD Internet. His latest book, Building Your High-Tech Small Office, is forthcoming from IDG Books Worldwide. You can reach him by sending e-mail to
robert@smallofficetech.com
.