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.

WPF Responsiveness Problem

Ran into an interesting problem where a WPF application was acting really, really, really slow. So slow that moving the application window was jumpy. Selecting items in a grid would take several seconds. Scrolling a list box of simple items would grind the CPUs for a while. And even typing in a regular text box was so delayed that I could type a word, sit back, and every few seconds a character would appear.

The problem turned out to be with the input stack at the operating system. Seems that the Pen / Tablet Driver was bringing the system to its knees, but only affecting WPF applications.

Disabling the driver and restarting the WPF application instantly showed colossal speed improvements for response time; the application responded near instantly. Re-enabling the driver while the application was running reverted the system to the broken state, although turning the driver back off did not bring the WPF application out of it’s slow like crawl. Restarting the WPF application resolved the problem, but the driver had to be disabled.

(Test conducted with WPF 3.5 SP 1 and Windows 7.)

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.

Holiday Inn, Holiday Over

As with most things, it’s the little details that matter, and for my most recent vacation, everything about staying at Holiday Inn got on my last nerve, so much so that we checked out a day early on a pre-paid room and were glad to do so. This blog is simply a note to myself, reminding me to avoid that chain when booking hotels in the future.

Overdraft and Bad WiFi

So I won’t forget the why: in my opinion, the first sign something wasn’t right was literally a sign indicating they would put a hold on accounts that may result in overdraft fees that wouldn’t then be their fault; nice welcome. There was no in-room refrigerator so we couldn’t store food or drinks over night. There were no tissues. The toilet always took three attempts to flush. The toilet paper was on the opposite wall of the toilet, better than an arm’s reach away (brilliant). The tub felt like the was grit on the bottom of it. The toilet was crammed between the sink and the tub, just enough to bang one’s elbows. Same with the soap dishes in the tub, at elbow height. It was a horrible room design, where just slightly too much space was squeezed out. For instance, if you sat in a chair, you hit your head on the lamp. There was no exhaust fan in the bathroom. The wireless was horribly slow and kept requiring an annoying re-authentication process at random. Our room keys spontaneously and simultaneously stopped working, and when we went to the front desk to get them fixes, we were blamed for having them near a cell phone, that we know for a fact that wasn’t the case. I could go on, but I just wanted enough keywords so I could later find that place I didn’t ever want to stay at again.

Admittedly, some of this could have been the room, that hotel, its staff, or that chain. I feel little inclination to explore the matter further, I’m annoyed that much that I’m just done. I don’t expect perfection, but I also don’t want to loath returning to have to deal with the next surprise; certainly not on vacation.

But further related insult, though now not too surprising in retrospect, came when we were walking around Broadway at the Beach and noticed a number of signs at ticket areas that said Medieval Times Dinner & Tournament‎, 2 adults for $20. It was a deal that sounded too good to be true, and was. There was no branding or other information on the sign, but when one went to purchase the tickets, you couldn’t; what you got was a rep whipping out an appointment calendar for a timeshare tour. If you would go take their off-site multi-hour tour and listen to a sales pitch, they’d “give” you the tickets for “free.” But if you wanted to buy what they advertised, they’d never sell them to you. It was very bait and switch. Turns out, it was… Holiday Inn. When asked how come it didn’t say Holiday Inn or indicate there was a sales pitch, we were flat out told that people wouldn’t come in if they had put up the truth. This just solidified my vision of the corporate image.

Your own experiences may vary, but having stayed at other places in the same price range, I’m avoiding this chain.

Walt gives Holiday Inn one thumb down.

Help Wanted, Carpenter

My wife was driving down a highway in Pennsylvania and looking out the window I saw a scene before me that made me say out loud, “Oh, that’s just not right.” I instructed my wife to make the next available U-Turn and pull onto the shoulder. I needed a photo.

Makes me wonder what happened to the last one they had.

There before us was a sign that said ‘Help Wanted’ ‘Lead Carpenter’. And, behind it, a set of three crosses, one that belonged to a carpenter. Either way you look at it, that something happened to their last one, or that the need make more crosses, that’s most likely not the best location for this particular help wanted sign.

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