Remember the good-old-days when computers had 5 ¼” floppy disk drives? That was back in the days of the dinosaurs, when people also listened to music on records, or “LPs” as the cool kids called them. What, you don’t remember any of those? Oh, well, neither do the Scripting Guys; that was way before our time. But we’ve heard of all those things….
Of course, since then we’ve moved on to the wonderful world of CDs and DVDs. (Yes, iPods, too, but we’re not talking about those right now.) And now, with Windows Vista, Microsoft has decided to join the modern era (for the most part) and fully embrace the power of these little discs. How? By providing a scriptable application programming interface (API) that you can use to retrieve information on CD and DVD devices, read from the discs, and – yes, it’s true – write to the discs. With the new Image Mastering API (IMAPI2), you can do all these things through scripts.
In this article we’re going to introduce you to IMAPI2 by showing you how you can return a collection of all the CD/DVD devices on a computer and then read the properties from those devices. Towards the end we’ll throw in a couple methods you can use to do things like open and close the disc drives’ trays.
We know: you really want to see how to write to a CD or DVD. But it might be useful to know a couple small details first, like whether or not you even have a CD or DVD burner attached to the computer. So we’re going to start with that, and then, in Part 2, we’ll get to the fun stuff.
| Before We Begin… | |
| Reading Disc Recorder Properties | |
| Opening and Closing the Tray | |
| More to Come |
When this article was written, IMAPI2 was available only on Windows Vista (and the not-yet-released Windows Server 2008). Since that time the Optical Platforms team has release four downloads for earlier versions of Windows:
| • | |
| • | |
| • | |
| • | Image Mastering API v2.0 for Windows Server 2003 x64 Edition |
If you have Windows Vista you already have access to all the functionality we’re going to talk about. If you’re running Windows XP or Windows Server 2003, simply download the appropriate version then read on.
Let’s find out how to discover what type of disc drives you have connected to your computer. We’ll start by taking a look at the script:
Const IMAPI_PROFILE_TYPE_CDROM = &H8
Const IMAPI_PROFILE_TYPE_DVDROM = &H10
Const IMAPI_PROFILE_TYPE_CD_RECORDABLE = &H9
Const IMAPI_PROFILE_TYPE_DVD_PLUS_RW = &H1A
Set colDiscMaster = CreateObject("IMAPI2.MsftDiscMaster2")
For Each Id In colDiscMaster
Set objRecorder = CreateObject("IMAPI2.MsftDiscRecorder2")
objRecorder.InitializeDiscRecorder Id
WScript.Echo "Vendor: " & objRecorder.VendorId
Wscript.Echo "Product ID: " & objRecorder.ProductId
Wscript.Echo "Product Revision: " & objRecorder.ProductRevision
For Each strMountPoint In objRecorder.VolumePathNames
Wscript.Echo "First Mount Point: " & strMountPoint
Exit For
Next
For Each Profile In objRecorder.SupportedProfiles
Select Case Profile
Case IMAPI_PROFILE_TYPE_CDROM
Wscript.Echo "IMAPI_PROFILE_TYPE_CDROM"
Case IMAPI_PROFILE_TYPE_DVDROM
Wscript.Echo "IMAPI_PROFILE_TYPE_DVDROM"
Case IMAPI_PROFILE_TYPE_CD_RECORDABLE
Wscript.Echo "CD-R"
Case IMAPI_PROFILE_TYPE_DVD_PLUS_RW
Wscript.Echo "DVD+RW"
End Select
Next
Wscript.Echo
Next
Connecting to a Device
We start out by declaring some constants. Ignore those for now; we’ll get back to them later. Aside from declaring constants, the first thing we have to do any time we’re going to work with disc reading and writing devices is create an instance of the MsftDiscMaster2 class. We do that like this:
Set colDiscMaster = CreateObject("IMAPI2.MsftDiscMaster2")
The MsftDiscMaster2 object reference contains a collection of unique identifiers, each identifier representing a CD or DVD device connected to the computer. In other words, this isn’t actually a collection of objects that represent each device; it’s a collection of identifiers, each one, well, identifying a particular device. Kind of like a bar code on a box of cereal – just because you know the bar code doesn’t mean you actually have the cereal. If we want to work with a device, we need to use its identifier to first connect to the device; only then can we begin to work with that device. In this case we want to find all the devices, so we need to read through the collection of identifiers and retrieve each ID. We do that by using this For Each loop:
For Each Id In colDiscMaster
Each time through the loop we retrieve a device ID from the collection, assigning it to the variable Id. Once we know the device’s ID, we then connect to the device itself:
Set objRecorder = CreateObject("IMAPI2.MsftDiscRecorder2")
We now have an object reference, objRecorder, to a CD or DVD device. So we should be ready to get some properties from this device, right? Well, no, not yet. You might have noticed that, in creating the objRecorder object, we didn’t actually use our device ID; instead, we simply created a generic MsftDiscRecorder2 object. That means that right now there’s no device associated with this object reference. In other words, we have a device object, but it’s pretty useless at the moment. Before we can do anything with the device we need to specify which device we’re working with.
This is where our identifier comes in. In order to connect to a specific device we have to call the InitializeDiscRecorder method of the MsftDiscRecorder2 object, passing it the ID of the device we want to connect to, like this:
objRecorder.InitializeDiscRecorder Id
We’ve now initialized our recorder, meaning we’re ready to work with the first device in our collection.
Reading Properties
IMAPIv2 provides quite a bit of information about CD and DVD devices. We’ll start off by retrieving the name of the hardware vendor (VendorId), the product ID (ProductId), and the revision number (ProductRevision):
WScript.Echo "Vendor: " & objRecorder.VendorId
Wscript.Echo "Product ID: " & objRecorder.ProductId
Wscript.Echo "Product Revision: " & objRecorder.ProductRevision
Keep in mind that different hardware vendors make different information available, so some of the properties might not return any information. With any luck, we’ve chosen properties here that are pretty standard and will most likely show you some information.
The next bit of information we want is the mount points. In many cases this will simply be the drive letter of the device. A device can have multiple mount points, so we need to set up a For Each loop and read through the VolumePathNames property to retrieve each individual mount point:
For Each strMountPoint In objRecorder.VolumePathNames
Wscript.Echo "Mount Point: " & strMountPoint
Next
Remember those constants we defined at the beginning of our script?:
Const IMAPI_PROFILE_TYPE_CDROM = &H8 Const IMAPI_PROFILE_TYPE_DVDROM = &H10 Const IMAPI_PROFILE_TYPE_CD_RECORDABLE = &H9 Const IMAPI_PROFILE_TYPE_DVD_PLUS_RW = &H1A
It’s finally time to use them. The SupportedProfiles property returns a list of, well, supported profiles. These profiles tell you whether the device is a CD-ROM, DVD-ROM, CD-R, DVD-R, and so on. Because a device can support more than one profile (for example, it might support both CDs and DVDs), we again need a For Each loop to loop through the values in this property:
For Each strProfile In objRecorder.SupportedProfiles
At this point we want to echo back the supported profiles. The problem is that SupportedProfiles contains hexadecimal values rather than nicely-readable strings such as “CD-ROM.” That’s where the constants come in. In this case we’re going to see whether the device supports CD-ROM and DVD-ROM and whether it can write to either of those. If the device can read CDs then the value returned by SupportedProfiles is hexadecimal 8; the value for DVDs is hexadecimal 10; and so on. So we’ve set up a Select Case statement and, using the constants we defined earlier, we display a string based on the hexadecimal value:
Select Case strProfile
Case IMAPI_PROFILE_TYPE_CDROM
Wscript.Echo "CD-ROM"
Case IMAPI_PROFILE_TYPE_DVDROM
Wscript.Echo "DVD-ROM"
Case IMAPI_PROFILE_TYPE_CD_RECORDABLE
Wscript.Echo "CD-R"
Case IMAPI_PROFILE_TYPE_DVD_PLUS_RW
Wscript.Echo "DVD+RW"
End Select
There are many profiles available, but in the interest of keeping our script to a reasonable length we’ve chosen to include only these four. If you’d like to see the full list, check out MSDN.
When you run this script, you’ll receive output similar to this:
Vendor: SAMSUNG Product ID: CD-ROM SC-148A Product Revision: B403 Mount Point: D:\ CD-ROM Vendor: PLEXTOR Product ID: DVDR PX-740A Product Revision: 1.01 Mount Point: E:\ DVD+RW DVD-ROM CD-R CD-ROM
As you can see, on the Scripting Guys’ test computer there are two devices: one on drive D: that’s CD-ROM only, another on drive E: that can read and write CDs and DVDs.
Now that we know how to read some properties, let’s take a look at a couple of simple methods that we can use to manipulate these devices, in particular, methods that open and close the device tray. Here’s a script that opens the tray, waits five seconds (5000 milliseconds), then closes the tray:
Set colDiscMaster = CreateObject("IMAPI2.MsftDiscMaster2")
For Each Id In colDiscMaster
Set objRecorder = CreateObject("IMAPI2.MsftDiscRecorder2")
objRecorder.InitializeDiscRecorder Id
objRecorder.EjectMedia()
Wscript.Sleep 5000
objRecorder.CloseTray()
Next
Once again, we create a collection of all the disc device IDs on the computer by calling CreateObject and the MsftDiscMaster2 class. We then loop through the unique identifiers for each device, create a recorder object (objRecorder), then call InitializeDiscRecorder to connect to the specific device. After that it’s simple:
objRecorder.EjectMedia() Wscript.Sleep 5000 objRecorder.CloseTray()
We call the EjectMedia method to open the tray. We then leave the tray open for five seconds, then call CloseTray to close it again.
Yes, we know: this was a very short introduction to IMAPI2. But as you saw, it’s not an entirely straightforward process: you have to create an object to get the IDs, then create another object to get a device, then initialize a specific device…. that’s a lot to digest. So we’re going to take a break for now, and in Part 2 we’ll get into the really interesting stuff: burning CDs and DVDs.