With the release of Windows XP and later, the Windows operating system gained a built-in CD burning feature. The Microsoft Image Mastering API (IMAPI) was created to provide programmers with a method of creating disc images and to provide access to Windows’ CD burning feature.
Contributed by Nilpo Rating: / 4 November 03, 2008
There are currently two versions of the IMAPI control. The original version shipped with Windows XP and Windows Server 2003. Its successor, IMAPI2, shipped with Windows Vista and Windows Server 2008. Unfortunately, version 1 of the control does not provide adequate scripting access. Not to worry though; you can install the IMAPI2 update on older systems.
We’re going to take a look at burning single-session data discs from a directory of files. This means that once the disc is written, no other writing will be possible. This script is also going to assume that the device is ready and that it contains blank media. There are several ways to check these things from within your script; however, that is far beyond the scope of this article.
To begin, you’ll need a directory of files to burn. This directory may contain subfolders if you wish. We’re going to burn the entire directory tree. This is convenient if you wish to write a script that will burn CDs for backup purposes.
The IMAPI control can be used to write disc images to other storage devices as well.
Finally, this script will also assume that you know which drive you need to use on your system. Since the drive will need to have blank media in it, I thought it rather foolish to spend time creating a script to auto-detect a drive.
The drive will be identified by number on your system. I’ll show you a small script that will display your drive information so that you can correctly identify which drive you need to be using.
The IMAPI2 control exposes several different objects that we will be using. It may seem a little complicated at first glance but I’ll do my best to show you how it all fits together. You’ll need to know several different prog IDs. I’ll get into that in a bit. First, let’s start putting a script together.
intIndex = 0
strPath = "C:BurnTemp"
Set objDiscMaster = WScript.CreateObject("IMAPI2.MsftDiscMaster2")
You’ll want to begin your script by identifying a device index number and a path to the directory structure that you wish to burn to CD. Next, you’ll want to connect to the IMAPI DiscMaster object.
The process for burning DVDs is the same as it is for CDs. The only additional requirements are a supporting drive and supporting media.
The DiscMaster object enumerates all optical devices in the system and returns them as a string array containing each device identifier. Keep in mind that arrays are zero-base, so a 0 index represents the first optical drive in the system, a 1 represents the second, and so forth. If you are unsure which device to use, you can run the small script below to list information about each drive in order.
Const IMAPI_PROFILE_TYPE_CDROM = &H8
Const IMAPI_PROFILE_TYPE_CD_RECORDABLE = &H9
Const IMAPI_PROFILE_TYPE_CD_REWRITABLE = &HA
Const IMAPI_PROFILE_TYPE_DVDROM = &H10
Const IMAPI_PROFILE_TYPE_DVD_PLUS_RW = &H1A
Const IMAPI_PROFILE_TYPE_DVD_PLUS_R = &H1B
Set colDevices = CreateObject("IMAPI2.MsftDiscMaster2")
Set objRecorder = CreateObject("IMAPI2.MsftDiscRecorder2")
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 "CD-ROM"
Case IMAPI_PROFILE_TYPE_CD_RECORDABLE
WScript.Echo "CD-R"
Case IMAPI_PROFILE_TYPE_CD_REWRITABLE
WScript.Echo "CD-RW"
Case IMAPI_PROFILE_TYPE_DVDROM
WScript.Echo "DVD-ROM"
Case IMAPI_PROFILE_TYPE_DVD_DASH_RECORDABLE
WScript.Echo "DVD-R"
Case IMAPI_PROFILE_TYPE_DVD_PLUS_RW
WScript.Echo "DVD+RW"
Case IMAPI_PROFILE_TYPE_DVD_PLUS_R
WScript.Echo "DVD+R"
End Select
Next
WScript.Echo
Next
This script enumerates each optical device on the system and then prints information about them in order. This information includes driver make and model along with some of the supported capabilities of the drive. This script is certainly not all-inclusive, but it should provide you with enough information to determine which device to use.
Now you’ll need to initialize the burn device and begin preparing a disc image to write. Remember that files cannot be copied directly to a CD. Instead, an image of the new disc's file system must be created first and then written to the disc.
Set objRecorder = WScript.CreateObject("IMAPI2.MsftDiscRecorder2")
strDevice = objDiscMaster.Item(intIndex)
objRecorder.InitializeDiscRecorder(strDevice)
Continuing with the burn script, you’ll need to connect to the IMAPI DiscRecorder object. This is an object that will be used to reference the CD burner that will be used to write the disc. You’ll first need to retrieve the device identifier string from the DiscMaster object. Then, you must attach the device to the Recorder object reference using the InitializeDiscRecorder method.
This is overly complicated. This is just a fancy way of telling the IMAPI control what device we want to use as a burner.
Set objImageWriter = CreateObject("IMAPI2.MsftDiscFormat2Data")
objImageWriter.Recorder = objRecorder
objImageWriter.ClientName = "IMAPI Script"
IMAPI’s MsftDiscFormat2Data interface is used to create an image writer object. You can then specify a recording device using the Recorder property. The ClientName property is used to specify a friendly name for the image writer client.
Set objFSI = CreateObject("IMAPI2FS.MsftFileSystemImage")
objFSI.ChooseImageDefaults(objRecorder)
Now that the recording device has been selected and initialized, it’s time to begin building the actual burn image. The MsftFileSystemImage interface is used to create an image object. Think of this as a kind of empty ISO file.
You must also specify the type of file system to use along with the other settings for the image. This is most easily done by using the ChooseImageDefaults method. This method will examine the provided device and its current media and set the image settings accordingly.
objFSI.FileSystemsToCreate = 1
Rather than using the ChooseImageDefaults method, you may specify a file system for the resulting image if you wish. This can be accomplished using the FileSystemToCreate property. The possible choices are listed in the table below.
Next, you need to add a directory structure to the newly created disc image. The AddTree method accepts two parameters. The first parameter is a string indicating the path to the folder that contains the files to be burned. The second parameter is a Boolean value that indicates whether or not the folder itself should be included in the image or whether the image should just contain the folder’s subfolders and files.
Set objImage = objFSI.CreateResultImage()
Stream = objImage.ImageStream
Finally, the image needs to be created from the files provided using the CreateResultImage method. This is similar to saving an ISO image of the disc you are creating. Once the image is created, you can create a reference to the image stream. The image is not written to disc as a whole; instead, the image is streamed and written on piece at a time.
objImageWriter.Write(Stream)
Once you have an image stream, you can return to the ImageWriter object and start the actual burn process using the Write method. At this point, control will not return to your script until the burn process has completed.
The script that we’ve put together is just a basic example of what you can accomplish using the IMAPI2 control. There are several other methods available that can be used for error-checking as well as methods that can be used to further control the recorder by handling advanced settings such as write speed. For more information, check out the MSDN documentation for the IMAPI2 Reference.
Unfortunately, that’s all the space that I have for today. This should put you well on your way to writing scripts capable of burning data CDs using the IMAPI2 control. Don’t be afraid to play around with this script and see what you can accomplish. You may end up throwing away some CDs, but I think you’ll have some fun in the process. Until next time, keep coding!