user3165438
user3165438

Reputation: 2661

Could not load Microsoft.Office.Interop.Word

I develop a dll which uses Microsoft.Office.Interop.Word reference version 14. Word version installed on my machine is 2010.

When I install my dll on other machines which have Word 2007 or 2003 version, I get the following error:

  Could not load file or assembly 'Microsoft.Office.Interop.Word version=14.0.0

I found here that setting 'Embed Interop Types' reference to 'True' could solve the problem, but when I do so, an error is occures when I use Microsoft.Office.Interop.Word.ApplicationClass in the code;

Interop type 'Microsoft.Office.Interop.Word.ApplicationClass' cannot be embedded   

Any ideas what should I do in order to install the dll on machines with previous Word version?

Upvotes: 1

Views: 1470

Answers (1)

Sinatr
Sinatr

Reputation: 22052

I'll give here a working example of using late binding with word. It was made some time ago and probably worth to be rewritten with dynamic:

            // try to open word
            Type typeWordApplication = Type.GetTypeFromProgID("Word.Application");
            if (typeWordApplication == null)
                throw new Exception("Word is not installed (Word.Application is not found)");
            object objWordApplication = Activator.CreateInstance(typeWordApplication);
            object objDocuments = objWordApplication.GetType().InvokeMember("Documents", BindingFlags.GetProperty, null, objWordApplication, null);
            object[] param = new object[] { Missing.Value, Missing.Value, Missing.Value, Missing.Value };
            object objDocument = objDocuments.GetType().InvokeMember("Add", BindingFlags.InvokeMethod, null, objDocuments, param);
            object start = 0;
            object end = 0;
            object objRange = objDocument.GetType().InvokeMember("Range", BindingFlags.InvokeMethod, null, objDocument, new object[] { start, end });
            // set text
            objRange.GetType().InvokeMember("Text", BindingFlags.SetProperty, null, objRange, new object[] { text });
            // set font
            object objFont = objRange.GetType().InvokeMember("Font", BindingFlags.GetProperty, null, objRange, null);
            objFont.GetType().InvokeMember("Name", BindingFlags.SetProperty, null, objFont, new object[] { "Courier" });
            objFont.GetType().InvokeMember("Size", BindingFlags.SetProperty, null, objFont, new object[] { (float)8 });
            start = objRange.GetType().InvokeMember("End", BindingFlags.GetProperty, null, objRange, null);
            end = start;
            objRange = objDocument.GetType().InvokeMember("Range", BindingFlags.InvokeMethod, null, objDocument, new object[] { start, end });
            // select text
            objRange.GetType().InvokeMember("Select", BindingFlags.InvokeMethod, null, objRange, null);
            objWordApplication.GetType().InvokeMember("Visible", BindingFlags.SetProperty, null, objWordApplication, new object[] { true });
            Marshal.ReleaseComObject(objWordApplication);

Advantages of it:

  • you don't need to reference or distribute anything (if GetTypeFromProgID fails - you just ask user to install something).
  • it will more likely works with any version of installed application, because many supports backward compatibility.

Disadvantages:

  • no intellisense, you will have to browse yourself documentation and class object, figure out unobvious things, get experience, etc.
  • very bulky code (unless dynamic is used);

Upvotes: 1

Related Questions