I have moved my household and its belongings something like 15 times in my adult (that is, post-high school) life. I've moved across the country (twice, from Houston to Boston and then from Boston to Los Angeles) and so many local moves I've lost actual count. When I was younger, I could pack all my stuff in a small truck and in two or three hours, be unpacked and ready to go again in less than a day. As we get older, we accumulate more junk. It's no longer so simple. By now, I've amassed four cats and a big house full of big house stuff that must be moved into a condo with a great view, but not much legroom. So, here we go again. We're heading back to the right coast (as opposed to the "left" coast, not the "wrong" coast.)
One has to wonder how to best transport four house cats across the country. I've had friends drive across the country with animals in the car. No thanks. I've also tried putting animals in the airplane cargo hold, but I won't begin to describe the state in which I retrieved my poor furry friends at the other end. This time, I've hired two friends to act as "cat mules," because apparently, no adult can handle more than one caged animal on an airline. (I tried to convince the airline folks that I was large enough to require two seats. They were happy to let me purchase two seats, but I could still only carry one cat. Go figure.) I'm really not looking forward, as you might imagine, to five hours in steerage with my little companions. My guess is that we'll be less popular on the plane than the family with newborn triplets screaming their way across the country.
Figuring that the housing market in CA was as hot as it was going to get for a while, and that it was time to downsize a little, we put the house on the market and it sold immediately. If you haven't sold a house, just wait. Among the non-biological milestones I can imagine, I assert that selling a house is just about the most stressful. Combine it with buying a new house, and starting a new job, and you've got a prime candidate for many sleepless nights. Fortunately, I'm neither buying a new house, nor starting a new job. This makes the stress far more manageable. At every point when selling a house, it becomes clear that you have no leverage and the buyer has all the control. In our case, after the buyer made the offer, he provided a list of repairs he demanded be done to the house, and in the interest of making the sale, we agreed. Now, after having done the research, we realize that if we renege on any one of these items, the buyer can walk away without purchasing the house, and without losing his down payment.
As a side note, anyone who knows me personally knows that I am passionate about the strange elitist art form, live theater. I go to the theater a lot. In a New York weekend visit, we can cram in four or five shows. It's possible, if you try hard enough and don't really need to pay for food or hotel as well. Back in the 90s, I saw the amazing and heart-wrenching play, "Angels in America" (recently reduced and abused by HBO, but it was better than nothing) as many times as I could. In one scene (not included in the HBO version), a real estate agent in Salt Lake City was attempting to convince a friend not to put her house on the market and leave town, and she said: "I always thought: People ought to stay put. That's why I got my license to sell real estate. It's a way of saying: Have a house! Stay put! It's a way of saying traveling's no good. Plus I needed the cash." (In the context of the play, this line has far more resonance than it does in the context of this little diatribe. It's ripe with metaphors. The play's about big issues: life, death, humans and higher beings, our place in the universe, politics and the treatment of the disenfranchised, and more. But I digress.) And now, I couldn't agree more. We should all just stay put. And goodness knows, my real estate agent made a lot of cash on this one.
In an effort to simplify our lives, we're moving from 3300 sq. ft. into 1500 sq. ft., and so are making the requisite adjustments to the amount of stuff we own. We've given tons of clothes and other belongings to charity; the woman who has cleaned our house and taken care of our lives for the past seven years has a new used TV, DVD player, computer, bed, sofa, chair, and more. Our friends the "cat mules" found boxes of tarps, duct tape, garden tools, and ten pounds of frozen chicken dumped at their doorstep. Anyone who comes to the house at this point gets a party favor. The plumber walked out with a new shovel. All my friends ended up with more used techie stuff than they care to admit. It all feels a little morbid, but it's got to be done. You have to understand how much space you have, and work with it.
And speaking of working within your space (you knew it had to turn technical somewhere), were you as surprised as I was to find that the .NET Framework didn't include any support for determining information about the file system, and how much free space exists on your drives? The first application I tried to write in .NET needed to have this information, yet it wasn't available within managed code.
As far as I can tell, you have three alternatives for determining drive size and free space: you can call the Win32 API directly; you can create an instance of the FileSystemObject using the Microsoft Scripting Runtime COM component, SCRRUN.DLL; or you can use the underrated, misunderstood WMI (Windows Management Instrumentation) interfaces built into the .NET Framework.
From my own perspective, I refuse to use Win32 API calls in managed code unless there is simply no alternative. All other reasons aside, it just feels "so 1995." The COM-based scripting runtime component is fine and does an excellent job, but it does inject its own versioning and deployment issues and complicates the distribution of your application. The third solution, using WMI, is the most complex of the three, but learning how to use WMI in managed applications is a skill that will provide you with solutions to tons of .NET problems, and it's worth investigating. I'll provide the code here to determine the free space on a drive using WMI, and point you at resources for learning more. (For what it's worth, this particular issue is resolved in the .NET Framework 2.0, due out in 2005?they've added some file system information to the base class library.)
WMI (Windows Management Instrumentation) is Microsoft's implementation of the standard cross-platform Common Interface Model (CIM), and WMI makes it possible to interact with hardware, software, Windows, network features, and much, much more. WMI itself is a huge topic, and we'll just cover a single tiny corner of it here. CIM provides a large group of base classes from which WMI inherits, and you can use managed wrappers around these WMI classes from within your .NET applications. Look for classes that begin with WIN32_ in your online or local MSDN documentation. (Start with the following URL as a good place to investigate the various WMI classes you're likely to use: http://msdn.microsoft.com/library/en-us/wmisdk/wmi/win32_classes.asp).
As promised, the code for retrieving the amount of free disk space is relatively short, but totally non-obvious:
VB:
Dim mo As New ManagementObject( _
"Win32_LogicalDisk.DeviceId='C:'")
mo.Get()
Dim ulngFreeSpace As UInt64 = _
CType(mo("FreeSpace"), UInt64)
MessageBox.Show(ulngFreeSpace.ToString())
C#:
ManagementObject mo = new
ManagementObject(
"Win32_LogicalDisk.DeviceId='C:'");
mo.Get();
UInt64 ulngFreeSpace =
UInt64) mo["FreeSpace"];
MessageBox.Show(
ulngFreeSpace.ToString());
The code assumes you've both set a reference to the System.Management assembly, and have added an Imports/using statement at the top of the file, importing the System.Management namespace:
VB:
Imports System.Management
C#:
using System.Management;
Next, the code creates a new instance of the ManagementObject class. This class provides a wrapper around a single WMI object. You can pass its constructor a reference to the object you want to work with. In this case, the code requests an instance of a WMI object that refers to the Win32_LogicalDisk class providing information about your C: drive. (For information on the properties of the Win32_LogicalDisk class, see http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wmisdk/wmi/win32_logicaldisk.asp.) This line of code sets up the variable mo so that it contains a reference to the WMI object corresponding to your C: drive:
VB:
Dim mo As New ManagementObject( _
"Win32_LogicalDisk.DeviceId='C:'")
C#:
ManagementObject mo = new
ManagementObject(
"Win32_LogicalDisk.DeviceId='C:'");
Because retrieving information about the physical hardware can be time-consuming, a ManagementObject instance doesn't retrieve information about its host object until you request it explicitly, by calling the Get method of the object:
VB:
mo.Get()
C#:
mo.Get();
Calling the Get method fills in a name/value collection of properties; you index into the collection using the name of the property. For example, to retrieve the FreeSpace property of the Win32_LogicalDisk instance, you could use code like this:
VB:
mo("FreeSpace")
C#:
mo["FreeSpace"]
The FreeSpace property of a Win32_LogicalDisk instance returns an unsigned 64-bit integer value. The .NET Framework provides a structure you can use to contain this value, the UInt64 structure. Therefore, the sample code retrieves the free space into one of those structures:
VB:
Dim ulngFreeSpace As UInt64 = _
CType(mo("FreeSpace"), UInt64)
C#:
UInt64 ulngFreeSpace = (UInt64)
mo["FreeSpace"];
Once you have the value, you can do what you like with it?in this case, I just used the MessageBox.Show method to display the value. Investigating the Win32_LogicalDisk class documentation should provide you with some ideas on the kinds of things you can do with WMI, and although this is a huge topic (of which we've just covered a tiny, tiny fraction), you should consider WMI as another tool on your "toolbelt"?that is, you may not use it every day, but when you need it, it's there.
I'll report in next time on how the trip cross-country with the four cats went. Hopefully, they'll all make it, and I'll find the whole thing funny by then. I may have to agree with the fictional real estate agent: perhaps "staying put" is the best suggestion. But no matter what, if you need to find out how much space you've got, WMI is a good bet in .NET.