Feed
Contact
XING
LinkedIn
Twitter
ICQ
meebo.com

Mehr Infos zu nichts sagenden Fehlermeldungen

by Roland Schumacher alias GENiALi 16. October 2009 -- 116 Wörter  -- 171 mal gelesen
Dieser Beitrag ist mir was wert:  

Wer wusste das?

Ich bekomme zur Zeit immer eine Fehlermeldung im Word die mir eigenartig vorkommt.

Fehlermeldung

Das ist ein eingebettetes Excel im Word. Alles unter Office 2007. Excel ist aber sicher installiert.
Diese Meldung kommt nur wenn man a) ein Add-in im Excel hat das einige Events registriert hat und b) wenn Excel vor dem Word mit dem eingebetteten Excel startet. Aber sie kann durchaus auch in anderen Situationen auftreten. Ich habe ihm Internet einige gefunden.

Aber was interessant ist. Drückt mal “Ctrl + Shift + i”.

Fehlernummer unten rechts im Dialog

Es erscheint unten rechts eine Fehlernummer. Habe dazu zwar noch nichts gefunden aber das wird schon noch kommen.

Ich bin gespannt wo ich noch mehr von diesen Meldungen finde.

kick it on dotnet-kicks.de

Tags: , , , ,

Entwicklung

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

by Roland Schumacher alias GENiALi 15. October 2009 -- 449 Wörter  -- 347 mal gelesen
Dieser Beitrag ist mir was wert:  

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

Tags: , , , ,

Entwicklung

Office XP - deploy Add-in – Wie registriert man die Extensibility.dll

by Roland Schumacher alias GENiALi 28. November 2008 -- 457 Wörter  -- 230 mal gelesen
Dieser Beitrag ist mir was wert:  

Wer suched der findet. Bei mir hat es jetzt sehr, sehr lange gedauert.

Ich habe ein Office XP Add-in das auf diversen Systemen mit verschiedenen Konfigurationen installiert werden muss. Ein Add-in für Office XP/2002 muss die Schnittstelle Extensibility.IDTExtensibility2 implementieren. Diese ist in der Extensibilty.dll definiert.

Auf einem XP mit SP2 und Office XP/2002 ohne SP ist die DLL aber nicht registriert, dass heisst nicht im GAC.

Auf dem Entwicklungsclient habe ich die DLL natürlich. Also, ich nehme die dll, kopiere sie auf das Zielsystem und versuche das Teil mit RegAsm.exe zu registrieren. Das führt zu einer Fehlermeldung in dieser form.

RegAsm : error RA0000 : Could not load file or assembly 'Extensibility, Version= 7.0.3300.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of

Das Teil will einfach nicht in den GAC.

Wie bin ich nun vorgegangen um das Add-in auf einem frisch aufgesetzten System an den Start zu bringen.

  1. Man mache ein Setup. Das Setup mache ich NUR weil ich nicht weiss was alles in die Registry muss.
    Die Primäre Ausgabe wird bei Register auf vsdrpCOM gestellt.
    image
  2. Bei den Abhängigkeiten genau das selbe. Wenn ich die Office XP/2002 PIA Abhängigkeiten aus dem Setup ausschliesse, und sie deshalb nicht registriert werden, läuft das Add-in nicht mehr. Aber eigentlich müssten die Office XP/2002 PIA’s ja schon bei der Installation der Office XP/2002 PIA’s registriert worden sein.
    image
  3. Wenn man schon dabei ist, dann kann man auch gleich noch drei Registry Key importieren. Für jedes Office Programm das ein Add-in hat ein Schlüssel.

    Windows Registry Editor Version 5.00

    [HKEY_CURRENT_USER\Software\Microsoft\Office\Word\Addins\namespace.namespace]
    "Description"="Bschreibung"
    "FriendlyName"="Angezeigter Name des AddIns im Office"
    "LoadBehavior"=dword:00000003

    Die rot markierten Textteile müssen dann noch passend ersetzt werden.

  4. Das Add-in hat einen sehr einfachen Code.
  5. using System;
    using System.Text;
    using System.Reflection;
    using Extensibility;
    using System.Runtime.InteropServices;
    using System.Windows.Forms;
    
    namespace LAG.WordPlus.OfficeAddIns.Word2002
    {
    	public class Word2002 : Object, Extensibility.IDTExtensibility2
    	{
    		#region IDTExtensibility2 Member
    
    		public void OnAddInsUpdate(ref Array custom)
    		{
    		}
    
    		public void OnBeginShutdown(ref Array custom)
    		{
    
    		}
    
    		public void OnConnection(object Application, ext_ConnectMode ConnectMode, object AddInInst, ref Array custom)
    		{
    			MessageBox.Show("OnConnection -- Hallo :-)");
    		}
    
    		public void OnDisconnection(ext_DisconnectMode RemoveMode, ref Array custom)
    		{
    			MessageBox.Show("OnDisconnection -- ByBy :-)");
    		}
    
    		public void OnStartupComplete(ref Array custom)
    		{
    			MessageBox.Show("OnStartupComplete -- TippTopp :-)");
    		}
    		#endregion
    	}
    }
  6. Dann besorgt man sich folgenden VS2005-KB908002-ENU-x86.EXE fix. Die Thematik des KB interessiert nicht wirklich. Dort drin gibt es eine ganz bestimmtes MSI Packet.
  7. Man führt die EXE aus. Im Ordner C:\Programme\Microsoft Visual Studio 8\SDK\v2.0\BootStrapper\Packages\KB908002 findet man nun die Datei extensibilityMSM.msi. Und die ist für dieses Problem Gold wert. Ich habe leider keinen anderen Weg gefunden wie man an das MSI kommt.
  8. Auf dem Zielsystem führt man nun das extensibilityMSM.msi aus und anschliessend noch das eigene Setup. 

