VSTO – Word Office XP/2002 – normal.dot wird immer grösser

 Entwicklung  Kommentare deaktiviert für VSTO – Word Office XP/2002 – normal.dot wird immer grösser
Okt 152009
 

Für WordPlus 4 generiere ich ein Menü im Word. Wir mussten feststellen, dass nach dem Word geschlossen wurde die normal.dot immer um ein paar KB grösser wurde. 30,40,50,60KB … bis es Kunden gab die mit mehr als 10MB zu kämpfen hatten. Das darf aber nicht sein. Nicht wegen einem Menü.

Wenn ein Menüpunkt dem Word hinzugefügt passiert das in etwa so.

Office.CommandBar toolBar = word.CommandBars.Add("Name des Menüpunkte", 
Microsoft.Office.Core.MsoBarPosition.msoBarTop, Type.Missing, true);

Der letzte Parameter würde eigentlich angeben das der Eintrag nur temporär wäre. Aber die VSTO scheint das zu ignorieren. Deshalb wird die normal.dot immer grösser.

Im Netzt gibt es einige Lösungen für das Problem.

– Die normal.dot schreibschützen. Nein, nicht gut.

– Das Menü in ein Menu.dot auslagern und das installieren. Auch nicht gut, da bei uns das Menü dynamisch aufgebaut wird.

– Den CusomizationContext auf der WordApplication ändern. Das tönt nicht schlecht.

Den letzten Punkt habe ich dann mal umgesetzt.

private Word.Template GetCustomTemplate()
{
	object templatePath = Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().CodeBase), "Menu.dot").Replace(@"file:\", "");            

	if (!File.Exists(templatePath as string))
	{
		return null;
	}

	object install = true;
	word.AddIns.Add(templatePath.ToString(), ref install);
	return word.Templates.get_Item(ref templatePath);
}

private void CreateMenu(string ribbonXml, string iconPath)
{
	Word.Template customTemplateTemp = (Word.Template)word.CustomizationContext;
	Word.Template newTemplate = null;

	try
	{
		//TemplateContext in Sicherheit bringen
		newTemplate = GetCustomTemplate();
		if (newTemplate != null)
		{
			word.CustomizationContext = newTemplate;
		}

		//Menü erstellen
	}
	finally
	{
		if (newTemplate != null)
		{
			((Word.Template)word.CustomizationContext).Saved = true;
			word.CustomizationContext = customTemplateTemp;
		}
	}
}

Es wird also ein Menu.dot gesucht. Wenn es diese gibt wird der CustomizationContext damit ausgetauscht und das original vorher noch in Sicherheit gebracht. Das Menü wird erstellt und danach wieder der alte Context angehängt. Ist eine Empfehlung aus dem Netzt und wurde früher in VBA auch so gelöst.

Bei mir funktionierte das einwandfrei. Egel ob ich Word aus Visual Studio heraus startete oder nicht. Das Menü wurde richtig geladen und die Klickevents funktionierten.

Ich musste jetzt aber feststellen, dass es Clients gibt bei denen einfach kein Klickevent ausgelöst wird. Wenn auf ein Menüeintrag geklickt wurde passierte einfach nichts. Aber nicht auf allen Clients. Auf dem Entwicklungsclient klappte es. Egal ob ich das AddIn aus VS heraus startete oder nicht. Menü tat immer. Man finde jetzt das Problem.

Word hat zudem die dumme Angewohnheit ein altes Menü immer noch anzuzeigen, obwohl das AddIn nicht geladen wurde. Ich ging also immer davon aus, dass das AddIn geladen wird.

Nach langem suchen wurde dann klar was los ist.

Das AddIn wird geladen, dass Menü erstellt und auch angezeigt. Aber sobald der Code in der Zeile 36 vorbei kam verschwand das Menü. Also wusste ich das es mit dem CustomizationContext zusammen hängen musste.

Die Lösung ist jetzt äusserst einfach.

//Menü erstellen
((Word.Template)word.CustomizationContext).Saved = true;

Das Menü wird nun angezeigt und funktioniert auch. Kein Context wechsel mehr.

Die normal.dot wird aber nicht mehr grösser. Wenn Änderungen an Word vorgenommen werden, z.b. Toolbar Anpassungen, werden diese aber sehr wohl in der normal.dot gespeichert. Aber das automatisch generierte Menü kommt nicht mehr in die normal.dot. Ziel erreicht.

kick it on dotnet-kicks.de