Bang for Buck

Think that extended trial periods hurt sales? Think again.

There’s a wonderful application for the Mac called TypeIt4Me that does instant macro expansions as one types. I first learned about it at a No Fluff Just Stuff technical conference when some of the presenters were using it to give some slick presentations.

I’m a big believer in try-before-you-buy, and have long advocated using the 30/30/30 model for generating sales.

Here’s evidence that my bang-for-buck ratio was pretty low:

Bang for Buck FAIL

The problem? At the time, I just couldn’t find just the right need for it within my own workflow. But you can see, I kept it around.

However, because the software didn’t shutdown and lock me out, which would have gotten it deleted, it was there the moment I had need. And, Ettore Software got a sale.

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)

MySQL Cascade Delete Problem

MySQL 5.1.51 introduced a nasty little bug that has the potential to really cause some production servers some ill — cascading delete and updates can sometimes fail if you’re dealing with “too much” data at once. Where “too much” is a relatively small amount. You may get bit if you have a one-to-many relationship.

A note of warning to MySQL users using 5.1.51, you may want to downgrade to 5.1.50 for a little bit.

There’s a problem with 5.1.51 in which cascading deletes or updates throw an error. Not good if you have constraints and one to many relationships.

ERROR 1030 (HY000): Got error -1 from storage engine

The mysql error log will say something like:

InnoDB: Cannot delete/update rows with cascading foreign key constraints that exceed max depth of 250

This is a confirmed bug in MySQL and is repeatable. The error will cause a transaction rollback. Not good news for people running production systems.

See MySQL Bug #357255.

While the problem was quickly identified and apparently resolved, as the defect report is closed, it does not look like the 06-Oct-2010 change has made it out to the production baseline as of the time of this writing.

Additionally, the MySQL pre-release snapshots on labs.mysql.com show there is a mysql-5.1.52 pending with a September date, and this hasn’t made it to general production yet.

That leaves one to speculate that the fix will appear in the 5.1.53 version, and we won’t be seeing that for a month or two. Yikes.

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.

Mysterious Copyright

This is clearly one of those things I did to myself as a good idea, then forgot about, only to be plagued by it later.

I noticed that all of my photographs on my camera were reporting a copyright with a 2009 year inside the exif data.

I’ve been unable to figure out where it was coming from, resorting to exiftool to remote it.

My natural thought was that perhaps it was some preference in a photo editing tool or a geospatial locator tool. But, no. Turns out I did it to myself.

The Canon EOS Utility has a nifty ability to include a value for the Copyright tag. And about a year ago when I tethered it to the computer, I must have noticed this and set it to some precanned value that includes the year.

It looked something like this:
Copyright (c) 2009 by Walt Stoneburner, All Rights Reserved.

And ever since then, my photos were stamped with that value. Which was fine, back in 2009.

Fixing the problem was as simple as tethering the camera again and firing up Canon EOS Utility. It also gave me an opportunity to update the firmware.

Strange copyright exif data: mystery solved.

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.

Pages: 16 Exabytes

Pages just asked OS X for 16 Exabytes. Got a clue just how large that is?

So I decided to make some business cards using Pages, however after adding a few tiny JPGs, I started getting the spinning beach ball — you know the one, the one you’re never supposed to get in OS X.

So, I decided to open Activity Monitor to see what was up.

Pages had allocated 16 Exabytes of memory. My computer has 6 Gig.

Remember, it goes from Megabytes, to Gigabytes (1,000Meg), to Terabytes (1,000Gig), to Petabytes (1,000 TB), to Exabytes (1,000 PB).

16 Exabytes

Virtual Server Problems

I recently switched operating system vendors, and to my surprise when I went to port over the web content from one system to another, things didn’t go as smoothly as I had hoped. What used to be /etc/httpd was now /etc/apache2, and inside this directory files were organized differently that I was used to, and so forth. Still, I would have hoped moving from Apache2 on RedHat to Apache2 on Ubuntu would have been easier.

Empirical evidence was suggesting that all of my user’s virtual sites were working, but all of mine, no matter where I had them on the system, were reporting the error: You don’t have permission to access / on this server.

Here’s what was going on, primarily recounted so if I ever do this to myself in the future, I’ll know what to look for.

The virtual host files, which now appear in /etc/apache2/sites-available as *.conf files, had a slight difference. Some of them had this in their Directory directive:

    Order allow,deny
    allow from all

Mine did not. But, then again, some other websites did not as well. Turns out those directives were placed inside their .htaccess files.

Now, not all sites had the .htaccess file, and things had been working before without the explicit directive in each virtual host .conf file.

Turns out I had some how tromped on the default file, which contains a directive that looks like this:

    <Directory />

      Options FollowSymLinks
      AllowOverride None

    </Directory>

If it is not present, then all virtual hosts must explicitly allow access (via .htaccess or their .conf file).

This directive allows Apache to serve up any file the URL asks for… which one may not want to do. It seems the secure way is to edit the virtual host .conf files, and not rely on some default magic.

But, because that was in my old configuration long ago, and not in the new one, my virtual host .conf files didn’t have it, but my more modern ones for my users did. Depending on which template I used to base new sites off was how some sites worked and some didn’t.

After fixing this, I ran into a new problem. Some sites weren’t coming up still, but this time with permission errors.

When I migrated over the web content, it preserved user and group ownerships from the other system. These did not match the new Apache2 user and group on the new system.

