Fixes: U4-3290 PackageBinaryInspector returns error during install
This commit is contained in:
@@ -62,28 +62,39 @@ namespace Umbraco.Core.Packaging
|
||||
var files = Directory.GetFiles(dllPath, "*.dll");
|
||||
var dllsWithReference = new List<string>();
|
||||
var errors = new List<string>();
|
||||
var assembliesWithErrors = new List<string>();
|
||||
var assembliesWithErrors = new List<Assembly>();
|
||||
|
||||
//we need this handler to resolve assembly dependencies below
|
||||
AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += (s, e) =>
|
||||
{
|
||||
var a = Assembly.ReflectionOnlyLoadFrom(GetAssemblyPath(Assembly.ReflectionOnlyLoad(e.Name)));
|
||||
var a = Assembly.ReflectionOnlyLoad(e.Name);
|
||||
if (a == null) throw new TypeLoadException("Could not load assembly " + e.Name);
|
||||
return a;
|
||||
};
|
||||
|
||||
//First load each dll file into the context
|
||||
foreach (var f in files) Assembly.ReflectionOnlyLoadFrom(f);
|
||||
|
||||
//Then load each referenced assembly into the context
|
||||
foreach (var f in files)
|
||||
//First load each dll file into the context
|
||||
var loaded = files.Select(Assembly.ReflectionOnlyLoadFrom).ToList();
|
||||
|
||||
//load each of the LoadFrom assemblies into the Load context too
|
||||
foreach (var a in loaded)
|
||||
{
|
||||
var reflectedAssembly = Assembly.ReflectionOnlyLoadFrom(f);
|
||||
foreach (var assemblyName in reflectedAssembly.GetReferencedAssemblies())
|
||||
Assembly.ReflectionOnlyLoad(a.FullName);
|
||||
}
|
||||
|
||||
//get the list of assembly names to compare below
|
||||
var loadedNames = loaded.Select(x => x.GetName().Name).ToArray();
|
||||
|
||||
//Then load each referenced assembly into the context
|
||||
foreach (var a in loaded)
|
||||
{
|
||||
//don't load any referenced assemblies that are already found in the loaded array - this is based on name
|
||||
// regardless of version. We'll assume that if the assembly found in the folder matches the assembly name
|
||||
// being looked for, that is the version the user has shipped their package with and therefore it 'must' be correct
|
||||
foreach (var assemblyName in a.GetReferencedAssemblies().Where(ass => loadedNames.Contains(ass.Name) == false))
|
||||
{
|
||||
try
|
||||
{
|
||||
Assembly.ReflectionOnlyLoadFrom(GetAssemblyPath(Assembly.ReflectionOnlyLoad(assemblyName.FullName)));
|
||||
Assembly.ReflectionOnlyLoad(assemblyName.FullName);
|
||||
}
|
||||
catch (FileNotFoundException)
|
||||
{
|
||||
@@ -92,7 +103,7 @@ namespace Umbraco.Core.Packaging
|
||||
string.Concat("This package references the assembly '",
|
||||
assemblyName.Name,
|
||||
"' which was not found"));
|
||||
assembliesWithErrors.Add(f);
|
||||
assembliesWithErrors.Add(a);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -101,7 +112,7 @@ namespace Umbraco.Core.Packaging
|
||||
string.Concat("This package could not be verified for compatibility. An error occurred while loading a referenced assembly '",
|
||||
assemblyName.Name,
|
||||
"' see error log for full details."));
|
||||
assembliesWithErrors.Add(f);
|
||||
assembliesWithErrors.Add(a);
|
||||
LogHelper.Error<PackageBinaryInspector>("An error occurred scanning package assemblies", ex);
|
||||
}
|
||||
}
|
||||
@@ -110,34 +121,62 @@ namespace Umbraco.Core.Packaging
|
||||
var contractType = GetLoadFromContractType<T>();
|
||||
|
||||
//now that we have all referenced types into the context we can look up stuff
|
||||
foreach (var f in files.Except(assembliesWithErrors))
|
||||
foreach (var a in loaded.Except(assembliesWithErrors))
|
||||
{
|
||||
//now we need to see if they contain any type 'T'
|
||||
var reflectedAssembly = Assembly.ReflectionOnlyLoadFrom(f);
|
||||
|
||||
var found = reflectedAssembly.GetExportedTypes()
|
||||
.Where(contractType.IsAssignableFrom);
|
||||
|
||||
if (found.Any())
|
||||
var reflectedAssembly = a;
|
||||
|
||||
try
|
||||
{
|
||||
dllsWithReference.Add(reflectedAssembly.FullName);
|
||||
var found = reflectedAssembly.GetExportedTypes()
|
||||
.Where(contractType.IsAssignableFrom);
|
||||
|
||||
if (found.Any())
|
||||
{
|
||||
dllsWithReference.Add(reflectedAssembly.FullName);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
//This is a hack that nobody can seem to get around, I've read everything and it seems that
|
||||
// this is quite a common thing when loading types into reflection only load context, so
|
||||
// we're just going to ignore this specific one for now
|
||||
var typeLoadEx = ex as TypeLoadException;
|
||||
if (typeLoadEx != null)
|
||||
{
|
||||
if (typeLoadEx.Message.InvariantContains("does not have an implementation"))
|
||||
{
|
||||
//ignore
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
errors.Add(
|
||||
string.Concat("This package could not be verified for compatibility. An error occurred while scanning a packaged assembly '",
|
||||
a.GetName().Name,
|
||||
"' see error log for full details."));
|
||||
assembliesWithErrors.Add(a);
|
||||
LogHelper.Error<PackageBinaryInspector>("An error occurred scanning package assemblies", ex);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
errorReport = errors.ToArray();
|
||||
return dllsWithReference;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// In order to compare types, the types must be in the same context, this method will return the type that
|
||||
/// we are checking against but from the LoadFrom context.
|
||||
/// we are checking against but from the Load context.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <returns></returns>
|
||||
private static Type GetLoadFromContractType<T>()
|
||||
{
|
||||
var contractAssemblyLoadFrom = Assembly.ReflectionOnlyLoadFrom(
|
||||
GetAssemblyPath(Assembly.ReflectionOnlyLoad(typeof (T).Assembly.FullName)));
|
||||
var contractAssemblyLoadFrom =Assembly.ReflectionOnlyLoad(typeof (T).Assembly.FullName);
|
||||
|
||||
var contractType = contractAssemblyLoadFrom.GetExportedTypes()
|
||||
.FirstOrDefault(x => x.FullName == typeof(T).FullName && x.Assembly.FullName == typeof(T).Assembly.FullName);
|
||||
|
||||
Reference in New Issue
Block a user