Sunday, September 18, 2005


It's been way too long since my last post. A couple of weeks ago, the whole family came down with some sort of sinus infection. I'm still not quite done with it, but I think I'm through the worst. This weekend I felt well enough to tinker around with my old Gateway PC. One thing had been really frustrating me for a while: I couldn't boot from a CD-ROM. Not only that, but if I tried using something like SmartBootManager or another Torito stack trick to boot the CD-ROM, I would get an Error 0xAA message. So booting from the CD-ROM was a no-go, even with a boot floppy. I thought maybe it had something to do with the fact that I had upgraded the CPU a couple years back using one of the Evergreen Spectra kits. I took the PC apart and put the old 100 MHz chip back in and flashed the BIOS back to the gateway supplied one (1.0.10.BR0T). It was kind of nostalgic to see that Gateway 2000 logo popup again when I booted the PC.

Anyway, booting from the CD-ROM was an option again in the bios, so I flipped it on and put in my SLAX live CD. Unfortunately, I got an ISOLINUX error. Evidently it was able to try to boot from the CD-ROM, but it ran into some other hurdle in the process. Fortunately, I have lots of spare CD drives hanging around. I took the spare Dell one and put it in, and sure enough it booted up fine. Something about that Plextor CD-R/W was not happy about booting. So then I thought, well maybe I can get this guy to boot to CD-ROM with the upgraded chip back in there. Well, it doesn't work perfectly, but using the SmartBootManager disk I can get it to boot to CD-ROM with the 400 MHz chip installed. Huzzah!

That leads to tonight. I've been trying to get the latest distro of Slackware Linux (10.2) running. It's installed, and I can use it, but it won't recognize my USB mouse. I have a PS/2 mouse plugged in now, and it likes that, but it is sort of a pain because the cable from the KVM is USB. So now I have 2 mice on my deks, one for the Dell, and one for the Gateway. Solving problems like this is part of the "joy" of using Linux. I'm sure I'll have it figured out in the next couple of days, or else I'll just switch to the next distribution.

Wednesday, July 27, 2005


I learned how to program in a UNIX environment. In a UNIX environment, almost everything is done from the command line (or can be). Sure, there was a GUI that you could click around on, but if you really wanted to get something done, your just wrote a script for it and fired it off on the command line. One of the tools that was really useful was the "grep" command. This command would take a search string as an argument, and then search through all of the files in the directories you specified for that string. It was very useful when debugging code, because you could quickly determine all of the code files that touched a particular class or header file.

Sadly, grep was missing from my list of command line utilities when I moved over to developing on a Windows platform. In fact, the command line was pretty well shunned. Instead, Visual development was the word of the day. I still missed my friendly grep command though. Sometime last fall, I discovered the FINDSTR command in windows. On the command line, the FINDSTR command works much like grep in that it will search for a given string in the subdirectories you specify. It's much handier (to me anyway) than the graphical search tool because I don't have to worry that it isn't skipping files it doesn't recognize as text files. If you want to use it, here is the info:

Searches for strings in files.

FINDSTR [/B] [/E] [/L] [/R] [/S] [/I] [/X] [/V] [/N] [/M] [/O] [/P] [/F:file]
[/C:string] [/G:file] [/D:dir list] [/A:color attributes] [/OFF[LINE]]
strings [[drive:][path]filename[ ...]]

/B Matches pattern if at the beginning of a line.
/E Matches pattern if at the end of a line.
/L Uses search strings literally.
/R Uses search strings as regular expressions.
/S Searches for matching files in the current directory and all
/I Specifies that the search is not to be case-sensitive.
/X Prints lines that match exactly.
/V Prints only lines that do not contain a match.
/N Prints the line number before each line that matches.
/M Prints only the filename if a file contains a match.
/O Prints character offset before each matching line.
/P Skip files with non-printable characters.
/OFF[LINE] Do not skip files with offline attribute set.
/A:attr Specifies color attribute with two hex digits. See "color /?"
/F:file Reads file list from the specified file(/ stands for console).
/C:string Uses specified string as a literal search string.
/G:file Gets search strings from the specified file(/ stands for console).
/D:dir Search a semicolon delimited list of directories
strings Text to be searched for.
Specifies a file or files to search.

Use spaces to separate multiple search strings unless the argument is prefixed
with /C. For example, 'FINDSTR "hello there" x.y' searches for "hello" or
"there" in file x.y. 'FINDSTR /C:"hello there" x.y' searches for
"hello there" in file x.y.