However, I got lucky. There was no user/group mapping on the new system, which meant I could execute a find command to find and fix them. It looked something like this:

    find /home -nogroup -print
    find /home -nouser -print
    find /home -group 49 -exec chgrp www-data ‘{}’ \;

WebCams on OS X

Lots of cool software exists for webcams on OS X.

OS X is capable of using USB and Firewire cameras, with perhaps the most famous being the iSight, second to the Built-in iSight of Apple’s laptops.

Use other cameras!
But it turns out you can use a lot of third party cameras using the Macam driver.

Use multiple cameras!
If you’re using multiple cameras at once, say for security monitoring, you’re going to want to take a look at SecuritySpy, which has motion detection, time lapse, and the ability to view from a remote browser, plus many other features.

Barcode Reader!
EvoBarcode will let you use your camera as a bar code reader.

Web Streaming!
EvoCam will let you stream multiple cameras and push images to servers.

Stop Motion Photographer!
iStopMotion will help you make your own stop motion movies.

Real-time Special Effects!
iGlasses will enhance and alter your video feeds.

Drag’n’Drop Problems with Parallels 4

Since installing Snow Leopard, I can no longer Drag’n’Drop files from Windows to the hosting OS X environment, though the inverse works just fine. Is anyone else having this problem, because I’m not seeing much about it on the Parallel’s forums. I think the bug is real.

To say that I’m distrusting of Microsoft Windows’ security is putting things lightly. And when I’m in a situation where Microsoft’s anti-open standards force Microsoft as a necessity, I tend to use a virtual machine to sandbox its activities.

On Mac OS X, I use a wonderful product called Parallels, which has the added bonus of being able to drag’n’drop files and directories between the guest operating system (Windows) and the host operating system (OS X).

After installing the latest Snow Leopard (10.6), I found that while I could drag files into Windows from OS X, the reverse was no longer true. Dragging something from the Windows desktop out to the OS X desktop, which used to work in Leopard (10.5), simply results in nothing happening.

Parallels 4.x Shared Services Drag'n'Drop

Now, I’m aware that Apple did some pretty big changes under the hood in Snow Leopard. And, I’m aware that even the Finder got a fairly intensive overhaul. And, I’m even willing to accept that there might be bumps during the transition process, as the good folks at Parallels update their product to address little tidbits like this.

However, I’m kinda surprised that this kind of thing snuck past testing. Even more to my surprise is that I don’t hear many people talking about it. Such conclusions lead me to think that perhaps I have a local configuration issue.

But then I heard from another user of Parallels that updated to Snow Leopard. He ran into the same problem: Drag’n’Drop worked only in one direction now.

Most of the Snow Leopard fuss currently centers on the fact that Parallels 2.x and 3.x no longer work under Snow Leopard. Parallels made such a good and stable product that early users saw no need to update as it met their needs. However, Apple’s approach to operating systems is far more progressive than Microsoft’s, as they are willing to sacrifice backwards compatibility in software and hardware, if the technology is substantially old and the new benefits far outweigh the trouble. Thus, Apples tends to fix problems, rather than bandaid-ing workarounds; in the long haul everyone benefits with faster, smaller, more featured applications instead of bloatware.

However, I’m riding the Parallels 4.x wave on the bleeding edge. I’ve got the Parallels Tools installed. I’ve got the Enable Drag’n’Drop checked in the Shared Services config. Still, nothing.

I did a little digging around and found one user, Jamie Daniel, who was experiencing the same problem. As his question went unanswered, I tried myself.

I wrote an entry in the Parallels forum entitled Drag files from Guest to Host no longer working, detailing the problem.

And, while I was luckier than Jamie and got an answer, it was fairly clear someone gave a cursory glance and cut’n’pasted a response without reading what I was asking. In short that I did not want Windows to be able to read or write to any OS X drives. For, should Windows get a virus, I didn’t want it having free reign of the OS X filesystem to corrupt. Thus only I, via Drag’n’Drop, should be able to marshal content between the two environments.

Willing to accept the fact that I may have a configuration problem, despite being a power user of Parallels since day one, I am also willing to accept that this is simply a Snow Leopard compatibility issue that Parallels will soon be addressing. Problem is, I can’t seem to raise the issue to a level where someone can confirm or deny it.

Worse yet, I can’t seem to be able to login to Windows via the Finder anymore to mouse a Windows disk within OS X, where as I used to be able to do that as well. While workarounds, from using a USB disk (which mounts in both environments), DropBox, and using the Windows Guest account’s Parallel’s mount point, I’d really like the old capability back.

So, I ask, Parallels 4.x users that are using Snow Leopard, are you no longer able to drag from Windows to the OS X desktop?

If you can, how are you doing it?

If you can’t, please head over to the Parallels forum and let them know it’s broken for you as well. This is not an attack Parallels request, they’re good people — this is just to raise awareness to let them know the issue is real so they can look into it.

UPDATE 14-Sep-2009: Found a work around, but I’m not happy about it. What I don’t like about it is that it appears to expose Windows disks to OS X. While I trust OS X, the inverse does not appear to be necessary to perform a Drag’n’Drop from OS X to Windows. I’d expect the Enable Drag-and-Drop to be enough.

If you turn on the Share All Disks with OS X, then Drag’n’Drop from the Windows desktop to OS X Desktop works.

Parallels 4 Drag'n'Drop Hack