תופעות
בעת הפיכת יישום Microsoft Office לאוטומטי מ- Microsoft Visual Basic .NET או Microsoft Visual C# .NET, יישום Office אינו יוצא כאשר אתה מתקשר לפעולת השירות Quit.
סיבה
כאשר Visual Studio .NET קורא לאובייקט COM מתוך קוד מנוהל, הוא יוצר באופן אוטומטי עטיפת קריאה בזמן ריצה (RCW). המרשלים של 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.
-
כדי לשחרר את ההפניה למשתנה, הגדר את המשתנה שווה ל- Nothing או Null.
-
השתמש בשיטה Quit של Office היישום כדי לומר לשרת לכבות.
מצב
אופן פעולה זה הוא לפי עיצוב.
מידע נוסף
שלבים לשכפול אופן הפעולה
-
התחל Visual Studio .NET.
-
בתפריט קובץ, לחץ על חדש ולאחר מכן לחץ על Project. תחת Visual Basic פרוייקטים, בחר Windows יישום ולאחר מכן לחץ על אישור.
הערה Form1 נוצר כברירת מחדל. -
הוסף הפניה לספריית האובייקטים Microsoft Excel שלך. לשם כך, בצע את השלבים הבאים:
-
בתפריט Project, לחץ על הוסף הפניה.
-
בכרטיסיה COM, אתר את ספריית האובייקטים עבור Excel ולאחר מכן לחץ על בחר.
עבור Microsoft Excel 2002: Microsoft Excel 10.0 Object LibraryNote אם עדיין לא עשית זאת, מומלץ להוריד ולהתקין את ההרכבות של Microsoft Office XP Primary Interop (PIAs). לקבלת מידע נוסף אודות Office PIAs של XP, עבור אל המאמר הבא מתוך מאגר הידע Microsoft Knowledge Base:328912 Microsoft Office ההרכבות הראשיות של XP interop (PIAs) זמינות להורדה עבור Microsoft Office Excel 2003: Microsoft Excel 11.0 ספריית אובייקטים
-
לחץ על אישור בתיבת הדו-שיח הוספת הפניות כדי לקבל את הבחירות שלך.
-
-
בתפריט תצוגה, לחץ על ארגז כלים ולאחר מכן גרור פקד לחצן אל טופס1.
-
לחץ פעמיים על לחצן1.
הערה חלון הקוד עבור הטופס מופיע. -
הוסף את הקוד הבא לראש Form1.vb:
Imports Microsoft.Office.Interop
-
החלף את הקוד הבא בחלון הקוד:
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
-
הקש F5 כדי להפעיל את היישום.
-
פתח Windows המשימות. בתיבת Visual Studio, הצג את חלון הפלט כדי לראות את הודעות איתור הבאגים. לחץ על לחצן הפקודה. שים לב שמופע של Excel.exe מופיע ברשימה תהליכים.
-
המופע של Excel עדיין פועל ברשימת המשימות גם לאחר שהיישום סיים את השינה. סגור את תיבת הדו-שיח ובחין Excel כבר לא מופיע ברשימה תהליכים.
-
בעת ביצוע השלבים בסעיף 'פתרון הבעיה', היישום 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. שיטת Collect() וה- GC. פעולת השירות WaitForPendingFinalizers() לאחר שתשחרר את האובייקט האחרון. מאחר וזמן הריצה מבצע איסוף אשפה ב- RCW, ה- GC. פעולת השירות Collect() כפה על אספן האשפה לפעול וייתכן שתשחרר את כל ההפניות שעדיין יש ל- RCW. The GC. פעולת השירות Collect() מנסה לקבל מחדש את הזיכרון המרבי הזמין. שים לב כי פעולה זו אינה מבטיחה שכל הזיכרון יפורסם מחדש.
חל על
מאמר זה חל גם על:
-
Microsoft Visual Basic .NET (כל המהדורות)
-
Microsoft Visual C# .NET (כל המהדורות)
-
Microsoft Office 2016 (כל המהדורות)
-
Microsoft Office 2013 (כל המהדורות)