Langsames Ausführen von Word bei der Ansterung über C#

15/01/2009 - 12:24 von Thomas Meutzner | Report spam
Hallo,

ich habe in unserer Anwendung eine Schnittstelle zu Word geschaffen,
um eine komfortable Druckfunktion zu integrieren.
Als Word-Versionen sollen alle Versionen ab Word 2000 unterstützt
werden. Um dies zu realisieren habe ich mittlerweile LateBinding
verwendet.

Ich habe dazu eine Funktion erstellt (siehe Quellcode unten), der ich
die Vorlagendatei und eine Liste vom Typ "TextBookmark" übergebe, die
die Namen und Werte der einzelnen Textmarken enthàlt, die gefüllt
werden sollen.

Ich bzw. unsere Kunden haben aber zwei Probleme festgestellt.

1.) Beim Aufruf von Type.GetTypeFromProgID("Word.Application");
erhalte ich manchmal mehrfach den Wert NULL und dann funktioniert es
wieder. Speziell bei zwei PCs mit Windows-XP und Office 2000 hatte ich
das Problem. Gibt es dafür eine Erklàrung?

2.) Beim ersten Start dauert es ca. 1 bis 2 Sekunden bis Word
gestartet und die Textmarken in der Vorlage mit den Werten ausgefüllt
waren. Bei weiteren Test dauerte der Vorgang teilweise mehr als 15
Sekunden (Word war geschlossen). Schneller wurde es hingegen, wenn
Word bei diesen Versuchen schon gestartet war.
Kann ich meine Funktion noch irgendwie optimieren, damit dies
schneller geht oder habe ich einen Denkfehler in der Funktion?


class Class1
{
private object mDocument=null;
private object mDocuments=null;
private object mWordApplication=null;
private Type mWordType=null;

/// <summary>
/// Ruft Word mit der angegebenen Vorlage auf und fàŒllt die
Textmarken.
/// </summary>
/// <param name="templateFile">Word-Vorlage</param>
/// <param name="bookmarkList">Liste mit den Namen und Werten
der Textmarken, die im Word-Dokument ersetzt werden sollen.</param>
private void TestWord(string templateFile, IList<TextBookmark>
bookmarkList)
{
this.mWordType Type.GetTypeFromProgID("Word.Application", true);
if (this.mWordType == null)
{
MessageBox.Show("Es ist kein Word auf dem PC
installiert.", "WordTest", MessageBoxButtons.OK, MessageBoxIcon.Error,
MessageBoxDefaultButton.Button1);
}
else
{
try
{
// Vorhandene Word-Instanz holen
this.mWordApplication Marshal.GetActiveObject("Word.Application");
}
catch
{
// Neue Word-Instanz erzeugen
try
{
this.mWordApplication Activator.CreateInstance(this.mWordType);
}
catch (Exception ex)
{
MessageBox.Show("Fehler beim Starten von
Word:" + ex.Message, "WordTest", MessageBoxButtons.OK,
MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
}
}

if (this.mWordApplication != null)
{
// Alle Dokumente laden
this.mDocuments this.mWordApplication.GetType().InvokeMember("Documents",
BindingFlags.GetProperty, null, this.mWordApplication, new object[0]);
this.mDocuments.GetType().InvokeMember("Add",
BindingFlags.InvokeMethod | BindingFlags.OptionalParamBinding, null,
this.mDocuments, new object[] { templateFile });

// Aktuelles Dokument holen
this.mDocument this.mWordType.InvokeMember("ActiveDocument",
BindingFlags.GetProperty, null, this.mWordApplication, new object[0]);

Object mWordSelection this.mWordApplication.GetType().InvokeMember("Selection",
BindingFlags.GetProperty, null, this.mWordApplication, null);

// Alle Textmarken holen
object bookMarks this.mDocument.GetType().InvokeMember("Bookmarks",
BindingFlags.GetProperty, null, this.mDocument, null);

foreach (object bm in bookMarks as
System.Collections.IEnumerable)
{
object range bm.GetType().InvokeMember("Range", BindingFlags.GetProperty, null, bm,
null);
string bmName (string)bm.GetType().InvokeMember("Name", BindingFlags.GetProperty,
null, bm, null);

object select bm.GetType().InvokeMember("Select", BindingFlags.InvokeMethod, null,
bm, null);

bm.GetType().InvokeMember("Text",
BindingFlags.SetProperty, null, mWordSelection, new object[] {
ContainsInList(bookmarkList, bmName) });
}

this.mWordType.InvokeMember("Visible",
BindingFlags.SetProperty, null, this.mWordApplication, new object[] {
true });

}
}
}


/// <summary>
/// Gibt den Wert der Textmarke zurück, die dem angegebenen Namen
entspricht. Der Name ist der Name der im Word-Dokument enthaltenen
Textmarke. Diese muss nicht unbedingt in der Auflistung bookmarkList
enthalten sein.
/// </summary>
private string ContainsInList(IList<TextBookmark>
bookmarkList, string bookmarkName)
{
if (bookmarkList == null || bookmarkList.Count == 0)
return string.Empty;

for (int i = 0; i < bookmarkList.Count; i++)
if (bookmarkList[i].BookmarkName == bookmarkName)
return bookmarkList[i].BookmarkValue;

return string.Empty;
}
}


Vielen Dank für Eure Hilfe.
MfG
Thomas
 

Lesen sie die antworten

#1 tcnt.Dzaebel
15/01/2009 - 15:25 | Warnen spam
Hallo Thomas,

Word langsam ...



[Word startet, druckt oder làdt Dokumente langsam]
http://support.microsoft.com/kb/280821/de

Auch Reflection->Invoke ist eher langsam.
Führe normal nur Methoden, die in anderen
Office-Version andere Signaturen haben
latebind aus.

Installiere jeweils die aktuellsten SPs,
in denen oft auch Performance-Updates mit
enthalten sind.

Hier die gàngigen Ausführungszeiten:

[Benchmarking Microsoft Word 95 through Word 2007 - OpenOffice.org
Ninja]
http://www.oooninja.com/2008/07/ben...-2007.html

Hàufiger Performance Trick bei Office ist es
auch, Dinge temporàr in die Zwischenablage zu
tun und dann nur über Automation zu pasten.


ciao Frank
Dipl.Inf. Frank Dzaebel [MCP/MVP C#]
http://Dzaebel.NET

Ähnliche fragen