List iTunes Apps by Purchaser

I finally developed a way to list all your iTune applications by Purchaser, and even better, I can do it from the command line.

Last year I was helping a friend who has pretty poor internet connectivity upgrade his iPad to the latest version of iOS. To do this, I connected his iPad to my system, performed a backup in iTunes, then synchronized to update the operating system. This had the side effect of beaming some of his applications to my iTunes, which in order to continue, he authenticated against. His iPad updated great, and he was on his way.

Things on my machine seemed okay for a while, that was until some of the apps he purchased that I didn’t have wanted to update. Not having his password, I wasn’t able to update them, but even worse, Apple wasn’t announcing which apps needed updating with his account so I could simply delete them as I wanted to.

Instead, for over a year, I was greeted in iTunes by a numerical indicator saying I needed up update my apps, but when I went to do it, I was up to date. Every once in a while I’d recognize an app that I didn’t purchase (in a haystack of nearly 1,000 iPhone apps) and delete it. Only then did the number drop, but later rise again when some other app needed updating.

What I needed to do was list out all the apps by Purchaser.

One of things that really annoys me about Apple is that stuff that is trivial to implement, like putting an optional Purchaser column in iTunes, they don’t do. The feature is half heartedly there, though. Press Command-I for Info, and you can see the purchaser for an item.

Only now you have to click and inspect your whole app list. And with the number of applications I own, this doesn’t scale well at all.

Searching the web reveals that others are in a similar bind, and that Apple seems to really care less about the few handful of users with this problem. Like much on the Apple Support Site, it’s unhelpfully silent.

Frustrated, I decided to solve this problem once and for all.  Open Terminal and cut’n’paste the following in:

