Loader for loading embedded assemblies z

using System;

using System.Collections.Generic;

using System.IO;

using System.Linq;

using System.Reflection;

using System.Runtime.InteropServices;

namespace Utility

{

public class Loader

{

const string LibsFolder = "Libs";

static readonly Dictionary<string,
Assembly> Libraries = new
Dictionary<string, Assembly>();

static readonly Dictionary<string,
Assembly> ReflectionOnlyLibraries = new
Dictionary<string, Assembly>();

public static void Start()

{

AppDomain.CurrentDomain.AssemblyResolve += FindAssembly;

PreloadUnmanagedLibraries();

var app = new App();

app.Run();

}

[DllImport("kernel32.dll")]

private static extern IntPtr LoadLibrary(string dllToLoad);

private static void PreloadUnmanagedLibraries()

{

// Preload correct
library

var bittyness = "x86";

if (IntPtr.Size == 8)

bittyness
= "x64";

var assemblyName = Assembly.GetExecutingAssembly().GetName();

var libraries = Assembly.GetExecutingAssembly().GetManifestResourceNames()

.Where(s => s.StartsWith(String.Format("{1}.{2}.{0}.", bittyness, assemblyName.Name, LibsFolder)))

.ToArray();

var dirName = Path.Combine(Path.GetTempPath(), String.Format("{2}.{1}.{0}", assemblyName.Version, bittyness, assemblyName.Name));

if (!Directory.Exists(dirName))

Directory.CreateDirectory(dirName);

foreach (var lib in libraries)

{

string dllPath = Path.Combine(dirName, String.Join(".", lib.Split(‘.‘).Skip(3)));

if (!File.Exists(dllPath))

{

using (Stream stm = Assembly.GetExecutingAssembly().GetManifestResourceStream(lib))

{

// Copy the assembly
to the temporary file

try

{

using (Stream outFile
= File.Create(dllPath))

{

stm.CopyTo(outFile);

}

}

catch

{

// This may happen
if another process has already created and loaded the file.

// Since the
directory includes the version number of this assembly we can

// assume that it‘s
the same bits, so we just ignore the excecption here and

// load the
DLL.

}

}

}

// We must
explicitly load the DLL here because the temporary directory

// is not in the
PATH.

// Once it is
loaded, the DllImport directives that use the DLL will use

// the one that is
already loaded into the process.

LoadLibrary(dllPath);

}

}

internal static Assembly LoadAssembly(string fullName)

{

Assembly a;

var executingAssembly = Assembly.GetExecutingAssembly();

var assemblyName = executingAssembly.GetName();

var shortName = new
AssemblyName(fullName).Name;

if (Libraries.ContainsKey(shortName))

return Libraries[shortName];

var resourceName = String.Format("{0}.{2}.{1}.dll", assemblyName.Name, shortName, LibsFolder);

var actualName = executingAssembly.GetManifestResourceNames().FirstOrDefault(n => string.Equals(n, resourceName,
StringComparison.OrdinalIgnoreCase));

if (string.IsNullOrEmpty(actualName))

{

// The library might
be a mixed mode assembly. Try loading from the bitty folders.

var bittyness = "x86";

if (IntPtr.Size == 8)

bittyness
= "x64";

resourceName
= String.Format("{0}.{3}.{1}.{2}.dll", assemblyName.Name, bittyness, shortName, LibsFolder);

actualName
= executingAssembly.GetManifestResourceNames().FirstOrDefault(n => string.Equals(n, resourceName,
StringComparison.OrdinalIgnoreCase));

if (string.IsNullOrEmpty(actualName))

{

Libraries[shortName] =
null;

return null;

}

// Ok, mixed mode
assemblies cannot be loaded through Assembly.Load.

// See
http://stackoverflow.com/questions/2945080/ and
http://connect.microsoft.com/VisualStudio/feedback/details/97801/

// But, since it‘s
an unmanaged library we‘ve already dumped it to disk to preload it into the
process.

// So, we‘ll just
load it from there.

var dirName = Path.Combine(Path.GetTempPath(), String.Format("{2}.{1}.{0}", assemblyName.Version, bittyness, assemblyName.Name));

var dllPath = Path.Combine(dirName, String.Join(".", actualName.Split(‘.‘).Skip(3)));

if (!File.Exists(dllPath))

{

Libraries[shortName] =
null;

return null;

}

a = Assembly.LoadFile(dllPath);

Libraries[shortName] =
a;

return a;

}

using (var s = executingAssembly.GetManifestResourceStream(actualName))

{

var data = new BinaryReader(s).ReadBytes((int)s.Length);

byte[] debugData =
null;

if (executingAssembly.GetManifestResourceNames().Contains(String.Format("{0}.{2}.{1}.pdb", assemblyName.Name, shortName, LibsFolder)))

{

using (var ds = executingAssembly.GetManifestResourceStream(String.Format("{0}.{2}.{1}.pdb", assemblyName.Name, shortName, LibsFolder)))

{

debugData
= new BinaryReader(ds).ReadBytes((int)ds.Length);

}

}

if (debugData !=
null)

{

a = Assembly.Load(data, debugData);

Libraries[shortName] =
a;

return a;

}

a = Assembly.Load(data);

Libraries[shortName] =
a;

return a;

}

}

internal
static Assembly ReflectionOnlyLoadAssembly(string
fullName)

{

var executingAssembly = Assembly.GetExecutingAssembly();

var assemblyName = Assembly.GetExecutingAssembly().GetName();

string shortName = new
AssemblyName(fullName).Name;

if (ReflectionOnlyLibraries.ContainsKey(shortName))

return ReflectionOnlyLibraries[shortName];

var resourceName = String.Format("{0}.{2}.{1}.dll", assemblyName.Name, shortName, LibsFolder);

if (!executingAssembly.GetManifestResourceNames().Contains(resourceName))

{

ReflectionOnlyLibraries[shortName] =
null;

return null;

}

using (var s = executingAssembly.GetManifestResourceStream(resourceName))

{

var data = new BinaryReader(s).ReadBytes((int)s.Length);

var a = Assembly.ReflectionOnlyLoad(data);

ReflectionOnlyLibraries[shortName] =
a;

return a;

}

}

internal
static Assembly FindAssembly(object sender,
ResolveEventArgs args)

{

return LoadAssembly(args.Name);

}

internal
static Assembly FindReflectionOnlyAssembly(object
sender, ResolveEventArgs args)

{

return ReflectionOnlyLoadAssembly(args.Name);

}

}

}

