2009-06-11 7 views
9

से बाहर नहीं निकलता है अरे मैं एक सी # WinForms एप्लिकेशन से PowerPoint और Excel को स्वचालित कर रहा हूं; मैं जो करता हूं वह PowerPoint से स्लाइड्स पढ़ता है और उन्हें Excel में सहेजता है और फिर दोनों ऐप्स को छोड़ देता है। एक्सेल सफलतापूर्वक छोड़ देता है लेकिन पावरपॉइंट्स छोड़ नहीं जाता है। समस्या यह है कि जब मैं पहली बार परिवर्तित करता हूं तो यह छोड़ता नहीं है, लेकिन जब मैं फिर से परिवर्तित करता हूं तो यह करता है।सी # के माध्यम से लॉन्च किया गया पावरपॉइंट

यहाँ मेरी कोड

try 
{ 
    PowerPoint.Application ppApp; 
    PowerPoint.Presentation ppPres; 
    List<Company> companies = new List<Company>(); 

    ppApp = new PowerPoint.Application(); 
    ppApp.Visible = Microsoft.Office.Core.MsoTriState.msoTrue; 
    ppApp.WindowState = Microsoft.Office.Interop.PowerPoint.PpWindowState.ppWindowMinimized; 

    ppPres = ppApp.Presentations.Open(fileTxtBox.Text, 
             Microsoft.Office.Core.MsoTriState.msoFalse, 
             Microsoft.Office.Core.MsoTriState.msoFalse, 
             Microsoft.Office.Core.MsoTriState.msoTrue); 

    int slides = ppPres.Slides.Count; 

    for (int slide = 1; slide <= slides; slide++) 
    { 
     int rows = 1; 
     PowerPoint.Cell cell; 
     int shape = 1; 

     for (; shape < ppPres.Slides[slide].Shapes.Count; shape++) 
     { 
      if (ppPres.Slides[slide].Shapes[shape].HasTable == Microsoft.Office.Core.MsoTriState.msoTrue) 
      { 
       cell = ppPres.Slides[slide].Shapes[shape].Table.Cell(1, 1); 

       if (cell.Shape.TextFrame.TextRange.Text.Trim().ToLower().Contains("realized")) 
       { 
        rows = ppPres.Slides[slide].Shapes[shape].Table.Rows.Count; 
        break; 
       } 
      } 
     } 

     Company comp = new Company(rows); 
     InitializeCompany(ref comp, ppPres.Slides[slide]); 
     companies.Add(comp); 
    } 

    SaveInExcel(companies); 

    ppPres.Close(); 
    ppPres = null; 
    ppApp.Quit(); 
    ppApp = null; 

    return; 
} 

catch (Exception ex) 
{ 
    MessageBox.Show(ex.Message); 
} 

finally 
{ 
    GC.Collect(); 
    GC.WaitForPendingFinalizers(); 
} 

उत्तर

12

अपने माइक्रोसॉफ्ट ऑफिस एप्लिकेशन को बंद करना पहले सही होने के लिए मुश्किल लग सकता है, लेकिन एक बार जब आप संचालन के सही क्रम को स्थापित कर लेते हैं, तो वास्तव में यह बहुत मुश्किल नहीं है।

रिलीज़ करना आपके एमएस ऑफ़िस आवेदन दो चरणों में सुरक्षित रूप से और प्रभावी ढंग से किया जा सकता है:

(1) सबसे पहले सभी नाबालिग वस्तुओं जो करने के लिए आप एक नामित चर के भीतर एक संदर्भ पकड़ नहीं है जारी। आप इसे GC.Collect() पर कॉल करके और फिर GC.WaitForPendingFinalizers() पर कॉल करते हैं। ध्यान दें कि यदि आप Office (VSTO) के लिए विजुअल स्टूडियो टूल्स का उपयोग कर रहे हैं, तो COM COM ऑब्जेक्ट्स को सफलतापूर्वक रिलीज़ करने के लिए आपको दो बार आदेशों की इस जोड़ी को कॉल करने की आवश्यकता है। आप वीएसटीओ का उपयोग नहीं कर रहे हैं, हालांकि, उन्हें एक बार कॉल करना पर्याप्त है।

