Nombreux sont ceux qui rencontrent ce problème : lorsque vous quittez une automation, vous utilisez (à quelques détails près) cette portion de code :
1 2
| monAppli.Quit();
monAppli = null; |
Le plus souvent, ceci ne suffit pas à fermer le processus office : vous pouvez toujours le voir dans le gestionnaire des tâches. Ainsi, lorsque vous ouvrez le document, avec lequel vous avez travaillé par automation, depuis Windows, il refuse de l’ouvrir au titre qu’il est en cours d’utilisation par… vous-même !
Voilà donc quelques astuces pour libérer les ressources automation efficacement :
1. Déclarer les objets avec des variables indépendantes :
Par exemple, ne faites pas :
Workbook monClasseur = monAppli.Workbooks.Add();
Mais plutôt :
1 2
| Workbooks mesClasseurs = monappli.Workbooks;
Workbook monClasseur = mesClasseurs.Add(); |
Pour une automation simple, cela peut passer ; mais pour une automation complexe, cela peut s’avérer extrêmement fastidieux !
2. Libérer les références aux objets COM :
Utilisez la méthode suivante pour libérer les références à vos objets COM :
System.Runtime.InteropServices.Marshal.ReleaseComObject(monAppli);
3. Utiliser le Garbage Collector (GC) :
1 2
| GC.Collect();
GC.WaitForPendingFinalizers(); |
Il peut être utile de doubler cette portion, dans le cas où la référence mémoire du process est conservée après le premier appel.
4. Récupérer l’identifiant du processus office :
La méthode la plus définitive est de tuer le processus à la fin de l’automation.
Il faut pour cela, dans un premier temps, récupérer l’identifiant du processus, et le stocker pendant tout le temps que doit durer l’automation. Exemple pour une automation Word :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| int processId = 0;
// 1. Additionner les identifiants des processus winword avant louverture de lautomation :
foreach (Process item in Process.GetProcessesByName("winword"))
processId -= item.Id;
// 2. Ouvrir lautomation :
ApplicationClass monAppli = new ApplicationClass();
// 3. Ajouter les identifiants des processus winword après louverture de lautomation,
// la différence (après - avant) donnera lidentifiant du processus ouvert :
foreach (Process item in Process.GetProcessesByName("winword"))
processId += item.Id;
// Automation...
// Enfin, lorsque lautomation est terminée, il suffit de tuer le processus à partir de son identifiant :
Process.GetProcessById(processId).Kill(); |
Partager