2008-11-26 5 views
4

je suit dans un programme (écrit en VB.NET):avoir tué un processus d'application Interop

Imports Microsoft.Office.Interop.Excel 

Public Class Form1 
    Dim eApp As New Excel.Application 
    Dim w As Excel.Workbook 
    w = eApp.Workbooks.Open("path.xls", ReadOnly:=True) 
    .. Processing Code .. 
    //Attempts at killing the excel application 
    w.Close() 
    eApp.Workbooks.Close() 
    eApp.Quit() 
End Class 

Quand je lance ce deux ou trois fois, je reçois un tas de cas excel.exe dans mon Gestionnaire des tâches. Comment puis-je tuer ces processus dans le code? Tous ceux dans le code ont été essayés et n'ont pas fonctionné.

boucle

Répondre

3

je devais faire un certain temps dans NET 1.1, s'il vous plaît pardonnez la rouille .

Sur l'eApp, il y avait un Hwind (un handle de fenêtre win32 - http://msdn.microsoft.com/en-us/library/bb255823.aspx) ou un objet similaire. J'ai dû utiliser cela et un pInvoke (http://www.pinvoke.net/default.aspx/user32.GetWindowThreadProcessId) pour obtenir l'id de processus. Avec ça j'ai pu faire un Process.Kill() sur l'exe.

Il existe peut-être une meilleure façon de le faire maintenant, mais cela devrait fonctionner.

3

la ligne ci-dessous du code jusqu'à ce que le résultat est égal à zéro ou moins

System.Runtime.InteropServices.Marshal.ReleaseComObject(eApp) 

ou consultez ce link

+0

En fait, je viens de trouver cela aussi. Super lien, d'ailleurs. –

+0

Salut, je pense que cette solution ne fonctionnera pas si Excel affiche un dialogue modal. Dans un tel cas, vous devrez tuer le processus Excel comme décrit par StingyJack Il est généralement recommandé de désactiver les alertes (Application.DisplayAlerts = False) lors de l'automatisation ainsi que le recalcul automatique. –

0

J'ai posté une solution à ce il y a quelques jours: Killing Excel.EXE on server

Même méthode que StingyJack mentionne; le seul que je connaisse vraiment.

2

Pour quitter Excel, vous devez appeler Application.Quit et utiliser l'une des techniques suivantes.

  • Appelez Marshal.ReleaseComObject sur chaque objet Excel que vous instanciez. Il y a un KnowledgeBase article qui décrit comment le faire. Par exemple, dans votre exemple de code "eApp.Workbooks.Open" instancie un objet Workbooks sans lui affecter de variable. Vous devez affecter une variable comme décrit dans l'article de la base de connaissances afin de pouvoir la libérer ultérieurement. Le problème est qu'avec n'importe quel scénario d'automatisation, il est très difficile d'être sûr de toujours libérer tous ces objets dans tous les chemins de code (par exemple en utilisant try/finally pour s'assurer qu'ils sont libérés lorsqu'une exception est levée).

  • Appelez GC.Collect et GC.WaitForPendingFinalizers après avoir libéré le dernier objet Excel. Certaines personnes ont suggéré que vous pourriez devoir le faire deux fois.

0

Utilisez le bloc utilisant

Using eApp As New Excel.Application 
    Using w As Excel.Workbook 
    w = eApp.Workbooks.Open("path.xls", ReadOnly:=True) 
    .. Processing Code .. 
    //Attempts at killing the excel application 
    w.Close() 
    eApp.Workbooks.Close() 
    eApp.Quit() 
    End Using 
End Using 

similaires essayer/finally avec une élimination en enfin, ce disposera automatiquement le Excel.Application et Excel.Workbook.

Comme mentionné dans un autre post, System.Runtime.InteropServices.Marshal.ReleaseComObject (eApp) peut également être nécessaire ????

0

Après ExcelApplication.Quit(), ajoutez le code suivant.

Il va tuer l'application Excel du processus.

  Process[] Proc = Process.GetProcessesByName("Excel"); 
      foreach (Process p in Proc) 
      { 
       if (p.MainWindowTitle == "") 
        p.Kill(); 
      } 
1

Démarrer Excel:

Microsoft.Office.Interop.Excel.Application xlApp = new Microsoft.Office.Interop.Excel.Application(); 
Workbook wb = xlApp.Workbooks.Open(...); 
Worksheet ws = (Worksheet)wb.Worksheets[1]; 

kills Excel:

System.Runtime.InteropServices.Marshal.ReleaseComObject(ws); 
System.Runtime.InteropServices.Marshal.ReleaseComObject(wb); 
wb = null; 
ws = null; 

uint idProcess; 
GetWindowThreadProcessId((IntPtr)xlApp.Hwnd, out idProcess); 

xlApp.DisplayAlerts = false; 
xlApp.Quit(); 
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApp); 
xlApp = null; 
xlApp = null; 
GC.Collect(); 
GC.WaitForPendingFinalizers(); 
GC.Collect(); 
GC.WaitForPendingFinalizers(); 

Process processo = null; 
try 
{     
    processo = Process.GetProcessById((int)idProcess); 
} 
catch { } 

if (processo != null) 
    processo.Kill(); 
+0

Il semble que je devrais écrire une fonction appelée KillItWithFire et mettre cela dedans. Je n'utilise plus vraiment le programme mais je voudrais essayer ce changement et regarder ce qui se passe dans les multiples collectes de GC, ce qui me semble un peu étrange. –

0

solution Tagore Peethala est en avant et fonctionne directement. Fondamentalement, assurez-vous de WorkBook.CLOSE .. puis ExcelApplication.QUIT ... alors il suffit de chercher une instance de Excel en cours d'exécution avec rien ouvert et fermez-le.

myExcelWorksheet = null; 
if (myExcelWorkbook != null) 
       { 
        myExcelWorkbook.Close(); 
        myExcelWorkbook = null; 
       } 
       if (myExcelApp != null) 
       { 
        myExcelApp.Quit(); 
        myExcelApp = null; 
       } 
       foreach (System.Diagnostics.Process myProcess in System.Diagnostics.Process.GetProcessesByName("Excel")) 
       { 
        if (myProcess.MainWindowTitle == "") 
        { 
         myProcess.Kill(); 
        } 
       } 
0
//Quit Excel application 
eApp.Quit(); 

//Release COM objects (every object you used in eApp,like workbooks, Workbook, Sheets, Worksheet) 
System.Runtime.InteropServices.Marshal.ReleaseComObject(obj); 
obj = null; 

// Force garbage collector cleaning 
GC.Collect(); 
Questions connexes