[.NET & COM] Gérer Excel à partir de .NET 2005

Gérer Excel à partir de .NET 2005 [.NET & COM] - C#/.NET managed - Programmation

Marsh Posté le 03-03-2006 à 11:59:40    

Bon pas mal de question ces temps ci (jdois me remettre au dev pour une ptite appli)
 
Voilà mon appli doit importer des données à partir d'Excel, pour cela
je dois avant tout utiliser un Objet Excel COM (Microsoft.Office.Interop.Excel) pour récuperer les noms des feuilles de calcul et deux/trois autres trucs
 
Donc j'ouvre mon objet excel :
 

           m_objExcel = New Excel.Application
            m_objExcel.Workbooks.Open("MonFichierExcel" )
            <BLABLAH MON TRAITEMENT>


 
et je referme excel

           m_objExcel.Workbooks(1).Close
            m_objExcel.Quit
            m_objExcel = nothing


 
Tour va bien...mais en fait non, dans ma liste de processus Excel est tjs présent !
 
impossible à le killer "proprement" via un appel COM
 
ai-je rater quelque chose ?
 
merci de votre aide !


---------------
Galerie Photo (Canon)
Reply

Marsh Posté le 03-03-2006 à 11:59:40   

Reply

Marsh Posté le 15-03-2006 à 12:30:56    

Ah ça je connais !
 
la réponse est détaillée ici :
http://support.microsoft.com/defau [...] -us;317109
 
en gros, il faut expliciter tous les accès aux objets Excel, y compris les collections genre Workbooks, worksheets...dans des objets à qui tu feras subir un Marshall.ReleaseComObject à la fin
 
 
edit : bon, d'accord, 12 jours après, c'est un peu tard, mais au moins, la solution sera archivée dans les threads...


Message édité par lohworm le 15-03-2006 à 12:32:11
Reply

Marsh Posté le 15-03-2006 à 12:44:25    

et là aussi :
 
http://geekswithblogs.net/jolson/a [...] /1716.aspx
 
 

Citation :


I ran across a nice little Com Interop “gotcha” when I was working with Excel automation from C# today. I'm sure that a lot of you with more COM Interop experience than me already know about this but I figured I would share so that those with lesser experience can avoid the heartburn that I had today. The gotcha occurred when I was working with Excel ranges to pull information out of a spreadsheet from C#. When working with Office automation from a managed language, one needs to understand that under-the-hood, there are still reference counters! If you are not careful when writing code, it is VERY easy to expose your program to some basic memory leaks.
 
Below is a sample of some easy pseudo-code to pull information out of a range. Can you spot the problem? (I know I sure couldn't earlier)
 
Excel.Range range;
 
range = GetFirstRange(....);
// Do Something With Range
 
range = GetSecondRange(....);
// Do Something With New Range
 
Marshal.ReleaseComObject(range);
range = null;
 
The problem is that range is not released before the call to GetSecondRange and hence the reference counter after the call is at two, instead of one (I assume). What does this mean? This means that when your program exits, Excel will remain loaded in memory. The correct code looks like:
 
Excel.Range range;
 
range = GetFirstRange(....);
// Do Something With Range
 
Marshal.ReleaseComObject(range);
range = GetSecondRange(....);
// Do Something With New Range
 
Marshal.ReleaseComObject(range);
range = null;
 
While this gets pretty easy to spot with the example above, it gets a little more tricky when dealing with loops and test conditions.  
 
Sounds easy enough, right? WRONG! The real tricky part comes when you are dealing with temporary variables used by the runtime. For instance, when dealing with opening up a workbook, the workbooks collection will be a temporary variable used by the runtime:
 
Excel.Workbook myWorkbook = myExcelApplication.Workbooks.Open(....);
// Do something with workbook
 
Marshal.ReleaseComObject(myWorkbook);
myWorkbook = null;
 
Can you spot what's wrong with the code above? The problem is that “.Workbooks.Open” will introduce a memory leak. The answer? Change to the following:
 
Excel.Workbooks myWorkbooks = myExcelApplication.Workbooks;
Excel.Workbook myWorkbook = myWorkbooks.Open(....);
// Do something with workbook
 
Marshal.ReleaseComObject(myWorkbook);
Marshal.ReleaseComObject(myWorkbooks);
myWorkbook = null;
myWorkbooks = null;
 
Now I assume (because I haven't researched for sure yet) that this memory leak is caused because the reference counter on the Workbooks com wrapper will still be increased even though there is not a local variable reference to that object.
 
Am I wrong here? My feeling is that most of this SHOULD be taken care of for you when using a managed language, but ISN'T. Because of this, one is almost no better off using a managed language with COM interop than using an unmanaged language. In all fairness, I know that it would most likely be quite tricky for the runtime to take care of this under-the-hood, and that if you are programming COM Interop you are most likely a “Big Boy“ programmer and should be able to take care of this yourself. After all, even one of my biggest pet peeves is a lazy programmer. Perhaps I should just file it away in the back of my mind as another lesson learned in order to make me a better programmer. What are all of your thoughts on this situation?  
 
 


Message édité par lohworm le 15-03-2006 à 17:55:24
Reply

Marsh Posté le 15-03-2006 à 13:32:37    

Super !
 
meme 12 jours après c'est utile! merci pour le lien de la KB, j'avais pas réussi à mettre la main dessus !
 
Merci beaucoup !

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed