2010-12-06 24 views
5

我有一個WinForms應用程序,我正在使用Word Automation通過模板構建文檔,然後將它們保存到數據庫。在創建文檔後,我從數據庫檢索文檔,將其寫入臨時目錄中的文件系統,然後使用Word Interop服務打開文檔。Word Automation - 文件正在被其他應用程序或用戶使用

有一個加載的文檔列表,用戶只能打開每個文檔的一個實例,但可以同時打開多個不同的文檔。我沒有與打開,保存,和關閉任何問題,當他們打開1號文件,然而,當他們同時打開多個文檔,我關閉所有我的Word的實例時收到以下錯誤:

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. 

我使用下面的代碼來打開文檔和處理BeforeDocumentClosed事件:

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

有誰看到什麼問題,我做的,允許在同一時間多個文檔的開放?我對Word自動化和Word Interop服務相當陌生,所以有任何建議。謝謝。

+0

你直接在你的代碼打開鎖定的文件(C:\ ... \模板\的Normal.dotm),或者該自動訪問? 如果你是打開它的人,你可以創建一個副本或類似的東西,以避免鎖定,或嘗試只讀訪問它。 – 2010-12-06 14:02:06

回答

8

我發現通過這個MSDN文章的解決方案:http://support.microsoft.com/kb/285885

你需要調用Application.Quit之前做到這一點();

_wordApplication.NormalTemplate.Saved = true; 

這可以防止Word嘗試保存Normal.dotm模板。我希望這可以幫助別人。

+0

你應該接受你自己的答案,我知道這聽起來有點奇怪,但是這是正確的做法 – 2010-12-06 15:49:53

0

記住代碼:

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

會一直旋轉起來Word的一個新實例,即使已經有加載一個實例。

通常情況下,您最好檢查一個加載的實例(通過GETOBJECT)並在有的情況下使用它,如果需要的話只加一個新的實例。

2

我在C#doc2pdf應用程序中使用了Word。關閉文件之前,這樣設置保存選項:

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

我在我的應用程序幫助聯繫,並想打開一個特定的Word文檔到特定的書籤。如果文檔已經打開,則不應再打開它。如果Word已經打開,它不應該打開Word的新實例。

此代碼爲我工作:

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(); 
} 
相關問題