<CharlieDigital/> Programming, Politics, and uhh…pineapples



Posted by Charles Chen

There are few technologies that I truly hate and InfoPath is right up there.  The problem isn't necessarily InfoPath itself (okay, yes, I do hate it and it sucks hard), but the misconceptions from many former and current customers and business users about the utility and suitability of InfoPath cause it to be deployed in a variety of situations where it has no business being in a web-based enterprise architecture.

It's a technology that has been oversold and over-promised but always under-delivers and "enterprise architects" love the stuffin's out of it for some reason without a real grasp on why it's such a lame, terrible technology.

Now it seems that it's reached the end of the line:

In an effort to streamline our investments and deliver a more integrated Office forms user experience, we’re retiring InfoPath and investing in new forms technology across SharePoint, Access, and Word. This means that InfoPath 2013 is the last release of the desktop client, and InfoPath Forms Services in SharePoint Server 2013 is the last release of InfoPath Forms Services.

Microsoft makes many great things like .NET and Visual Studio and some total duds like InfoPath (a solution looking for a problem).

This is my favorite part of the blog post:

Industry trends and feedback from our customers and partners make it clear that today’s businesses demand an intelligent, integrated forms experience that spans devices. We are looking to make investments that allow you to easily design, deploy, and use intelligent, integrated forms across Office clients, servers, and services—forms that everyone can use on their PC, tablet, or phone.

Hey Microsoft, here's a tip for you: HTML!  What took you so long?  I mean, holy smokes, why did you even waste the money to conceive of InfoPath Forms Services to convert InfoPath forms into HTML in the first place? Why did you even bother with forcing developers to build forms in some terrible designer with a terrible programming experience only to convert those forms right back into HTML so that people could fill it out?

Any idiot could have seen the utter uselessness and un-ceremonial end of InfoPath years ago.

Filed under: Awesome, Office No Comments

VSTO: The Customization Cannot Be Installed

Posted by Charles Chen

Got this strange error today with an Excel add-in I'm working on:

The customization cannot be installed because another version is
currently installed and cannot be upgraded from this location.
To install this version of the customization, first use Add or
Remove Programs to uninstall this program

Now this seems pretty straightforward, right?  However, the add-in doesn't show up in the Add/Remove programs menu!

No amount of clean solution or rebuild would resolve this issue.

Google didn't turn up any results on MSDN.  So I fired up ProcMon.exe to try to isolate the source of the issue and what it was trying to load.

Turns out that it was trying to read values from a key at:


Deleting this key fixed the issue 😀

Still not sure what caused the issue in the first place, but this is a quick any dirty way to resolve it (for now).

Filed under: Office No Comments

Getting All Content Controls using OpenXML

Posted by Charles Chen

If you're trying to get all of the content controls in an OpenXML document, the most obvious way to do it would be:

// Get the document instance
WordprocessingDocument document = ...; 

// Get all of the SdtBlock elements

But this will only get you some of the content controls.  Basically, it won't return any nested, inline content controls (nested, non-inline content controls are still returned).  Nested, inline content controls are still tagged as <sdt/>, but the corresponding class name is actually SdtRun, not SdtBlock.

To get all of the content controls, you need to use the following code instead:

// Get the document instance
WordprocessingDocument document = ...; 

// Get all of the SdtElement elements

The resultset will include SdtBlock and SdtRun elements.  This had me coding in circles for a few hours....

Note that likewise, the content element is different between the two.  For SdtBlock, the content element is an SdtContentBlock.  For SdtRun, the content element is an SdtContentRun.

Filed under: .Net, Office No Comments

Inserting HTML into Word Documents

Posted by Charles Chen

For a recent prototype, I was tasked with building a solution to allow authors to create "standard text" entries in SharePoint 2010 which could then be re-used by authors.

One of the challenges was trying to figure out the best way to store this type of content.  Word documents is one obvious solution, but I approached it differently: using SharePoint's HTML field type.

List wth standard text items.

You can see in the screen on the left, a list with a column called Default Text.  This is simply a multi-line text field set to either Rich text or Enhanced rich text.

SharePoint's rich text editor is fairly competent for most text formatting scenarios.

This design allows authors to create basic text bodies with formatting entirely in SharePoint

The next question is how to take advantage of this.

Add-in panel in Word 2010