(2) फिर आपके द्वारा प्रत्येक चर पर Marshall.FinalReleaseComObject() पर कॉल का उपयोग करके नामित चर के माध्यम से आपके द्वारा रखी गई वस्तुओं को स्पष्ट रूप से रिलीज़ करें।

स्पष्ट रूप से सभी वैरिएबल को रिलीज़ करना याद रखें जो आपके पास COM घटक हैं। यदि आप एक भी याद करते हैं, तो आपका एमएस ऑफिस एप्लीकेशन लटका होगा। आपके कोड में, आपके पास तीन नामित चर हैं जो आपके पावरपॉइंट एप्लिकेशन का संदर्भ रखते हैं: ppApp, ppPres, और cell

सभी को ध्यान में इस ले रहा है, मुझे लगता है कि आपके सफाई निम्नलिखित, जो या तो नाम स्थान के अंदर या कोड दस्तावेज़ के शीर्ष पर using System.Runtime.InteropServices का उपयोग करता है कुछ ऐसा दिखाई देगा:

// using System.Runtime.InteropServices 

// Cleanup: 
GC.Collect(); 
GC.WaitForPendingFinalizers(); 

Marshal.ReleaseComObject(cell); 

ppPres.Close(); 
Marshal.ReleaseComObject(ppPres); 

ppApp.Quit(); 
Marshal.ReleaseComObject(ppApp); 

यह एक दें कोशिश करें, मुझे लगता है कि यह आपके लिए काम करना चाहिए ... (यदि नहीं, तो आपको अपने कोड का और भी अधिक दिखाना पड़ सकता है।) अधिक जानकारी के लिए, मैं यहां एक एक्सेल एप्लिकेशन को ठीक से कैसे रिलीज़ करने के बारे में एक विस्तृत स्पष्टीकरण देता हूं:

How to properly clean up Excel interop objects in C#

उम्मीद है कि यह मदद करता है, हमें बताएं कि यह कैसे जाता है ...

- माइक

+1

अरे माइक धन्यवाद, लेकिन यह didn नहीं है काम नहीं किया। एक बात जो मैं आपको बताना चाहता हूं वह यह है कि जब मैं अपना स्वयं का WinForm ऐप बंद करता हूं, तो PowerPoint भी बंद हो जाता है। – akif

+1

हाँ जब आप अपना WinForm बंद करते हैं तो इसे बंद करना सामान्य है क्योंकि आप जिस भी ऑब्जेक्ट को रिलीज़ करने में विफल रहे हैं, अंत में रिलीज डी जब रनटाइम टूट गया है। आप जीसी.कोलेक्ट() और जीसी.WaitForPending() फ़ाइनलाइजर्स TWICE को कॉल करने का प्रयास कर सकते हैं। इससे कोई फर्क नहीं पड़ता कि आप वीएसटीओ का उपयोग नहीं कर रहे हैं, लेकिन यह चोट नहीं पहुंचा सकता है। आपको इस बारे में सोचना होगा कि यहां अन्य चर क्या हैं ... (अगली टिप्पणी देखें।) –

+2

आपको इस बारे में सोचना होगा कि यहां अन्य चर क्या हैं, और उन्हें छोड़ दें। उदा। (1) क्या कहीं भी कोई अन्य स्थैतिक चर है? (2) आपका प्रारंभिक कॉम्पैनी क्या है (रेफ कॉम्प, पीपीपीआरएस स्लाइड [स्लाइड]) कॉल करते हैं? यदि यह आपकी कंपनी ऑब्जेक्ट के भीतर पावरपॉइंट स्लाइड का संदर्भ संग्रहीत करता है, तो यह कॉल कंपनियों के साथ। Add (comp) PowerPoint संदर्भ के लिए स्थायी संदर्भ बनाएगा। इन्हें मार्शल को कॉल करके इस्तेमाल किया जाना चाहिए। FinalReleaseComObject() या अन्यथा PowerPoint लटका होगा। मुझे नहीं पता कि यह क्या हो रहा है, लेकिन आपको * सभी * अपने पावरपॉइंट संदर्भों को रिलीज़ करने की आवश्यकता है। –

