Assembly.LoadFrom() und %20 chars = Exception; brauche Hilfe

Rando

Mitglied
Moin allerseits,

wieder mal ein kleines Problem. Ich hoffe der ein oder andere hat damit schon mal zu tun gehabt und es hoffentlich auch gelöst und kann mir hier weiterhelfen.

Folgendes Schnipsel Code:
Assembly assembly=Assembly.LoadFrom(assembly_name);

Die Variable assembly_name wird aus einem XML Reader, der ein File einliest gefüllt und zwar mit dem Wert:
file:///c:/Dokumente%20und%20Einstellungen/Mein%20Name/Desktop/Lite/bin/Text_Chip.DLL

Dabei wird genau in der obigen Codezeile eine System.IO.FileNotFound Exception geschmissen.

Habe ich aber folgenden Pfad in der XML-Datei:
file:///d:/HOME/CS/CS_Chip/ChipLite.0-0-03/Lite/bin/Text_Chip.DLL
funktioniert alles einwandfrei.

Also führen ALLE Characters "%.." dazu, dass die Exception geworfen wird. Ich brauche aber eine allgemeingültige Lösung inkl. eventueller Whitespace und anderer Sonderzeichen.

Kann jemand helfen?
Vielen Dank schon mal
Greeds Rando :D
 
