Click here to Skip to main content
15,896,063 members
Articles / Programming Languages / XML

WMP Playlist Fix

Rate me:
Please Sign up or sign in to vote.
4.80/5 (2 votes)
6 Dec 2013CPOL6 min read 20.5K   546   5  
The goal is to clean-up double entries in Windows Media Player playlists because the player doesn’t do that itself. For that, a WPL class has been written, and a program that uses that class.
//
// WMPPlayListTool - Simple Windows Media Player Playlist Controller.
// Copyright (C) 2009-2013 John Janssen
// http://www.travelisfun.net 
//
// This program is free software; you can redistribute it and/or modify
// it any way you want as long as the above copyright statement is maintained.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
//

using System;
using System.Collections.Generic;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Xml;
using System.Diagnostics;
using Microsoft.Win32;

namespace WPLControlLib
{
  
  public partial class WMPPlayListCtrl : UserControl
  {
    // default registry path. The same for all instances.
    private String registryPath = @"Software\J-Software\WMPPlayListCtrl";
    private String WMPPlayListFolder { get { return WMPPlayList.GetPlayListSavePath(); } }
    private RecentFileList fileSelection = new RecentFileList();
    private RecentFileList folderSelection = new RecentFileList();
    private Boolean formLoading = false;
    private WMPRemoveDoubleType removeType = WMPRemoveDoubleType.BasedOnTrackTitle;

    public String RegistryPath
    {
      get { return registryPath; }
      set { registryPath = value; }
    }

