2010-12-06 7 views
5

मेरे पास WinForms एप्लिकेशन है जहां मैं टेम्पलेट के माध्यम से दस्तावेज़ बनाने के लिए वर्ड ऑटोमेशन का उपयोग कर रहा हूं, और फिर उन्हें डेटाबेस में सहेजता हूं। दस्तावेज़ बनने के बाद, मैं डेटाबेस से दस्तावेज़ पुनर्प्राप्त करता हूं, इसे एक फ़ाइल निर्देशिका में फ़ाइल सिस्टम में लिखता हूं, और फिर Word Interop सेवाओं का उपयोग कर दस्तावेज़ खोलता हूं।वर्ड ऑटोमेशन - फ़ाइल किसी अन्य एप्लिकेशन या उपयोगकर्ता द्वारा उपयोग की जा रही है

लोड किए गए दस्तावेज़ों की एक सूची है और उपयोगकर्ता प्रत्येक दस्तावेज़ का केवल 1 उदाहरण खोल सकता है, लेकिन एक साथ कई अलग-अलग दस्तावेज़ खोल सकता है। मैं खोलने, बचत, और समापन के साथ कोई समस्या नहीं है, जब वे खोलने 1 दस्तावेज़, तथापि, जब वे एक से अधिक दस्तावेज़ एक साथ खोलने के लिए, मैं निम्नलिखित त्रुटि जब पद के अपने उदाहरणों में से किसी को बंद मिलता है:

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. 

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

किसी को भी कुछ भी गलत है कि मैं एक ही समय में एक से अधिक दस्तावेज़ के उद्घाटन अनुमति देने के लिए कर रहा हूँ देखना है: मैं दस्तावेज़ को खोलने और BeforeDocumentClosed घटना को संभालने के लिए निम्नलिखित कोड का उपयोग कर रहा हूँ? मैं वर्ड ऑटोमेशन और वर्ड इंटरऑप सेवाओं के लिए बिल्कुल नया हूं, इसलिए किसी भी सलाह की सराहना की जाती है। धन्यवाद।

+0

आप सीधे अपने कोड में बंद फ़ाइल को खोलने करें (C: \ ... \ टेम्पलेट्स \ Normal.dotm) या यह स्वचालित रूप से एक्सेस किया जाता है? यदि आप इसे खोलने वाले हैं, तो आप लॉकिंग से बचने के लिए एक प्रतिलिपि या ऐसा कुछ बना सकते हैं, या इसे पढ़ने की कोशिश कर सकते हैं। –

उत्तर

8

मैं इस MSDN लेख के माध्यम से समाधान नहीं मिला: http://support.microsoft.com/kb/285885

आप Application.Quit कॉल करने से पहले यह करने के लिए() की जरूरत है;

_wordApplication.NormalTemplate.Saved = true; 

यह Word को Normal.dotm टेम्पलेट को सहेजने की कोशिश करने से रोकता है। मैं उम्मीद करता हूं कि इससे किसी की मदद होगी।

+0

आपको अपना खुद का जवाब स्वीकार करना चाहिए जो मुझे पता है कि अजीब लगता है लेकिन –

+0

करने के लिए सही बात यह है कि मुझे दुर्भाग्य से मुझे दो दिन पहले इंतजार करना पड़ेगा। – Brandon

0

ध्यान रखें कोड है कि:

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

हमेशा वर्ड का एक नया उदाहरण ऊपर घूमता रहेगा, वहाँ पहले से ही है, भले ही एक उदाहरण लोड।

आमतौर पर, आप लोड किए गए इंस्टेंस (GETOBJECT के माध्यम से) की जांच करना बेहतर कर रहे हैं और यदि कोई है तो इसका उपयोग कर रहे हैं, और यदि आपको आवश्यकता हो तो केवल एक नया उदाहरण कताई करना।

2

मैंने सी # doc2pdf एप्लिकेशन में वर्ड का उपयोग किया है।

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 का एक नया उदाहरण नहीं खोलना चाहिए।

इस कोड मेरे लिए काम किया:

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