Word Automation - File in use by another application or user

I have a WinForms application where I use Word Automation to create documents through a template and then save them to a database. After creating the document, I extract the document from the database, write it to the file system in the temporary directory, and then open the document using Word Interop services.

There is a list of downloaded documents, and the user can open only one copy of each document, but can simultaneously open several different documents. I have no problem opening, saving and closing when they open one document, however, when they open several documents at the same time, I get the following error when closing any of my Word instances:

The file is in use by another application or user. (C:\...\Templates\Normal.dotm) This error is commonly encountered when a read lock is set on the file that you are attempting to open. 

I use the following code to open a document and handle the BeforeDocumentClosed event:

 public void OpenDocument(string filePath, Protocol protocol, string docTitle, byte[] document) { _protocol = protocol; documentTitle = docTitle; _path = filePath; if (!_wordDocuments.ContainsKey(_path)) { FileUtility.WriteToFileSystem(filePath, document); Word.Application wordApplication = new Word.Application(); wordApplication.DocumentBeforeClose += WordApplicationDocumentBeforeClose; wordApplication.Documents.Open(_path); _wordDocuments.Add(_path, wordApplication); } _wordApplication = _wordDocuments[_path]; _currentWordDocument = _wordApplication.ActiveDocument; ShowWordApplication(); } public void ShowWordApplication() { if (_wordApplication != null) { _wordApplication.Visible = true; _wordApplication.Activate(); _wordApplication.ActiveWindow.SetFocus(); } } private void WordApplicationDocumentBeforeClose(Document doc, ref bool cancel) { if (!_currentWordDocument.Saved) { DialogResult dr = MessageHandler.ShowConfirmationYnc(String.Format(Strings.DocumentNotSavedMsg, _documentTitle), Strings.DocumentNotSavedCaption); switch (dr) { case DialogResult.Yes: SaveDocument(_path); break; case DialogResult.Cancel: cancel = true; return; } } try { if (_currentWordDocument != null) _currentWordDocument.Close(); } finally { Cleanup(); } } public void Cleanup() { if (_currentWordDocument != null) while(Marshal.ReleaseComObject(_currentWordDocument) > 0); if (_wordApplication != null) { _wordApplication.Quit(); while (Marshal.ReleaseComObject(_wordApplication) > 0); _wordDocuments.Remove(_path); } } 

Does anyone see something wrong that I am doing to open multiple documents at the same time? I am new to Word Automation and Word Interop services, so any advice is appreciated. Thanks.

+6
c # ms-word winforms word-automation
source share
4 answers

I found a solution through this MSDN article: http://support.microsoft.com/kb/285885

You need to do this before calling Application.Quit ();

 _wordApplication.NormalTemplate.Saved = true; 

This prevents Word from trying to save the Normal.dotm template. Hope this helps someone else.

+9
source share

I used Word in a C # doc2pdf application. Before closing the document, set the save option as follows:

 object saveOption = Microsoft.Office.Interop.Word.WdSaveOptions.wdDoNotSaveChanges; oDoc.Close(ref saveOption, ref oMissing, ref oMissing); oWord.Quit(ref saveOption, ref oMissing, ref oMissing); 
+2
source share

I have help links in my application and you want to open a specific doc document for a specific bookmark. If the document is already open, it should not open it again. If Word is already open, it should not open a new instance of Word.

This code worked for me:

 object filename = @"C:\Documents and Settings\blah\My Documents\chapters.docx"; object confirmConversions = false; object readOnly = true; object visible = true; object missing = Type.Missing; Application wordApp; object word; try { word = System.Runtime.InteropServices.Marshal.GetActiveObject("Word.Application"); } catch (COMException) { Type type = Type.GetTypeFromProgID("Word.Application"); word = System.Activator.CreateInstance(type); } wordApp = (Application) word; wordApp.Visible = true; Console.WriteLine("There are {0} documents open.", wordApp.Documents.Count); var wordDoc = wordApp.Documents.Open(ref filename, ref confirmConversions, ref readOnly, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref visible, ref missing, ref missing, ref missing, ref missing); wordApp.Activate(); object bookmarkName = "Chapter2"; if (wordDoc.Bookmarks.Exists(bookmarkName.ToString())) { var bookmark = wordDoc.Bookmarks.get_Item(bookmarkName); bookmark.Select(); } 
+1
source share

Keep in mind that the code is:

 Word.Application wordApplication = new Word.Application(); 

will always create a new instance of Word, even if it is already loaded.

Generally, you better check the loaded instance (via GETOBJECT) and use it if you have one, and only deploy a new instance if you need to.

0
source share

All Articles