2016-12-09 4 views
0

Question: Pourquoi le processus Excel ne se ferme-t-il pas lorsque l'application est en cours d'exécution? S'il vous plaît ne pas sauter le pistolet et le marquer en double. Si vous pouviez montrer le changement nécessaire dans le code, je l'apprécie vraiment. Le processus Excel se ferme correctement lorsque je ferme l'application. J'ai étudié ce problème pour quelques derniers jours lire plusieurs messages SO et essayé plusieurs choses, mais rien ne fonctionne sauf pour appeler process.kill que je préfère éviter si possible.Pourquoi le processus Excel ne se ferme-t-il pas lorsque l'application est en cours d'exécution?

Imports Microsoft.Office.Interop 
Imports System.Runtime.InteropServices 

Public Class Form1 

    Public Sub New() 

     ' This call is required by the designer. 
     InitializeComponent() 

     ' Add any initialization after the InitializeComponent() call. 
    End Sub 

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click 
     Dim xlApp As Excel.Application 
     Dim xlWorkBook As Excel.Workbook 
     Dim misValue As Object 
     Dim xlWorkSheet As Excel.Worksheet 

     Try 
      ''EXCEL CREATION/INITAILIAZATION 
      misValue = System.Reflection.Missing.Value 
      xlApp = New Microsoft.Office.Interop.Excel.Application() 
      If xlApp Is Nothing Then 
       MessageBox.Show("Excel is not properly installed!!") 
       xlApp = Nothing 
      End If 
      xlWorkBook = xlApp.Workbooks.Add(misValue) 


      ''WRITE TO WORKSHEET 
      xlWorkSheet = TryCast(xlWorkBook.Sheets("sheet1"), Excel.Worksheet) 
      xlWorkSheet.Cells(1, 1) = "THIS" 
      xlWorkSheet.Cells(1, 2) = "IS" 
      xlWorkSheet.Cells(1, 3) = "A" 
      xlWorkSheet.Cells(1, 4) = "TEST" 

      ''FORCEFULLY CAUSING ERROR, NOW THE EXCEL PROCESS HANGING IN TASK MANAGER 
      ''xlWorkSheet.Cells(1, -1) = "ERROR LINE" 

      ''SAVE WORKSHEET 
      Dim Name = DateTime.Now.ToString("s").Replace(":", "_") 
      Dim Dir = AppDomain.CurrentDomain.BaseDirectory & "Output\" & Name & "Output.xls" 
      xlApp.DisplayAlerts = False 
      xlWorkBook.CheckCompatibility = False 
      xlWorkBook.DoNotPromptForConvert = True 
      xlWorkBook.SaveAs(Dir, Excel.XlFileFormat.xlWorkbookNormal, Type.Missing, Type.Missing, Type.Missing, Type.Missing, _ 
           Excel.XlSaveAsAccessMode.xlExclusive, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing) 
      xlWorkBook.Close(False) 
      xlApp.Quit() 

      misValue = Nothing 

      If Not IsNothing(xlWorkSheet) And System.Runtime.InteropServices.Marshal.IsComObject(xlWorkSheet) Then 
       System.Runtime.InteropServices.Marshal.ReleaseComObject(xlWorkSheet) 
       xlWorkSheet = Nothing 
      End If 

      If Not IsNothing(xlWorkBook) And System.Runtime.InteropServices.Marshal.IsComObject(xlWorkBook) Then 
       System.Runtime.InteropServices.Marshal.ReleaseComObject(xlWorkBook) 
       xlWorkBook = Nothing 
      End If 

      If Not IsNothing(xlApp) And System.Runtime.InteropServices.Marshal.IsComObject(xlApp) Then 
       System.Runtime.InteropServices.Marshal.FinalReleaseComObject(xlApp) 
       xlApp = Nothing 
      End If 

      GC.Collect() 
      GC.WaitForPendingFinalizers() 

     Catch ex As Exception 
      Dim exMsg = ex.Message 
     End Try 
    End Sub 

End Class 
+0

Ce n'est pas une réponse, mais si vous le pouvez, je vous suggère de trouver une bonne API pour enregistrer des fichiers Excel. Avec l'interop vous pouvez avoir des problèmes comme ça et c'est très lent. –

+0

Quel est votre problème? Vous clairement en gras * processus Excel se ferme bien lorsque je ferme l'application * qui répond à votre question. Aussi, pas trop familier avec VB.Net, mais vous devriez libérer des ressources ('xlApp = Nothing') dans le' Catch' ou mieux encore dans le '' Finally'' (https://msdn.microsoft.com/en -us/library/fk6t46tz.aspx) clause – Parfait

