Applies ToVisual Studio 2015

ดูผลิตภัณฑ์อื่นๆ ที่บทความนี้ใช้กับ

อาการ

เมื่อคุณอัตโนมัติแอปพลิเคชัน Microsoft Office จาก Microsoft Visual Basic .NET หรือ Microsoft Visual C# .NET แอปพลิเคชัน Office จะไม่ออกเมื่อคุณเรียกใช้เมธอด Quit

สาเหตุ

When Visual Studio .NET calls a COM object from managed code, it automatically creates a Runtime Callable Wrapper (RCW). MARShals RCW จะโทรระหว่างแอปพลิเคชัน .NET และวัตถุ COM RCW จะนับการอ้างอิงบนวัตถุ COM ดังนั้น ถ้าการอ้างอิงทั้งหมดยังไม่ได้เผยแพร่บน RCW วัตถุ COM จะไม่ออก

การแก้ไข

เมื่อต้องการตรวจสอบให้แน่ใจว่าแอปพลิเคชัน Officeออก ให้ระบุว่าโค้ดอัตโนมัติของคุณตรงตามเกณฑ์ต่อไปนี้หรือไม่:

  • ประกาศแต่ละวัตถุเป็นตัวแปรใหม่ ตัวอย่างเช่น เปลี่ยนบรรทัดของโค้ดต่อไปนี้:

    oBook = oExcel.Workbooks.Add()
    

    เปลี่ยนเป็นดังต่อไปนี้:

    dim oBooks as Excel.Workbooks
    oBooks = oExcel.Workbooks
    oBook = oBooks.Add()
    
  • ใช้ System.Runtime.InteropServices.Marshal.ReleaseComObject ในการวนรอบจนกว่าจะส่งกลับค่า 0 เมื่อคุณเสร็จสิ้นการใช้วัตถุ System.Runtime.InteropServices.Marshal.ReleaseComObject จะนับการอ้างอิงของ RCW และการวนรอบจะทําให้แน่ใจว่าคอมโพเนนต์ COM ที่ขีดเส้นใต้จะถูกเผยแพร่โดยไม่เกี่ยวกับระยะเวลาที่ใส่ CLR อีกครั้ง

  • เมื่อต้องการปล่อยการอ้างอิงไปยังตัวแปร ให้ตั้งค่าตัวแปรเท่ากับ ไม่มี หรือ Null

  • ใช้เมธอด Quit ของวัตถุOfficeแอปพลิเคชันหลักเพื่อบอกให้เซิร์ฟเวอร์ปิดระบบ

สถานะ

พฤติกรรมเช่นนี้เกิดจากการออกแบบ

ข้อมูลเพิ่มเติม

ขั้นตอนในการสร้างลักษณะการเกิดขึ้น

  1. เริ่ม Visual Studio .NET

  2. บนเมนู ไฟล์ ให้คลิก ใหม่ แล้วคลิก Projectใหม่ ภายใต้ Visual Basicโครงการ Windows แอปพลิเคชันของคุณ แล้วคลิก ตกลงหมายเหตุ Form1 จะถูกสร้างขึ้นตามค่าเริ่มต้น

  3. เพิ่มการอ้างอิงไปยังMicrosoft Excelวัตถุของคุณ เมื่อต้องการให้ปฏิบัติตามขั้นตอนเหล่านี้:

    1. บนเมนู Project ให้คลิก เพิ่มการอ้างอิง

    2. บนแท็บ COM ให้ค้นหาไลบรารีวัตถุExcelไลบรารีวัตถุ แล้วคลิก เลือกFor Microsoft Excel 2002: Microsoft Excel 10.0 Object LibraryNote ถ้าคุณยังไม่ได้เสร็จสิ้น, เราขอแนะให้ คุณดาวน์โหลด และติดตั้ง Microsoft Office XP Primary Interop Assemblies (PIAs)For more information about Office XP PIAs, go to the following Microsoft Knowledge Base article:

      328912 Microsoft Officeประกอบหลัก (PIAs) ของ XP มีให้ดาวน์โหลด   For Microsoft Office Excel 2003: Microsoft Excel 11.0 Object Library

    3. คลิก ตกลง ในกล่องโต้ตอบ เพิ่มการอ้างอิง เพื่อยอมรับการเลือกของคุณ

  4. บนเมนู มุมมอง ให้คลิก กล่องเครื่องมือ แล้วลากตัวควบคุม ปุ่ม ไปยัง Form1

  5. ดับเบิลคลิก ปุ่ม1หมายเหตุ หน้าต่างโค้ดของฟอร์มจะปรากฏขึ้น

  6. เพิ่มโค้ดต่อไปนี้ที่ด้านบนของ Form1.vb:

    Imports Microsoft.Office.Interop
    
  7. แทนที่โค้ดต่อไปนี้ในหน้าต่างโค้ด:

        Private Sub Button1_Click(ByVal sender As System.Object, _
           ByVal e As System.EventArgs) Handles Button1.Click
        End Sub
    

    แทนที่โค้ดต่อไปนี้:

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim oApp As New Excel.Application()
        Dim oBook As Excel.Workbook = oApp.Workbooks.Add
        Dim oSheet As Excel.Worksheet = oApp.ActiveSheet
    
        oSheet = Nothing
        oBook.Close(False)
        oBook = Nothing
        oApp.Quit()
        oApp = Nothing
    
        Debug.WriteLine("Sleeping...")
        System.Threading.Thread.Sleep(5000)
        Debug.WriteLine("End Excel")
    End Sub
    
  8. กด F5 เพื่อเรียกใช้แอปพลิเคชัน

  9. เปิด Windowsจัดการงาน In Visual Studio, display the Output window to see the debug messages. คลิกปุ่มสั่ง โปรดสังเกตว่า อินสแตนซ์Excel.exeจะปรากฏในรายการ กระบวนการ

  10. อินสแตนซ์ของExcelยังคงเรียกใช้ในรายการงานแม้ว่าหลังจากแอปพลิเคชันได้นอนเสร็จแล้ว ปิดกล่องโต้ตอบและExcelไม่ปรากฏขึ้นในรายการ กระบวนการ อีกต่อไป

  11. เมื่อคุณปฏิบัติตามขั้นตอนในส่วน "การแก้ปัญหา" แอปพลิเคชัน Officeออกจากแอปพลิเคชันหลังจากเผยแพร่ตัวแปรสุดท้าย แทนที่ฟังก์ชันในขั้นตอนที่ 5 โดยใช้รหัสต่อไปนี้:

      Private Sub NAR(ByVal o As Object)
        Try
          While (System.Runtime.InteropServices.Marshal.ReleaseComObject(o) > 0)
          End While
        Catch
        Finally
          o = Nothing
        End Try
      End Sub
    
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim oApp As New Excel.Application()
        Dim oBooks As Excel.Workbooks = oApp.Workbooks
        Dim oBook As Excel.Workbook = oBooks.Add
        Dim oSheet As Excel.Worksheet = oApp.ActiveSheet
    
        NAR(oSheet)
        oBook.Close(False)
        NAR(oBook)
        NAR(oBooks)
        oApp.Quit()
        NAR(oApp)
    
        Debug.WriteLine("Sleeping...")
        System.Threading.Thread.Sleep(5000)
        Debug.WriteLine("End Excel")
    End Sub
    

