WPD content enumeration in C# is pretty close to the C++ style. Here's a basic example that enumerates the object IDs of the objects present on the device.

static void Enumerate(
    ref PortableDeviceApiLib.IPortableDeviceContent pContent,
    string parentID,
    string indent)
{
    //
    // Output object ID
    //
    Console.WriteLine(indent + parentID);

    indent += "    ";

    //
    // Enumerate children (if any)
    //
    PortableDeviceApiLib.IEnumPortableDeviceObjectIDs pEnum;
    pContent.EnumObjects(0, parentID, null, out pEnum);

    uint cFetched = 0;
    do
    {
        string objectID;
        pEnum.Next(1, out objectID, ref cFetched);

        if (cFetched > 0)
        {
            //
            // Recurse into children
            //
            Enumerate(ref pContent, objectID, indent);
        }
    } while (cFetched > 0);
}

static void StartEnumerate(
    ref PortableDeviceApiLib.PortableDeviceClass pPortableDevice)
{
    //
    // Get content interface required to enumerate
    //
    PortableDeviceApiLib.IPortableDeviceContent pContent;
    pPortableDevice.Content(out pContent);

    Enumerate(ref pContent, "DEVICE", "");
}

StartEnumerate is the entry point into the enumeration. This needs to be called with a valid opened device connection. StartEnumerate then defers to the recursive Enumerate function which requires the parent object ID to enumerate. Using the EnumObjects API, we get back the IEnumPortableDeviceObjectIDs enumerator. For each object in the enumeration, we call Enumerate again.

Caveats:

  • IEnumPortableDeviceObjectIDs::Next allows more than one object IDs to be returned. We don't take advantage of this optimization since the default interop doesn't handle the array very well. If you need to use this, you will have to edit the interop by hand and fix up the assembly to handle the array correctly.