MissingManifestResourceException when using Portable Class Libraries within WinRT
Our team recently ran into a strange issue. Our Windows Phone application targets Silverlight 8.1 but we have several WinRT 8.1 based background tasks. Recen...
I like VSTO. I like C#. What I don’t like is having to write VSTO code in C# like:
object fileName = "Test.docx";
object missing = System.Reflection.Missing.Value;
doc.SaveAs(ref fileName, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing);
This code creates a copy of a Word document, but it’s not very elegant. The SaveAs()
method accepts a long list of arguments to tweak the way the file is copied. For a simple copy, however, only the first argument–the new file name–is needed. So why am I stuck passing this “missing” value for each and every omitted argument? The definition of the SaveAs method on the Word Document COM interface defines each argument as optional (see below). This would seem to allow callers to omit the irrelevant arguments. VB developers wouldn’t give this another thought.
HRESULT SaveAs(
[in, optional] VARIANT* FileName,
[in, optional] VARIANT* FileFormat,
[in, optional] VARIANT* LockComments,
[in, optional] VARIANT* Password,
[in, optional] VARIANT* AddToRecentFiles,
[in, optional] VARIANT* WritePassword,
[in, optional] VARIANT* ReadOnlyRecommended,
[in, optional] VARIANT* EmbedTrueTypeFonts,
[in, optional] VARIANT* SaveNativePictureFormat,
[in, optional] VARIANT* SaveFormsData,
[in, optional] VARIANT* SaveAsAOCELetter,
[in, optional] VARIANT* Encoding,
[in, optional] VARIANT* InsertLineBreaks,
[in, optional] VARIANT* AllowSubstitution,
[in, optional] VARIANT* LineEnding,
[in, optional] VARIANT* AddBiDiMask);
Unfortunately, the C# language and compiler do not comprehend optional arguments. What’s worse, unlike the rest of the Office object model, Word interfaces use VARIANT*
instead of VARIANT
. That is, they are passed by reference rather than by value. This means that, not only does the C# developer have to pass a value for each and every argument, he or she must do so by reference. That means creating an extra object on the stack and then passing it to the method using the ref
keyword. How tedious! And it gets even worse; because the values are all passed using objects, we’ve now lost all of the compile-time advantages of the strongly-typed C# language. How easy would it be to accidentally swap the order of the arguments?
In a perfect world, a simple copy of the document could be created like this:
doc.SaveAs("Test.docx");
The method would take a strongly-typed string argument by value. And if I wanted to change the format of the newly-saved document, I could write the following:
doc.SaveAs("Test.html", WdSaveFormat.wdFormatHTML);
This method would take the same string argument and another strongly-typed format specifier. We could imagine a series of method overloads that incrementally add to the argument list. But what if I need to specify a disjoint set of arguments? Why can’t I simply write:
doc.SaveAs(new DocumentSaveAsArgs
{
FileName = "Test.docx",
AddBiDiMarks = false
});
The method would take an instance of an arguments class where I could set–using the fancy new C# 3.0 object initializer syntax–only the properties necessary. Furthermore, all the properties would be strongly-typed so that any accidentally swapped arguments could be caught at compile-time and not after the application has been deployed to thousands of clients.
Am I just dreaming? Must I be content with typing ref
over and over again for as long as I develop Office applications? Must I leave my beloved C# for the seductive VB? The answer is a resounding NO! The VSTO Power Tools announced at this week’s Office Developer Conference are expected to be released in the very near future. One of those tools is the Office Interop API Extensions, a set of libraries that extend the Office object model and provide a more elegant and consistent API for the C# developer. The three examples above are all possible using the Word extensions shipped as part of this tool. Furthermore, many other interfaces* from across the Office object model have been extended in a similar manner in order to make the lives of C# developers easier. Keep an eye out for this tool and use it to banish Missing.Value
(and its close cousin Type.Missing
) from your C# Office applications.
*In this initial release, most of the extension work was focused on Word and Excel. The Outlook extensions had an entirely different focus which I’ll discuss in a later post.
This post was migrated from my MSDN blog, Visual Studio Tools and Anything Else I Can Think Of, and written as a Microsoft employee.
Our team recently ran into a strange issue. Our Windows Phone application targets Silverlight 8.1 but we have several WinRT 8.1 based background tasks. Recen...
In a previous post I introduced the concept of Role Content Folders and how they can be used to deploy additional content (e.g. configuration files, runtime ...
The latest versions of the Windows Azure Tools for Visual Studio have the ability to maintain multiple versions of the Service Configuration (.cscfg) file.&n...
When a package fails to deploy to Windows Azure (or deploys but its roles fail to start properly) it can be difficult to determine what went wrong. In many c...
Windows Azure applications often need to package and deploy additional content. This could be advanced configuration files such as the diagnostics.wadcfg for...
The LINQ-to-DASL provider of the Office Interop API Extensions provides a very limited set of mappings between its query types and their associated DASL prop...
When your LINQ-to-DASL queries do not return the results you expect, how do you determine where the problem is? The issue could be that the query simpl...
I received an email over the weekend asking why the following LINQ to DASL query threw an exception: Outlook.Folder folder = (Outlook.Folder)Application.Se...
Now that the Office Interop API Extensions have been released, I thought I would post a complete walkthrough of a simple LINQ to DASL application. Let's star...
One of the disadvantages of C# compared with VB is its lack of support for parameterized properties. Instead, parameterized properties in C# are exposed as ...
As announced in Andrew Whitechapel’s post, version 1.0 of the VSTO Power Tools have been released! One of those tools is the Office Interop API Extensions, a...
In an earlier post I discussed LINQ to DASL, part of the Office Interop API Extensions, which is one of the forthcoming VSTO Power Tools. LINQ to DASL ...
In my last post I talked about LINQ to DASL, a LINQ provider that converts query expressions into their DASL equivalent in order to efficiently filter item c...
Quick, tell me what the following code does:
I like VSTO. I like C#. What I don’t like is having to write VSTO code in C# like:
Yesterday I gave a presentation on VSTO at the third annual Portland Code Camp. I demonstrated an Outlook 2007 add-in that used Outlook Form Regions, WCF, an...