Regular expression quick reference:
. Wildcard: any character
* Repeat: zero or more occurances of previous character or class
^ Line position: beginning of line
$ Line position: end of line
[class] Character class: any one character in set
[^class] Inverse class: any one character not in set
[x-y] Range: any characters within the specified range
\x Escape: literal use of metacharacter x
\ xyz\> Word position: end of word

For full information on FINDSTR regular expressions refer to the online Command

Thursday, June 30, 2005

How to Use a Managed (.NET) Control in an Unmanaged Container

It seems that in the first beta of the Visual Studio .NET tools, you were able to create a user control (like a button or a form), and the mark it for COM compatibility to use it like an ActiveX control in your legacy Visual Studio 6 projects. Unfortunately, Microsoft decided to yank that feature prior to the official 1.0 release of the .NET SDK. It has yet to reappear.

Fortunately, some clever folks have figured out how to work-around this and get it to work. The first clue I came across was a Microsoft hosted page that suggested building an interop ActiveX control in VC7, and then using the interop ActiveX control from within the VC6 project. I went along this idea for a while, but was eventually advised against it by some of the other developers here as they had seen issues in mixing VC6 and VC7 libraries.

Then I hit the jackpot. I found two websites that, when combined, got me exactly what I wanted. Those websites were:

I had to add two functions to my control class. One function to add some extra Registry information to mark the component as an ActiveX control, and the other to remove those entries when the component is unregistered. I also had to mark the class with a ClassInterface and a GUID. Below is the class declaration info:

public class MyActiveXControl : System.Windows.Forms.Button

Then I used the following two functions for my extra registry settings.

#region COM Interop / ActiveX Functions

public static void RegisterClass ( string key )
// Strip off HKEY_CLASSES_ROOT\ from the passed key as I don't need it
StringBuilder sb = new StringBuilder ( key ) ;

// Open the CLSID\{guid} key for write access
RegistryKey k = Registry.ClassesRoot.OpenSubKey(sb.ToString(),true);

// And create the 'Control' key - this allows it to show up in
// the ActiveX control container
RegistryKey ctrl = k.CreateSubKey ( "Control" ) ;
ctrl.Close ( ) ;

// Next create the CodeBase entry - needed if not string named and GACced.
RegistryKey inprocServer32 = k.OpenSubKey ( "InprocServer32" , true ) ;
inprocServer32.SetValue (
"CodeBase" , Assembly.GetExecutingAssembly().CodeBase ) ;
inprocServer32.Close ( ) ;

// Create a miscellaneous status key to prevent flickering
RegistryKey miscStatus = k.CreateSubKey("MiscStatus");
"", "131457");

// Reference the type library
RegistryKey typeLib = k.CreateSubKey("TypeLib");
Guid libid = Marshal.GetTypeLibGuidForAssembly(Assembly.GetExecutingAssembly());
"", libid.ToString("B"));

// Assign the version of the control
RegistryKey versionKey = k.CreateSubKey("Version");
Version ver = Assembly.GetExecutingAssembly().GetName().Version;
string version = string.Format("{0}.{1}", ver.Major, ver.Minor);

if( version == "0.0" )
version =
"", version);

// Finally close the main key
k.Close ( ) ;

public static void UnregisterClass ( string key )
StringBuilder sb =
new StringBuilder ( key ) ;

// Open HKCR\CLSID\{guid} for write access
RegistryKey k = Registry.ClassesRoot.OpenSubKey(sb.ToString(),true);

// Delete the 'Control' key, but don't throw an exception if it does not exist
k.DeleteSubKey ( "Control" , false ) ;

// Next open up InprocServer32
RegistryKey inprocServer32 = k.OpenSubKey ( "InprocServer32" , true ) ;

// And delete the CodeBase key, again not throwing if missing
k.DeleteSubKey ( "CodeBase" , false ) ;

// Finally close the main key
k.Close ( ) ;


With that code inserted, I then compiled the .NET code. To prove that the object will work, go to the Tools menu and choose ActiveX Test Control Container. Here you can add a sample instance of your control to prove to yourself it is working. The next step is to actually embed the control in you Visual Studio 6.0 project. Open up your dialog editor in VC++ and right-click the dialog. Choose "Insert ActiveX Control" and pick your control out of the list. Next, right-click the form and choose "Class Wizard...". Go to the Member variables tab and double click the ResourceID for your control to add a member variable in your code to access the functionality of the object. This last step is only necessary if you need to call methods or set properties on your user control.