1

है ऐसा लगता है कि पावर प्वाइंट आवेदन उदाहरण दिखाई बना रहे हैं, लेकिन अगर नहीं, तो यह है कि वहाँ एक संवाद प्रस्तुत किया जा रहा है कि आप नहीं दिख रहा है संभव है - शायद एक परिवर्तन संवाद सहेजें। यदि ऐप छुपा रहा है, तो यह देखने के लिए दृश्यमान करें कि क्या ऐसे कोई संवाद पॉप-अप हो रहे हैं, जिससे पावर प्वाइंट बंद होने से रोका जा सकता है।

+0

नहीं वहाँ किसी भी तरह के बात :( – akif

0

छोड़ो लागू करने के बाद() अपने ppApp वस्तु के लिए हालांकि कोशिश निम्नलिखित

System.Runtime.InteropServices.Marshal.ReleaseComObject(ppApp); 

कोई वादे, यह काम हो सकता है, या यह सब पर कुछ भी नहीं हो सकता है। कार्यालय COM सामान को उचित रूप से बंद करना हमेशा मेरे लिए वूडू जैसा ही रहा है।

+0

काम नहीं किया :( – akif

2

यहाँ है एक MSDN लेख है कि समस्या और समाधान

http://msdn.microsoft.com/en-us/library/aa679807%28office.11%29.aspx

मूल रूप से recomondation करना है का वर्णन करता है (नोट:) GC.Collect के दो पुनरावृत्तियों (

GC.Collect(); 
      GC.WaitForPendingFinalizers(); 
      GC.Collect(); 
      GC.WaitForPendingFinalizers(); 
+0

यह मेरे लिए भी काम करता है, लेकिन मुझे पता नहीं लगा कि यह 2 कॉल क्यों मेरी जिंदगी बदलती है। – pix

2

हे दोस्तों। मैंने हाल ही में देखा है कि कचरे से मेरे लिए कुछ भी नहीं किया गया है ताकि वस्तुओं को छोड़ने और बंद करने के लिए एकत्र किया जा सके। इसलिए मैं कैम एक विकल्प के साथ ई। एक बार मेरा काम पूरा होने के बाद मुझे चल रही प्रक्रिया मिली, और फिर कोड के माध्यम से इसे मार डाला।

कोड:

Process[] pros = Process.GetProcesses(); 
    for (int i = 0; i < pros.Count(); i++) 
    { 
    if (pros[i].ProcessName.ToLower().Contains("powerpnt")) 
     { 
      pros[i].Kill(); 
     } 
    } 
+1

उन इंटरऑप सर्विसेज के साथ काम बहुत तनावपूर्ण है, लेकिन यह समाधान काम करता है, इसलिए धन्यवाद। यह मजाकिया है कि वर्षों के बाद भी यह एक ही समस्या/मुश्किल है। –

0

के लिए यह काम करने के लिए मुझे

 var app = new PowerPoint.Application(); 
      PowerPoint.Presentations pres = app.Presentations; 
      PowerPoint.Presentation ActivePresentation = pres.Open(fileIn, MsoTriState.msoTrue, MsoTriState.msoTrue, MsoTriState.msoFalse); 
(...) 
      ActivePresentation.SaveAs(fileOut, PowerPoint.PpSaveAsFileType.ppSaveAsDefault, MsoTriState.msoTrue); 

      ActivePresentation.Close(); 
      app.Quit(); 
संबंधित मुद्दे