I have some good news and some bad news. The bad news is that the Library Project does not make direct reads or writes of standard files, and has no need for file streams. That means we won't be adding any code to the project in this chapter at all. The good news is that we still have interesting things to talk about. Besides, I figured that since you had reached the half-way point of the book, you could use a break.
Chapter 15 does not include any project templates, so don't bother looking in Visual Studio for them.
Configuring Log Output
Whenever an error occurs in the Library application, the GeneralError routine first shows the error message to the user, and then logs it to any configured "log listeners."
Public Sub GeneralError(ByVal routineName As String, _ ByVal theError As System.Exception) ' ----- Report an error to the user. On Error Resume Next MsgBox("The following error occurred at location '" & _ routineName & "':" & vbCrLf & vbCrLf & _ theError.Message, MsgBoxStyle.OkOnly Or _ MsgBoxStyle.Exclamation, ProgramTitle) My.Application.Log.WriteException(theError) End Sub
So, who's listening? If you are running the program within Visual Studio, Visual Basic always configures a log listener that displays the text in the Immediate Window panel. But that doesn't do much good in a compiled and deployed application.
You can design your own log listeners, but .NET also includes several predefined listeners, all of which can be enabled and configured through the application's app.config file. If you access the "After" version of the project in Chapter 14, you will find content in its app.config file that sets up one such listener. Here's a portion of that file, showing just the relevant sections.
The <sharedListeners> section defines the details for a particular log listener. In this case, it's the FileLogTraceListener listener, a class in the Microsoft.VisualBasic.Logging namespace. It's enabled in the <source>/<listeners> section, where it's included through an <add> tag. There's a lot of stuff here that seems bizarre or extremely picky (such as the public key token). Fortunately, it's all documented in MSDN if you ever need the details.
The FileLogTraceListener listener sends relevant logging data to an application-specific log file. By default, the file resides in the following:
C:\Documents and Settings\username\Application Data\ Company\Product\Version\AppName.log
The username part is replaced by the name of the current logged-in user. The Company, Product, and Version parts represent the company name, product name, and version number of your assembly as defined in its assembly attributes. AppName is the name of your application with the ".exe" extension stripped off. On my system, the log file for the Library Project appears here.
C:\Documents and Settings\username\Application Data\ ACME\Library\18.104.22.168\Library.log
If you don't like that location, you can change the output to any location you choose. To do it, you'll need to alter the <add> tag in the <sharedListeners> section, adding two additional attributes to that tag.
The new location and customLocation attributes do the trick. Set the customLocation attribute to the directory where the log file should go. These attributes link to properties of the same name in the FileLogTraceListener class. Visual Studio's documentation describes these properties and attributes, plus others that are available for you to configure through app.config.
This app.config change is based on an MSDN article named "How to: Write Event Information to a Text File" that you can search for in your online help. (Use the Search feature, not the Index feature.)
Other Log Output Options
Another MSDN article, "Walkthrough: Changing Where My.Application.Log Writes Information," describes how to send log output to more than just a simple text file. It discusses ways to log application information to the system Event Log, to a delimited file, to an XML-formatted file, and to the console display.
Some of the changes you need to make to the app.config file are, again, mysterious, so I'll just list them here for your examination. Add the following content to the app.config file to define the available listeners.
The initializeData attribute in each entry contains the values sent to the arguments of the relevant class constructor. Other attributes (except for type) modify the properties of the same name in the class specified through the type attribute. For all the options available to you for each listener, look up its class entry in the Visual Studio documentation.
To enable any of these listeners, use an <add> tag in the <source>/ <listeners> section. The following XML block enables all the listeners defined in this chapter project.
<sources> <!-- This section defines the logging configuration for My.Application.Log --> <source name="DefaultSource" switchName="DefaultSwitch"> <listeners> <add name="FileLog"/> <add name="EventLog" /> <add name="Delimited" /> <add name="XmlWriter" /> <add name="Console" /> </listeners> </source> </sources>
Obtaining a Barcode Font
Because we have a little time left, let's talk about obtaining a barcode font. The Library Project will include barcode printing support, but only if you have a barcode font installed on your system. It's no emergency, but you should obtain one before you reach Chapter 17, "GDI+," where we develop the barcode configuration code.
When you downloaded the code for this book, it didn't include a barcode font. It's all due to licensing issues and the like, you understand. But barcode fonts are easy to get. You can purchase a professional barcode font if you want to, and if you plan on deploying this project into an actual library setting, you probably should. But if you're only reading this book for the great humor, you can download one of the many free barcode fonts available on the Internet. I've included some links to barcode font providers on the Web site where you obtained the source code for this book. Even if you don't plan on using the barcode printing features, I recommend that you download a free barcode font just so you can try out some of the Chapter 17 features.
Once you've installed the font, you will need to tell the Library program to use it. The settings form designed in the previous chapter included a selection field for this font. It's the Barcode Font Name field on the System-Wide tab of the Maintenance form. You can see it in the middle of Figure 14-6. I made it a system-wide setting because it seemed best to have all administrators in a single library using a common font.
If your font is a "Code 3 of 9" barcode font (also called "Code 39"), make sure you select the Barcode is "Code 39" or "Code 3 of 9" field on that same form. (The provider of the font will let you know if it is a Code 3 of 9 font or not.) These fonts require an asterisk before and after the barcode number. Selecting this field will cause the Library program to add the asterisk characters automatically.
Well, I'm getting tired of talking about files, be they fonts or config files. In the next chapter, we'll go back into the world of code and its fraternal twin, data.