Danach müsste ein Dialog erscheinen der etwa so aussieht.

image

Es kann aber noch 1000 andere Gründe geben.

- Sind die nötigen .NET Versionen installiert?
- Sind die Office CP/2002 PIA’s installiert?

Jedenfalls habe ich jetzt endlich einen Weg gefunden wie ich das Add-in lauffähig bringe.

Tags: , ,

Entwicklung | Software

VSTO – Probleme mit Zeilenumbrüchen

by Roland Schumacher alias GENiALi 18. November 2008 -- 123 Wörter  -- 72 mal gelesen
Dieser Beitrag ist mir was wert:  

Es kann durchaus sein, dass in einer Anwendung (WordPlus) ein solcher Dialog auftaucht.

image

Dargestellt werden die eingegebenen Daten so:

image

Hier wird also ein Zeilenumbruch eingefügt. Das macht man in der Regel mit Environment.NewLine;.

Diese Adresse wird jetzt dem Word oder Excel übergeben. Das kann dann so aussehen.

image

Was mich jetzt aber am meisten erstaunt ist die Tatsache, dass es bei einem DOCPROPERTY richtig aussieht und bei einer DOCVARIABLE nicht. Dort gibt es für den Zeilenumbruch ganz spezielle Sonderzeichen.

image

Das selbe kenne ich noch von gewissen Feldern im Excel. Wenn das auftritt, dann macht man einfach ein Replace("\r\n", "\r"); auf den String den man nutzen will. Und schon sieht es wieder normal aus.

image

Was Microsoft hier wohl überlegt hat?

Tags: ,

Entwicklung

Die Assembly Irgendwas, Version=4 … kann nicht gefunden werden.

by Roland Schumacher alias GENiALi 8. October 2008 -- 303 Wörter  -- 123 mal gelesen
Dieser Beitrag ist mir was wert:  

Wie oft habe ich nun diese Fehlermeldung schon bekommen. Es ist unglaublich.

Ich portiere zur Zeit ein Office 2003/2007 Add-In, dass mit VSTO entwickelt wurde, nach Office 2002/XP. Dort ist nicht mehr die VSTO aktuell sondern die PIA’s (Primary Interop Assemblies) für Office XP. Im grossen und ganzen wird das Add-In einfach anders geladen. Vor allem darf man mit dem Extensibility.IDTExtensibility2 Interface arbeiten. Den restlichen Code kann man 1 zu 1 übernehmen.

Das Add-In wird im Office als ganz normales COM Add-In registriert und auch als solches behandelt. Genau das verursacht nun diverse Probleme die umschifft werden müssen.

Die .NET Laufzeit sucht in dieser Konstellation die diversen beteiligten Verweise im Ausführungsverzeichnis von der startenden Office-Anwendung. Das ist dann meist im Ordner “C:\Programme\Microsoft Office\Office10”. Dort sind die Assemblies aber nicht vorhanden. Was kann man dagegen tun?

Zum Beispiel hilft diese Datei, die man genau in den besagten Order tut, bei Word schon einiges. Die Datei heisst WINWORD.EXE.config und hat folgenden Inhalt.

<?xml version="1.0"?>
<configuration>
    <startup>
        <supportedRuntime version="v2.0.50727"/>
    </startup>
</configuration>

Das erleichtert einem schon einiges. Die Standard-Assemblies werden so gefunden.

Aber beim BinaryFormatter greift auch das nicht. Hier muss man es anders Lösen.

licenses = (LicenseCollection)formatter.Deserialize(licensestream);

Hier kommt die Meldung, dass die Assembly für den Typ LicenseCollection nicht gefunden werden kann. Das ist dann natürlich sehr ärgerlich.

Hier habe ich dann die Lösung gefunden.

private static void InitializeLicenses()
{
	ResolveEventHandler loadComponentAssembly = new ResolveEventHandler(LoadComponentAssembly);
	AppDomain.CurrentDomain.AssemblyResolve += loadComponentAssembly;

    licenses = new LicenseCollection();

	string licensefilename = 
		Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.
		GetExecutingAssembly().CodeBase), 
		"license.dat").Replace(@"file:\", "");

    if(File.Exists(licensefilename))
    {
		try
		{
			FileStream licensestream = 
				new FileStream(licensefilename, FileMode.Open, FileAccess.Read);
			BinaryFormatter formatter = 
				new BinaryFormatter();

			formatter.AssemblyFormat = 
				System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Simple;

			licenses = (LicenseCollection)formatter.Deserialize(licensestream);
			licensestream.Close();
		}
		catch (Exception ex)
		{}
		finally
		{
			AppDomain.CurrentDomain.AssemblyResolve -= loadComponentAssembly;
		}
    }
    else
    {
        ErrorHandler.LogInfo(1000, "License not found!");
    }
}

static Assembly LoadComponentAssembly(Object sender, ResolveEventArgs args)
{
	string simpleName = args.Name.Substring(0, args.Name.IndexOf(','));
	string assemblyPath = simpleName + ".dll";
	return Assembly.LoadFrom(Path.Combine
				(Path.GetDirectoryName
				(System.Reflection.Assembly.GetExecutingAssembly().CodeBase), 
				assemblyPath).Replace(@"file:\", ""));
}

So wird die Assembly gefunden.

Und wieder ein Problem weniger. Ab zum nächsten. :-)

Tags: , ,

Entwicklung | Software

Übersetzen

Diverses

Seitwert

Locations of visitors to this page

Rating
Excellent - 97%overlay Icon

Statistik