mardi 8 juin 2010

Interopérabilité Word 2007 Un composant externe a levé une exception

J’ai travaillé sur une application Winforms développée en C# qui génère des documents Word.
La génération consiste à remplacer les mots clés dans le document par les données de la base de données.

Sur certains postes d'utilisateur, la génération renvoie une exception:
"Composant externe a levé une exception" ou "Le relais a reçu des données incorrectes"

Après plusieurs recherches, c'est lors d'appel de l'objet Find qui pose problème.
Ceci est dû à l'enregistrement des bibliothèques antérieures à 2007 qui sont enregistrées dans la base de registre Windows après celles de 2007.

Deux solutions possibles:
1. Exécuter la ligne de commande: C:\Program Files\Microsoft Office\Office12\Winword.exe /r qui force la réinscription des dll Word dans la base de registre Windows.
Ou s'il n'y a qu'une seule version Word sur le poste, aller dans Démarrer -> Exécuter -> winword.exe /r

2. Utilisez liaison tardive pour l'objet Find (late binding).
J'ai transformé le code suivant:
object missingValue = Type.Missing;
object replaceAll = Microsoft.Office.Interop.Word.WdReplace.wdReplaceAll; Microsoft.Office.Interop.Word.Find find = ThisApplication.Selection.Range.Find;
object texteRecherche = TextRecherche;
object texteRemplace = TextNew;
find.Execute(ref texteRecherche ref missingValue, ref missingValue, ref missingValue,
ref missingValue, ref missingValue, ref missingValue, ref missingValue, ref missingValue, ref texteRemplace,
ref replaceAll, ref missingValue, ref missingValue, ref missingValue, ref missingValue);
à
object missingValue = Type.Missing;
object replaceAll = Microsoft.Office.Interop.Word.WdReplace.wdReplaceAll; Microsoft.Office.Interop.Word.Find find = ThisApplication.Selection.Range.Find;
object texteRecherche = TextRecherche;
object texteRemplace = TextNew;
object[] Parameters;
Parameters = new object[15];
Parameters[0] = texteRecherche
Parameters[1] = missingValue;
Parameters[2] = missingValue;
Parameters[3] = missingValue;
Parameters[4] = missingValue;
Parameters[5] = missingValue;
Parameters[6] = missingValue;
Parameters[7] = missingValue;
Parameters[8] = missingValue;
Parameters[9] = texteRemplace
Parameters[10] = replaceAll;
Parameters[11] = missingValue;
Parameters[12] = missingValue;
Parameters[13] = missingValue;
Parameters[14] = missingValue;
find.GetType().InvokeMember("Execute", System.Reflection.BindingFlags.InvokeMethod, null, find,Parameters);
// Libérer les ressources
System.Runtime.InteropServices.Marshal.ReleaseComObject(oFind);
oFind = null;
System.Runtime.InteropServices.Marshal.ReleaseComObject(oSelection);
oSelection = null;

Le problème a été résolu.

NB: Bien que la première méthode est plus facile, l'application peut échouer par la suite, si la bibliothèque de type Excel 95,… est réinscrite par une autre application ou un service pack.

Pour aller plus loin:
http://support.microsoft.com/kb/313104
http://support.microsoft.com/kb/210565

Aucun commentaire:

Enregistrer un commentaire