With VS2010 and .Net 4, working with the office interops has become a lot easier. This article gives a step by step view of how to open a word document without needing the tools of Visual Studio Tools for Office (VSTO). *
The following topics are demonstrated:
- Open and properly close a Word Document.
- Write to a Word document.
- Remove the Word document’s meta data.
- Properly close the Word Application and clean up resources opened by the underlying Office Interop calls.
- Properly cast method calls to specific interops to avoid “Ambiguity between method” issue CS0467 C# compiler warning.
- Why the developer no longer has to reference null when passing in optional parameters to COM objects thanks to .Net 4.
Steps
- In VS2010 create a Console Application.
- In the Solutions Explorer right click on the References folder and select Add Reference. In the .Net tab search for
Microsoft.Office.Interop.Word.
Note you can use version 12 or version 14; but you might as well use the latest 14. - Insert the following usings:
using Microsoft.Office.Interop.Word;
- Create an existing Word document. The example code below uses an existing document at C:\TestDoc.docx.
- Insert this code:
Application ap = new Application(); try { Document doc = ap.Documents.Open( @"C:\TestDoc.docx", ReadOnly: false, Visible: false ); doc.Activate(); Selection sel = ap.Selection; if ( sel != null ) { switch ( sel.Type ) { case WdSelectionType.wdSelectionIP: sel.TypeText( DateTime.Now.ToString() ); sel.TypeParagraph(); break; default: Console.WriteLine( "Selection type not handled; no writing done" ); break; } // Remove all meta data. doc.RemoveDocumentInformation( WdRemoveDocInfoType.wdRDIAll ); ap.Documents.Save( NoPrompt: true, OriginalFormat: true ); } else { Console.WriteLine( "Unable to acquire Selection...no writing to document done.." ); } ap.Documents.Close( SaveChanges: false, OriginalFormat: false, RouteDocument: false ); } catch ( Exception ex ) { Console.WriteLine( "Exception Caught: " + ex.Message ); // Could be that the document is already open (/) or Word is in Memory(?) } finally { // Ambiguity between method 'Microsoft.Office.Interop.Word._Application.Quit(ref object, ref object, ref object)' and non-method 'Microsoft.Office.Interop.Word.ApplicationEvents4_Event.Quit'. Using method group. // ap.Quit( SaveChanges: false, OriginalFormat: false, RouteDocument: false ); ( (_Application)ap ).Quit( SaveChanges: false, OriginalFormat: false, RouteDocument: false ); System.Runtime.InteropServices.Marshal.ReleaseComObject( ap ); }
Explanation
- Line 1: Open Word application object found in the Microsoft.Office.Interop.Word namespace.
- Line 6: Open up the Word document we are interested in. This is first instance of using named parameters in calling the underlying COM functionality.
- Line 7: Activate makes sure our document has focus in the event that Word is already open.
- Line 9-17: This code is a template to working with a selection and its type. Word distinguishes areas of interest by selections. Our selection is at the beginning of the document. When we get the selection we write the current date and time (line 16).
- Line 27: Remove all of the meta data of the document. This is not required for writing, just as an added bonus of how-to.
- Line 29: Save what we have done.
- Line 37: Close the document.
- Line 48: In line 47 if we call without the cast we get the ambiguity warning message from the compiler. By casting to the Application interface we avoid that warning.
- Line 50: Release any COM handles or resources we may have inadvertently gotten in this process.
* For the record VSTO is only needed when we are creating a smart document or an addin to one of the office applications. This is pure interop programming and not VSTO.
Pingback: C# Open Word Documents using Visual Studio 2010 and .Net 4 at … | Source code bank
#1 by Emiliano Eloi Silva Barbosa on May 27, 2010 - 6:17 pm
Quote
I can not open a document in a web application.
#2 by OmegaMan on May 27, 2010 - 7:03 pm
Quote
You are running into permission issues. Sites are not allowed to access local items on a PC for virus reasons.
#3 by hermione7 on June 25, 2010 - 7:49 pm
Quote
hi,
I have Microsoft office 2010 (beta) and visual studio 2010 (ultimate). I did the steps that u put up, but I got an exception.
An unhandled exception of type ‘System.Runtime.InteropServices.COMException’ occurred in mscorlib.dll
Additional information: Retrieving the COM class factory for component with CLSID {000209FF-0000-0000-C000-000000000046} failed due to the following error: 80040154 Class not registered (Exception from HRESULT: 0×80040154 (REGDB_E_CLASSNOTREG)).
Could you help me here?
I have been trying to simply open a word file(2010) from VS 2010 but I havent been successful as yet.
#4 by OmegaMan on June 26, 2010 - 8:28 am
Quote
Did you pull in Office v14 or v12?
#5 by hermione7 on June 26, 2010 - 4:39 pm
Quote
Thats the thing the COM tab has only v11 not 12 not 14
#6 by OmegaMan on June 26, 2010 - 5:33 pm
Quote
Hmmm, something is up with the beta. As mentioned in the software, this one is for v12 or v14. Try getting a non-beta copy. Sorry.
#7 by hermione7 on June 26, 2010 - 7:15 pm
Quote
I check in another laptop, the .Net tab has both Microsoft.Office.Interop.Word v12 and v14. I added v14 and tried again. But still I get the same error. Do u still think this is because of Word being beta? [This laptop also has VS2010 and Word 2010(beta)]
#8 by OmegaMan on June 26, 2010 - 8:02 pm
Quote
Hard to say…when I wrote the article both versions v14/12 where shown. It is possible that the interop work was not done for the beta you have(?). Firstly I recommend you get a current trial version or a licensed version. Otherwise try posting this question to TechnetInterop Development. GL HTH
#9 by Roschi on June 29, 2010 - 7:26 am
Quote
Hello
How can I open a wordfile and save it as PDF (ExportAsFixedFormat) from a Service?
#10 by OmegaMan on June 29, 2010 - 3:43 pm
Quote
This is out of the scope of this article. I recommend you post it to the Visual C# forum on MSDN GL
#11 by Mark on August 6, 2010 - 6:14 am
Quote
I like this article but would like to see more. How do write C# data to a new word document and format the data (bullets, fonts, etc.)
#12 by OmegaMan on August 8, 2010 - 9:04 pm
Quote
As I discuss here on my blog entitled, Tribal Knowledge: Working with Office Interops, one way to divine the inner workings of any office document and how to manage it via the interops is to record a macro of the process needed. Once done examine the vba code, it will show settings changes and other items of interest that can lead the way through the tribal knowledge of the interops. Most the object calls are the same under the covers…good luck
#13 by Manoj Pandey on August 28, 2010 - 1:04 am
Quote
I need code of console application in c# that read Word file
#14 by Tatiana on August 31, 2010 - 3:05 am
Quote
How can I subscribe to event of Word document starting?
In the Word 2003 I did it by assembly:System.ComponentModel.DescriptionAttribute(“OfficeStartupClass, Version=1.0, Class=ClassLibrary1.OfficeCodeBehind”)
#15 by Michael Sevestre on October 7, 2010 - 6:58 am
Quote
Line 50: “Release any COM handles or resources we may have inadvertently gotten in this process.” disturbs me a little.
Should not you release any handles created to COM Objects, even implicitly?
In your example, doc and sel? Or has this issue been corrected with .NET4? In the version 3.5 of the framework you would definitely get some memory leaks.
#16 by adrian on December 30, 2010 - 9:33 am
Quote
I am using (in a similar fashio to your example)
Document doc = ap.Documents.Open(report, ReadOnly: false, Visible: false);
It works fine on Windows 7 development environment, but not on the live server (server2008).
It just returns null, no indication of why.
I have ensured all IIS users have permissions for the files and directories, all application pools are set correctly, .NET v4 is installed, I have run Word as the user (impersonated) and have now run out of ideas
Any further suggestions would be very helpful.
#17 by OmegaMan on December 31, 2010 - 2:37 pm
Quote
If I am reading you right, this is a web site. The user has logged in and his/her credentials are burned and is running as the IIS process as specified in the thread pool. I surmise that service/user does not have the privlidges needed to do what you want to do. HTH
#18 by soula on January 26, 2011 - 11:28 pm
Quote
hello, i tried to do the same method in v9 but it didn’t work, is there any possible way for it to work?..or should i get the newer version?…thanks..
#19 by rao on February 21, 2011 - 11:32 am
Quote
I try to open a word file in console application but when i run project it open a document and raise exception could you help me
#20 by jungie on March 20, 2011 - 6:39 pm
Quote
i’ve tried your code.. but i got some errors like this: “Application is an ambiguous reference bwtween System.Windows.Forms.Applicatio and Microsoft.Office.Interop.Word.Application”
#21 by Rhonda on April 8, 2011 - 1:11 pm
Quote
Is there a way to do this without MS Word appearing on the User’s desktop. When I Open the document I set Visible to false. But when I Close, Word pops open.
object missing = System.Reflection.Missing.Value;
object sTempTextFile = @”C:\Doc_Vitals\Doc_VitalsText.txt”;
object FileFormat = Microsoft.Office.Interop.Word.WdSaveFormat.wdFormatEncodedText;
Microsoft.Office.Interop.Word.Application ap = new Microsoft.Office.Interop.Word.Application();
Document doc = ap.Documents.Open(sFileName, false, true, false, missing, missing, missing, missing,
missing, missing, missing, false, missing, missing, missing, missing);
doc.Activate();
doc.SaveAs(ref sTempTextFile, ref FileFormat);
ap.Documents.Close();
#22 by Rhonda on April 12, 2011 - 11:31 am
Quote
I found the solution to my problem with Word opening when I use Documents.Close(). Obviously, don’t use Documents.Close(). Here’s my new working code:
#23 by OmegaMan on April 14, 2011 - 10:21 am
Quote
Thanks Rhonda for taking the time to show us your solution!
#24 by Fellipe Vieira on April 14, 2011 - 8:51 am
Quote
Hi,
Is there a way to open a word document in a web application for users edit, and after the user close the document those changes to be reflected in the database ?
#25 by OmegaMan on April 14, 2011 - 10:20 am
Quote
To my knowledge no, that is a whole new product from Microsoft to use Office online.
#26 by Joe on April 28, 2011 - 11:16 am
Quote
Felipe – yes, it’s called SharePoint.
#27 by Nicky on May 27, 2011 - 1:27 pm
Quote
Hi,
I have some WORD templates where in I need to fill with data returned from my sql into the Word tables using Interop.Word. I am able to generate the document on my local machine using my code, but failing to generate one on the deployed server. I get this error: “Retrieving the COM class factory for component with CLSID {000209FF-0000-0000-C000-000000000046} failed due to the following error: 80070005 Access is denied.”
Please suggest in this regards.
BTW, I am using VS 2010 and C#.
Thanks in advance…
#28 by OmegaMan on May 28, 2011 - 2:34 pm
Quote
Since you say server it makes me think that this is running in a hosted asp.net web site? If so I surmise that the Application Pool identity does not have access to the required interops and is failing. In general I try to avoid running the interops on a Server! I suggest you hit the forums for this question for I cannot answer this one. Sorry.
#29 by Skeewe on July 5, 2011 - 5:02 am
Quote
I have a problem in first line:
when:
Application ap = new Application();
Error 1: ‘Application’ is an ambiguous reference between ‘System.Windows.Forms.Application’ and ‘Microsoft.Office.Interop.Word.Application’
when:
System.Windows.Forms.Application ap = new System.Windows.Forms.Application();
Error : The type ‘System.Windows.Forms.Application’ has no constructors defined
Thanks
#30 by Amardeep on September 18, 2011 - 10:50 am
Quote
Hey why i am getting this error..i am using visual studio2008 and .net framework 3.5..please help me…
Error 1 The type or namespace name ‘Office’ does not exist in the namespace ‘Microsoft’ (are you missing an assembly reference?) F:\C# working\ConsoleApplication1\ConsoleApplication1\program.cs 7 17 ConsoleApplication1
#31 by Andrew on October 17, 2011 - 9:13 am
Quote
“Hi,
I have some WORD templates where in I need to fill with data returned from my sql into the Word tables using Interop.Word. I am able to generate the document on my local machine using my code, but failing to generate one on the deployed server. I get this error: “Retrieving the COM class factory for component with CLSID {000209FF-0000-0000-C000-000000000046} failed due to the following error: 80070005 Access is denied.”
Please suggest in this regards.
BTW, I am using VS 2010 and C#.
Thanks in advance…”
Go to Start -> Control Panel -> Administrative Tools -> Computer Management -> ‘local users & groups’ -> Users -> Select the ASP.NET user account and make him a member of administrators …
This will likely fix your problem with the permissions, BUT its not very secure as now your ASP.net account has administrator rights.
#32 by Andrew on October 17, 2011 - 9:16 am
Quote
“Hey why i am getting this error..i am using visual studio2008 and .net framework 3.5..please help me…
Error 1 The type or namespace name ‘Office’ does not exist in the namespace ‘Microsoft’ (are you missing an assembly reference?) F:\C# working\ConsoleApplication1\ConsoleApplication1\program.cs 7 17 ConsoleApplication1″
You must reference the com object, in your csharp project,
right click references
Add Reference
Click the ‘COM’ tab
find Microsoft Office 12.0 Object library
and add that to your project.
#33 by Andrew on October 17, 2011 - 9:18 am
Quote
I have a problem in first line:
when:
Application ap = new Application();
“Error 1: ‘Application’ is an ambiguous reference between ‘System.Windows.Forms.Application’ and ‘Microsoft.Office.Interop.Word.Application’
when:
System.Windows.Forms.Application ap = new System.Windows.Forms.Application();
Error : The type ‘System.Windows.Forms.Application’ has no constructors defined
Thanks”
use Microsoft.Office.Interop.Word.Application’ instead
Microsoft.Office.Interop.Word.Application ap = new Microsoft.Office.Interop.Word.Application();
#34 by basu on February 17, 2012 - 9:21 pm
Quote
When i use the code, i am getting “object reference set to instance” error at word doc.open line. the value is being set to null over there…
anything wrong here?
#35 by Adiposa on March 13, 2012 - 4:41 am
Quote
on using this code I get the following error message in line 6;
This file could not be found.
(C:\Users\…\Weekdays\Monday)
#36 by Praveen on April 9, 2012 - 12:50 am
Quote
Hi,
I’m using following code to save a Word 2010 template and simultaneously make it visible to user. Following code is working as expected in case of word 2003 and word 2007 on other machines but my machine has Office 2010 and it saves template document but does not make it visible.
My Concern is how to make template document visible in case of Office 2010 installed. Please help me solve this problem.
Dim oWord As Word.Application
Dim oDoc As Word.Document
Dim DocNoParam As Object = Type.Missing
Dim SaveToFormat As Object = Microsoft.Office.Interop.Word.WdSaveFormat.wdFormatDocument
Dim DirectoryPath As String = Server.MapPath(“~/Temp/”)
oWord = CType(CreateObject(“Word.Application”), Word.Application)
oDoc = oWord.Documents.Add(Server.MapPath(hdnPhysicalPath.Value))
documentMapperDTOList.ForEach(Function(k)
oDoc.Bookmarks(k.BookMarkName).Range.Text = customerDetails.GetType().GetProperty(k.ObjectPropertyName_FK).GetValue(customerDetails, Nothing)
End Function)
Dim fileName As String = “CaseInfo_” & txtCaseNumber.Text & “_” & DateTime.Now.ToString().Replace(“\”, String.Empty).Replace(“/”, String.Empty).Replace(“-”, String.Empty).Replace(“:”, String.Empty).Replace(” “, String.Empty)
” Checking whether directory exists with Case Number and Save Template Document in Physical system
Dim directory As New System.IO.DirectoryInfo(DirectoryPath)
If Not directory.Exists Then
directory.CreateSubdirectory(“Temp”)
End If
oDoc.SaveAs(Path.Combine(DirectoryPath, fileName), SaveToFormat, DocNoParam, DocNoParam, DocNoParam, DocNoParam, _
DocNoParam, DocNoParam, DocNoParam, DocNoParam, DocNoParam, DocNoParam, _
DocNoParam, DocNoParam, DocNoParam, DocNoParam)
Dim fileInfo As FileInfo = directory.GetFiles().Where(Function(k) k.Name.Equals(fileName & “.doc”)).FirstOrDefault()
oWord.Visible = True
#37 by San on May 20, 2012 - 10:28 am
Quote
How do i create a new document from a template?
#38 by Wayne Russell on May 31, 2012 - 1:07 am
Quote
Hi,
Great article, the finally clause was very useful to know.
Wayne
#39 by ishu on June 12, 2012 - 3:50 am
Quote
I want to know the difference between a class object and a string. Though both are reference type then, why there is a difference in the result when they are assigned.?
#40 by Leek Nike on July 23, 2012 - 10:00 pm
Quote
Using office automation cannot recommand to open Word Documents in ASP.NET. I meet same problem, recommand to use Spire.Doc.
#41 by Sbandara on August 29, 2012 - 12:59 pm
Quote
when i debug above coding give errors wherever the ‘Application’ appears saying that ambiguity between
using System.Windows.Forms.Application; and
using Microsoft.Office.Interop.Word;
could you help me to solve this?
#42 by Shilpa on April 23, 2013 - 12:31 am
Quote
How can I access Docx File AutoText in C# 2010 Code