C# Open Word Documents using Visual Studio 2010 and .Net 4

Posted by OmegaMan at April 22, 2010

Category: Microsoft Office, Word

Tags: ,

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:

  1. Open and properly close a Word Document.
  2. Write to a Word document.
  3. Remove the Word document’s meta data.
  4. Properly close the Word Application and clean up resources opened by the underlying Office Interop calls.
  5. Properly cast method calls to specific interops to avoid “Ambiguity between method” issue CS0467 C# compiler warning.
  6. Why the developer no longer has to reference null when passing in optional parameters to COM objects thanks to .Net 4.

Steps

  1. In VS2010 create a Console Application.
  2. 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.  
  3. Insert the following usings:
    using Microsoft.Office.Interop.Word;
  4. Create an existing Word document. The example code below uses an existing document at C:\TestDoc.docx.
  5. 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.

Share

45 Comments

  1. […] here: C# Open Word Documents using Visual Studio 2010 and .Net 4 at … If you enjoyed this article please consider sharing […]

    Reply
  2. Emiliano Eloi Silva Barbosa says

    I can not open a document in a web application.

    Reply
    • OmegaMan says

      You are running into permission issues. Sites are not allowed to access local items on a PC for virus reasons.

      Reply
  3. hermione7 says

    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: 0x80040154 (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.

    Reply
    • OmegaMan says

      Did you pull in Office v14 or v12?

      Reply
  4. hermione7 says

    Thats the thing the COM tab has only v11 not 12 not 14

    Reply
    • OmegaMan says

      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.

      Reply
  5. hermione7 says

    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)]

    Reply
    • OmegaMan says

      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

      Reply
  6. Roschi says

    Hello

    How can I open a wordfile and save it as PDF (ExportAsFixedFormat) from a Service?

    Reply
    • OmegaMan says

      This is out of the scope of this article. I recommend you post it to the Visual C# forum on MSDN GL

      Reply
  7. Mark says

    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.)

    Reply
    • OmegaMan says

      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

      Reply
  8. Manoj Pandey says

    I need code of console application in c# that read Word file

    Reply
  9. Tatiana says

    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”)

    Reply
  10. Michael Sevestre says

    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.

    Reply
  11. adrian says

    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.

    Reply
    • OmegaMan says

      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

      Reply
  12. soula says

    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..

    Reply
  13. rao says

    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

    Reply
  14. jungie says

    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”

    Reply
  15. Rhonda says

    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();

    Reply
  16. Rhonda says

    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:

    object oMissing = System.Reflection.Missing.Value;
    object oTrue = true;
    object oFalse = false;
    object sTempTextFile = @”C:\Doc_Vitals\Doc_VitalsText.txt”;
    object FileFormat = Microsoft.Office.Interop.Word.WdSaveFormat.wdFormatUnicodeText;
    
    Microsoft.Office.Interop.Word.Application ap = new Microsoft.Office.Interop.Word.Application();
    ap.Visible = false;
    
    Document doc = ap.Documents.Open(sFileName,
    ref oFalse, ref oTrue, ref oFalse,
    ref oMissing, ref oMissing, ref oMissing, ref oMissing,
    ref oMissing, ref oMissing, ref oMissing, ref oFalse,
    ref oMissing, ref oMissing, ref oMissing, ref oMissing);
    
    doc.Activate();
    doc.SaveAs(ref sTempTextFile, ref FileFormat);
    ap.Quit(ref oMissing, ref oMissing, ref oMissing);
    
    
    Reply
    • OmegaMan says

      Thanks Rhonda for taking the time to show us your solution!

      Reply
  17. Fellipe Vieira says

    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 ?

    Reply
    • OmegaMan says

      To my knowledge no, that is a whole new product from Microsoft to use Office online.

      Reply
  18. Joe says

    Felipe – yes, it’s called SharePoint.

    Reply
  19. Nicky says

    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…

    Reply
    • OmegaMan says

      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.

      Reply
  20. Skeewe says

    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

    Reply
  21. Amardeep says

    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

    Reply
  22. Andrew says

    “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.

    Reply
  23. Andrew says

    “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.

    Reply
  24. Andrew says

    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();

    Reply
  25. basu says

    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?

    Reply
  26. Adiposa says

    on using this code I get the following error message in line 6;

    This file could not be found.
    (C:\Users\…\Weekdays\Monday)

    Reply
  27. Praveen says

    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

    Reply
  28. San says

    How do i create a new document from a template?

    Reply
  29. Wayne Russell says

    Hi,
    Great article, the finally clause was very useful to know.

    Wayne

    Reply
  30. ishu says

    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.?

    Reply
  31. Leek Nike says

    Using office automation cannot recommand to open Word Documents in ASP.NET. I meet same problem, recommand to use Spire.Doc.

    Reply
  32. Sbandara says

    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?

    Reply
  33. Shilpa says

    How can I access Docx File AutoText in C# 2010 Code

    Reply
  34. Ferdinand says

    Hi,

    How can I open the Word document while preventing any macros from starting?

    Reply
  35. thanhquan says

    Hello everybody!
    i were read word file in C# using Microsoft.Office.Interop.Word
    but this file also opened by office. i dont want.
    What I do?
    Thank you.

    Reply

Leave a comment

(required)
(required) (will not be published)

This site uses Akismet to reduce spam. Learn how your comment data is processed.