    public WMPPlayListCtrl()
    {
      InitializeComponent();
    }
    public WMPPlayListCtrl(String registryPath)
    {
      this.RegistryPath = registryPath;
      InitializeComponent();
    }
    /// <summary>
    /// 
    /// </summary>
    /// <returns></returns>
    public override string ToString()
    {
      return "Process WPL files";
    }
    /// <summary>
    /// 
    /// </summary>
    private void ReadRegistry()
    {
      try
      {
        fileSelection.Load(RegistryPath + @"\FileSelection");
        folderSelection.Load(RegistryPath + @"\FolderSelection");

        //int i;
        RegistryKey key = Registry.CurrentUser.OpenSubKey(RegistryPath, false);
        if (key != null)
        {
          comboBoxFolder.Text = (String)key.GetValue("Input folder", comboBoxFolder.Text);
          comboBoxFile.Text = (String)key.GetValue("Input file", String.Empty);
          checkBoxRemoveTID.Checked = ((int)key.GetValue("RemoveTID", 1) != 0);
          checkBoxRemoveDoubles.Checked = ((int)key.GetValue("RemoveDoubles", 1) != 0);
          checkBoxRemoveNonFiles.Checked = ((int)key.GetValue("RemoveNonFiles", 1) != 0);

          int i = (int)key.GetValue("BasedOnFilename", 1);
          if (i == (int)WMPRemoveDoubleType.BasedOnTrackTitle)
          {
            radioButtonBasedOnTrackTitle.Checked = true;
            removeType = WMPRemoveDoubleType.BasedOnTrackTitle;
          }
          else if (i == (int)WMPRemoveDoubleType.BasedOnLocation)
          {
            radioButtonBasedOnLocation.Checked = true;
            removeType = WMPRemoveDoubleType.BasedOnLocation;
          }
          else if (i == (int)WMPRemoveDoubleType.BasedOnFilename)
          {
            radioButtonBasedOnFilename.Checked = true;
            removeType = WMPRemoveDoubleType.BasedOnFilename;
          }
        }
      }
      catch { }
    }
    /// <summary>
    /// Store the application data in the registry.
    /// </summary>
    private void WriteRegistry()
    {
      if (formLoading)
        return;

      DataExchange(comboBoxFile, fileSelection, true);
      DataExchange(comboBoxFolder, folderSelection, true);

      fileSelection.Store(RegistryPath + @"\FileSelection");
      folderSelection.Store(RegistryPath + @"\FolderSelection");

      try
      {
        RegistryKey key = Registry.CurrentUser.CreateSubKey(RegistryPath);
        if (key != null)
        {
          key.SetValue("Input folder", comboBoxFolder.Text);
          key.SetValue("Input file", comboBoxFile.Text);
          key.SetValue("RemoveTID", checkBoxRemoveTID.Checked ? 1 : 0);
          key.SetValue("RemoveDoubles", checkBoxRemoveDoubles.Checked ? 1 : 0);
          key.SetValue("RemoveNonFiles", checkBoxRemoveNonFiles.Checked ? 1 : 0);

          if (radioButtonBasedOnTrackTitle.Checked)
            key.SetValue("BasedOnFilename", (int)WMPRemoveDoubleType.BasedOnTrackTitle);
          else if (radioButtonBasedOnLocation.Checked)
            key.SetValue("BasedOnFilename", (int)WMPRemoveDoubleType.BasedOnLocation);
          else if (radioButtonBasedOnFilename.Checked)
            key.SetValue("BasedOnFilename", (int)WMPRemoveDoubleType.BasedOnFilename);
          else
            key.SetValue("BasedOnFilename", (int)WMPRemoveDoubleType.BasedOnLocation);
        }
      }
      catch { }
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void WMPPlayListCtrl_Load(object sender, EventArgs e)
    {
      formLoading = true;

      progressBar1.Visible = false;
      labelProgress.Visible = false;
      labelProgress.AutoSize = false;
      //labelProgress.Bounds = progressBar1.Bounds;
      labelProgress.Text = String.Empty;
      labelProgress.BackColor = Color.Transparent;
      labelProgress.ForeColor = Color.Black;

      comboBoxFolder.Text = WMPPlayList.GetPlayListSavePath();

      radioButtonBasedOnTrackTitle.Checked = true;
      radioButtonBasedOnLocation.Checked = false;
      ReadRegistry();

      // fill the file selection with defaults, the playlists in the WPL folder.
      if (fileSelection.Count == 0)
      {
        String[] files = Directory.GetFiles(WMPPlayListFolder, "*.wpl");
        foreach (String s in files)
        {
          fileSelection.Add(s);
          comboBoxFile.Items.Add(s);
        }
        if (files.Length > 0)
          comboBoxFile.Text = files[0];
      }

      // Put the recent file selection lists in the comboboxes.
      DataExchange(comboBoxFile, fileSelection, false);
      DataExchange(comboBoxFolder, folderSelection, false);

      formLoading = false;
      checkBoxRemoveDoubles_CheckedChanged(null, null);
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="combobox"></param>
    /// <param name="recent"></param>
    /// <param name="read"></param>
    private void DataExchange(ComboBox combobox, RecentFileList recent, Boolean read)
    {
      if (read)
      {
        recent.Clear();
        foreach (Object s in combobox.Items)
        {
          recent.Add((String)s);
        }
        recent.Insert(0, combobox.Text);
      }
      else
      {
        combobox.Items.Clear();
        foreach (String s in recent)
          combobox.Items.Add(s);
        if (recent.Count > 0)
          combobox.Text = recent[0];
      }
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void checkBoxRemoveDoubles_CheckedChanged(object sender, EventArgs e)
    {
      if (!formLoading)
      {
        radioButtonBasedOnTrackTitle.Enabled = checkBoxRemoveDoubles.Checked;
        radioButtonBasedOnLocation.Enabled = checkBoxRemoveDoubles.Checked;
        radioButtonBasedOnFilename.Enabled = checkBoxRemoveDoubles.Checked;
      }
      WriteRegistry();
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void comboBoxFile_SelectedIndexChanged(object sender, EventArgs e)
    {
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void checkBoxRemoveTID_CheckedChanged(object sender, EventArgs e)
    {
      if (formLoading)
        return;
      WriteRegistry();
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void radioButtonBasedOnTrackTitle_CheckedChanged(object sender, EventArgs e)
    {
      if (formLoading)
        return;
      removeType = WMPRemoveDoubleType.BasedOnTrackTitle;
      WriteRegistry();
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void radioButtonBasedOnLocation_CheckedChanged(object sender, EventArgs e)
    {
      if (formLoading)
        return;
      removeType = WMPRemoveDoubleType.BasedOnLocation;
      WriteRegistry();
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void buttonBrowseSingleFile_Click(object sender, EventArgs e)
    {
      OpenFileDialog frm = new OpenFileDialog();
      frm.CheckFileExists = true;
      frm.CheckPathExists = true;
      frm.DefaultExt = ".WPL";
      frm.Filter = "Playlists *.WPL|*.WPL";
      frm.FileName = comboBoxFile.Text;
      frm.Multiselect = false;
      frm.Title = "Select a Playlist file.";
      if (frm.ShowDialog(this) == DialogResult.OK)
      {
        comboBoxFile.Text = frm.FileName;
        fileSelection.Insert(0, frm.FileName);
        WriteRegistry();
      }
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void buttonBrowseFolder_Click(object sender, EventArgs e)
    {
      FolderBrowserDialog frm = new FolderBrowserDialog();
      frm.RootFolder = Environment.SpecialFolder.MyComputer;
      frm.SelectedPath = comboBoxFolder.Text;
      frm.ShowNewFolderButton = false;
      frm.Description = "Select the folder with Playlist files.";
      if (frm.ShowDialog(this) == DialogResult.OK)
      {
        comboBoxFolder.Text = frm.SelectedPath;
        folderSelection.Insert(0, frm.SelectedPath);
        WriteRegistry();
      }
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void comboBoxFile_TextChanged(object sender, EventArgs e)
    {
      if (formLoading)
        return;
      WriteRegistry();
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void comboBoxFolder_TextChanged(object sender, EventArgs e)
    {
      if (formLoading)
        return;
      WriteRegistry();
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void buttonProcessFile_Click(object sender, EventArgs e)
    {
      if (backgroundWorker.IsBusy)
      {
        // terminate any ongoing playlist process.
        WMPPlayList.RequestAbort();
        backgroundWorker.CancelAsync();
      }
      else
      {
        buttonProcessFile.Text = "Stop processing";
        buttonProcessFolder.Enabled = false;
        ThreadParameters param = new ThreadParameters();
        param.fileName = comboBoxFile.Text;

        backgroundWorker.RunWorkerAsync(param);
      }
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void buttonProcessFolder_Click(object sender, EventArgs e)
    {
      if (backgroundWorker.IsBusy)
      {
        backgroundWorker.CancelAsync();
      }
      else
      {
        if (!Directory.Exists(comboBoxFolder.Text))
        {
          return;
        }
        buttonProcessFolder.Text = "Stop processing";
        buttonProcessFile.Enabled = false;
        ThreadParameters param = new ThreadParameters();
        param.folderName = comboBoxFolder.Text;
        backgroundWorker.RunWorkerAsync(param);
      }
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="filename"></param>
    private void ProcessWpl(String filename)
    {
      try
      {
        if (!File.Exists(filename))
          return;

        WMPPlayList pl = new WMPPlayList();
        pl.Load(filename);

        if (checkBoxRemoveNonFiles.Checked)
          pl.RemoveNonFiles();
        if (checkBoxRemoveDoubles.Checked)
          pl.RemoveDoubles(removeType);
        if (checkBoxRemoveTID.Checked)
          pl.RemoveTIDAndCIS();

        pl.Store(filename, null);
      }
      catch (Exception exp)
      {
        MessageBox.Show(exp.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
      }
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void checkBoxRemoveNonFiles_CheckedChanged(object sender, EventArgs e)
    {
      if (formLoading)
        return;
      WriteRegistry();
    }

    class ThreadParameters
    {
      public String folderName = null;
      public String fileName = null;
    }
    class ThreadProgress
    {
      public Boolean IsSetup { get; set; }
      public String Text { get; set; }
      public int Value { get; set; }
      public ThreadProgress()
      {
        IsSetup = false;
      }
      public ThreadProgress(int value, Boolean isSetup)
      {
        IsSetup = isSetup;
        Value = value;
      }
      public ThreadProgress(String text, int value)
      {
        IsSetup = false;
        Text = text;
        Value = value;
      }
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
    {
      BackgroundWorker thread = (BackgroundWorker)sender;
      ThreadParameters param = e.Argument as ThreadParameters;
      String[] filelist = null;

      if (param.fileName != null)
      {
        filelist = new String[] { param.fileName };
      }
      else if (param.folderName != null)
      {
        filelist = Directory.GetFiles(param.folderName, "*.wpl");
      }
      else
        return;

      thread.ReportProgress(0, new ThreadProgress(filelist.Length, true)); // setup the progress.

      int count = 0;
      foreach (String filename in filelist)
      {
        if (thread.CancellationPending)
          break;

        thread.ReportProgress(0, new ThreadProgress(filename, count++));
        ProcessWpl(filename);
      }
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
      ThreadProgress progress = e.UserState as ThreadProgress;
      if (progress != null)
      {
        if (progress.IsSetup)
        {
          progressBar1.Visible = true;
          labelProgress.Visible = true;
          labelProgress.Text = String.Empty;
          progressBar1.Minimum = 0;
          progressBar1.Maximum = progress.Value;
        }
        else
        {
          labelProgress.Text = progress.Text;
          progressBar1.Value = progress.Value;
        }
      }
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
      if (buttonProcessFile.Enabled)
        buttonProcessFile.Text = "Process file";
      if (buttonProcessFolder.Enabled)
        buttonProcessFolder.Text = "Process folder";

      buttonProcessFile.Enabled = File.Exists(comboBoxFile.Text);
      buttonProcessFolder.Enabled = Directory.Exists(comboBoxFolder.Text);
      progressBar1.Visible = false;
      labelProgress.Visible = false;

      WMPPlayList.CancelAbortRequest(); // reset the abort request.
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void buttonOpenFolder_Click(object sender, EventArgs e)
    {
      if (Directory.Exists(comboBoxFolder.Text))
      {
        Process.Start(comboBoxFolder.Text);
      }
    }

    private void buttonShuffle_Click(object sender, EventArgs e)
    {
      if (File.Exists(comboBoxFile.Text))
      {
        WMPPlayList list = new WMPPlayList(comboBoxFile.Text);
        list.Shuffle();
        list.Store(comboBoxFile.Text, null);
      }
    }
  }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
South Africa South Africa
Started in 1988 programming in Pascal, making a 68000 emulator on a DOS platform. Then from Pascal to Clipper, to C++ and now using C#. I've been programming for all walks of businesses; opticians, opthomologist, carbage collectors, reinforcement steel producers, retail chains, and more.
I'm now travelling through Africa with a home-build expedition truck.

Comments and Discussions