Skeuomorphism is back

I find it interesting that gizmodo is complaining about skeuomorphism again, but this time saying that it’s a good thing.

I’ve always liked skeuomorphism. I like the look of the new apple watch. I won’t be getting one because I believe that a watch needs to be able to go at least a week without requiring a charge to be useful.

Moving iTunes Library in two steps using COM interface and RoboCopy

Several years ago I migrated from storing my data on on server to another. I had all of my music stored in an hierarchy under the UNC sharename of \\Via\Music and moved it to a different server with the sharename of \\FortMeade\Music.

My music collection is around 60 gigabytes, and my experience with apple software in windows has not been very good. Telling the itunes application itself to do the moving did not seem like the best of plans if I wanted to be able to use my computer any time soon.

I decided that the most reliable method of transfering the files was to use the robocopy command and the windows command prompt. This took several hours over gigabit ethernet but got the data copied over.

I wanted to maintain as much of the data as possible about the individual tracks, and decided I could write a program using the COM interface to control iTunes and copy the entries from the old tracks and put them in for the new location.

I wrote a program in C++ using Microsoft Visual Studio, and successfully maintained the last played date and the number of plays. Unfortunately the location data of a track seems to be read only, otherwise I’d simply have changed that and been able to maintain all of the data.

Several years later, and I want to move to another server. Now when I modify my program and attempt to run it with the new names, it adds the tracks in the new location, but when it tries to modify the PlayedCount value, it traps a COM error (0xA0040203), and the error doesn’t seem to have a description.

// iManipulate.cpp : Defines the entry point for the console application.

#include "stdafx.h"
#include "iManipulate.h"
#ifdef _DEBUG
#define new DEBUG_NEW

#undef GetFreeSpace /* macros are evil */
#import "C:/Program Files (x86)/iTunes/iTunes.exe"
using namespace iTunesLib;

// The one and only application object
CWinApp theApp;

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
  int nRetCode = 0;
  // initialize MFC and print and error on failure
  if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
    _tprintf(_T("Fatal Error: MFC initialization failed\n"));
    nRetCode = 1;
    // initialize COM libraries
    HRESULT hr = CoInitialize(NULL);
    if (SUCCEEDED(hr))
      CComPtr<IiTunes> iTunes;
      if (S_OK == iTunes.CoCreateInstance(__uuidof(iTunesApp)))
        CComPtr<IITLibraryPlaylist> MyLibrary = iTunes->LibraryPlaylist;
        CComPtr<IITTrackCollection> MyTrackCollection = MyLibrary->Tracks;
        for (long index = 1; index <= MyTrackCollection->Count ; index++)
          CComPtr<IITTrack> MyTrack = MyTrackCollection->Item[index];
          if (MyTrack->Kind == ITTrackKindFile)
            CComPtr<IITFileOrCDTrack> MyFileOrCDTrack;
            if (S_OK == MyTrack->QueryInterface(&MyFileOrCDTrack))
              _tprintf(_T("%d"), index);
              BSTR MyTrackLocation = MyFileOrCDTrack->Location;
              _tprintf(_T("\t%s"), MyTrackLocation);
              CString NewLocation(MyTrackLocation);
              CString NewLocationAllLowerCase(NewLocation);
              CString TextToReplace(_T("\\\\fortmeade\\music"));
              CString NewText(_T("\\\\Acid\\Music"));
              int ReplaceStart = NewLocationAllLowerCase.Find(TextToReplace);
              if (ReplaceStart >= 0)
               if (-1 != _taccess(NewLocation,0))
                   CComBSTR FileToAdd(NewLocation);
                   CComPtr<IITOperationStatus> MyOperationStatus = MyLibrary->AddFile(FileToAdd.m_str);
                   while ( VARIANT_TRUE == MyOperationStatus->GetInProgress())
                   CComPtr<IITTrackCollection> MyAddedTrackCollection = MyOperationStatus->GetTracks();
                   if (1 == MyAddedTrackCollection->Count)
                     CComPtr<IITTrack> MyAddedTrack = MyAddedTrackCollection->GetItem(1);
                     //MyAddedTrack->DateAdded = MyFileOrCDTrack->DateAdded;
                     if (MyFileOrCDTrack->Rating > 0)
                     if (MyFileOrCDTrack->PlayedCount > 0)
                     _tprintf(_T("\t%s\n"), FileToAdd);
                 catch(_com_error &e)
                   _tprintf(_T("\t(COM ERROR:%#lx %s, %s)\n"), e.Error(), e.Source(), e.Description());
 return nRetCode;