for f in ~/Music/iTunes/iTunes\ Media/Mobile\ Applications/*.ipa; \
 do (echo "$f" ; unzip -p "$f" "iTunesMetadata.plist" | \
 plutil -p - | egrep -i "\\"(itemName|artistName|AppleID)\\"" ) | \
 perl -e 'while (<>) { if (m!^/!) { chop; $fqn=$_; } if (m/"(.+)" => (".+")/) { $e{lc($1)}=$2; } } print "\\"${fqn}\\",$e{\\"itemname\\"},$e{\\"artistname\\"},$e{\\"appleid\\"}\n";'; \
done

Where’s my JDK?

Caught in the Java depreciation battle under OS 10.6 and can’t find where the Java Development Kit (JDK) now resides? Here’s a command that will tell you, allowing you to still use InteliJ and other IDEs on OS X.

There’s a lot going on with Java at the moment. Oracle acquires Sun, putting the language in squarely in hands that don’t inspire trust; the same thing happened with MySQL. Meanwhile, the Apache Software Foundation quits the Java SE/EE Executive Committee. And now Apple deprecates Java, and the reason doesn’t appear to be what you’d think.

Starting with OS X 10.6.3 update, developers got caught in the back lash. Things moved on the file system.

Upgrading IntelliJ, the IDE was asking me where my JDK was, as it certainly wasn’t where the software, or I, thought it should be.

You won’t find the location using /Applications/Utilities/Java Preferences.app.

But you can find it with some digging. Thanks to this developer release note from Apple, the following command from Terminal will spew out some XML.

$ /usr/libexec/java_home –xml

Find the dictionary section that has ‘x86_64’ in it, and you’ll find an entry that has a ‘JVMHomePath’ with something like:

/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home

You want to provide this full path to the IDE as where the JDK lives.

It’s worth pointing out that Apple recommends that if you install any 3rd party JVMs they should be installed in /Library/Java/JavaVirtualMachines or ~/Library/Java/JavaVirtualMachines.

Camera is in use by another application

Trying to video conference with Skype and getting a message saying the camera is in use by another application with no video feed sent out? Try this.

Blind SkypeRecently I was attempting to use Skype, but it reported that “Your camera is in use by another application” and I couldn’t get any video feed, though the camera turned on.

Then I found this post which suggested removing the file
/Library/QuickTime/CamCamX5.component from the system, although I found it’s possible just to move it out of that directory.

Restarting Skype, the video conference worked perfectly.

Yahoo concurs. Here’s more on CamCamX. And here’s another thread saying to remove it.

Operating System: OS X 10.6 (Snow Leopard)

Defined in Multiple Assemblies

The predefined type ‘System.Func’ is defined in multiple assemblies in the global alias … mscorlib.dll and System.Core.dll. SOLVED!

Today I migrated a C#/WPF project in Visual Studio 2010 from .NET 3.5 SP1 to .NET 4.0. Immediately the compile failed issuing this set of errors:

  • The predefined type ‘System.Func’ is defined in multiple assemblies in the global alias; using definition from ‘c:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\mscorlib.dll’
  • The predefined type ‘System.Func’ is defined in multiple assemblies in the global alias; using definition from ‘c:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.Core.dll’

To resolve this error involved understanding a little bit more about C#, .NET, and the Common Language Runtime (CLR).

According to C# 4.0 In A Nutshell from O’Reilly Press, on page 181 it says:

Some of the .NET types are used directly by the CLR and are essential for the managed hosting environment. These types reside in an assembly called mscorlib.dll and include C#’s built in types, ….

At a level above this are additional types that “flesh out” the CLR-functionality, …. These reside in System.dll, System.Xml.dll, and System.Core.dll, and together with mscorlib the provide a rich programming environment….

So mscorlib and System.Core are both needed. This begs the question, why is Func declared in both and thus causing a conflict? Or is it?

Further on in C# 4.0 In A Nutshell from O’Reilly Press, on page 183 in a general note it says:

A notable exception is the following types, which Framework 4.0 have moved from System.Core to mscorlib.dll:

  • The Action and Func delegates

This suggests a case exists where mscorlib is from our current .NET (the later one has Func), and System.Core is coming from the old one (which is where Func lives for that version).

How is this possible? It’s our projects fault.

This question on StackOverflow provides some insight; check out Simon‘s answer.

  1. Right-click the project and select Unload Project
  2. Right-click the project again and select Edit Project
  3. Scroll down in the XML to find the ItemGroup element; it’ll have Reference elements insider of it.
  4. Locate the Reference element that has Include=”System.Core” as an attribute.
  5. If it has other qualifiers, remove them. If it has a TargetFrameworkVersion subelement remove it.
  6. Save the XML.
  7. Right-click the project and reload it; try a build now.

In my case, I had an entry that looked like this:

<ItemGroup>
  <Reference Include=”System.Core”>
    <TargetFrameworkVersion>3.5</TargetFrameworkVersion>
  </Reference>
</ItemGroup>

Removing the TargetFrameworkVersion, shown in red above, un-pinned the dll from the older .NET framework and things worked just fine.

Error 0x80070057 (SOLVED)

Copy File

An unexpected error is keeping you from copying the file. If you continue to receive this error, you can use the error code to search for help with this problem.

Error 0x80070057: The parameter is incorrect.

SOLVED!

Went to copy a directory on Windows 7 from one drive to another, something that I had done quite frequently, even earlier that day.

However, this time, and nothing had changed substantially with the source files, I got an Error 0x80070057 message stating “The parameter is incorrect.” At that point the copy dialog from my simple drag and drop would allow me to retry (useless) or abort mid-copy.

The error message was unusually cryptic and less that helpful:

Copy File

An unexpected error is keeping you from copying the file. If you continue to receive this error, you can use the error code to search for help with this problem.

Error 0x80070057: The parameter is incorrect.

The disk was not full and a check disk revealed no errors.

THE SOLUTION
The destination directory name that I was copying into was pretty long, I basically had used a descriptive prefix, a date stamp of YYMMDDHHMMSS, by a space dash space, and a short descriptive comment. All in all it was about ~55 characters in length.

The directory I was copying from was a fairly deep structure.

That made me wonder if the fully qualified name of some directory path wasn’t exceeding some limit. On Windows, it appears to be 256 characters. On a Mac it appears to be 1023 characters.

Tricks aside, I was limited to the file system limits.

So, on the same disk, with the same files, immediately after yet-another-failure to copy, I renamed the destination folder to something considerably shorter and tried again.

Quick experimentation showed that was indeed the problem: the resulting path name formed during the copy was too long.

Solution: shorten the destination folder name and/or tighten up the path.

Find and Replace in Word using C# .NET

Solution to how to do a global search and replace in MS-Word, including across floating text objects, in C#/.NET.

Heads up, this article contains high quantity of geek content. Non-geeks should move along.

I’ve been trying to use Microsoft.Office.Interop.Word to perform a global bulk search and replace operations across an entire document. The problem was, however, if a document contained a floating text box, which manifested itself as a shape object of type textbox, the find and replace wouldn’t substitute the text for that region. Even using Word’s capability to record a macro and show the VBA code wasn’t helpful, as the source code in BASIC wasn’t performing the same operation as inside the Word environment.

What I wanted was a simple routine to replace text anywhere inside of a document. If you Google for this you’ll get the wrong kind of textbox, the wrong language, people telling you not to use floating textboxes, and all kinds of weird story iterators.

One site seemed to have the solution; many kind thanks to Doug Robbins, Greg Maxey, Peter Hewett, and Jonathan West for coming up with this solution and explaining it so well.

However, the solution was in Visual Basic for Applications, and I needed a C# solution for a .NET project. Here’s my port, which works with Office 2010 and Visual Studio 2010 C#/.NET 4.0. I’ve left a lot of redundant qualifiers and casting on to help people searching for this article.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using Microsoft.Office.Interop.Word;

// BEGIN: Somewhere in your code
Application app = null;
Document doc = null;
try
{
  app = new Microsoft.Office.Interop.Word.Application();

  doc = app.Documents.Open(filename, Missing, Missing, Missing, Missing, Missing, Missing, Missing, Missing, Missing);

  FindReplaceAnywhere(app, find_text, replace_text);

  doc.SaveAs(outfilename, Missing, Missing, Missing, Missing, Missing, Missing, Missing, Missing, Missing);
}
finally
{
  try
  {
      if (doc != null) ((Microsoft.Office.Interop.Word._Document) doc).Close(true, Missing, Missing);
  }
  finally { }
  if (app != null) ((Microsoft.Office.Interop.Word._Application) app).Quit(true, Missing, Missing);
}
// END: Somewhere in your code             



// Helper
private static void searchAndReplaceInStory(Microsoft.Office.Interop.Word.Range rngStory, string strSearch, string strReplace)
{
    rngStory.Find.ClearFormatting();
    rngStory.Find.Replacement.ClearFormatting();
    rngStory.Find.Text = strSearch;
    rngStory.Find.Replacement.Text = strReplace;
    rngStory.Find.Wrap = WdFindWrap.wdFindContinue;

    object arg1 = Missing; // Find Pattern
    object arg2 = Missing; //MatchCase
    object arg3 = Missing; //MatchWholeWord
    object arg4 = Missing; //MatchWildcards
    object arg5 = Missing; //MatchSoundsLike
    object arg6 = Missing; //MatchAllWordForms
    object arg7 = Missing; //Forward
    object arg8 = Missing; //Wrap
    object arg9 = Missing; //Format
    object arg10 = Missing; //ReplaceWith
    object arg11 = WdReplace.wdReplaceAll; //Replace
    object arg12 = Missing; //MatchKashida
    object arg13 = Missing; //MatchDiacritics
    object arg14 = Missing; //MatchAlefHamza
    object arg15 = Missing; //MatchControl

    rngStory.Find.Execute(ref arg1, ref arg2, ref arg3, ref arg4, ref arg5, ref arg6, ref arg7, ref arg8, ref arg9, ref arg10, ref arg11, ref arg12, ref arg13, ref arg14, ref arg15);
}

// Main routine to find text and replace it,
//   var app = new Microsoft.Office.Interop.Word.Application();
public static void FindReplaceAnywhere(Microsoft.Office.Interop.Word.Application app, string findText, string replaceText)
{
    // http://forums.asp.net/p/1501791/3739871.aspx
    var doc = app.ActiveDocument;

    // Fix the skipped blank Header/Footer problem
    //    http://msdn.microsoft.com/en-us/library/aa211923(office.11).aspx
    Microsoft.Office.Interop.Word.WdStoryType lngJunk = doc.Sections[1].Headers[WdHeaderFooterIndex.wdHeaderFooterPrimary].Range.StoryType;

    // Iterate through all story types in the current document
    foreach (Microsoft.Office.Interop.Word.Range rngStory in doc.StoryRanges)
    {

        // Iterate through all linked stories
        var internalRangeStory = rngStory;

        do
        {
            searchAndReplaceInStory(internalRangeStory, findText, replaceText);

            try
            {
                //   6 , 7 , 8 , 9 , 10 , 11 -- http://msdn.microsoft.com/en-us/library/aa211923(office.11).aspx
                switch (internalRangeStory.StoryType)
                {
                    case Microsoft.Office.Interop.Word.WdStoryType.wdEvenPagesHeaderStory: // 6
                    case Microsoft.Office.Interop.Word.WdStoryType.wdPrimaryHeaderStory:   // 7
                    case Microsoft.Office.Interop.Word.WdStoryType.wdEvenPagesFooterStory: // 8
                    case Microsoft.Office.Interop.Word.WdStoryType.wdPrimaryFooterStory:   // 9
                    case Microsoft.Office.Interop.Word.WdStoryType.wdFirstPageHeaderStory: // 10
                    case Microsoft.Office.Interop.Word.WdStoryType.wdFirstPageFooterStory: // 11

                        if (internalRangeStory.ShapeRange.Count &gt; 0)
                        {
                            foreach (Microsoft.Office.Interop.Word.Shape oShp in internalRangeStory.ShapeRange)
                            {
                                if (oShp.TextFrame.HasText != 0)
                                {
                                    searchAndReplaceInStory(oShp.TextFrame.TextRange, findText, replaceText);
                                }
                            }
                        }
                        break;

                    default:
                        break;
                }
            }
            catch
            {
                // On Error Resume Next
            }

            // ON ERROR GOTO 0 -- http://www.harding.edu/fmccown/vbnet_csharp_comparison.html

            // Get next linked story (if any)
            internalRangeStory = internalRangeStory.NextStoryRange;
        } while (internalRangeStory != null); // http://www.harding.edu/fmccown/vbnet_csharp_comparison.html
    }

}

Let me know if it worked for you; bug fixes and enhancements welcome.

Printing in Parallels

Using Parallels virtualization, I got this pretty scary error message: pstopdffilter/pstocupsraster failed with err number -31000. I’m almost ashamed to tell you what the solution is to get past it.

Parallels is a virtualization package for the Macintosh that primarily is used for running Microsoft Windows in a virtualized environment on OS X.

At some point you’re going to run into the problem of wanting to print something from the guest OS. Do not try to install a Windows XP print driver for the device that’s connected directly to your Apple. That’s not how it works.

You have a virtual machine. Surprise, you have a virtual printer too.

To set it up is trivial:

  1. Stop your Windows VM if it’s running.
  2. Open VM Configuration Editor (Parallels Desktop menu – Edit – Virtual Machine)
  3. Add Parallel Port Printer to the VM Configuration: click “Add” – select “Parallel Port”, hit “Next” – select “Use a printer” – select the printer you have available in the Mac OS.
  4. Make sure that you are able to print using that printer from the Mac OS side.
  5. Start Windows and try printing some document using “HP Color LaserJet 8500 PS” (it’s generic driver that’s being used for printing from the Virtual Machine to any Mac OS compatible printer).

This creates a HP Color LaserJet 8500 PS printer, which then gets redirected to the host operating system’s default printer. Printing then works normally, queuing and all.

Now, I did run into this problem using Microsoft Office on Windows XP with a HP DeskJet 6980 connected wirelessly through an Apple AirPort Extreme in bridge mode:

pstopdffilter/pstocupsraster failed with err number -31000

Here’s how I solved it.
I deleted the print queue on the host operating system, then I turned the power off and back on again on the printer, and tried again.

Seriously. I power cycled the printer. That’s all that was required. Second time through, it worked like a champ.

Big scary error message, itty-bitty solution.

NOTE: You will want to scan through your document if you’re using exotic fonts. In my case apostrophes were coming out as í.

Telemarketing + Mute = Revenge

Apparently I managed to cause some problems for a telemarketer by pressing MUTE at the right time.

Stumbled upon this by accident, but it may prove useful in the future.

I know two people who’ve done telemarketing, and they report that their objective is to place as many calls as possible and sell as much as possible in that duration. So, not placing calls, or overly long calls, seems to be a serious negative.

Additionally, the system used appears to be an pre-emptive autodialer that looks for a human response and if found quickly connects with an operator. Should not be available, it hangs up, which explains why people report calls from mystery numbers that disconnect after being answered.

The operators sit there listening to silence until someone says “hello” and then they start. They have a button to dump the call, and the system goes on to the next.

Today I received a pre-emptive call and the moment I heard it transferring me to an operator, I pressed MUTE.

The unexpected happened.

I was greeted by just the sounds breathing and keyboard clicking. Within a moment it was possible to deduce from the background conversations that it was Yahoo trying to sell advertising to businesses.

Leaving mute on, I could hear the telemarketer cursing under his breath, as his line remained silent, but his co-workers were all yammering away. While I would have expected a call duration counter to have been the dead give away, it took him about 10-15 minutes to realize something was seriously wrong before he got assistance and it sounded like a reboot was about to be attempted before I got disconnected.

I’m guessing they run Windows.

ModRewrite Woes (Solved!)

Problems with ModRewrite, relative URLs, base paths, things executing without extensions being specified, and using MultiViews — read on.

While working on a project, I stumbled into some of the weirdest Apache2 mod_rewrite problems that I’d ever seen.

The goal was to make a URL like http//www.nowhere.com/item/1234 turn into http://www.nowhere.com/item.php?id=1234. Trivial, and I’ve done it all the time.

RewriteEngine on
RewriteRule ^item/(.+)$ item.php?id=$1 [L]

This time it wasn’t working the way I expected. When I used the human-readable version, my page got delivered by I had no images, no css, no javascript. Yet, if I used the computer-friendly long form with parameters, it worked just fine.

A little examination with Safari’s activity window showed me that in the initial case the browsers were looking at all relative URLs as if they were prefixed with /item/. This make sense, because the URL redirect knows how to play rewrite games with the rules to get to my page, but the relative links on those pages, to css, graphics, and js, had no clue this was a fake base url.

Many thanks to richardk who pointed out multiple solutions back in 2005.

  • Don’t use /, and there isn’t a problem.
  • Use absolute paths, though you have to edit all the links on your page; if using PHP, consider a variable for the base path.
  • Use a RewriteRule to hack off the offensive directory that doesn’t exist.
  • Or, use the <BASE …> tag.

Well, that rendered the page prettier, but I realized my argument wasn’t being passed in. Yet, the re-write rule was correct.

So I tried http//www.nowhere.com/item, which should not have matched and should not have brought up a page. Yet it did.

A little experimentation showed that any page that had a known extension was getting delivered.

What this meant was that the moment the browser saw /item it found the item.php page and delivered it without ever going through Apache’s rewrite module, and hence no parameters.

Luckily, I’ve encountered this symptom before in a different context. The offender: MultiViews. This is the bugger that deals with multiple language support; you know, where you have a zillion internationalized instances based on filename extensions….

Turning that off instantly solved the problem of delivering a file without an extension:
# Options Indexes FollowSymLinks MultiViews
Options Indexes FollowSymLinks

That also meant that the mod-rewrite rules worked. And that meant the parameters were passed correctly. And that meant I was was happy, because the code was working.