|Products Purchase Articles Support Company Contact|
Articles > Persistence of Data
Persistence of Data
2nd edition - June 2002
Visual Basic programmers have access to an array of choices for persisting data to disk, including databases, the registry, .INI files and regular disk files. With the introduction of .NET, programmers have access to the above and new features such as Isolated Storage and XML. When is it appropriate to use each of these systems? What is OLE Structured Storage, and where does it fit into the above? Find out in this article by the author of "Moving to VB.Net: Strategies, Concepts and Code", and one of Desaware's senior software developers
by Daniel Appleman and Stjepan Pejic
This article may be reproduced only in its entirety and may be freely reproduced and distributed via both print and electronic means. In fact, you are encouraged to do so. All copies of the article must include the entire article including the copyright notice and StorageTools product information page. No other use of this article is permitted without prior consent of the author except for brief quotations used in critical articles and reviews, in which case such use must be properly attributed
The following technology white paper is based the original Persistence of Data white paper written in 1996. It is being distributed in an effort to educate Visual Basic and .NET programmers regarding available techniques for implementing data storage in their applications. The paper focuses on matching an appropriate data storage technology to the needs of individual applications, and discusses the advantages and disadvantages of each approach. The end of this article does discuss a Desaware product (the company for which I work), however you will find that the bulk of the article is an objective and technical discussion on storage techniques that should prove valuable to every Visual Basic programmer. By reading this article you will gain:
OLE structured storage is an exciting technology. It can dramatically change the way you work with files. It is......
Wait. Isn't this the way most articles begin when describing a cool technology? They focus on the features and capabilities of the tool or technique being described. But is this really the information that most programmers need?
You see, most programmers (myself included) tend to fall in love with technology. We hear about a cool new tool or technique, and it becomes, for a while, the greatest thing that we've ever heard of. When I was studying computer science I remember being introduced to a new language every week or two, and each one instantly became the "best" language in my repertoire - the language that I could surely use to perform any task more efficiently and quickly than any other. And it would remain the "best" language until the next one came along. These days XML is the "hot new technology", and there is a tendency to want to use it everywhere, even where it is not the best choice.
This is something that I think is common among many programmers and engineers. We become passionate about technology. We tend to love our work. Our preferences of languages, tools and machines are almost religious in their intensity (in fact, I dare say that there are programmers who are considerably more passionate about their programming tools than their religion).
So before discussing OLE structured storage, I think it is important that we pause for a moment and place it in perspective.
You see, as programmers our real job is not to fall in love with technology. It is to solve problems using software. And as such, it is our professional responsibility to choose the tools that will best help us solve the problem at hand - not the one that we happen to be excited about at the moment, or the one that the industry is busy hyping.
That said, here is the truth about OLE structured storage: It is a powerful technology that is highly suited to solving particular problems, and totally unsuitable for others. So, how does one determine which problems are right for this technology? Let us start with considering the entire class of problem at hand: that of persistence of data.
Persistence of Data
Imagine a program such as a word processor that was unable to save information from one session to the next. With such a program, you would have to type a document from scratch every time you needed a printout - roughly akin to the way offices used typewriters just a few decades ago. Much of the value of computers comes from the ability of applications to store information - to persist their data. There are many technologies available for persisting data, and not all of them are appropriate for every situation.
There are four major reasons for persisting data in an application and one or all may be appropriate for any given program. They are as follows:
1. Application configuration information: Many applications save state information from one session to the next. It may remember user settings such as whether a backup should be generated for each file, or the positions of windows so that the application will restore itself to the same state that it was in when it was last closed. The application might save general configuration information as well as user specific configuration settings (for applications that run on operating systems that support multiple users).
2. Documents: Many applications work on documents that are opened at the beginning of a session and saved or closed when the session is over. Typical documents are word processing documents, spreadsheets, pictures and so forth. Documents can often contain many types of objects. The key thing to remember about documents is that they generally correspond to a single disk file. This makes a document easy to manage as an individual unit. For example: it can be copied to a diskette, or sent via Email.
3. Records: Applications that need to keep track of multiple records which are similar to each other will typically use some sort of database storage mechanism. Databases support searching and filtering and are designed to be easily shared by multiple applications simultaneously.
4. Publication: Given the importance of the Internet, many applications have a need to persist data to a file that can be read by other applications, even ones that run on different operating systems. Such files need to follow public standards and be suited to transfer over the Internet, although efficiency in size and access speed might suffer.
Each of these reasons for storing data influences the choice of technology that can best solve the particular storage problem. But the choice of technology is not always obvious. Let's take a look at the major storage technologies in use under Windows and how appropriate each is for the problems listed above.
Private Initialization Files
Initialization files (with the .INI extension) are an older technology that goes back to Window 2.0 (version 1.0 did not support private initialization files, only win.ini). Windows documentation suggested that Visual Basic 6 programmers should always use the registry instead of initialization files, but this is not necessarily the case. Initialization files maintain a number of advantages over the registry for some applications. They can be edited by hand using any text editor such as Notepad. They can be easily copied or saved using simple file commands. They are very easy to work with using a few simple API functions or Visual Basic commands.
Are initialization files appropriate for saving application configuration information? Yes - absolutely. A program's state can often be stored as a relatively small number of short string entries or numeric entries - exactly the kind of information that initialization files handle best. It would take more effort to handle user specific configuration information - each user would have to have their own section in the file, but it is still a viable solution.
However, initialization files are not suited for other purposes. Also, there is no allowance for applications used by multiple users. Settings written for one user will overwrite settings originally saved for another.
The System Registry
The system registry (originally called the "registration database") provides hierarchical storage in a central location on each system. Each key in the registry may have any number of named values associated with it, and those values can be one of a wide selection of available data types including raw binary data. Each value is generally under 2k bytes in length.
Is the registry appropriate for saving application configuration information? Absolutely. It provides a far more sophisticated structure for saving configuration information than initialization files. Also, a particular root of the registry (HKEY_CURRENT_USER) is automatically changed to correspond to the user currently logged on, so you can create user-specific or computer-specific configuration data as needed. The registry is, however, harder for an end user to edit (which is either an advantage or disadvantage, depending on your application). Editing the registry always creates the risk that the user might accidentally make a change that could interfere with the correct operation of the system - since the registry, unlike private initialization files, also contains configuration information for the system itself. Before .NET the registry was harder to access programmatically than private initialization files, requiring the use of sophisticated API commands. .NET includes classes for accessing the registry.
Is the registry appropriate for saving documents or record information? Certainly not. There is no clean mechanism for managing individual parts of the registry - how would you copy part of the registry to a disk file or send it through Email? The registry is, by its very nature, not document oriented. It is also strongly recommended that each value in the registry be kept relatively small.
As program become more complicated, their configuration settings needs also grew. The registry model of small amounts of information in a hierarchical structure is no longer sufficient for all programmers. Also, .NET objects might need settings that are unique to particular assemblies and/or domains as well as particular users. To suit this need, .NET introduced Isolated Storage. It creates a virtual file system that lets you create files and directories of any format, without concern for naming conflicts with other configuration files, and with automatic handling of different users, assemblies and domains. Within this virtual file system, or "store", you can use the regular .NET I/O classes such as StreamWrite and StreamRead to access the files containing the configuration information. For most purposes, this replaces initialization files and the registry.
Again, this system is not appropriate for saving documents or record information. An Isolated Storage store can consist of many files and directories and they are placed in obscure locations on the computer's drive, making them difficult to access. In fact, if you want advanced users to have access to at least some of the settings, you should place those settings in the registry. The Microsoft tools for manipulating Isolated Storages are primitive command line programs only suitable for the most basic tasks.
One of the most common methods used by applications to persist data is to store the required information in document files on disk. There are a number of standard formats for disk files, for example: .BMP files (Windows bitmap format) is a standard file format for bitmap images. RTF (rich text format) is a standard formatted text document format. In many cases, applications define their own private file formats - in fact, many standard formats originated in that manner. Whether a private or public file format is appropriate for a given application is one of the design choices that must be made by the developer.
With document files, the contents of the file are the responsibility of the application, as are all of the file operations. File operations are implemented using either API commands or a wide variety of Visual Basic specific commands and .NET classes that allow you to work with text, records or binary data.
Are document files appropriate for saving application configuration information? Yes, however you would lose some of the extra features available by using the registry or Isolated Storage.
Document files are easy to manage on disk. They can be copied, moved, sent via Email, and managed using standard file management software.
The task of reading and writing document files can range from very simple to extremely complex, depending on the type of document. A simple text document can be created by simply printing lines of text into the file, each one separated by a carriage-return line-feed combination. If, however, you wish to insert a line into the middle of the file, or remove a line from the file, you will generally need to write the entire file from scratch - there is no easy way to shift information in a disk file.
What if you wish to save many different types of information in the document? For example: a word processing file that contains both text and pictures? In that case you need to define a more complex file format that keeps track of where individual objects are located within the disk file. You might need to actually define an internal directory within the disk file that lists the various parts of the file and where they are located. In fact, if you think about it, you might reach a level of complexity in file organization that is used by database systems (which routinely track large numbers of arbitrarily sized objects within a disk file).
Which brings us to the subject of records. Is a document file appropriate for storing multiple records of data that are similar to each other? The answer here is yes and no. Let's say your application uses a user defined type (data structure) internally to store data, and needs to persist an array of these structures. In this case, a document file can be an extremely efficient way to store this information. Visual Basic includes record I/O file operations that are fast and have low overhead.
The document approach towards storing records does, however, have a number of potential disadvantages. Insertion and deletion of individual records can be complex. If there is a chance that the structure format might change, your application will need to keep track of document versions and implement a scheme for updating documents from one version to the next. Use of variable length records requires a more complex storage scheme that includes some mechanism for finding the start and end location of each record. Also, any searching or filtering schemes need to be implemented by the application.
Independent documents are frequently used to publish information. As long as certain standards are followed (such as the JPEG or GIF standards for images, or MPEG standard for video) then the information will be available to many different applications, even ones running on different machines. Most of these standards have no support within Visual Basic or .NET, which does make writing programs more difficult. Also, each of these standards are written to contain a single item per file - more interesting documents that are made up of multiple images, text, and other items will be spread across multiple files making distribution more difficult.
In many cases you may need to persist groups of records, where the records are similar to each other in structure. These often take the form of tables of records, where each record contains the same fields. You may need to work with different types of records in the same file (multiple tables). In many cases, you will want the information to be accessible to multiple users or applications at once. This is the type of information that is typically stored using a database system. This might include use of a specialized database command set or the database controls and commands built into Visual Basic or the .NET framework.
You may be thinking that this is a somewhat convoluted way of talking about databases. Why go to all of the trouble to differentiate between "saving records" and building a database? Because it is important to distinguish between the goal and the solution. The goal is to persist a certain type of data: records that are similar to each other. One solution is a database - but it is not the only solution.
You have already seen that it is possible to store records in a document file. However, if a database is clearly designed for record storage, why would you ever want to store records in a document file? You might want to do so if you do not need the database's searching and filtering capability, if you have little or no need to share the file and if the records are simple and of fixed length. In that case not only might the document approach be easier to program - it will probably be faster and will allow you to avoid the overhead of including a database engine with your application.
The case for application configuration information is easier to see. A database would almost always be extreme overkill for this type of data persistence. Even storage of per user application information is more easily accomplished using any of the other techniques.
What about documents? Is it appropriate to use a database to store document information - a word processing document, for example? It certainly can be done. You can imagine a complex database structure that includes one table for the lines of the document (perhaps with formatting information), and other tables that contain different types of objects, perhaps in blob format to hold images, video, sound, and so forth. These tables can be linked through the relational capabilities of the database.
This approach would work - but it can become quite complex - easily as complex as implementing the document using a proprietary format and performing your own disk operations. The database approach also can have a significant impact on performance and involves significant overhead.
It is also a poor technology for publishing information. Database files typically contain internal tables and other structures that make searching them faster. However, this creates a great deal of redundancy within the file, making it very large. These files are also written in a private format unique to the database system that created them - they may not be readable by different versions of the same system, let alone by different systems on computers with different operating systems.
XML files are another way of storing record data within a file, but one that was specifically designed to be published and shared. XML is a public standard, and programs on any computer can be written to handle them. It is a human readable text file, similar to HTML files. Containing only the data and some markings describing where the data fits into the schema, they can be much smaller than database files. .NET also includes extensive tools for creating and managing such files, including tools that let you graphically draw the schema that the records will follow.
The markings used to describe the internal structure of the XML file can occupy a large percentage of the file itself, making them less space efficient than records written directly to a normal independent document. There is no provision for adding more information to it (an independent document at least allows you to add more data to the end). If any changes are required, you will need to read in all the information, make the changes to the data, and write out the whole file again. And while a wide variety of data can be written, it is not designed with Visual Basic or .Net data types in mind.
XML is not only for putting a set of records on a web site. .NET programs can be documented using XML. XML is also used to save configuration information for .NET itself and many other programs. If your configuration data is complex, you can put XML files within an Isolated Storage store to gain the benefits of both systems.
The XML format is less useful for documents, though it is often adopted for that purpose. Its support for binary data is primitive, is very inefficient in terms of space needed to store anything other than basic text and numeric data, and as mentioned earlier, does not support incremental updates.
The Missing Technology
All programmers have to deal with the problem of persisting data, and there is a tendency to jump straight to a solution without considering the problem in the context of the requirements of a particular software project. It is true, as you have seen, that application configuration information is usually best handled using either the system registry, Isolated Storage or XML files (when not user specific). It is true that record storage is usually best handled by a database and, when you want to publish it on the Internet, XML. It is true that simple documents are usually best handled by reading and writing a disk file directly. But you have also seen that each of the six technologies that we've discussed can be applied for any of these persistence tasks, and the obvious choice is not always the best.
It is also clear from the previous discussion that there is one type of persistence problem for which none of the technologies is ideal. What is the best way to store complex documents that contain different types of information? Implementing a complex file format is a great deal of work. And databases are designed for records that are similar to each other - using them to store arbitrary types of information of arbitrary length is possible in many cases, but can be even more work. XML files are inefficient and do not allow for incremental update - a serious problem when you need to store large amounts of data (including images, sound, and video).
Before looking at OLE structured storage in the context of this problem, let's pause for a moment and consider the characteristics of the ideal complex document storage system - a system able to manage a complex document file. Assume for the moment, that the term "object" refers to any block of data that you care to define.
The complexity of implementing such a system on your own is substantial - and one of the reasons that it is so tempting to look for alternatives to creating a private file format. At the same time, this description might sound familiar - in fact, a storage system that meets these criteria is present on every Windows and DOS based system.
It is the file system.
Think for a moment of files as objects. A file system can handle many thousands of objects. Each file can range from zero bytes to gigabytes in size. You can certainly add and remove files without fear of one file interfering with the next. And writing into one file cannot corrupt any other. Files are named, and can be organized in a hierarchy of directories.
In fact, you will find some applications that solve the problem of complex document storage by using the file system - dividing their documents into multiple disk files. An example that I worked with recently is Corel Ventura Publisher, in which one publication can consist of multiple chapters each of which contains links to documents of different types. A single publication can thus be made up of hundreds of files, which are typically organized in one or more directories.
The disadvantages of this approach are clear when you try to copy a document to a floppy disk, to another directory, or to send it via Email. Copying the publication requires a special utility that can search out all of the linked files and copy them to the correct destination. If even one file is missing, the entire publication can fail to load at worst, have missing information at best.
Which brings us to OLE Structured Storage.
OLE Structured Storage
It sometimes seems that part of the challenge of being a Windows developer (whether you use Visual Basic or another language) is coping with the multitude of new terms and acronyms that are generated with great frequency from Redmond. OLE Structured Storage is one of these.
Fortunately, this is where the somewhat long introductory material that you have read up to now serves its purpose. Because it makes it possible to understand exactly what OLE Structured Storage is and why it exists and even how it might fit into your own development plans.
Think again, for a moment, about a file system - both its advantages and disadvantages, and how it might be used to address the problem of creating complex documents. Consider then, that a file system exists on a hard disk drive - a large area that is able to store information. What would happen if, instead, you could place an entire file system within a single disk file? Suddenly you would have all of the advantages of a file system, with none of the disadvantages. Since the entire file system is within a single disk file, you can copy, move and Email all of the objects for that file system by simply copying, moving or Emailing the file that contains the file system.
OLE Structure Storage is a technology that places an entire file system within a single disk file. And understanding that this is what OLE structured storage is, you know nearly as much about it as any of the experts.
In a file system you have directories and files. Each directory has a top level root directory. Each directory can contain multiple subdirectories and any number of files.
In OLE Structured Storage, the term Storage is used in place of directory, and the term Stream is used in place of file. When working with OLE Structured Storage Files, you start with a top level storage (root storage). This storage can contain additional sub storages and streams. Streams can be created, opened and closed just like files. You can write into streams without worrying that one might interfere with another. OLE Structured Storage takes care of allocating space for streams and storages, and managing space allocation within the disk file.
OLE Structured Storage also defines a name for a disk file that is managed by this technology. These files are called Compound Documents.
Why is Structured Storage a part of OLE?
Structured Storage accurately describes what this compound document technology does, but why is this part of OLE? - the "Object Linking and Embedding" standard from Microsoft?
Part of this is the fact that OLE is in fact a collection of technologies - a sort of grab bag under which many of the new developments for Windows falls. But part of it has to do with one of the major goals of OLE - the ability for users to deal with documents instead of applications.
Consider what happens when you embed an Excel spreadsheet into a Word document. When you click on the spreadsheet part of the document, the Excel user interface appears within Word - a technology called "in-place editing". The document is a word document, yet clearly, Word is able to somehow store and manipulate the Excel spreadsheet object that is somehow embedded into the Word file. Or can it?
In fact, Word has no idea what data is contained in the Excel spreadsheet or how to work with it. What actually happens is that the Word file is a compound document. One of the storages in the document is a place where objects foreign to Word are stored including, in this case, the Excel spreadsheet. Each object is stored in its own stream. When you save the word document, Word does not know how to store the spreadsheet object, but it does not need to - all it has to do is pass a handle to the stream to Excel. Excel then saves the spreadsheet data into the stream.
When you reload the document, Word looks at the objects in its object pool. Each of the streams starts with a GUID - a universal identifier. Word looks at that identifier and calls the OLE libraries asking it to create an object based on that stream information. OLE looks through the system registry, sees that it is an Excel spreadsheet object, then loads those parts of Excel that are necessary to display the object and allow the user to edit it.
As you can see, OLE Structured storage fills the critical need of allowing an application to store objects even though it does not know their internal format - it can simply pass a stream handle to a server that knows how to work with that object. You can use this same technique in Visual Basic in conjunction with the OLE container control to store foreign objects inside your own compound document files.
A quick look with a compound document browser shows that OLE Structured Storage is used by many Microsoft Applications including most of the Microsoft Office applications.
Isn't OLE Structured Storage Obsolete?
Because it has "OLE" in its name, there may be a tendency to think that this technology is obsolete in the age of .NET. Nothing can be further from the truth. Remember, OLE was a "grab bag" of loosely related technologies of which Structured Storage was just one. Structured Storage will remain built in to the Windows operating system for the foreseeable future - removing it would break huge numbers of applications.
The unique advantages that Structured Storage offers are highly relevant in the age of .NET, and offer features that are not available in any native .NET technology.
Should you use a Compound Document or a Database?
I've been asked this question any number of times. In fact, a large part of the purpose of this article is to dispel this question. Note that I say dispel - not answer. The question can't be answered because it is intimately tied to the design of each individual application.
If your application is storing multiple groups of records, where all of the records in a group are similar to each other, and requires sophisticated search and filtering capabilities and support for the definition of relationships between records in different groups (tables), then you probably need a database.
If you wish to create a private document format that contains arbitrary types of data of different sizes, and perhaps objects from other applications, Structured Storage might be a better choice.
In either case, the problem is first to determine the needs of your particular application. Once the requirements are defined, the choice of technology will, in most cases, be clear.
Private vs. Public Information
While the contents of any particular stream in a compound document is defined entirely by the application or object that it contains, the management of streams and storages within the document is the responsibility of OLE itself. This means that it is possible for any application to browse through the structure and contents of the document - just as any application can open and read a disk file.
One of the nice results of this characteristic of compound document files is that you can mix private and public data within a file. You can, for example, place a plain text description in a stream with a given name that any application can read.
Microsoft has actually defined two standard properties format streams called "SummaryInformation" and "DocumentSummaryInformation". These streams contain standard summary information such as the document Title, Author, Comments and so forth. This means that any application can read this summary information. You can use it in your own documents, or use it to obtain information about other documents that use this feature.
Self Persisting Classes
You've seen how OLE Structured Storage allows each application to be responsible for its own objects within a single document. You can use the same technique within your own application by creating self-persisting classes.
Say you create an application that contains a number of different classes and you wish to persist collections of objects from each class. One technique involves creating high level routines for saving and loading all of the objects. The disadvantage of this approach is that any changes to a class require that you modify the high level routines. This includes adding new classes, or changing the formats that a class uses to save its data. This kind of centralized approach is necessary in most cases where you are creating a private file format that you are managing yourself.
OLE structured storage makes possible a better approach in which each class knows how to transfer its data to and from a stream. In this case, all the high level routine has to do is call a "Save" or "Load" method for each instance of each class. If a class needs to change its data format, it can do so at will (assuming it maintains the ability to load the older format). The high level persistence routines do not need to be modified in any way.
Use of self-persisting classes can improve the long term reliability of an application by making it less likely that the persistence operation of one class might interfere with those of others used by the application - even when the code or data formats for individual classes are modified.
OLE structured storage files can easily support binary or XML streams of .NET serialized classes, as well as COM based classes that use the standard COM serialization interfaces (IPersistStream, IPersistStorage).
Other capabilities of OLE Structured Storage
Compound document files support sharing - individual storages can be opened for exclusive or shared access, in much the same way as disk files support sharing. Different storages and streams can be opened at the same time as long as they have unique paths from the root storage.
OLE Structured Storage also supports transactioning. You can open a storage in transacted mode. After modifying the contents of the storage you then have the choice of committing those changes or reverting to the original contents. This can be ideal for implementing features such as incremental Undo operations. This also creates an effective buffer system, making multiple reads and writes to a compound document very fast.
OLE Structured Storage and Visual Basic
There is just one catch that exists when it comes to using OLE Structured Storage technology from Visual Basic. That is that Visual Basic.NET and C# do not support this technology. OLE Structured Storage is not implemented using API calls but rather OLE interfaces, a system not supported in VB. And while you can call OLE interfaces directly in .NET, the functions are not designed to use common variable types such as integers, arrays or pictures. The Summary Information streams are particularly difficult to deal with.
Fortunately, you can access all of the capabilities of OLE structured storage from Visual Basic using a third party package called "StorageTools" from Desaware. This package includes OLE components for accessing structured storage, for simplified access to only Summary Information streams, and for easy access to the system registry, including search capability.
You may have heard about OLE 2.0 with its ability to control applications and embed objects from one application into another. But there's another feature built into OLE 2.0 that until now was not accessible to Visual Basic programmers. It's called "Structured Storage" and StorageTools is your key to this powerful technology. Now in version 3.0, StorageTools includes full support for Microsoft's new .NET platform.
Structured Storage allows you to create files that organize information easily. Blocks of data can be placed in hierarchical form, just as files are placed in directories. Its like having an entire file system in each file. You can also create and work with compound documents - a new standard for document storage.
OLE 2.0 takes care of allocating and freeing space within a file, so just as you need not concern yourself with the physical placement of files on disk, you can disregard the actual location of data in the file. Plus: with its support for transactioning you can easily implement undo operations and incremental saves in your application.
StorageTools allows you to take advantage of the same file storage system used by Microsoft's own applications. Includes sample programs (with source) that let you examine the structure of any OLE 2.0 based file so you can see exactly how they do it!
StorageTools Storage Components:
The Storage component uses objects to represent storages and streams, creating a familiar interface for manipulating those elements. Within the Structured Storage standard are a number of functions that let you upgrade your file handling procedures easily: you can detect whether files are in Structured Storage format or not, and you can read any normal file as if it was a Structured Storage file. The Storage component also adds a number of features specifically for Visual Basic programmers. It lets you read and write information in any of the styles Visual Basic uses, such as "Sequential", "Binary" or "Random", including arrays.
StorageTools is the key to unlocking the following Structured Storage capabilities:
StorageTools Registry Control (for COM):
The Registry Control makes it easy to access the Registry and the Registration Database and is ideal for use with VB6 and earlier versions of Visual Basic. It provides all the power of Windows API calls and more. Keys within the Registry are accessed like directories. Values are converted to data types compatible with Visual Basic. Powerful search capabilities are included, allowing you not to only search among keys and value names, but within the value data itself. The documentation includes descriptions of areas in the Registry that might be useful and how to access them.
Using StorageTools, the Registry becomes the key to transforming your Visual Basic program into a truly professional application. Here are just some of the thing you can do:
StorageTool Resource Compiler:
The Desaware Resource Compiler is a tool that allows you to easily embed bitmap, icon and string resources into your VB4 through VB6 executables (16 & 32 bits). The Desaware Resource Compiler runs as a stand-alone program or a VB add-in. It includes complete VB source code and a technical description of how it works.
StorageTools includes 16 & 32 bit ActiveX controls, .NET assemblies, an ATL based Storage Component, documentation and sample code. Supports VB 4 through .NET, C#, Windows 95-ME, NT-XP. Storage Tools is now part of the Desaware Universal COM and Desaware Universal .NET packages.
Desaware prides itself on products that address real-world programming issues. Desaware develops advanced tools that educate and expand the limits of software development. With the fast transition of today's technologies, our products reflect our commitment to remaining at the forefront of new technology, while maintaining long term support for our software in legacy applications.
For notification when new articles are available, sign up for Desaware's Newsletter.
|Products Purchase Articles Support Company Contact