I'm not guaranteeing that this code will work for you, but it has been working quite well for me. Sometimes when I open the dialog editor, I get an error message that says that the ActiveX control could not be instantiated, but it always compiles and works at runtime. Your mileage may vary.

Friday, June 24, 2005

Wiring up User Interface Events in C#

One of the things I really l like about C# is the way events work. I was already accustomed to creating event listeners and adding them to the event source in Java, so it was a no brainer to switch to C#. One thing that was a little confusing at first, though, was how to easily wire up my events for user interface components. In VB6 and VB.NET it was simple enough to just select the event from the drop down list at the top of the code window. Unfortunately, the drop down windows in the C# code window down show events, only the methods already implemented.

Fortunately, it is just a matter of looking in a different place. If you are looking at your C# code page, hit Shift-F7 to flip back to designer mode. Select the component you want to wire up an event for. Now look at the properties window (if you don't have it up, go to the View menu and select it). Notice the little lightning bolt icon in the toolbar? Click this and you will get to the list of public events exposed by the control. If you double click an event, the IDE will automatically insert the code skeleton and wire up the event. If you already have an event handler written, just click the arrow to get a dropdown list of all of the functions that can listen to the event.

Property list for a Windows Form (events button circled)

Event list for a Windows Form

Thursday, June 23, 2005

Database Connection String Wizard

Here's a simple trick for generating connection strings to your database. On your windows desktop, create a file with the *.udl extension. You'll notice that the icon for the file changes. Now double-click on the file to open it. This will launch the wizard for creating your connection string. Be careful, the wizard starts on page two. Backup to the first page and pick your target database protocol. Then step through the wizard to complete building your connection string. When you are finished, right click the file and open it with a text editor. You'll see that it contains your connection string!

Saturday, June 4, 2005

Mice and Keyboards

As a programmer, I'm very particular about the tools I use. In college I got used to writing code using Vi, an antiquated command line only text editing program. To this day I still use Vi to occassionally edit text files or code. Sure, I use a slightly updated version with nice syntax highlighting and windows support, but it is still the same Vi where you could do all of your editing through a strange concoction of keystrokes and key combination. Using Vi, you never had to touch the mouse, which was good in its time since mice might not have been invented yet.

Just as I'm picky about the software tools I use, I'm very picky about the hardware that I use. Particularly keyboards and mice. I've become a very proficient touch typist. I'm frustrated each time I need to change keyboards, because invariably the keyboard maker has done something to "improve" their keyboard which throws off my ability to find the right keys. This comes up because when I arrived for my first day of work, I was greeted by a very, very poor keyboard. The keys didn't have the right clicky-ness feel, they stuck, the layout was all wrong.... I didn't like it and it had to go. When I went searching for a replacement, I realized just how much the tools of the trade have changed. Follow with me as we travel down my keyboard and mouse hall of memories.

The MacIntosh IIsi Keyboard and Mouse

The first keyboard and mouse and I used extensively were on the Mac IIsi we had growin up. Learning to type on this board was a "hunt and peck" affair. I didn't take a typing course until my senior year of high school, but I was quite good at using the "One-Finger-Wonder" technique to stab out what I needed. Mac's were unique, even at that time. One trait that endures even to this day is the one button mouse. Simple, yet utterly effective. Another neat feature of the Mac keyboard was the cabling. I plugged the cord into both sides of the keyboard to show that it had two ports. One port would plug into the back of the PC, and the other was used for the mouse. That's why the cable for the mouse is so short, it only had to run a couple of inches to the keyboard. Brilliant! As wth all keyboards of this time, it weighed about as much as it cost. The Mac keyboard is a good 10 pounds, if not more. All of the keys have a nice weight to them, and make an enticing clicking sound when you press them. Another unique Mac feature is the power button in the upper right hand corner.

Gateway AnyKey Keyboard and Mouse

Upon graduating high school and moving on to college, it was time to get a new PC of my own. I opted for a state of the art Gateway P100 with an Intel Pentium 100MHz processor, 16MB of RAM, and a full 1GB of hard drive space. It came with the Gateway AnyKey keyboard, and a standard two button mouse. The mouse is only interesting in that it had a half-hearted nod to ergonomics. The curved shaped was great.... if you were right handed. Lefties would be totally miffed by this mouse, but I didn't have to worry about that. This keyboard was awesome, and I used it for the longest that I ever used a single keyboard. It had an eight-way arrow pad, which was great for video games. I can't remember what the middle key does between all of the arrows, but I'm sure it had some use. It had not 12 but 24 Function keys (F1-F24). This was a boon when I needed to telnet into the school's UNIX machines and execute some odd-ball command. What really set this keyboard apart, though, was the fact that it was completely prorammable. The keyboard encoder could be reprogrammed on the fly to change any key to function in some other way. Software was available to backup and restore these configurations. Like I said before, I am a Vi user. The school labs all had Sun machines, and Sun machines have a different keyboard layout (sorry for the lack of a photo, but I never OWNED a Sun keyboard). On Sun keyboards, the Control key and CapsLock keys are switched. The Escape key and the tilde/squiggle (`/~) key are switched. And Sun keyboards had a variety of other special "function" keys (Stop and Halt come to mind). When I would back from my labs and go to work on my homework, I could download a new keyboard configuration and use my keyboard just like the Sun ones at the lab. Great! When I was done, I just switched it back to the original layout and I was on my way. I LOVED this keyboard. Unfortunately, it has seen too many years of use, and the keys started to fail. Something messed up the G and H keys, and when keys stop working, it's time for a new keyboard.

Ergonomic Keyboard and Optical Mouse

About the time the AnyKey died, the price of optical mice and ergonomic keyboards was falling. Optical mice had the benefit of not using a mouse ball to track movement, but instead detect motion through a tiny light sensor on the bottom of the mouse. It would detect the movement of the pattern under the mouse and move the cursor accordingly. Sun mice worked like this for years, but required a special mouse pad. The new series of mice would work on almost any surface, and you would never worry about cleaning the lint out of your mouse balls again (shiver). Another neat feature was the scroll wheel. This had been around for a while in non-optical mice, but this was the first mouse I had with a scroll wheel. The scroll wheels were a tremendously good idea. They allowed you to quickly scroll up and down a window, such as a web page or word document. No more hunting for the scroll bars. The wheel could also be depressed for a third mouse button. I never really used this feature until later software (Firefox's tabbed browsing) took good advantage of it.

The ergonomic keyboards were a pretty radical change as well. Mind you, I had spent the better part of the last ten years mastering a particular keyboard layout. I was more than a little wary of these strange beasts with their split layout and curved surface. I decided to take the plunge though, and after an adjustment period, found that the layout truly was much more natural. Regular keyboards cause your hands and wrists to be at too much of an strange angle. Your fingers are oriented straigh up and down while your wrists are bent to accomodate the width of your shoulders. This isn't such a problem for occassional PC users, but for someone who spends 8 or more hours a day typing, it can get to be quie a nuissance. I never realized how much so until I went from the ergo keyboard back to a laptop keyboard for work. They really are more comfortable, and only take a week or so of use to get really accustomed to. Still, I lost a lot with this keyboard. I was down 12 function keys, my 8 way arrow pad was down to a four-way cross, and my Insert-Home-Page Up / Delete-End-Page Down keys had been turned on their side.

Dual Optical Logitech Mouse

I liked my optical mouse, but I wanted more out of it. Enter the Logitech dual optical mouse. It was another right-handers only mouse, and the design really fit my hand well. It featured two motion tracking sensors on the bottom, which eliminated a lot of the jitter you get out of the single optical variety. It also had a handy extra button on the side. This button was configurable, but I liked the default, which was as a back button in your browser. The scroll wheel is still present. I absolutely love this mouse, and use it to this day.

Microsoft Comfort Wireless Desktop

Which brings us to my shopping trip today. I was really disappointed when I walked down the aisle at Fry's. All I really wanted was another ergonomic keyboard, and possibly a dual-optical mouse like I had at a cheap price. No chance. The hot feature now is wireless. At my desk, I really don't mind having wires, but there were very few choices for corded keyboards and mice. In addition, finding an ergonomic keyboard with a half-way sane key layout was a real chore. There are so many additional "feature" keys like homepage, e-mail, volume controls, finger-print readers, and so on that I was really put off. Frustrated with Fry's, I went to the local Target. There I found a reduced set of the same things, albeit at much lower prices. I decided I'd give the Microsoft Comfort Wireless Desktop set a try. It was an ergonomic keyboard with a mostly okay layout. Notice that my once mighty 8-way arrow layout is now down to an almost forgotten upside down T tucked at the bottom of the keyboard. My delete key up and swallowed (or did it delete it) the insert key. I'm not entirely upset about that as I found the insert key completely useless. Thankfully, I haven't lost any more function keys (although I do need F-Lock on to get to them), and I still have a full number pad. However, I am now completely surrounded by "helper" stuff around the keyboard. The left side has a zoom slider.... not sure I'll ever get into the routine of using that. It also has hot buttons for e-mail, web browsing, instant messenger, calendar, and my documents folder. Across the top are volume and playback controls, as well as a customizable set of keys. My function keys are now overloaded to offer common editing functions with the F-Lock is turned off. The built-in wrist pad is actually pretty comfortable. After using the keyboard this evening, and to write this post, I have to admit that I'm actually pretty hapy with it. Compared to the old mac keyboard, it is incredibly light, and the lack of cables dangling around does clean up some of the clutter in the room.

The mouse has it's ups and downs. I still prefer my logitech dual-optical mouse over this one, and when the wireless stuff goes to work on Monday, it will make a triumphant return to the mousepad. The wireless optical mouse is no longer bigoted to handed-ness (lefties welcome, Mr. Ned Flanders), but the design doesn't fit my hand quite as well as the logitech does. My back button is gone completely. There was a more expensive version of this setup which included a mouse with both a back, forward, and a couple of other extra buttons on it, but it wasn't worth doubling the price. The one new feature is that the scroll wheel now tips left and right to scroll horizontally. I'm not often faced with horizontal scrolling, so I'm not sure how useful this will be. It can't hurt anything though. One minor nuissance is that the wheel button itself is much more difficult to click. When doing so, it is very easy to lean and end up scrolling rather than clicking.

So there you have it. That is my history with keyboards and mice. I have pictures because I still have all of these old monsters laying around the house. The wireless stuff will travel with me to work on Monday, and I'll be back to hacking bliss!

Monday, April 25, 2005

I'm Certifiable!

This morning I took the Microsoft Certification Exam 70-320 : XML Web Services and .NET Remoting in Microsoft Visual C#. I passed with flying colors, which means that I'm now not only certified in that subject, but I've passed the requisite exams to be a Microsoft Certified Application Developer (MCAD). In the MS developer track, you are a Microsoft Certified Professional (MCP) after passing any exam. I've been an MCP for several years, but I've not put the effort forth to get through the exams to get my next certification level. Until a couple of years ago, the hurdle was pretty high. To reach Microsoft Certified Solution Developer (MCSD) status, you had to pass five exams. Microsoft introduced the MCAD certification as a mid-step between the two. It was just the motivation I needed. That, and the fact that we have a state grant at Flexware to get reimbursed for any certifications we get.

So now I have two more exams to pass to get my MCSD. I need the 70-300 Solution Architectures exam, and an elective. I'll likely take the SQL Server exam as my elective. This latest exam was probably one of the hardest I've taken, and I've been putting it off for almost an entire year. I'm glad it is finally over and I can move on to the next one.

Saturday, April 9, 2005

Get My Geek On

Every once in a while, I get bitten by the bug to do some very geeky project. A couple of years ago, that project was to build an arcade cabinet. This week, I got the bug again, although to a much lesser degree. I've been trying to clear out all of the unnecessary stuff from my desk at work. I have piles of stuff I never use, and it clutters up the limited space I have. I had three PCs sitting under the desk that were switched off 90% of the time, and I had a three piece speaker set with a giant subwoofer that I never used. I always wear my headphones, and never use the speakers, but I plug my headphones into the speakers. It was time for all of this stuff to go.

After moving my speakers out, I plugged my headphones directly into the line-out jack on my Sirius radio. That's when I discovered my problem. The radio did not have a volume control. It was intended to be plugged into a stereo receiver, and the receiver would supply volume control. I was faced with a decision: spend $30 or more on a new set of headphones that had a built in volume control, or spend $15 to build my own volume knob. I knew that a volume know is just a variable resistor (Potentiometer) in line with the signal, and I had used them before in lab for class. I headed down to the radio shack and picked up a hobby kit, a nice shiny knob, and a good two channel potentiometer.

Potentiometers are pretty easy to use. In most cases, there are three solder points. You wire ground to one of the points, your source signal to the other, and the output to the one in the middle. As you dial the potentiometer back and forth, the resistance applied between the source signal and the output changes, and in effect changes the volume on the headphones. My potentiometer had two channels, one for the left speaker and one for the right. It was a simple matter to get the wiring done, and the dremel did nice work of poking holes in the sides of the hobby kit. And now, I have a fully functional volume knob!

Now that I'm done with this little project, I do have one thing I would have changed. I used a 100K Ohm potentiometer. That's a lot of resistance. I think my headphones only provide a 10K Ohm load, if that. The result is that I have to dial the "volume" on the potentiometer way up to hear anything, and once I do hear something, the knob is very sensitive to changes. A little to the right, and it gets very loud. A little to the left, and it goes silent. It works for what I need, but if I were to do it again, I'd get a much weaker potentiometer.

This was a fun little project that didn't cost a lot of money, and it let me geek out for a little bit.

The knob and potentiometer, pre-assembly

Finished Volume Control

Monday, January 31, 2005

My Adventure with Linux

I've always been a fan of open source software. Not so much because I like to tinker with the code, but because I can get some really great software for free. When I was in college I ran RedHat Linux as my operating system. We used Sun Solaris machines for all of our engineering homework, so it made sense to use a UNIX compatible machine at home. When Jenn and I moved to Maryland, I tried using Linux for a while, but Windows was much easier for Jenn to work with, so we switched over to that. Our new PC came with Windows XP Home already installed, and we've been using that ever since.

Lately, I've been wanting to do a little bit more with our home machine as a server. I'd like to be able to host images, video, and other stuff for the blog sites. I've also been interested in trying out some of the open source technologies for work. So over the past week I attempted to get Linux installed on a Virtual Machine instance. I am using Microsoft Virtual PC 2004 as the VM. I had so many problems trying to get this stuff installed. I first started with the Suse 9.2 professional mini-installer. This installer contacts an FTP server and attempts to download all of the components during the installation process. After several tries I was having no luck. I was following the instructions that said to go to the manual install option. The installer asked me to select my network card type, and I had no idea what the virtual PC was emulating the network connection as. After much frustration with guessing the card type, and failing to find anything on Google, I decided to switch distros.

So that night I downloaded Mandrake Linux and started that install. I gave up waiting for it to complete at 1am. When I woke up, it had a couple of errors but had finished installing from discs. I brought it into work and found that the X windows server failed to install properly, and I had a bear of a time getting it repaired. The one bright spot was that Mandrake successfully recognized the type of network card the Virtual PC was emulating: a DEC 21140 (Tulip) card. Armed with that information, I went back to the Suse installer.

Success.... oh, wait. Suse began installing, and loaded up the RAM disk from the FTP site I had selected ( However, after going through the hardware detection phase, it was unable to pull down the package list from the ftp site. I searched Google some more and only found a couple of items about whether the preceding '/' in the ftp path was necessary, but it didn't help. I tried several other servers, but it still didn't work. While I was playing around, I did notice that if I modified the install type from the main bootup screen of the installer to FTP, the installer successfully identified my network card. Why this doesn't happen when you do a manual install I'm not sure.

In any case, I was done wasting time on that at work. I figured I would play around with it more when I got home that night. After Jenn and Corbin went to bed, I fired up the VM instance again to try installing SuSE. There must be some undocumented network port needed to download packages, because from home the same FTP servers downloaded the package contents and the install worked flawlessly. I'm back at work now, and when I try to review the package list, it still fails, so there must be some additional outgoing port necessary for the download to occur. Does it use SSH? I don't know, but in any case, SuSE 9.2 is now installed on a virtual machine for me to play with.

All of that effort cost me about 12 hours. I have a short list of things I'd like to try now: developing in Mono, using Bugzilla, and playing with other open source development tools. I have to give it to Microsoft that they have done a great job of creating an installer for their OS. Still, now that it is installed, SuSE has been fairly easy to use. The YaST install tool is intuitive, and I've been able to find RPM packages for the software that I would normally use most often on Windows (Thunderbird and Firefox). Jenn can't quite understand why I think this is fun, but maybe I can find an example of something that only works in Linux that will wow her. Or, alternatively, I'll just prove to her what a big geek I am.