PluginManager.cs 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. using System.Reflection.Emit;
  2. using System.Threading;
  3. namespace IndexFormula.Finance
  4. {
  5. using System;
  6. using System.Collections;
  7. using System.IO;
  8. using System.Net;
  9. using System.Reflection;
  10. using System.Runtime.CompilerServices;
  11. public class PluginManager
  12. {
  13. //程序信存储
  14. private static Hashtable htAssembly = new Hashtable(CaseInsensitiveHashCodeProvider.Default, CaseInsensitiveComparer.Default);
  15. private static Hashtable htFormulaSpace = new Hashtable();
  16. private static Hashtable htShadow = new Hashtable();
  17. private static string PluginsDir;
  18. public static event FileSystemEventHandler OnPluginChanged;
  19. private PluginManager()
  20. {
  21. }
  22. public static string DllToFml(string Filename)
  23. {
  24. if ((Filename != null) && Filename.EndsWith("_fml.dll"))
  25. {
  26. return (Filename.Substring(0, Filename.Length - 8) + ".fml");
  27. }
  28. return null;
  29. }
  30. private static string GetAssemblyHash(byte[] bs)
  31. {
  32. int num = 0;
  33. for (int i = 0; i < bs.Length; i++)
  34. {
  35. num += bs[i];
  36. }
  37. return num.ToString();
  38. }
  39. private static byte[] GetByteFromFile(string FileName)
  40. {
  41. if (File.Exists(FileName))
  42. {
  43. using (FileStream stream = File.OpenRead(FileName))
  44. {
  45. using (BinaryReader reader = new BinaryReader(stream))
  46. {
  47. return reader.ReadBytes((int) stream.Length);
  48. }
  49. }
  50. }
  51. return null;
  52. }
  53. private static byte[] GetByteFromWeb(string FileName)
  54. {
  55. WebClient client = new WebClient();
  56. try
  57. {
  58. return client.DownloadData(FileName);
  59. }
  60. catch
  61. {
  62. return null;
  63. }
  64. }
  65. public static string GetFormulaFile(FormulaBase fb)
  66. {
  67. string assemblyKey = FormulaBase.GetAssemblyKey(fb.GetType().Assembly);
  68. if (assemblyKey != null)
  69. {
  70. foreach (string str2 in htAssembly.Keys)
  71. {
  72. if (htAssembly[str2].ToString() == assemblyKey)
  73. {
  74. return str2;
  75. }
  76. }
  77. }
  78. return null;
  79. }
  80. public static void Load(string Path)
  81. {
  82. PluginsDir = Path;
  83. if (Directory.Exists(PluginsDir))
  84. {
  85. FileSystemWatcher watcher = new FileSystemWatcher(PluginsDir, "*.dll");
  86. watcher.Created += new FileSystemEventHandler(PluginManager.OnFileChange);
  87. watcher.Changed += new FileSystemEventHandler(PluginManager.OnFileChange);
  88. watcher.Deleted += new FileSystemEventHandler(PluginManager.OnFileChange);
  89. foreach (string str in Directory.GetFiles(PluginsDir, "*.dll"))
  90. {
  91. LoadAssembly(str);
  92. }
  93. watcher.EnableRaisingEvents = true;
  94. }
  95. }
  96. public static void LoadDll(string dllName)
  97. {
  98. if (Path.GetExtension(dllName) != ".dll")
  99. {
  100. return;
  101. }
  102. if (!string.IsNullOrEmpty(dllName))
  103. {
  104. LoadAssembly(dllName);
  105. }
  106. }
  107. private static void LoadAssembly(string FileName)
  108. {
  109. if (FileName.StartsWith("http"))
  110. {
  111. Assembly a = Assembly.LoadFrom(FileName);
  112. FormulaBase.RegAssembly(a.GetHashCode().ToString(), a);
  113. }
  114. else
  115. {
  116. //var StrongFile = PluginsDir + @"/MuchInfo.Chart.WPF.snk";
  117. //if (File.Exists(StrongFile))
  118. //{
  119. // using (var fstream = new FileStream(StrongFile, FileMode.Open))
  120. // {
  121. // // byte[] byteFromFile = GetByteFromFile(FileName);
  122. // // Assembly assembly2 = Assembly.Load(byteFromFile);
  123. // var an = AssemblyName.GetAssemblyName(FileName);
  124. // StrongNameKeyPair kp = new StrongNameKeyPair(fstream);
  125. // var appDomain = Thread.GetDomain();
  126. // var assemblyb = appDomain.DefineDynamicAssembly(an, AssemblyBuilderAccess.RunAndSave);
  127. // htAssembly[FileName] = assemblyb.GetHashCode(); // GetAssemblyHash(byteFromFile);
  128. // FormulaBase.RegAssembly(htAssembly[FileName].ToString(), assemblyb);
  129. // }
  130. //}
  131. byte[] byteFromFile = GetByteFromFile(FileName);
  132. Assembly assembly2 = Assembly.Load(byteFromFile);
  133. htAssembly[FileName] = GetAssemblyHash(byteFromFile);
  134. FormulaBase.RegAssembly(htAssembly[FileName].ToString(), assembly2);
  135. }
  136. }
  137. public static void htAssemblyClear()
  138. {
  139. htAssembly.Clear();
  140. FormulaBase.SupportedAssemblies.Clear();
  141. }
  142. public static void LoadFromWeb()
  143. {
  144. string codeBase = Assembly.GetExecutingAssembly().CodeBase;
  145. int length = codeBase.LastIndexOf("/");
  146. if (length > 0)
  147. {
  148. codeBase = codeBase.Substring(0, length);
  149. }
  150. LoadFromWeb(codeBase);
  151. }
  152. public static void LoadFromWeb(string Path)
  153. {
  154. if (!Path.EndsWith("/"))
  155. {
  156. Path = Path + "/";
  157. }
  158. Path = Path + "Plugins/";
  159. PluginsDir = Path;
  160. LoadAssembly(Path + "Basic_fml.dll");
  161. }
  162. public static Assembly LoadShadowAssembly(string FileName)
  163. {
  164. byte[] byteFromFile = GetByteFromFile(FileName);
  165. string str = (string) htAssembly[FileName];
  166. string assemblyHash = GetAssemblyHash(byteFromFile);
  167. if (str == assemblyHash)
  168. {
  169. return (Assembly) htShadow[assemblyHash];
  170. }
  171. htAssembly[FileName] = assemblyHash;
  172. Assembly assembly = Assembly.Load(byteFromFile);
  173. htShadow[assemblyHash] = assembly;
  174. return assembly;
  175. }
  176. private static void OnFileChange(object source, FileSystemEventArgs e)
  177. {
  178. try
  179. {
  180. byte[] byteFromFile = GetByteFromFile(e.FullPath);
  181. if ((byteFromFile.Length != 0) || (e.ChangeType == WatcherChangeTypes.Deleted))
  182. {
  183. string assemblyHash = GetAssemblyHash(byteFromFile);
  184. string key = htAssembly[e.FullPath].ToString();
  185. if (key != assemblyHash)
  186. {
  187. FormulaBase.UnregAssembly(key);
  188. if (byteFromFile.Length > 0)
  189. {
  190. FormulaBase.RegAssembly(assemblyHash, Assembly.Load(byteFromFile));
  191. htAssembly[e.FullPath] = assemblyHash;
  192. }
  193. if (OnPluginChanged != null)
  194. {
  195. OnPluginChanged(null, e);
  196. }
  197. }
  198. }
  199. }
  200. catch
  201. {
  202. }
  203. }
  204. public static void RegAssembly(Assembly a)
  205. {
  206. FormulaBase.RegAssembly(a.GetHashCode().ToString(), a);
  207. }
  208. public static void RegAssemblyFromMemory()
  209. {
  210. foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
  211. {
  212. if (assembly.FullName.IndexOf("_fml") >= 0)
  213. {
  214. RegAssembly(assembly);
  215. }
  216. }
  217. }
  218. public static void RegExecutingAssembly()
  219. {
  220. RegAssembly(Assembly.GetCallingAssembly());
  221. }
  222. public static void SetAssembly(string FileName)
  223. {
  224. if (File.Exists(FileName))
  225. {
  226. FormulaBase.UnregAllAssemblies();
  227. htAssembly.Clear();
  228. LoadAssembly(FileName);
  229. }
  230. }
  231. }
  232. }