2 // BaseAssemblyResolver.cs
5 // Jb Evain (jbevain@gmail.com)
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 namespace Mono.Cecil {
32 using System.Collections;
34 using SR = System.Reflection;
37 public abstract class BaseAssemblyResolver : IAssemblyResolver {
39 ArrayList m_directories;
41 public void AddSearchDirectory (string directory)
43 m_directories.Add (directory);
46 public void RemoveSearchDirectory (string directory)
48 m_directories.Remove (directory);
51 public string [] GetSearchDirectories ()
53 return (string []) m_directories.ToArray (typeof (string));
56 public virtual AssemblyDefinition Resolve (string fullName)
58 return Resolve (AssemblyNameReference.Parse (fullName));
61 public BaseAssemblyResolver ()
63 m_directories = new ArrayList ();
64 m_directories.Add (".");
65 m_directories.Add ("bin");
68 public virtual AssemblyDefinition Resolve (AssemblyNameReference name)
70 AssemblyDefinition assembly;
71 string frameworkdir = Path.GetDirectoryName (typeof (object).Module.FullyQualifiedName);
73 assembly = SearchDirectory (name, m_directories);
77 if (IsZero (name.Version)) {
78 assembly = SearchDirectory (name, new string [] {frameworkdir});
83 #if !CF_1_0 && !CF_2_0
84 if (name.Name == "mscorlib") {
85 assembly = GetCorlib (name);
90 assembly = GetAssemblyInGac (name);
95 assembly = SearchDirectory (name, new string [] {frameworkdir});
99 throw new FileNotFoundException ("Could not resolve: " + name);
102 static readonly string [] _extentions = new string [] { ".dll", ".exe" };
104 static AssemblyDefinition SearchDirectory (AssemblyNameReference name, IEnumerable directories)
106 foreach (string dir in directories) {
107 foreach (string ext in _extentions) {
108 string file = Path.Combine (dir, name.Name + ext);
109 if (File.Exists (file))
110 return AssemblyFactory.GetAssembly (file);
117 static bool IsZero (Version version)
119 return version.Major == 0 && version.Minor == 0 && version.Build == 0 && version.Revision == 0;
122 #if !CF_1_0 && !CF_2_0
123 static AssemblyDefinition GetCorlib (AssemblyNameReference reference)
125 SR.AssemblyName corlib = typeof (object).Assembly.GetName ();
126 if (corlib.Version == reference.Version || IsZero (reference.Version))
127 return AssemblyFactory.GetAssembly (typeof (object).Module.FullyQualifiedName);
129 string path = Directory.GetParent (
130 Directory.GetParent (
131 typeof (object).Module.FullyQualifiedName).FullName
135 if (reference.Version.Major == 1)
136 path = Path.Combine (path, "1.0");
137 else if (reference.Version.Major == 2) {
138 if (reference.Version.Minor == 1)
139 path = Path.Combine (path, "2.1");
141 path = Path.Combine (path, "2.0");
143 throw new NotSupportedException ("Version not supported: " + reference.Version);
145 if (reference.Version.ToString () == "1.0.3300.0")
146 path = Path.Combine (path, "v1.0.3705");
147 else if (reference.Version.ToString () == "1.0.5000.0")
148 path = Path.Combine (path, "v1.1.4322");
149 else if (reference.Version.ToString () == "2.0.0.0")
150 path = Path.Combine (path, "v2.0.50727");
152 throw new NotSupportedException ("Version not supported: " + reference.Version);
155 if (File.Exists (Path.Combine (path, "mscorlib.dll")))
156 return AssemblyFactory.GetAssembly (Path.Combine (path, "mscorlib.dll"));
161 public static bool OnMono ()
163 return typeof (object).Assembly.GetType ("System.MonoType", false) != null;
166 static AssemblyDefinition GetAssemblyInGac (AssemblyNameReference reference)
168 if (reference.PublicKeyToken == null || reference.PublicKeyToken.Length == 0)
171 string currentGac = GetCurrentGacPath ();
173 string s = GetAssemblyFile (reference, currentGac);
175 return AssemblyFactory.GetAssembly (s);
177 string [] gacs = new string [] {"GAC_MSIL", "GAC_32", "GAC"};
178 for (int i = 0; i < gacs.Length; i++) {
179 string gac = Path.Combine (Directory.GetParent (currentGac).FullName, gacs [i]);
180 string asm = GetAssemblyFile (reference, gac);
181 if (Directory.Exists (gac) && File.Exists (asm))
182 return AssemblyFactory.GetAssembly (asm);
189 static string GetAssemblyFile (AssemblyNameReference reference, string gac)
191 StringBuilder sb = new StringBuilder ();
192 sb.Append (reference.Version);
194 for (int i = 0; i < reference.PublicKeyToken.Length; i++)
195 sb.Append (reference.PublicKeyToken [i].ToString ("x2"));
197 return Path.Combine (
199 Path.Combine (gac, reference.Name), sb.ToString ()),
200 string.Concat (reference.Name, ".dll"));
203 static string GetCurrentGacPath ()
205 return Directory.GetParent (
206 Directory.GetParent (
207 Path.GetDirectoryName (
208 typeof (Uri).Module.FullyQualifiedName)