Loader for loading embedded assemblies z

时间: 2024-11-07 13:24:14

Loader for loading embedded assemblies z的相关文章

ExtJS笔记 Ext.Loader

Ext.Loader is the heart of the new dynamic dependency loading capability in Ext JS 4+. It is most commonly used via the Ext.requireshorthand. Ext.Loader supports both asynchronous and synchronous loading approaches, and leverage their advantages for

使用JavaScript实现在页面上所有内容加载完之前一直显示loading...页面

Html 1 <body class="is-loading"> 2 <div class="curtain"> 3 <div class="loader"> 4 loading... 5 </div> 6 </div> 7 <div> 8 <!--这里 正文 --> 9 </div> 10 </body> Css 1 .loader {

63.1拓展之纯 CSS 创作一个摇摇晃晃的 loader

效果地址:https://scrimba.com/c/cqKv4VCR HTML code: <div class="loader"> <span>Loading...</span> </div> CSS code: html, body { margin: 0; padding: 0; } /* 设置body的子元素水平垂直居中 */ body { height: 100vh; display: flex; justify-conten

63.(原65)纯 CSS 创作一个摇摇晃晃的 loader

原文地址:https://segmentfault.com/a/1190000015424389 修改后地址:https://scrimba.com/c/cqKv4VCR HTML code: <div class="loader"> <span>Loading...</span> </div> CSS code: html, body { margin: 0; padding: 0; } /* 设置body的子元素水平垂直居中 */ b

[Angular] Show a Loading Indicator for Lazy Routes in Angular

We can easily code split and lazy load a route in Angular. However when the user then clicks that lazy loaded route, it make some time to actually fetch and run the JavaScript bundle. In this lesson we'll see how we can implement a loading indicator

转载:.NET Memory Leak: XmlSerializing your way to a Memory Leak

原文地址:http://blogs.msdn.com/b/tess/archive/2006/02/15/532804.aspx I hate to give away the resolution in the title of the blog since it takes away a lot of the suspense:) but I can't figure out a better way to name the blog posts and still keep them ni

mono环境变量

mono环境变量 2013-05-11 01:14:33|  分类: mono|举报|字号 订阅 下载LOFTER我的照片书  | Name mono - Mono's ECMA-CLI native code generator (Just-in-Time and Ahead-of-Time) Synopsis mono [options] file [arguments...] Description mono is a runtime implementation of the ECMA

Living in the Matrix with Bytecode Manipulation--转

原文地址:https://www.infoq.com/articles/Living-Matrix-Bytecode-Manipulation You are probably all too familiar with the following sequence: You input a .java file into a Java compiler, (likely using javac or a build tool like ANT, Maven or Gradle), the co

ConfigurableBeanFactory

ConfigurableBeanFactory :关系如下 在上面这样的一个关系图中可以先看下SingletonBeanRegistry的源代码: package org.springframework.beans.factory.config; public interface SingletonBeanRegistry { //在容器中创建一个指定的单利bean的类 void registerSingleton(String beanName, Object singletonObject)