Ja der Pfad, wird (ebenfalls über XML Methoden aus C#) bereits mit %20 abgespeichert.

Norbert Eder hat gesagt.:
Steht der Pfad schon mit %20 in dem XML File? Oder sind dort noch die Leerzeichen drinnen?

Greeds Rando :D

P.S.: Hier der Quellcode der Methode, die für das Schreiben der XML-Infos verantwortlich ist.

Code:
public virtual void WriteXml(XmlWriter writer)
	{
		writer.WriteAttributeString("assembly", 
			this.GetType().Assembly.EscapedCodeBase);
		writer.WriteStartElement("FormBorderStyle");
		new XmlSerializer(FormBorderStyle.GetType())
			.Serialize(writer,FormBorderStyle);
		writer.WriteEndElement();
	
		writer.WriteStartElement("Location");
		new XmlSerializer(Location.GetType())
			.Serialize(writer,Location);
		writer.WriteEndElement();
	
		writer.WriteStartElement("Size");
		new XmlSerializer(Size.GetType())
			.Serialize(writer,Size);
		writer.WriteEndElement();

		writer.WriteStartElement("ParentSlot");
		writer.WriteString(parent_slot);
		writer.WriteEndElement();
		writer.WriteStartElement("PrimarySlot");
		writer.WriteString(primary_slot);
		writer.WriteEndElement();
	
		writer.WriteStartElement("Model");
		new XmlSerializer(model.GetType()).Serialize(writer,model);
		writer.WriteEndElement();
	
		foreach(Chip_View child in child_chips)
		{
			writer.WriteStartElement("View");
			new XmlSerializer(child.GetType()).Serialize(writer,child);
			writer.WriteEndElement();
		}
	}
 
Und wie liest es ein? Deserialisierst die Dinge wieder?

Und wenn du schon die Form-Properties in ein Xml rausschreibst, wieso serialisierst, nicht gleich das komplette Object raus?
 
Nee sry, da hatte ich dich nun missverstanden. Beim abspeichern, wird das komplette Objekt rausserialisiert (s.Code):

Code:
public void Save()
	{
		String filename=null;
		SaveFileDialog dialog = new SaveFileDialog();
	
		dialog.Filter = "chip files (*.chp)|*.chp|All files (*.*)|*.*"  ;
		dialog.FilterIndex = 1 ;
		dialog.RestoreDirectory = true ;
	
		if(dialog.ShowDialog() == DialogResult.OK)
		{
			if((filename = dialog.FileName) != null)
			{
				try
				{
					XmlSerializer xml_serializer=
						new  XmlSerializer(this.GetType());
					XmlTextWriter writer = 
						new XmlTextWriter(new StreamWriter(filename));
					writer.Formatting = Formatting.Indented;
					xml_serializer.Serialize(writer,this);

					writer.Flush();
					writer.Close();
				}
				catch(Exception e){Console.WriteLine(e);}
			}
		}
	}

Für das Einlesen in diesem Falle sind diese beiden Methoden verantwortlich:

Code:
public static Chip_View LoadFromXml(String filename)
	{
		Chip_View new_view=null;
		XmlTextReader reader = new XmlTextReader(filename);
		new_view=LoadFromXml(reader);
		return new_view;
	}

	public static Chip_View LoadFromXml(XmlReader reader)
	{
		Chip_View new_view=null;
		String view_name=null;
		String assembly_name=null;
		
		try
		{
			while(reader.Read())
			{
				if(reader.NodeType==XmlNodeType.Element)
				{
					view_name=reader.Name;
					while (reader.MoveToNextAttribute())
					{
						if(reader.Name=="assembly")
						{
							assembly_name=reader.Value;
						}
					}
					break;
				}
			}
			Assembly assembly=Assembly.LoadFrom(assembly_name); //Bug: Here an FileNotFound exception occurs
			Type target=assembly.GetType(view_name);
			new_view=Chip_View.LoadChip(target);
			new_view.ReadXml(reader);
			new_view.UpdateView();
		}
		catch(Exception e)
		{
			MessageBox.Show(e.ToString());
		}
		return new_view;
	}

Hoffe nun wird das Problem etwas deutlicher. Deserialisiert werden die FormProperties in der Methode ReadXml, zu deren Aufruf es ja aber erst gar nicht kommt, weil es schon vorher knallt in der Assembly.LoadFrom-Zeile.
 
Ok, das heißt du übergibst deiner LoadFromXml (string) Methode den Dateinamen der eingelesen werden soll.

Jetzt hab ich noch eine Frage:
Dieser Filename beherbergt ja die nicht gewünschten %20. Woher kommt der Filename? OpenFileDialog, oder woher liest den ein? Hab den Aufruf dieser Methode jetzt nirgends gefunden.
 
schon wieder wahrscheinlich ein kleines Missverständnis. Also am Anfang steht ein FileOpen-Dialog, das siehst du 100% richtig:

Code:
public static Chip_View LoadFrom(String filename)
	{
		Chip_View new_view=null;
		String extension=Path.GetExtension(filename);
		if(extension==".chp"||extension==".xml")
		{
			new_view=LoadFromXml(filename);
		}
		else if(extension==".dll"||extension==".exe")
		{
			new_view=LoadFromAssembly(filename);
		}
		return new_view;
	}
Wie du siehst wird der Dateiname an die erste LoadFromXml-Methode übergeben (s. oben), die dann ihrerseits an die nächste LoadFromXml-Methode übergibt, aber mit dem zuvor angelegten TextReader.

ABER und hier liegt wohl das Missverständnis. Der erste übergebene Dateiname (filename) ist nicht das Problem, sondern die die Methode

public static Chip_View LoadFromXml(XmlReader reader)

beginnt Ihrerseits damit das XML-File selbst zu lesen und sucht darin nach dem Eintrag:

<?xml version="1.0" encoding="utf-8"?>
<Text_View assembly="file:///C:/MCAD/C%23/iPAD_V2/Chip_Lite/bin/Debug/Text_Pad.dll">


und das ist dann der Pfad zu der Assembly, die geöffnet werden soll und dann knallts, denn wie du siehst steht in diesem Beispiel nun "%23" im Pfad, was normalerweise ein # ist.

Auf jeden Fall schon mal BigTHX für deine Unterstützung.
Greeds Rando :D
 
OK habs gefunden. Selbst schuld ist der Mann :)

In der WriteXml Methode musste der Parameter

writer.WriteAttributeString("assembly",
this.GetType().Assembly.EscapedCodeBase);


zu

writer.WriteAttributeString("assembly",
this.GetType().Assembly.CodeBase);


geändert werden, dann lief es. Thanx @all (vor allem an Norbert) ;)

Greeds Rando :D
 

Neue Beiträge

Zurück