Home > Office Interop - TroubleShooting > Fechando WINWORD.EXE ao utilizar o PIA

Fechando WINWORD.EXE ao utilizar o PIA


CENÁRIO:

Cenário bem comum em automação de processos é precisar criar/editar arquivos Office de forma automática e sem iteração do usuário final.

Para isso, podemos usar o Open XML SDK 2.5 para Microsoft Office: https://www.microsoft.com/en-us/download/details.aspx?id=30425.

Mas o Open XML SDK é apenas para os arquivos atuais do Office (pós 2007) que usam o OpenXML em sua concepção (.docx, .xlsx, etc).

Em tempos primórdios, tínhamos que usar o Primary Interop Assemblies (PIA) para trabalhar com arquivos Office via código: https://www.microsoft.com/en-us/download/details.aspx?id=3508.

E o trabalho é BEM MAIS árduo do que usar o Open XML SDK.

ANÁLISE:

E um cenário deveras comum, é encontrar uma aplicação que usa o Interop para manipular arquivos Office consumindo memória e nunca mais devolvendo, criando diversos processos, sem fecha-los após uso.

clip_image002

Cada processo WINWORD.EXE, neste exemplo, consumindo 25Mb de memória. E cada utilização, mais processos, até estourar memória do servidor (ou fechar os processos manualmente).

SOLUÇÃO:

A primeira dica é evitar o uso de “2 pontos” no mesmo “comando”.

Exemplo – Ruim

WordDOC.Document doc = app.Documents.Open(@"c:\teste.doc");

 

Exemplo – Bom

WordDOC.Documents d = app.Documents;

WordDOC.Document doc = d.Open(@"c:\teste.doc");

 

Bom, essa dica vai evitar que sejam criados wrappers em objetos COM que segurem o processo em memória.

A outra dica é sinalizar que os objetos já podem ser finalizados. Após o uso, vá finalizando o uso do objetos regressivamente.

 

using WordDOC = Microsoft.Office.Interop.Word;

Application app = new Application();

WordDOC.Documents d = app.Documents;

object nullobject = Type.Missing;

object doNotSaveChanges = WordDOC.WdSaveOptions.wdDoNotSaveChanges;

try

{

WordDOC.Document doc = d.Open(@"c:\teste.doc");

doc.Activate();

doc.SaveAs(finfo.FullName.Replace(".doc", "_tmp.docx"), WordDOC.WdSaveFormat.wdFormatDocumentDefault);

((Microsoft.Office.Interop.Word._Document)doc).Close(ref doNotSaveChanges, ref nullobject, ref nullobject);

Marshal.FinalReleaseComObject(doc);

Marshal.FinalReleaseComObject(d);

((Microsoft.Office.Interop.Word._Application)app).Quit(ref nullobject, ref nullobject, ref nullobject);

Marshal.FinalReleaseComObject(app);

}

catch (Exception ex)

{

HandleException(ex);

}

 

Dessa forma os objetos serão finalizados quando o GC ocorrer.

Abraço!

Advertisements
  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: