media, music comments edit

I use Asset UPnP on my Windows Home Server to get my music streaming to my Xbox 360 and PS3. It’s pretty sweet, it’s free, and it’s easy to set up. The only thing missing from it is the various playlists I have in iTunes - Asset UPnP indexes your music, but it doesn’t go through iTunes or Windows Media Player, so your playlists don’t come along.

I did some searching and found a forum post that addresses how to get iTunes playlists into Asset UPnP, but I figured I’d expand on it a bit and give a better walkthrough.

Two important notes before we start:

  • I was only able to get playlists to work using Asset UPnP version 3, which is currently in beta but should be released imminently. If you are trying this in version 2 or earlier, I can’t guarantee it works.
  • As of version 3, playlists are a paid feature in Asset UPnP. If you want to do this, you need to register your copy of Asset for, at the time of this article, $26. I’ve definitely gotten my $26 worth of use out of it, so it was a no-brainer for me.


Asset UPnP understands playlistsin the .M3U format. In its simplest form, that means each playlist is a text file where the path to the songs are each on one line.

Given that, there are basically two things you have to do:

  1. Get your playlists in .M3U format.
  2. Put them in a place where Asset UPnP can index them.

So let’s do the first thing - get the playlists in .M3U format.

In Windows Media Player playlists are saved as .WPL files. You’ll find them in your “My Music” folder. To export the playlist as .M3U…

  1. Select the playlist in Windows Media Player.
  2. Double-click that playlist so it starts playing. You need it to be the “Now Playing” list.
  3. Select File -> Save Now Playing list as…
  4. Select a location to save the playlist. If you happen to save the .M3U playlist in the same folder as the original, Windows Media Player will end up showing you two copies of the same playlist - the original .WPL list and the .M3U list. You should save it somewhere you can find later but not right in your “My Music” folder or anywhere WMP indexes.
  5. In the “Save As Type” dropdown, select “M3U Playlist.” Save as type:
  6. Click OK to save the playlist.

Now, here’s the pain in the rear part of dealing with it in Windows Media Player: When WMP saves the playlist, all of the file paths in the playlist are relative to the playlist. If you look in there, you’ll see a lot of stuff like “..\Aerosmith\Dude Looks Like a Lady.mp3” style paths. Unfortunately, the paths need to be absolute paths and point to the music on your Windows Home Server (or at least be relative to the Asset installation). On Windows Home Server, Asset UPnP indexes the music share at D:\shares\Music by default, so if that’s where your music is, it means “..\Aerosmith\Dude Looks Like a Lady.mp3” needs to be “D:\shares\Music\Aerosmith\Dude Looks Like a Lady.mp3” - absolute paths that Asset UPnP can understand.

The lame thing is there’s no way to magically do that. You’re going to need to open up a text editor like Notepad2 and do some search-and-replace action. I’ll not get into how to search-and-replace here; if you can’t figure that out, setting up playlists is definitely beyond your capacity.

Also, if you’re exporting from Windows Media Player and you have music files that have names with international characters in them, you may need to manually rename the file to have the extension “.m3u8” rather than just “.m3u” - this tells Asset to look for international characters.

In iTunes playlists are saved internally to the database, so you have to use a script to get them out. Fortunately, there’s a great iTunes Export program that will do the heavy lifting.

  1. Go to the iTunes Export web site and install the application. It’s very easy and takes just a few minutes.
  2. Close iTunes if you have it open. The exporter uses the XML version of the library and you want to make sure both that iTunes isn’t locking that file and that the very latest has been written to disk so the exporter gets the right data.
  3. Run the iTunes exporter.
  4. Select the iTunes library XML file location. Select the library XML

  5. Wait while the application loads the iTunes library and discovers your playlists.
  6. Select the playlists that you want to export, then click “Next.” (The selected playlists will turn blue.) Select the playlists to

  7. Select your various export options and click “Next.” Make sure you…
    • Choose “M3U” as the playlist format.
    • Check the “Include UTF-8 BOM” and “Use Intl Extension (M3U8)” boxes. This allows you to have artist or track names that have international characters in them.
    • For “File Types” choose “All Files” since Asset UPnP will be transcoding things so they can all be understood by the target client.
    • In the “Music Folder (Prefix)” field, put the file path (relative to the Asset UPnP installation) where the music is stored on your server (this will most likely be d:\Shares\Music\) and don’t forget the trailing slash. Setting that “Music Folder (Prefix)” field makes it so you don’t have to do any search-and-replace later.
    • Make a note of the “Output Directory” setting because this is where the playlists will end up. Select export options in iTunes
  8. The exporter will finish and you can close it.
  9. Find the playlists you just exported and…
    1. Name the .M3U8 files the way you want to see them listed in Asset. For example, a playlist in iTunes called “I Love The 80’s” will be exported as “I Love The 80_s.m3u” by the exporter and Asset will show that as “I Love The 80_s” - the filename, not the original title.
    2. Open each file and remove the comment line from the top (the line that starts with a “#”).

By now you should have:

  • Your playlists in .M3U (.M3U8) format.
  • File paths in the playlists so Asset UPnP can find the music.

Now you need toput your playlists somewhere Asset can find them. I put mine in the Public share on my Windows Home Server under a folder called “Playlists” (e.g., \\myhomeserver\Public\Playlists). (Note: If you are using iTunes Export, you can make your life a lot easier by mapping a network drive to this location so you can export your playlists directly to the shared destination.)

Finally,you need to configure Asset UPnP to find the playlists you just put on the server.

  1. Open the Windows Home Server console and click “Settings.”
  2. Select “Asset UPnP.”
  3. In the Asset UPnP settings dialog, click the “Edit” button next to “Advanced Settings” - this will open the advanced settings dialog for Asset.
  4. In the top right corner you’ll see a box marked “Audio Library.” In it you should see the folder “D:\Shares\Music” listed - this is how Asset knows which folders to scan for contents. You should also see that “D:\Shares\Music” is listed as “Contains: Audio Tracks.”
  5. In the “Audio Library” box, click the “[Add Folder]” link.
  6. Browse to and select the location you placed your playlists. In my case, I placed them in the Public share in a “Playlists” folder, so I selected to “D:\Shares\Public\Playlists”
  7. By default, Asset sets the folder to contain music. Click the “Contains: Audio Tracks” text next to the playlist folder and a dropdown will appear. Select “Contains: Playlists” from there.
  8. Click OK. Asset will tell you it needs to restart. That’s OK. It will then rescan the library and your playlists will be included.

You now should be able to access your playlists through a suitable DLNA client. As it turns out, Xbox 360 does not support playlists, but Playstation 3 does. That’s not a problem with Asset UPnP; it’s a problem with the client.

net, vs comments edit

As of 2012.1.4, the DXCore “About” box no longer displays ProductModule contents. If you’re working with that version or later, don’t bother with this. You won’t see the results of your efforts.

Have you ever looked at the DevExpress menu in Visual Studio and selected the “About” option? There’s a list in there of all the installed “products” with associated version information, a textual description, and even a graphic with the product logo:

DXCore "About"

If you have the CR_Documentor plugin installed, you’ll notice it also shows up in that box:

DXCore "About" box showing the CR_Documentor

If you want to “make your plugin an official product” and show up in the “About” box, the way to do that is to implement a ProductModule.

Before we get into this, something to consider: You probably don’t need or want to implement a ProductModule for every plugin you write. Doing this is something for larger plugins or, better still, suites of multiple plugins that get distributed as a single product. If every plugin did this, that “About” box would get pretty noisy really quick… and does everyone need to see that little hotkey plugin in the “About” box? That said, if you have a sizable plugin or a plugin suite, here’s how you get into the “About” box…

This tutorial assumes your plugin(s) are all in one assembly. You may need to tweak a few things to get it to work for a multi-assembly suite, but the general principles should remain the same.

First, make sure your assembly is marked with title, version, copyright, and description attributes. We’ll use these attributes to generate the text that shows up in the “About” box.

[assembly: AssemblyTitle("Product Module Demo")]
[assembly: AssemblyCopyright("Copyright © 2010 Travis Illig")]
[assembly: AssemblyDescription("Demonstration that shows how the ProductModule works to get a plugin into the About box.")]
[assembly: AssemblyVersion("")]

Next, create your logo graphic. The image should be a 536 x 201 PNG image and should have your product logo as well as the name of your product. If you look at the above “About” box images, you’ll see a blue gradient that has the logo and product name on top - that’s what you’ll be creating. Your image should include the gradient and everything - that doesn’t get put in for you. To make it good, you’ll probably need to take a little time with a paint program of your choice. Just put your logo on the background; the little “version” information in the top right corner gets inserted for you by the “About” box.

For convenience, here’s a PNG image of the gradient background that I created and you can use to start with:

Gradient for "About" box

Add your logo image to your plugin project as an embedded resource. Drag it into your plugin project so it gets added in there and make sure in the properties the image is set as “Embedded Resource.”

Embedded resource

Add a class to your project that derives from DevExpress.CodeRush.Common.ProductModule. This is where all the information for the “About” box comes from.

In your derived ProductModule, you need to define some constants:

  • The path to the embedded resource that is your product logo graphic.
  • A GUID that uniquely identifies your product. Note that there is ONE product GUID, but there may be many plugins in that product. This GUID is not the same as the plugin IDs.
  • The minimum DXCore version that your product works with. This will be used to help DXCore determine if your product is compatible with the user’s installation.
  • A string with the short name of your plugin assembly (“MyPlugin.dll”). You could technically calculate this on the fly, but chances are it’s not going to change much (or ever) so it’s fairly safe to just hardcode it.

This will end up looking something like the following:

private const string LogoPath = "ProductModuleDemo.ProductModuleLogo.png";
private static readonly Guid ProductId = new Guid("0CB93ADC-7188-4632-B469-98D161074E48");
private static DevExpress.CodeRush.Common.Version MinEngineVersion = new DevExpress.CodeRush.Common.Version(10, 1, 6, 0);
private const string PluginAssemblyName = "ProductModuleDemo.dll";

Add a static constructor to your ProductModule to calculate some values based on the assembly. You need to calculate and store:

  • The assembly title.
  • The assembly copyright information.
  • The assembly description.
  • The assembly version, converted to a DXCore version value.

Get that information from the attributes you added to the assembly. For a ProductModule class called “About,” that’ll look like:

private static readonly string AssemblyTitle;
private static readonly string AssemblyCopyright;
private static readonly string AssemblyDescription;
private static readonly DevExpress.CodeRush.Common.Version AssemblyVersion;

static About()
  var assembly = typeof(About).Assembly;
  var version = assembly.GetName().Version;
  AssemblyVersion = new DevExpress.CodeRush.Common.Version(
  AssemblyTitle = GetCustomAttribute<AssemblyTitleAttribute>(assembly).Title;
  AssemblyCopyright = GetCustomAttribute<AssemblyCopyrightAttribute>(assembly).Copyright;
  AssemblyDescription = GetCustomAttribute<AssemblyDescriptionAttribute>(assembly).Description;

private static T GetCustomAttribute<T>(Assembly asm) where T : Attribute
  var attributes = (T[])asm.GetCustomAttributes(typeof(T), true);
  return attributes[0];

In your ProductModule, override and implement the following:

  • Copyright1 property: Return the assembly copyright information.
  • Description property: Return the assembly description information.
  • ID property: Return the Product ID GUID you created.
  • MinimumEngineVersion property: Return the minimum engine version value you created.
  • ModuleType property: This indicates what kind of product you have. If it’s a community/free plugin, return ModuleTypes.Free; if it’s a paid product, return ModuleTypes.Full.
  • Name property: Return the assembly title information.
  • SupportedLanguages property: This property returns an array of language strings that indicate what languages your plugin is valid for. You can find these values in the “Language” dropdown on the DevExpress options menu. At the time of this writing, they are: Basic, C/C++, CSharp, HTML, JavaScript, Plain Text, and XML. 
  • Version property: Return the assembly version information.

There are other properties you can override to return additional information, but these pretty much handle the stuff that shows up in the “About” box.

Override the BuildDefenition method. The “BuildDefenition” method (yes, it is misspelled) is responsible for defining which assemblies make up your complete product. For the purposes of this tutorial it’s just the one assembly, which makes it easy. For each assembly, you call the “DefinePlugIn” method and pass in the string name of the assembly (the constant string you defined earlier):

protected override void BuildDefenition()

Override the GetImage method. This is the method that grabs the embedded logo image and returns it for display in the “About” box. It’s a pretty simple two-line implementation where you get the embedded resource stream from your assembly and convert it to a bitmap, like this:

public override System.Drawing.Image GetImage()
  Assembly current = typeof(About).Assembly;
  return new System.Drawing.Bitmap(current.GetManifestResourceStream(LogoPath));

That’s all you have to do for the ProductModule. The last thing you have to do is mark your assembly so DXCore knows to look for your ProductModule.

Add a DXCoreProductAttribute to your assembly. The DXCoreProductAttribute points to your ProductModule so the “About” box knows what to look for. Really simple:

[assembly: DXCoreProduct(typeof(ProductModuleDemo.About))]

That’s it! Now fire up Visual Studio with your plugin in place and you should see your product information - with your logo, version, description, etc. - all in the DevExpress “About” box.

I’ve got a solution you can download with a working demo in it so you can see what the complete package looks like:

[ (11KB)]

Hopefully this will help you larger plugin developers to make some really cool “official” DXCore products!

downloads, vs, coderush comments edit

It’s been a while in the making, but the new version of CR_Documentor is out.

It took a while because I did two pretty major updates to it.

First, I totally overhauled the syntax preview generation so each preview style (NDoc or Sandcastle) uses the same syntax preview engine. As part of that, I added a bunch more testing and support for complex syntax like multiple type parameters with multiple type constraints per parameter. What? What does that mean? It means you can see stuff like this in your preview:

And, of course, it works in VB, too (which, based on the way Sandcastle does it, actually all ends up on one line…):

The other thing I did was add support for serving images and other files, so now when you look at the preview for a class and see all the members listed, you see the associated icons, too. Not a huge deal, but it does make the preview more authentic.

Hopefully that adds to you documentation preview enjoyment.

As always, it’s free. Go get it!

personal, gaming comments edit

I know technology is fallible and I know my standards are probably far too high for things, but I find that once a technology or gadget has shown its imperfections to me by way of failing or misbehaving, I have a really difficult time being excited about it or trusting it again.

For quite some time I was absolutely addicted to playing drums on Rock Band. I’ve always thought I would be a decent drummer and while I know it’s not “real drums” it’s fun and fulfills that tiny dream. I bought the Ion Drum Rocker kit and totally rocked out. Until, of course, I found a problem during practice mode where hitting the yellow cymbal changes the tempo on you. After switching out the drum kit controller like three times with Ion Support (which, by the way, sucks), it turns out the problem is software-based. I also started noticing things start randomly misbehaving, like the kick pedal not registering (or going off by itself), hits not registering on the pads… and that turns out to be a funky combination of static buildup, needing to unplug the drum controller for a few seconds, and bad luck.

During the course of solving that problem, I honestly lost my feel for it. I don’t play nearly as often now, and it’s because I don’t trust the technology to behave. To do what it’s intended to do. Playing it has become a bit less fun and a bit more worry and stress over why it’s not working.

Last week I got a Droid X. Love it. Had a bit of a weird issue where the speakers suddenly lost volume but fixed it by a simple power cycle. Then we went to the Oregon Coast Aquarium this past weekend and I noticed that there’s a flaw with the camera CMOS censor such that in darker shots there’s a noticeable magenta spot, like there’s something on the lens. Suddenly, I’m slightly less trusting, and slightly less enamored with it. I still like the phone, but I find I’m not tinkering with it or messing around with it as much since I saw that.

I stopped at the Verizon store and I’m getting a replacement unit, so it should be fixed when the new unit arrives in a day or two. It’s just… I hope I don’t lose my passion for it. My enthusiasm. It’s shown me weakness, fallibility, and it’s going to take some time for me to trust it again.

I am, admittedly, a perfectionist. I hold myself to very high standards and “it works” is generally not good enough. I’m thinking, though, that even if “it works” is good enough, there’s another question to be asked: is it trustworthy? Can I trust a product or service not to break in the middle of an operation? Even if a product isn’t super-feature-rich, if it does one thing and one thing really well, I’m fine with that.

Reliability is high on my priority list. Is it high on yours?

General Ramblings comments edit

Every year for Jenn’s birthday we take a trip to the beach with some friends of ours. This year we decided to go down to the Oregon Coast Aquarium in Newport.

I took several pictures that I’ll have to post later, but I did get a nice video of the Passages of the Deep exhibit where you walk under the various fish. This particular video shows the sharks in the exhibit.