ถ้าคุณใช้ฟังก์ชัน Visual C# .NET ให้อ้างอิงโค้ดของฟังก์ชัน NAR()

private void NAR(object o)
{
    try 
    {
        while (System.Runtime.InteropServices.Marshal.ReleaseComObject(o) > 0) ;
    }
    catch {}
    finally 
    {
        o = null;
    }
}

หมายเหตุ เริ่มต้นใน .NET Framework 2.0 คุณสามารถใช้ System.Runtime.InteropServices.Marshal.FinalReleaseComObject แทนการโทรวนรอบ System.Runtime.InteropServices.Marshal.ReleaseComObject เพื่อให้ได้ผลลัพธ์เดียวกัน  

การแก้ไขปัญหา

หมายเหตุ ถ้าคุณปฏิบัติตามขั้นตอนที่อธิบายไว้ในส่วน "ขั้นตอนที่จะเกิดพฤติกรรม" และเซิร์ฟเวอร์ยังคงไม่ปิดตัว คุณสามารถใช้ GC วิธีการเก็บรวบรวม() และ GC เมธอด WaitForPendingFinalizers() หลังจากที่คุณปล่อยวัตถุสุดท้าย เนื่องจากรันไทม์จะเก็บถังขยะบน RCW ดังนั้น GC วิธีการรวบรวม() บังคับให้ถังขยะถูกทิ้งให้ใช้งานและอาจเผยแพร่การอ้างอิงใดๆ ที่ RCW ยังคงมีอยู่ GC วิธีเก็บรวบรวม() พยายามเรียกคืนหน่วยความจําสูงสุดที่พร้อมใช้งาน โปรดสังเกตว่าวิธีนี้ไม่ได้รับประกันว่าหน่วยความจําทั้งหมดจะถูกเรียกคืน

นำไปใช้กับ

บทความนี้ยังใช้ได้กับ:

  • Microsoft Visual Basic .NET (ทุกรุ่น)

  • Microsoft Visual C# .NET (ทุกรุ่น)

  • Microsoft Office 2016 (ทุกรุ่น)

  • Microsoft Office 2013 (ทุกรุ่น)

ต้องการความช่วยเหลือเพิ่มเติมหรือไม่

ต้องการตัวเลือกเพิ่มเติมหรือไม่

สํารวจสิทธิประโยชน์ของการสมัครใช้งาน เรียกดูหลักสูตรการฝึกอบรม เรียนรู้วิธีการรักษาความปลอดภัยอุปกรณ์ของคุณ และอื่นๆ

ชุมชนช่วยให้คุณถามและตอบคําถาม ให้คําติชม และรับฟังจากผู้เชี่ยวชาญที่มีความรู้มากมาย