In the authoring environment, Word 2010, an add-in was written to allow users to connect to SharePoint and browse the list contents with fully formatted text.

You can see the screenshot on the right.  The UI is a mish-mash of WPF and classic Windows Forms controls (specifically, the WebBrowser control) to render the HTML contents for preview.

The add-in uses the SharePoint web services to connect to a configured list to retrieve the items using the trusty old Lists web service (the tool was written to support both 2007 and 2010).

The next step is to figure out how to add the text to the body of the Word document and retain the formatting.  In all honesty, I figured that this would be the most complicated part.  In fact, it was the easiest part and accomplished with only a few meager lines of code.

The trick is to leverage the InsertFile function of the Range.  This allows us to insert arbitrary HTML strings by first saving them as files to a temporary location on disk.

/// <summary>
/// Saves the default text to a temporary .html file which can then be inserted.
/// </summary>
/// <returns>The path to the temporary .html file.</returns>
public string SaveToTemporaryFile()
    string htmlTempFile = Path.Combine(Path.GetTempPath(),
        string.Format("{0}.html", Path.GetRandomFileName()));

    using (StreamWriter writer = File.CreateText(htmlTempFile))
        string html = string.Format("<html>{0}</html>", Default);


    return htmlTempFile;

The only trick is that <html/> must be the root element of the document.

Once the temporary file is saved to the disk, we can insert it into the Word document:

private object _opt = Missing.Value;

/// <summary>
/// Inserts the standard text into the active selection range by creating a
/// temporary file and using the <c>InsertFile</c> method to inject HTML into a
/// Word document.
/// </summary>
/// <param name="standardText">The standard text.</param>
/// <param name="contentControl">The content control.</param>
public void InsertStandardText(StandardText standardText, ContentControl contentControl)
    object range = Application.Selection.Range;

    if (contentControl == null)
        contentControl =
            WdContentControlType.wdContentControlRichText, ref range);

    contentControl.Title = standardText.Title;

    string path = standardText.SaveToTemporaryFile();

    contentControl.Range.InsertFile(path, ref _opt, ref _opt, ref _opt, ref _opt);

    // Snipped for brevity...

HTML content inserted into the Word document

The screenshot to the left is an example of HTML content inserted into a Word document.

As you can see, it retained inherited the local formatting (fonts, font size) where no explicit font specification is made.  But otherwise, it faithfully rendered the HTML content entered in the list.

That's it.  I like it when things are simple yet powerful.  For server side (OpenXML manipulation), the story is a little bit different - we'll explore that some other time.


When False Means True

Posted by Charles Chen

I encountered an interesting problem while working with our FirstPoint Office add-in (one of the many joys of working with the Office API!).

In this case, a call to ActiveDocument.CanCheckIn() would return true, even when the value was clearly false. Testing in the VB macro editor in Word would return the correct value consistent and so would invoking the method from the Visual Studio command window.

In Word 2007, this API call seems to work just fine. However, in Word 2003, I had to use reflection to invoke the method to get a proper result:

Type type = _host.ActiveDocument.GetType();
MethodInfo m = type.GetMethod("CanCheckin");
object result = m.Invoke(_host.ActiveDocument, null);
canCheckInDocument = Convert.ToBoolean(result);

Filed under: Office No Comments

The Impending Death Of Microsoft Office

Posted by Charles Chen

Okay, maybe "death" is a bit severe.  But certainly, I think in the next few years (if not months), Office will start to lose marketshare...significantly.

Now don't get me wrong; I love Office (okay, not really, but I work with it on a daily basis and the whole product strategy for my group revolves around the Office client and server suite), but there are some severe usability issues which have, amazingly, to this day, been pretty much unresolved.

The crux of the shortcomings of Office (aside from interoperability pre-12) is really document sharing.

Today, in the Office world, if you want to share documents (either with yourself (i.e. work on a different machine) or others), you really only have a few options:

  1. You can access your desktop remotely using a remote desktop client.  This sucks for a variety of reasons including responsiveness and the require setup to enable a remote access scenario.  It may not even be possible due to corporate firewalls.
  2. Email the document to yourself and/or collaborators.  This is what most people do today, I would gather.  It's one of the most annoying things that I deal with because I end up with a folder with a bunch of documents title "Spec rev.1", "Spec rev.2" and so on.  Not to mention what the clusterfuck that happens if I modify the document and rename it with "rev.X" and another collaborator does the same.  It sucks...but even I've been known to do this.
  3. Copy the document to a physical medium and pass it around.  This includes CDs, USB drives, external drives, etc.  I do this quite often when I travel and I know I will need to prepare a document.  But it sucks.
  4. Use a corporate SharePoint site to share your document.  This is a great solution...if your company has a SharePoint site.  What if you're not a full Microsoft shop?  What if you work for a small company?  It also means you'll probably need VPN access, which is generally annoying.  For the record, I've been using Office personally and professionally for more than 10 years now and I've never shared a document using this method.
  5. Use Office Live!  This is a relatively new offering from Microsoft who finally realized "Hey, maybe the rest of the non-corporate world would also like to share documents in a non-shitty way!" However, what sucks about this is that you still need to have the Office client...we'll touch on this point in a bit.
  6. Use some sort of remote file share (FTP location, network file share, etc.).  This has various perils as well in addition to the inconvenience of having to have a VPN connection.

None of these options are really appealing, but until recently, there really wasn't a choice.  Regardless of what desktop processor you use, you're pretty much constrained to the same set of options (you can replace SharePoint with whatever web platform your client integrates with).

This sucks, for the reasons listed above, but it also sucks because it means that you have to lug around your laptop everywhere you go to work on documents.  It's the reason why you see business people scrunched up in coach, contorting their bodies and praying that the person in front doesn't put their seat back so they can fold out their laptop.  The desktop document processor client makes us all slaves.

But the future is coming.  For personal use, I don't think I'll ever author another Word document in Office ever again.  Both Google Docs and Zoho offer what I need so far as basic document processing goes and I have the added convenience of being able to easily share documents with others.  There's also the absolute coolness of being able to edit the same document in a live session with your collaborators.  This alone is not enough to change how we work with documents.  The iPhone and the impending release of Android (along with the next generatin of smart phones) will leave the Office stack in the dust.

Connectivity is ever increasing. With cheap, unlimited data plans now and non-neutered mobile browsers, instead of doing the stupid shit listed above, you can just connect to Google Docs or Zoho and edit your documents directly. You can share your documents without having to have a SharePoint deployment (good for small business and non-Microsoft solutions deployments). You can have access to your documents from anywhere where you have a cell or WiFi connection (which for most business people, is everywhere).

Why bust out your laptop on a crowded plane (unless you have the luxury of sitting in business class) to review or make small edits to a document when you can do it on your wifi connected phone? Why lug your laptop around when 90% of the functionality that you need for day to day business can be accomplished on a phone? Android and the next generation of smartphones will cause a big shift in document processor usage in time, IMO. Microsoft has to start thinking heavily about a web based Office suite (or purchasing Zoho) or else they'll start losing ground in their bread and butter application suite.

For the time being, both Zoho and Google Docs are missing some core bits (mostly around security, but also integration of more complex "compound content"), but for a good percentage of document processing needs, Office has become irrelevant (this is not to say that it won't take a really, really, really long time before Office loses market share to any web based processor).

Filed under: Office 1 Comment

VSTO Versus Extensibility

Posted by Charles Chen

As we're currently mulling a full transition to VS2008 and .NET 3.5, I've been investigating VSTO3 and ClickOnce once again.  My initial encounters with VSTO and ClickOnce were lacking.  With regards to VSTO, I didn't find anything that I could do with it that I couldn't do without it.  Indeed, it's more of an extension of the extensibility model which provides some under the cover plumbing than anything else.

The decision to attach ourselves to VSTO3 and ClickOnce is no light matter.  Luckily, Cindy Meister (Office MVP) and Mary Lee (Microsoft) were kind enough to weigh in on the matter over at the MSDN forums.

I think all Office developers should head over and take a look as it contains a wealth of information (and clarifies some common misunderstandings) with regards to VSTO and ClickOnce.

Filed under: Office No Comments

Office Developers: Take Note!

Posted by Charles Chen

Microsoft has a very powerful set of group policy administrative templates which allow administrators to set configuration options for Office globally for all users in the domain.  This makes many development scenarios much easier since it allows you to easily ensure consistency in terms of Office configuration instead of writing custom code to do it in your add-in.

You can download the templates from MSDN.

You can find more details about installing and using the templates here.

And in case you were curious, here's a screen cap:

This is a must explore set of tools when working with Office applications.

Filed under: Office No Comments