Creating a WPD playlist object in C#

This is a C# follow-up post on the earlier C++ playlist creation post. Be sure to read the earlier post for background information on playlists and how it stores references. We will also re-use the StringToPropVariant helper function that we defined in our previous post.

To create a playlist object, the objects to be referenced should already have been transferred previously to the device. We'll write a function that will create a brand new playlist and set the references at creation-time. Setting the references is as easy as setting a property value, specifically the WPD_OBJECT_REFERENCES property.

 static void CreatePlaylistObject(
        PortableDeviceApiLib.PortableDeviceClass pPortableDevice,
        string parentID,
        string filename,
        ref string[] refObjectIDs,
        ref string newObjectID)
{
    // Get content interface required to create object
    PortableDeviceApiLib.IPortableDeviceContent pContent;
    pPortableDevice.Content(out pContent);

    // Create properties collection to send while creating object
    PortableDeviceApiLib.IPortableDeviceValues pValues =
        (PortableDeviceApiLib.IPortableDeviceValues)
            new PortableDeviceTypesLib.PortableDeviceValuesClass();

    pValues.SetStringValue(ref PortableDevicePKeys.WPD_OBJECT_PARENT_ID,
                            parentID);
    pValues.SetStringValue(ref PortableDevicePKeys.WPD_OBJECT_ORIGINAL_FILE_NAME,
                            filename);
    pValues.SetStringValue(ref PortableDevicePKeys.WPD_OBJECT_NAME,
                            filename);
    pValues.SetGuidValue(ref PortableDevicePKeys.WPD_OBJECT_FORMAT,
                            ref PortableDeviceGuids.WPD_OBJECT_FORMAT_WPLPLAYLIST);

    // References are stored in a PropVariantCollection object
    PortableDeviceApiLib.IPortableDevicePropVariantCollection pRefIDs =
        (PortableDeviceApiLib.IPortableDevicePropVariantCollection)
            new PortableDeviceTypesLib.PortableDevicePropVariantCollection();

    // Add the string object IDs to the references property
    for (int i = 0; i < refObjectIDs.Length; i++)
    {
        PortableDeviceApiLib.tag_inner_PROPVARIANT propvarValue;
        StringToPropVariant(refObjectIDs[i], out propvarValue);

        pRefIDs.Add(ref propvarValue);
    }

    // Add the references property to the property collection
    pValues.SetIPortableDevicePropVariantCollectionValue(
        ref PortableDevicePKeys.WPD_OBJECT_REFERENCES, pRefIDs);

    // Create the playlist object using the CreateObjectWithPropertiesOnly API
    // The properties to be set have already been defined in pValues
    pContent.CreateObjectWithPropertiesOnly(pValues, ref newObjectID);
}

Since the playlist object does not require any data to be transferred, we will be using the CreateObjectWithPropertiesOnly API to create it. The function takes in the parent object i.e. the location at which the playlist object should be created and the name to use for the object. The object IDs that the playlist object will reference are passed in as a string array. The function will return the object ID of the new playlist object on success.

We create an IPortableDeviceValues instance - pValues - that will hold the properties of the playlist object to be applied. We set the required parent object ID, name and format properties. To add the references, we convert each string into a PROPVARIANT using our StringToPropVariant converter. We then add the PROPVARIANT into an IPortableDevicePropVariantCollection object.

Once we are done converting the input string array of object IDs into a PropVariant collection, we add the WPD_OBJECT_REFERENCES property to the pValues values collection with the PropVariant collection as the value (which is the list of object IDs to add as a reference).

Once the properties have been prepared, we call the CreateObjectWithPropertiesOnly API and create the object. Once the API completes successfully, a new object ID is returned which is the object ID of the newly created playlist object.

Invoking this function would look something like this:

 string newObjectID = "";

// Set the playlist to reference objects o1 and o2
string[] refObjectIDs = new string[2];
refObjectIDs[0] = "o1";
refObjectIDs[1] = "o2";

CreatePlaylistObject(pPortableDevice, "s10001", "hits2006.pls",
                            ref refObjectIDs, ref newObjectID);

Creating properties-only objects of other formats follows the same style. An example of another properties-only object is a Contact object - name, email, phone, etc. are just properties of the object itself. The object doesn't have any data. You can modify the function we have just presented to use the appropriate WPD_OBJECT_FORMAT code and create a contact object.