[Monodevelop-patches-list] r2693 - in trunk/MonoDevelop/Core/src/MonoDevelop.Core: . AddIns
Lluis Sanchez <lluis@ximian.com>
lluis at mono-cvs.ximian.com
Fri Jul 29 06:18:31 EDT 2005
Author: lluis
Date: 2005-07-29 06:18:30 -0400 (Fri, 29 Jul 2005)
New Revision: 2693
Added:
trunk/MonoDevelop/Core/src/MonoDevelop.Core/AddIns/AssemblyLoader.cs
Modified:
trunk/MonoDevelop/Core/src/MonoDevelop.Core/AddIns/AddInTreeSingleton.cs
trunk/MonoDevelop/Core/src/MonoDevelop.Core/AddIns/DefaultAddInTree.cs
trunk/MonoDevelop/Core/src/MonoDevelop.Core/ChangeLog
trunk/MonoDevelop/Core/src/MonoDevelop.Core/Makefile.am
Log:
2005-07-29 Lluis Sanchez Gual <lluis at novell.com>
* AddIns/AssemblyLoader.cs:
* AddIns/DefaultAddInTree.cs:
* AddIns/AddInTreeSingleton.cs: Added an assembly sanity check, which
ensures that all addins reference the same assembly versions.
Modified: trunk/MonoDevelop/Core/src/MonoDevelop.Core/AddIns/AddInTreeSingleton.cs
===================================================================
--- trunk/MonoDevelop/Core/src/MonoDevelop.Core/AddIns/AddInTreeSingleton.cs 2005-07-29 10:07:53 UTC (rev 2692)
+++ trunk/MonoDevelop/Core/src/MonoDevelop.Core/AddIns/AddInTreeSingleton.cs 2005-07-29 10:18:30 UTC (rev 2693)
@@ -20,7 +20,7 @@
/// <summary>
/// Here is the ONLY point to get an <see cref="IAddInTree"/> object.
/// </summary>
- public class AddInTreeSingleton : DefaultAddInTree
+ public class AddInTreeSingleton
{
static IAddInTree addInTree = null;
readonly static string defaultCoreDirectory = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location) + // DON'T REPLACE
@@ -64,18 +64,21 @@
addInTree.InsertAddIn (addIn);
} catch (CodonNotFoundException ex) {
retryList.Add (addInFile);
- list.Add (new AddinError (addInFile, ex));
+ list.Add (new AddinError (addInFile, ex, false));
} catch (ConditionNotFoundException ex) {
retryList.Add (addInFile);
- list.Add (new AddinError (addInFile, ex));
+ list.Add (new AddinError (addInFile, ex, false));
} catch (MissingDependencyException ex) {
// Try to load the addin later. Maybe it depends on an
// addin that has not yet been loaded.
retryList.Add(addInFile);
- list.Add (new AddinError (addInFile, ex));
+ list.Add (new AddinError (addInFile, ex, false));
+ } catch (InvalidAssemblyVersionException ex) {
+ retryList.Add (addInFile);
+ list.Add (new AddinError (addInFile, ex, false));
} catch (Exception ex) {
retryList.Add (addInFile);
- list.Add (new AddinError (addInFile, ex));
+ list.Add (new AddinError (addInFile, ex, false));
}
}
@@ -85,8 +88,17 @@
public static AddinError[] InitializeAddins ()
{
+ AssemblyLoader loader = new AssemblyLoader();
+
+ try {
+ loader.CheckAssembly (Assembly.GetEntryAssembly ());
+ } catch (Exception ex) {
+ AddinError err = new AddinError (Assembly.GetEntryAssembly ().Location, ex, true);
+ return new AddinError[] { err };
+ }
+
AddinError[] errors = null;
- addInTree = new DefaultAddInTree();
+ addInTree = new DefaultAddInTree (loader);
FileUtilityService fileUtilityService = (FileUtilityService)ServiceManager.GetService(typeof(FileUtilityService));
@@ -131,11 +143,13 @@
{
string addinFile;
Exception exception;
+ bool fatal;
- public AddinError (string addin, Exception exception)
+ public AddinError (string addin, Exception exception, bool fatal)
{
this.addinFile = addin;
this.exception = exception;
+ this.fatal = fatal;
}
public string AddinFile {
@@ -145,5 +159,9 @@
public Exception Exception {
get { return exception; }
}
+
+ public bool Fatal {
+ get { return fatal; }
+ }
}
}
Added: trunk/MonoDevelop/Core/src/MonoDevelop.Core/AddIns/AssemblyLoader.cs
===================================================================
--- trunk/MonoDevelop/Core/src/MonoDevelop.Core/AddIns/AssemblyLoader.cs 2005-07-29 10:07:53 UTC (rev 2692)
+++ trunk/MonoDevelop/Core/src/MonoDevelop.Core/AddIns/AssemblyLoader.cs 2005-07-29 10:18:30 UTC (rev 2693)
@@ -0,0 +1,236 @@
+//
+// AssemblyLoader.cs
+//
+// Author:
+// Lluis Sanchez Gual
+//
+// Copyright (C) 2005 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Collections;
+using System.Reflection;
+using System.IO;
+using Mono.Cecil;
+
+namespace MonoDevelop.Core.AddIns
+{
+ class AssemblyLoader: MarshalByRefObject
+ {
+ Hashtable assemblies = new Hashtable ();
+
+ public Assembly LoadAssembly (string fileName)
+ {
+ Assembly asm = null;
+ if (File.Exists (fileName)) {
+ CheckAssemblyFile (fileName);
+ asm = Assembly.LoadFrom (fileName);
+ }
+ CheckAssembly (fileName);
+ if (asm == null) {
+ asm = Assembly.Load(fileName);
+ }
+ if (asm == null) {
+ asm = Assembly.LoadWithPartialName(fileName);
+ }
+ return asm;
+ }
+
+ public void CheckAssembly (Assembly asm)
+ {
+ CheckAssemblyFile (asm.Location);
+ }
+
+ public void CheckAssembly (string aname)
+ {
+ CheckAssemblyVersion (aname, null, Environment.CurrentDirectory);
+ }
+
+ public void CheckAssemblyFile (string assemblyFile)
+ {
+ IAssemblyDefinition asm = AssemblyFactory.GetAssembly (assemblyFile);
+ CheckAssemblyVersion (asm.Name.FullName, asm, Path.GetDirectoryName (assemblyFile));
+ }
+
+ void CheckAssemblyVersion (string aname, IAssemblyDefinition asm, string baseDirectory)
+ {
+ int i = aname.IndexOf (",");
+ if (i == -1) return;
+
+ string name = aname.Substring (0, i).Trim ();
+ if (IsSystemAssembly (name))
+ return;
+
+ string loadedVersion = (string) assemblies [name];
+
+ if (loadedVersion != null) {
+ if (loadedVersion != aname)
+ throw new InvalidAssemblyVersionException (loadedVersion, aname);
+ return;
+ }
+
+ assemblies [name] = aname;
+
+ if (asm == null) {
+ string file = FindAssembly (aname, baseDirectory);
+
+ if (file == null && baseDirectory != AppDomain.CurrentDomain.BaseDirectory)
+ file = FindAssembly (aname, AppDomain.CurrentDomain.BaseDirectory);
+
+ if (file == null)
+ return;
+
+ asm = AssemblyFactory.GetAssembly (file);
+ baseDirectory = Path.GetDirectoryName (file);
+ }
+
+ try {
+ foreach (IAssemblyNameReference ar in asm.MainModule.AssemblyReferences) {
+ CheckAssemblyVersion (ar.FullName, null, baseDirectory);
+ }
+ } catch {
+ assemblies.Remove (name);
+ throw;
+ }
+ }
+
+ string FindAssembly (string aname, string baseDirectory)
+ {
+ string name = aname.Substring (0, aname.IndexOf (",")).Trim ();
+ string file = Path.Combine (baseDirectory, name + ".dll");
+
+ if (File.Exists (file))
+ return file;
+
+ file = Path.Combine (baseDirectory, name + ".exe");
+ if (File.Exists (file))
+ return file;
+
+ // Look for the assembly in the GAC.
+ // WARNING: this is a hack, but there isn't right now a better
+ // way of doing it
+
+ string gacDir = typeof(Uri).Assembly.Location;
+ gacDir = Path.GetDirectoryName (gacDir);
+ gacDir = Path.GetDirectoryName (gacDir);
+ gacDir = Path.GetDirectoryName (gacDir);
+
+ string[] parts = aname.Split (',');
+ if (parts.Length != 4) return null;
+ name = parts[0].Trim ();
+
+ int i = parts[1].IndexOf ('=');
+ string version = i != -1 ? parts[1].Substring (i+1).Trim () : parts[1].Trim ();
+
+ i = parts[2].IndexOf ('=');
+ string culture = i != -1 ? parts[2].Substring (i+1).Trim () : parts[2].Trim ();
+ if (culture == "neutral") culture = "";
+
+ i = parts[3].IndexOf ('=');
+ string token = i != -1 ? parts[3].Substring (i+1).Trim () : parts[3].Trim ();
+
+ file = Path.Combine (gacDir, name);
+ file = Path.Combine (file, version + "_" + culture + "_" + token);
+ file = Path.Combine (file, name + ".dll");
+
+ if (File.Exists (file))
+ return file;
+ else
+ return null;
+ }
+
+ bool IsSystemAssembly (string aname)
+ {
+ return Array.IndexOf (systemAssemblies, aname) != -1;
+ }
+
+ // Those assemblies are automatically remapped by the runtime
+
+ string[] systemAssemblies = new string[] {
+ "Accessibility",
+ "Commons.Xml.Relaxng",
+ "I18N",
+ "I18N.CJK",
+ "I18N.MidEast",
+ "I18N.Other",
+ "I18N.Rare",
+ "I18N.West",
+ "Microsoft.VisualBasic",
+ "Microsoft.VisualC",
+ "Mono.Cairo",
+ "Mono.CompilerServices.SymbolWriter",
+ "Mono.Data",
+ "Mono.Data.SqliteClient",
+ "Mono.Data.SybaseClient",
+ "Mono.Data.Tds",
+ "Mono.Data.TdsClient",
+ "Mono.GetOptions",
+ "Mono.Http",
+ "Mono.Posix",
+ "Mono.Security",
+ "Mono.Security.Win32",
+ "Mono.Xml.Ext",
+ "Novell.Directory.Ldap",
+ "Npgsql",
+ "PEAPI",
+ "System",
+ "System.Configuration.Install",
+ "System.Data",
+ "System.Data.OracleClient",
+ "System.Data.SqlXml",
+ "System.Design",
+ "System.DirectoryServices",
+ "System.Drawing",
+ "System.Drawing.Design",
+ "System.EnterpriseServices",
+ "System.Management",
+ "System.Messaging",
+ "System.Runtime.Remoting",
+ "System.Runtime.Serialization.Formatters.Soap",
+ "System.Security",
+ "System.ServiceProcess",
+ "System.Web",
+ "System.Web.Mobile",
+ "System.Web.Services",
+ "System.Windows.Forms",
+ "System.Xml",
+ "mscorlib"
+ };
+ }
+
+ [Serializable]
+ public class InvalidAssemblyVersionException: Exception
+ {
+ string msg;
+
+ public InvalidAssemblyVersionException (string old, string anew)
+ {
+ msg = "An assembly version conflict has been detected. ";
+ msg += "The assembly '" + anew + "' has been requested, but ";
+ msg += "a different version of this assembly is already loaded: '" + old + "'.";
+ }
+
+ public override string Message {
+ get { return msg; }
+ }
+ }
+}
Modified: trunk/MonoDevelop/Core/src/MonoDevelop.Core/AddIns/DefaultAddInTree.cs
===================================================================
--- trunk/MonoDevelop/Core/src/MonoDevelop.Core/AddIns/DefaultAddInTree.cs 2005-07-29 10:07:53 UTC (rev 2692)
+++ trunk/MonoDevelop/Core/src/MonoDevelop.Core/AddIns/DefaultAddInTree.cs 2005-07-29 10:18:30 UTC (rev 2693)
@@ -23,6 +23,7 @@
/// </summary>
public class DefaultAddInTree : IAddInTree
{
+ AssemblyLoader loader;
AddInCollection addIns = new AddInCollection();
DefaultAddInTreeNode root = new DefaultAddInTreeNode();
@@ -65,8 +66,9 @@
/// <summary>
/// Constructs a new instance of the <code>DefaultAddInTree</code> object.
/// </summary>
- internal DefaultAddInTree()
+ internal DefaultAddInTree (AssemblyLoader loader)
{
+ this.loader = loader;
// load codons and conditions from the current assembly.
LoadCodonsAndConditions(Assembly.GetExecutingAssembly());
}
@@ -180,21 +182,12 @@
/// This method loads an assembly and gets all
/// it's defined codons and conditions
/// </summary>
- public Assembly LoadAssembly(string fileName)
+ public Assembly LoadAssembly (string fileName)
{
Assembly assembly = (Assembly)registeredAssemblies[fileName];
if (assembly == null) {
- Assembly asm = null;
- if (File.Exists(fileName)) {
- asm = Assembly.LoadFrom(fileName);
- }
- if (asm == null) {
- asm = Assembly.Load(fileName);
- }
- if (asm == null) {
- asm = Assembly.LoadWithPartialName(fileName);
- }
+ Assembly asm = loader.LoadAssembly (fileName);
registeredAssemblies[fileName] = assembly = asm;
LoadCodonsAndConditions(assembly);
}
Modified: trunk/MonoDevelop/Core/src/MonoDevelop.Core/ChangeLog
===================================================================
--- trunk/MonoDevelop/Core/src/MonoDevelop.Core/ChangeLog 2005-07-29 10:07:53 UTC (rev 2692)
+++ trunk/MonoDevelop/Core/src/MonoDevelop.Core/ChangeLog 2005-07-29 10:18:30 UTC (rev 2693)
@@ -1,3 +1,10 @@
+2005-07-29 Lluis Sanchez Gual <lluis at novell.com>
+
+ * AddIns/AssemblyLoader.cs:
+ * AddIns/DefaultAddInTree.cs:
+ * AddIns/AddInTreeSingleton.cs: Added an assembly sanity check, which
+ ensures that all addins reference the same assembly versions.
+
2005-07-22 John Luke <john.luke at gmail.com>
* AddIns/Addin.cs: remove unused variable warning
Modified: trunk/MonoDevelop/Core/src/MonoDevelop.Core/Makefile.am
===================================================================
--- trunk/MonoDevelop/Core/src/MonoDevelop.Core/Makefile.am 2005-07-29 10:07:53 UTC (rev 2692)
+++ trunk/MonoDevelop/Core/src/MonoDevelop.Core/Makefile.am 2005-07-29 10:18:30 UTC (rev 2693)
@@ -52,13 +52,15 @@
AddIns/TypeNotFoundException.cs \
AddIns/AddInInitializeException.cs \
AddIns/AddInCollection.cs \
+AddIns/AssemblyLoader.cs \
AddIns/AddInSignatureException.cs
build_sources = $(addprefix $(srcdir)/, $(FILES)) Services/GettextCatalog.cs AssemblyInfo.cs
DLL = $(top_builddir)/build/bin/MonoDevelop.Core.dll
-REFS = -r:Mono.Posix.dll
+REFS = -r:Mono.Posix.dll \
+ -r:$(top_builddir)/build/bin/Mono.Cecil.dll
all: $(DLL)
More information about the Monodevelop-patches-list
mailing list