+0

@Parfait Problème est la première déclaration en gras. Si l'objet est déclaré dans un sous-marin puis à la fin du sous-marin, il devrait être hors de portée. Pour rendre ceci plus clair si vous exécutez le code ci-dessus et cliquez sur le bouton plusieurs fois, vous remarquerez que toutes les instances de processus Excel sauf une se ferment à la fin du sous-marin. – glant

Répondre

0

Votre problème est la référence à double point dans .net. Lisez ici: https://msdn.microsoft.com/en-us/library/8bwh56xe(v=vs.110).aspx

donc une fois que vous déconstruire

xlWorkBook = xlApp.Workbooks.Add(misValue) 

comme

xlWorkBooks = xlApp.Workbooks 
xlWorkBook = xlWorkBooks.Add(misValue) 

puis relâchez, vous êtes tout bon.

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click 
    Call doSomeWork() 
    GC.Collect() 
End Sub 

Private Sub doSomeWork() 
    Dim xlApp As Excel.Application 
    Dim xlWorkBook As Excel.Workbook 
    Dim xlWorkBooks As Excel.Workbooks '// Added new variable to avoid double dot. 
    Dim misValue As Object 
    Dim xlWorkSheet As Excel.Worksheet 

    Try 
     ''EXCEL CREATION/INITAILIAZATION 
     misValue = System.Reflection.Missing.Value 
     xlApp = New Microsoft.Office.Interop.Excel.Application() 
     If xlApp Is Nothing Then 
      MessageBox.Show("Excel is not properly installed!!") 
      xlApp = Nothing 
     End If 
     xlWorkBooks = xlApp.Workbooks 
     xlWorkBook = xlWorkBooks.Add(misValue) 


     ''WRITE TO WORKSHEET 
     xlWorkSheet = xlWorkBook.Sheets(1) 

     'xlWorkSheet = TryCast(sheets("sheet1"), Excel.Worksheet) 
     xlWorkSheet.Cells(1, 1) = "THIS" 
     xlWorkSheet.Cells(1, 2) = "IS" 
     xlWorkSheet.Cells(1, 3) = "A" 
     xlWorkSheet.Cells(1, 4) = "TEST" 

     ''FORCEFULLY CAUSING ERROR, NOW THE EXCEL PROCESS HANGING IN TASK MANAGER 
     ''xlWorkSheet.Cells(1, -1) = "ERROR LINE" 

     ''SAVE WORKSHEET 
     Dim Name = DateTime.Now.ToString("s").Replace(":", "_") 
     Dim Dir = AppDomain.CurrentDomain.BaseDirectory & "Output\" & Name & "Output.xls" 
     xlApp.DisplayAlerts = False 
     xlWorkBook.CheckCompatibility = False 
     xlWorkBook.DoNotPromptForConvert = True 
     xlWorkBook.SaveAs("C:\temp\a.xls", Excel.XlFileFormat.xlWorkbookNormal, Type.Missing, Type.Missing, Type.Missing, Type.Missing, _ 
          Excel.XlSaveAsAccessMode.xlExclusive, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing) 
     xlWorkBook.Close(False) 
     xlApp.Quit() 

     misValue = Nothing 

    Catch ex As Exception 
    End Try 
End Sub 
+0

Merci pour votre réponse. J'avais déjà essayé avec xlWorkbooks comme variable séparée pour éviter les points de chaînage mais ça n'avait pas fonctionné, donc quand j'ai vu ta réponse marcher, je devais vraiment comprendre pourquoi ça ne fonctionnait pas pour moi auparavant et après tout le delta entre mes solution et la vôtre. Il s'avère que le bloc TRY/CATCH était le coupable. J'ai commenté le bloc try/catch et mon code original ci-dessus fonctionne. Merci pour la motivation que votre message m'a donné. – glant

+0

Si vous deviez ajouter try/catch block à cette solution, il échouera .. atleast Il a fait pour moi et testé sur la boîte de collaborateurs aussi ... Aucune idée pourquoi cela se produit – glant

+0

hmm .... du gestionnaire d'événements appelant un sous séparé qui fait tout le travail, vous permettra d'utiliser essayer de bloquer le catch. Appelez le sous-marin puis nettoyez-le. le code mis à jour fonctionne pour moi. – cyboashu