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);
}
}
}
- sencha警告:[WARN][Anonymous] [Ext.Loader] Synchronously loading 'Ext.field.Text'
chrome开发者工具下提示: [WARN][Anonymous] [Ext.Loader] Synchronously loading 'Ext.field.Text'; consider addi ...
- Best Practices for Assembly Loading
原文链接 This article discusses ways to avoid problems of type identity that can lead to InvalidCastExce ...
- ExtJS笔记 Ext.Loader
Ext.Loader is the heart of the new dynamic dependency loading capability in Ext JS 4+. It is most co ...
- 63.1拓展之纯 CSS 创作一个摇摇晃晃的 loader
效果地址:https://scrimba.com/c/cqKv4VCR HTML code: <div class="loader"> <span>Load ...
- 63.(原65)纯 CSS 创作一个摇摇晃晃的 loader
原文地址:https://segmentfault.com/a/1190000015424389 修改后地址:https://scrimba.com/c/cqKv4VCR HTML code: < ...
- [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 la ...
- 前端每日实战:65# 视频演示如何用纯 CSS 创作一个摇摇晃晃的 loader
效果预览 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览.https://codepen.io/comehope/pen/oyJvpe 可交互视频 此视频是可以 ...
- mono环境变量
mono环境变量 2013-05-11 01:14:33| 分类: mono|举报|字号 订阅 下载LOFTER我的照片书 | Name mono - Mono's ECMA-CL ...
- 转载:.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 ...
随机推荐
- 黑马程序员 c#单态的设计模式 (专题二)
<a href="http://edu.csdn.net"target="blank">ASP.Net+Android+IO开发S</a> ...
- Js setInterval与setTimeout(定时执行与循环执行)的代码(可以传入参数)
最近在做项目时用到了定时执行的js方法,setInterval与setTimeout时间长了不用有些生疏了,所以自己总结了一下,记下来,以便以后使用. Document自带的方法: 循环执行:var ...
- WEB开发人员必知的20+HTML5技巧(转)
互联网科技发展的速度真可谓惊人的快,一个稍不留神,你就可能无法跟上它的步伐. HTML5的变化和更新也压倒不少人,这篇文章将向大家介绍一些最基本也非常必要的 HTML技巧. 1. 新的文档类型(Doc ...
- Windows 2008 R2系统开机时如何不让Windows进行磁盘检测?
开始→运行,在运行对话框中键入“chkntfs /t:0”,即可将磁盘扫描等待时间设置为0, 如果要在计算机启动时忽略扫描某个分区,比如C盘,可以输入“chkntfs /x c:”命令:如果要恢复对C ...
- The 5th Zhejiang Provincial Collegiate Programming Contest------ProblemK:Kinds of Fuwas
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1974 题意:问四个角都有同一个福娃的矩形有多少个. #include<b ...
- The 5th Zhejiang Provincial Collegiate Programming Contest------ProblemA:Accurately Say "CocaCola"!
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2965 题意:一群人玩过“7”的游戏,有7的数字或者7的倍数就要喊“coca ...
- Hibernate-Validation的使用
首先是要加入下面两个包 hibernate-validator-4.1.0.Final.jar validation-api-1.0.0.GA.jar 如果在验证不通过的时候进行了添加.更新或删除操作 ...
- Flume学习——BasicChannelSemantics
public class MemoryChannel extends BasicChannelSemantics public abstract class BasicChannelSemantics ...
- PHP 性能分析第三篇: 性能调优实战
注意:本文是我们的 PHP 性能分析系列的第三篇,点此阅读 PHP 性能分析第一篇: XHProf & XHGui 介绍 ,或 PHP 性能分析第二篇: 深入研究 XHGui. 在本系列的 ...
- altium designer 13 学习之添加汉字
在altium desginer中如果你是想添加英文还是比较方便的,基本直接就可以输入了,但是添加中文就不是那么简单了,下面不介绍下如何在altium designer中快速的添加自己想要的中文 工具 ...