2
// BaseAssemblyResolver.cs
5
// Jb Evain (jbevain@gmail.com)
7
// (C) 2007 Novell, Inc.
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
// This code is a modified version of the assembly resolver implemented in Cecil.
30
// Keep in synch as much as possible.
33
using System.Collections;
34
using System.Collections.Specialized;
41
internal class AssemblyResolver : BaseAssemblyResolver {
43
Hashtable _assemblies;
44
ApplicationBackend app;
46
public IDictionary AssemblyCache {
47
get { return _assemblies; }
50
public AssemblyResolver (ApplicationBackend app)
53
_assemblies = new Hashtable ();
56
public StringCollection Directories = new StringCollection ();
58
public override AssemblyDefinition Resolve (AssemblyNameReference name)
60
AssemblyDefinition asm = (AssemblyDefinition) _assemblies [name.Name];
63
string ares = app.ResolveAssembly (name.Name);
65
asm = AssemblyFactory.GetAssembly (ares);
67
_assemblies [name.Name] = asm;
71
asm = base.Resolve (name);
73
_assemblies [name.Name] = asm;
79
public TypeDefinition Resolve (TypeReference type)
81
if (type is TypeDefinition)
82
return (TypeDefinition) type;
84
AssemblyNameReference reference = type.Scope as AssemblyNameReference;
85
if (reference != null) {
86
AssemblyDefinition assembly = Resolve (reference);
87
return assembly.MainModule.Types [type.FullName];
90
ModuleDefinition module = type.Scope as ModuleDefinition;
92
return module.Types [type.FullName];
94
throw new NotImplementedException ();
97
public void CacheAssembly (AssemblyDefinition assembly)
99
_assemblies [assembly.Name.FullName] = assembly;
100
assembly.Resolver = this;
103
public string Resolve (string assemblyName, string basePath)
106
string ares = app.ResolveAssembly (assemblyName);
111
StringCollection col = new StringCollection ();
113
foreach (string s in Directories)
117
return Resolve (AssemblyNameReference.Parse (assemblyName), col);
123
public string Resolve (AssemblyNameReference name, StringCollection basePaths)
125
string [] exts = new string [] { ".dll", ".exe" };
127
if (basePaths != null) {
128
foreach (string dir in basePaths) {
129
foreach (string ext in exts) {
130
string file = Path.Combine (dir, name.Name + ext);
131
if (File.Exists (file))
137
if (name.Name == "mscorlib")
138
return GetCorlib (name);
140
string asm = GetAssemblyInGac (name);
144
throw new FileNotFoundException ("Could not resolve: " + name);
147
string GetCorlib (AssemblyNameReference reference)
149
if (typeof (object).Assembly.GetName ().Version == reference.Version)
150
return typeof (object).Assembly.Location;
152
string path = Directory.GetParent (
153
Directory.GetParent (
154
typeof (object).Module.FullyQualifiedName).FullName
158
if (reference.Version.Major == 1)
159
path = Path.Combine (path, "1.0");
160
else if (reference.Version.Major == 2)
161
path = Path.Combine (path, "2.0");
163
throw new NotSupportedException ("Version not supported: " + reference.Version);
165
if (reference.Version.ToString () == "1.0.3300.0")
166
path = Path.Combine (path, "v1.0.3705");
167
else if (reference.Version.ToString () == "1.0.5000.0")
168
path = Path.Combine (path, "v1.1.4322");
169
else if (reference.Version.ToString () == "2.0.0.0")
170
path = Path.Combine (path, "v2.0.50727");
172
throw new NotSupportedException ("Version not supported: " + reference.Version);
175
return Path.Combine (path, "mscorlib.dll");
178
static string GetAssemblyInGac (AssemblyNameReference reference)
180
if (reference.PublicKeyToken == null || reference.PublicKeyToken.Length == 0)
183
string currentGac = GetCurrentGacPath ();
185
string s = GetAssemblyFile (reference, currentGac);
189
string [] gacs = new string [] {"GAC_MSIL", "GAC_32", "GAC"};
190
for (int i = 0; i < gacs.Length; i++) {
191
string gac = Path.Combine (Directory.GetParent (currentGac).FullName, gacs [i]);
192
string asm = GetAssemblyFile (reference, gac);
193
if (Directory.Exists (gac) && File.Exists (asm))
201
static string GetAssemblyFile (AssemblyNameReference reference, string gac)
203
StringBuilder sb = new StringBuilder ();
204
sb.Append (reference.Version);
206
for (int i = 0; i < reference.PublicKeyToken.Length; i++)
207
sb.Append (reference.PublicKeyToken [i].ToString ("x2"));
209
return Path.Combine (
211
Path.Combine (gac, reference.Name), sb.ToString ()),
212
string.Concat (reference.Name, ".dll"));
215
static string GetCurrentGacPath ()
217
return Directory.GetParent (
218
Directory.GetParent (
219
Path.GetDirectoryName (
220
typeof (Uri).Module.FullyQualifiedName)