Kernel.cs 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794
  1. #region BSD License
  2. /*
  3. Copyright (c) 2004-2008
  4. Matthew Holmes ([email protected]),
  5. Dan Moorehead ([email protected]),
  6. Rob Loach (http://www.robloach.net),
  7. C.J. Adams-Collier ([email protected])
  8. Redistribution and use in source and binary forms, with or without
  9. modification, are permitted provided that the following conditions are
  10. met:
  11. * Redistributions of source code must retain the above copyright
  12. notice, this list of conditions and the following disclaimer.
  13. * Redistributions in binary form must reproduce the above copyright
  14. notice, this list of conditions and the following disclaimer in the
  15. documentation and/or other materials provided with the distribution.
  16. * The name of the author may not be used to endorse or promote
  17. products derived from this software without specific prior written
  18. permission.
  19. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  20. IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  21. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  22. DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
  23. INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  24. (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  25. SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  26. HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  27. STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
  28. IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  29. POSSIBILITY OF SUCH DAMAGE.
  30. */
  31. #endregion
  32. #region CVS Information
  33. /*
  34. * $Source$
  35. * $Author: cjcollier $
  36. * $Date: 2008-02-08 01:31:29 +0900 (Fri, 08 Feb 2008) $
  37. * $Revision: 256 $
  38. */
  39. #endregion
  40. using System;
  41. using System.Diagnostics;
  42. using System.Collections;
  43. using System.Collections.Specialized;
  44. using System.IO;
  45. using System.Reflection;
  46. using System.Xml;
  47. using System.Xml.Schema;
  48. using System.Text;
  49. using Prebuild.Core.Attributes;
  50. using Prebuild.Core.Interfaces;
  51. using Prebuild.Core.Nodes;
  52. using Prebuild.Core.Parse;
  53. using Prebuild.Core.Utilities;
  54. namespace Prebuild.Core
  55. {
  56. /// <summary>
  57. ///
  58. /// </summary>
  59. public class Kernel : IDisposable
  60. {
  61. #region Inner Classes
  62. private struct NodeEntry
  63. {
  64. public Type Type;
  65. public DataNodeAttribute Attribute;
  66. }
  67. #endregion
  68. #region Fields
  69. private static Kernel m_Instance = new Kernel();
  70. /// <summary>
  71. /// This must match the version of the schema that is embeeded
  72. /// </summary>
  73. private static string m_SchemaVersion = "1.7";
  74. private static string m_Schema = "prebuild-" + m_SchemaVersion + ".xsd";
  75. private static string m_SchemaURI = "http://dnpb.sourceforge.net/schemas/" + m_Schema;
  76. bool disposed;
  77. private Version m_Version;
  78. private string m_Revision = "";
  79. private CommandLineCollection m_CommandLine;
  80. private Log m_Log;
  81. private CurrentDirectory m_CurrentWorkingDirectory;
  82. private XmlSchemaCollection m_Schemas;
  83. private Hashtable m_Targets;
  84. private Hashtable m_Nodes;
  85. ArrayList m_Solutions;
  86. string m_Target;
  87. string m_Clean;
  88. string[] m_RemoveDirectories;
  89. string m_CurrentFile;
  90. XmlDocument m_CurrentDoc;
  91. bool m_PauseAfterFinish;
  92. string[] m_ProjectGroups;
  93. StringCollection m_Refs;
  94. #endregion
  95. #region Constructors
  96. private Kernel()
  97. {
  98. }
  99. #endregion
  100. #region Properties
  101. /// <summary>
  102. /// Gets a value indicating whether [pause after finish].
  103. /// </summary>
  104. /// <value><c>true</c> if [pause after finish]; otherwise, <c>false</c>.</value>
  105. public bool PauseAfterFinish
  106. {
  107. get
  108. {
  109. return m_PauseAfterFinish;
  110. }
  111. }
  112. /// <summary>
  113. /// Gets the instance.
  114. /// </summary>
  115. /// <value>The instance.</value>
  116. public static Kernel Instance
  117. {
  118. get
  119. {
  120. return m_Instance;
  121. }
  122. }
  123. /// <summary>
  124. /// Gets the version.
  125. /// </summary>
  126. /// <value>The version.</value>
  127. public string Version
  128. {
  129. get
  130. {
  131. return String.Format("{0}.{1}.{2}{3}", m_Version.Major, m_Version.Minor, m_Version.Build, m_Revision);
  132. }
  133. }
  134. /// <summary>
  135. /// Gets the command line.
  136. /// </summary>
  137. /// <value>The command line.</value>
  138. public CommandLineCollection CommandLine
  139. {
  140. get
  141. {
  142. return m_CommandLine;
  143. }
  144. }
  145. /// <summary>
  146. /// Gets the targets.
  147. /// </summary>
  148. /// <value>The targets.</value>
  149. public Hashtable Targets
  150. {
  151. get
  152. {
  153. return m_Targets;
  154. }
  155. }
  156. /// <summary>
  157. /// Gets the log.
  158. /// </summary>
  159. /// <value>The log.</value>
  160. public Log Log
  161. {
  162. get
  163. {
  164. return m_Log;
  165. }
  166. }
  167. /// <summary>
  168. /// Gets the current working directory.
  169. /// </summary>
  170. /// <value>The current working directory.</value>
  171. public CurrentDirectory CurrentWorkingDirectory
  172. {
  173. get
  174. {
  175. return m_CurrentWorkingDirectory;
  176. }
  177. }
  178. /// <summary>
  179. /// Gets the solutions.
  180. /// </summary>
  181. /// <value>The solutions.</value>
  182. public ArrayList Solutions
  183. {
  184. get
  185. {
  186. return m_Solutions;
  187. }
  188. }
  189. /// <summary>
  190. /// Gets the XmlDocument object representing the prebuild.xml
  191. /// being processed
  192. /// </summary>
  193. /// <value>The XmlDocument object</value>
  194. public XmlDocument CurrentDoc
  195. {
  196. get
  197. {
  198. return m_CurrentDoc;
  199. }
  200. }
  201. #endregion
  202. #region Private Methods
  203. private void RemoveDirectories(string rootDir, string[] dirNames)
  204. {
  205. foreach(string dir in Directory.GetDirectories(rootDir))
  206. {
  207. string simpleName = Path.GetFileName(dir);
  208. if(Array.IndexOf(dirNames, simpleName) != -1)
  209. {
  210. //delete if the name matches one of the directory names to delete
  211. string fullDirPath = Path.GetFullPath(dir);
  212. Directory.Delete(fullDirPath,true);
  213. }
  214. else//not a match, so check children
  215. {
  216. RemoveDirectories(dir,dirNames);
  217. //recurse, checking children for them
  218. }
  219. }
  220. }
  221. // private void RemoveDirectoryMatches(string rootDir, string dirPattern)
  222. // {
  223. // foreach(string dir in Directory.GetDirectories(rootDir))
  224. // {
  225. // foreach(string match in Directory.GetDirectories(dir))
  226. // {//delete all child directories that match
  227. // Directory.Delete(Path.GetFullPath(match),true);
  228. // }
  229. // //recure through the rest checking for nested matches to delete
  230. // RemoveDirectoryMatches(dir,dirPattern);
  231. // }
  232. // }
  233. private void LoadSchema()
  234. {
  235. Assembly assembly = this.GetType().Assembly;
  236. Stream stream = assembly.GetManifestResourceStream("Prebuild.data." + m_Schema);
  237. if(stream == null)
  238. {
  239. //try without the default namespace prepending to it in case was compiled with SharpDevelop or MonoDevelop instead of Visual Studio .NET
  240. stream = assembly.GetManifestResourceStream(m_Schema);
  241. if(stream == null)
  242. {
  243. throw new System.Reflection.TargetException(string.Format("Could not find the scheme embedded resource file '{0}'.", m_Schema));
  244. }
  245. }
  246. XmlReader schema = new XmlTextReader(stream);
  247. m_Schemas = new XmlSchemaCollection();
  248. m_Schemas.Add(m_SchemaURI, schema);
  249. }
  250. private void CacheVersion()
  251. {
  252. m_Version = Assembly.GetEntryAssembly().GetName().Version;
  253. }
  254. private void CacheTargets(Assembly assm)
  255. {
  256. foreach(Type t in assm.GetTypes())
  257. {
  258. TargetAttribute ta = (TargetAttribute)Helper.CheckType(t, typeof(TargetAttribute), typeof(ITarget));
  259. if(ta == null)
  260. {
  261. continue;
  262. }
  263. ITarget target = (ITarget)assm.CreateInstance(t.FullName);
  264. if(target == null)
  265. {
  266. throw new MissingMethodException("Could not create ITarget instance");
  267. }
  268. m_Targets[ta.Name] = target;
  269. }
  270. }
  271. private void CacheNodeTypes(Assembly assm)
  272. {
  273. foreach(Type t in assm.GetTypes())
  274. {
  275. DataNodeAttribute dna = (DataNodeAttribute)Helper.CheckType(t, typeof(DataNodeAttribute), typeof(IDataNode));
  276. if(dna == null)
  277. {
  278. continue;
  279. }
  280. NodeEntry ne = new NodeEntry();
  281. ne.Type = t;
  282. ne.Attribute = dna;
  283. m_Nodes[dna.Name] = ne;
  284. }
  285. }
  286. private void LogBanner()
  287. {
  288. m_Log.Write("Prebuild v" + this.Version);
  289. m_Log.Write("Copyright (c) 2004-2008");
  290. m_Log.Write("Matthew Holmes ([email protected]),");
  291. m_Log.Write("Dan Moorehead ([email protected]),");
  292. m_Log.Write("David Hudson ([email protected]),");
  293. m_Log.Write("Rob Loach (http://www.robloach.net),");
  294. m_Log.Write("C.J. Adams-Collier ([email protected]),");
  295. m_Log.Write("See 'prebuild /usage' for help");
  296. m_Log.Write();
  297. }
  298. private void ProcessFile(string file)
  299. {
  300. m_CurrentWorkingDirectory.Push();
  301. string path = file;
  302. try
  303. {
  304. try
  305. {
  306. path = Helper.ResolvePath(path);
  307. }
  308. catch(ArgumentException)
  309. {
  310. m_Log.Write("Could not open Prebuild file: " + path);
  311. m_CurrentWorkingDirectory.Pop();
  312. return;
  313. }
  314. m_CurrentFile = path;
  315. Helper.SetCurrentDir(Path.GetDirectoryName(path));
  316. XmlTextReader reader = new XmlTextReader(path);
  317. Core.Parse.Preprocessor pre = new Core.Parse.Preprocessor();
  318. //register command line arguments as XML variables
  319. IDictionaryEnumerator dict = m_CommandLine.GetEnumerator();
  320. while (dict.MoveNext())
  321. {
  322. string name = dict.Key.ToString().Trim();
  323. if (name.Length > 0)
  324. pre.RegisterVariable(name, dict.Value.ToString());
  325. }
  326. string xml = pre.Process(reader);//remove script and evaulate pre-proccessing to get schema-conforming XML
  327. m_CurrentDoc = new XmlDocument();
  328. try
  329. {
  330. XmlValidatingReader validator = new XmlValidatingReader(new XmlTextReader(new StringReader(xml)));
  331. //validate while reading from string into XmlDocument DOM structure in memory
  332. foreach(XmlSchema schema in m_Schemas)
  333. {
  334. validator.Schemas.Add(schema);
  335. }
  336. m_CurrentDoc.Load(validator);
  337. }
  338. catch(XmlException e)
  339. {
  340. throw new XmlException(e.ToString());
  341. }
  342. //is there a purpose to writing it? An syntax/schema problem would have been found during pre.Process() and reported with details
  343. if(m_CommandLine.WasPassed("ppo"))
  344. {
  345. string ppoFile = m_CommandLine["ppo"];
  346. if(ppoFile == null || ppoFile.Trim().Length < 1)
  347. {
  348. ppoFile = "preprocessed.xml";
  349. }
  350. StreamWriter writer = null;
  351. try
  352. {
  353. writer = new StreamWriter(ppoFile);
  354. writer.Write(xml);
  355. }
  356. catch(IOException ex)
  357. {
  358. Console.WriteLine("Could not write PPO file '{0}': {1}", ppoFile, ex.Message);
  359. }
  360. finally
  361. {
  362. if(writer != null)
  363. {
  364. writer.Close();
  365. }
  366. }
  367. return;
  368. }
  369. //start reading the xml config file
  370. XmlElement rootNode = m_CurrentDoc.DocumentElement;
  371. //string suggestedVersion = Helper.AttributeValue(rootNode,"version","1.0");
  372. Helper.CheckForOSVariables = Helper.ParseBoolean(rootNode,"checkOsVars",false);
  373. foreach(XmlNode node in rootNode.ChildNodes)//solutions or if pre-proc instructions
  374. {
  375. IDataNode dataNode = ParseNode(node, null);
  376. if(dataNode is ProcessNode)
  377. {
  378. ProcessNode proc = (ProcessNode)dataNode;
  379. if(proc.IsValid)
  380. {
  381. ProcessFile(proc.Path);
  382. }
  383. }
  384. else if(dataNode is SolutionNode)
  385. {
  386. m_Solutions.Add(dataNode);
  387. }
  388. }
  389. }
  390. catch(XmlSchemaException xse)
  391. {
  392. m_Log.Write("XML validation error at line {0} in {1}:\n\n{2}",
  393. xse.LineNumber, path, xse.Message);
  394. }
  395. finally
  396. {
  397. m_CurrentWorkingDirectory.Pop();
  398. }
  399. }
  400. #endregion
  401. #region Public Methods
  402. /// <summary>
  403. /// Allows the project.
  404. /// </summary>
  405. /// <param name="projectGroupsFlags">The project groups flags.</param>
  406. /// <returns></returns>
  407. public bool AllowProject(string projectGroupsFlags)
  408. {
  409. if(m_ProjectGroups != null && m_ProjectGroups.Length > 0)
  410. {
  411. if(projectGroupsFlags != null && projectGroupsFlags.Length == 0)
  412. {
  413. foreach(string group in projectGroupsFlags.Split('|'))
  414. {
  415. if(Array.IndexOf(m_ProjectGroups, group) != -1) //if included in the filter list
  416. {
  417. return true;
  418. }
  419. }
  420. }
  421. return false;//not included in the list or no groups specified for the project
  422. }
  423. return true;//no filter specified in the command line args
  424. }
  425. /// <summary>
  426. /// Gets the type of the node.
  427. /// </summary>
  428. /// <param name="node">The node.</param>
  429. /// <returns></returns>
  430. public Type GetNodeType(XmlNode node)
  431. {
  432. if( node == null )
  433. {
  434. throw new ArgumentNullException("node");
  435. }
  436. if(!m_Nodes.ContainsKey(node.Name))
  437. {
  438. return null;
  439. }
  440. NodeEntry ne = (NodeEntry)m_Nodes[node.Name];
  441. return ne.Type;
  442. }
  443. /// <summary>
  444. ///
  445. /// </summary>
  446. /// <param name="node"></param>
  447. /// <param name="parent"></param>
  448. /// <returns></returns>
  449. public IDataNode ParseNode(XmlNode node, IDataNode parent)
  450. {
  451. return ParseNode(node, parent, null);
  452. }
  453. //Create an instance of the data node type that is mapped to the name of the xml DOM node
  454. /// <summary>
  455. /// Parses the node.
  456. /// </summary>
  457. /// <param name="node">The node.</param>
  458. /// <param name="parent">The parent.</param>
  459. /// <param name="preNode">The pre node.</param>
  460. /// <returns></returns>
  461. public IDataNode ParseNode(XmlNode node, IDataNode parent, IDataNode preNode)
  462. {
  463. IDataNode dataNode = null;
  464. try
  465. {
  466. if( node == null )
  467. {
  468. throw new ArgumentNullException("node");
  469. }
  470. if(preNode == null)
  471. {
  472. if(!m_Nodes.ContainsKey(node.Name))
  473. {
  474. //throw new XmlException("Unknown XML node: " + node.Name);
  475. return null;
  476. }
  477. NodeEntry ne = (NodeEntry)m_Nodes[node.Name];
  478. Type type = ne.Type;
  479. //DataNodeAttribute dna = ne.Attribute;
  480. dataNode = (IDataNode)type.Assembly.CreateInstance(type.FullName);
  481. if(dataNode == null)
  482. {
  483. throw new System.Reflection.TargetException("Could not create new parser instance: " + type.FullName);
  484. }
  485. }
  486. else
  487. dataNode = preNode;
  488. dataNode.Parent = parent;
  489. dataNode.Parse(node);
  490. }
  491. catch(WarningException wex)
  492. {
  493. m_Log.Write(LogType.Warning, wex.Message);
  494. return null;
  495. }
  496. catch(FatalException fex)
  497. {
  498. m_Log.WriteException(LogType.Error, fex);
  499. throw;
  500. }
  501. catch(Exception ex)
  502. {
  503. m_Log.WriteException(LogType.Error, ex);
  504. throw;
  505. }
  506. return dataNode;
  507. }
  508. /// <summary>
  509. /// Initializes the specified target.
  510. /// </summary>
  511. /// <param name="target">The target.</param>
  512. /// <param name="args">The args.</param>
  513. public void Initialize(LogTargets target, string[] args)
  514. {
  515. m_Targets = new Hashtable();
  516. CacheTargets(this.GetType().Assembly);
  517. m_Nodes = new Hashtable();
  518. CacheNodeTypes(this.GetType().Assembly);
  519. CacheVersion();
  520. m_CommandLine = new CommandLineCollection(args);
  521. string logFile = null;
  522. if(m_CommandLine.WasPassed("log"))
  523. {
  524. logFile = m_CommandLine["log"];
  525. if(logFile != null && logFile.Length == 0)
  526. {
  527. logFile = "Prebuild.log";
  528. }
  529. }
  530. else
  531. {
  532. target = target & ~LogTargets.File; //dont output to a file
  533. }
  534. m_Log = new Log(target, logFile);
  535. LogBanner();
  536. m_CurrentWorkingDirectory = new CurrentDirectory();
  537. m_Target = m_CommandLine["target"];
  538. m_Clean = m_CommandLine["clean"];
  539. string removeDirs = m_CommandLine["removedir"];
  540. if(removeDirs != null && removeDirs.Length == 0)
  541. {
  542. m_RemoveDirectories = removeDirs.Split('|');
  543. }
  544. string flags = m_CommandLine["allowedgroups"];//allows filtering by specifying a pipe-delimited list of groups to include
  545. if(flags != null && flags.Length == 0)
  546. {
  547. m_ProjectGroups = flags.Split('|');
  548. }
  549. m_PauseAfterFinish = m_CommandLine.WasPassed("pause");
  550. LoadSchema();
  551. m_Solutions = new ArrayList();
  552. m_Refs = new StringCollection();
  553. }
  554. /// <summary>
  555. /// Processes this instance.
  556. /// </summary>
  557. public void Process()
  558. {
  559. bool perfomedOtherTask = false;
  560. if(m_RemoveDirectories != null && m_RemoveDirectories.Length > 0)
  561. {
  562. try
  563. {
  564. RemoveDirectories(".",m_RemoveDirectories);
  565. }
  566. catch(IOException e)
  567. {
  568. m_Log.Write("Failed to remove directories named {0}",m_RemoveDirectories);
  569. m_Log.WriteException(LogType.Error,e);
  570. }
  571. catch(UnauthorizedAccessException e)
  572. {
  573. m_Log.Write("Failed to remove directories named {0}",m_RemoveDirectories);
  574. m_Log.WriteException(LogType.Error,e);
  575. }
  576. perfomedOtherTask = true;
  577. }
  578. if(m_Target != null && m_Clean != null)
  579. {
  580. m_Log.Write(LogType.Error, "The options /target and /clean cannot be passed together");
  581. return;
  582. }
  583. else if(m_Target == null && m_Clean == null)
  584. {
  585. if(perfomedOtherTask) //finished
  586. {
  587. return;
  588. }
  589. m_Log.Write(LogType.Error, "Must pass either /target or /clean to process a Prebuild file");
  590. return;
  591. }
  592. string file = "./prebuild.xml";
  593. if(m_CommandLine.WasPassed("file"))
  594. {
  595. file = m_CommandLine["file"];
  596. }
  597. ProcessFile(file);
  598. string target = (m_Target != null ? m_Target.ToLower() : m_Clean.ToLower());
  599. bool clean = (m_Target == null);
  600. if(clean && target != null && target.Length == 0)
  601. {
  602. target = "all";
  603. }
  604. if(clean && target == "all")//default to all if no target was specified for clean
  605. {
  606. //check if they passed yes
  607. if (!m_CommandLine.WasPassed("yes"))
  608. {
  609. Console.WriteLine("WARNING: This operation will clean ALL project files for all targets, are you sure? (y/n):");
  610. string ret = Console.ReadLine();
  611. if(ret == null)
  612. {
  613. return;
  614. }
  615. ret = ret.Trim().ToLower();
  616. if((ret.ToLower() != "y" && ret.ToLower() != "yes"))
  617. {
  618. return;
  619. }
  620. }
  621. //clean all targets (just cleaning vs2002 target didn't clean nant)
  622. foreach(ITarget targ in m_Targets.Values)
  623. {
  624. targ.Clean(this);
  625. }
  626. }
  627. else
  628. {
  629. if (!m_Targets.Contains(target)) {
  630. m_Log.Write(LogType.Error, "Unknown Target \"{0}\"", target);
  631. return;
  632. }
  633. ITarget targ = (ITarget)m_Targets[target];
  634. if(clean)
  635. {
  636. targ.Clean(this);
  637. }
  638. else
  639. {
  640. targ.Write(this);
  641. }
  642. }
  643. m_Log.Flush();
  644. }
  645. #endregion
  646. #region IDisposable Members
  647. /// <summary>
  648. ///
  649. /// </summary>
  650. public void Dispose()
  651. {
  652. Dispose(true);
  653. GC.SuppressFinalize(this);
  654. }
  655. /// <summary>
  656. /// Dispose objects
  657. /// </summary>
  658. /// <param name="disposing">
  659. /// If true, it will dispose close the handle
  660. /// </param>
  661. /// <remarks>
  662. /// Will dispose managed and unmanaged resources.
  663. /// </remarks>
  664. protected virtual void Dispose(bool disposing)
  665. {
  666. if (!this.disposed)
  667. {
  668. if (disposing)
  669. {
  670. if (this.m_Log != null)
  671. {
  672. this.m_Log.Close();
  673. this.m_Log = null;
  674. }
  675. }
  676. }
  677. this.disposed = true;
  678. }
  679. /// <summary>
  680. ///
  681. /// </summary>
  682. ~Kernel()
  683. {
  684. this.Dispose(false);
  685. }
  686. /// <summary>
  687. /// Closes and destroys this object
  688. /// </summary>
  689. /// <remarks>
  690. /// Same as Dispose(true)
  691. /// </remarks>
  692. public void Close()
  693. {
  694. Dispose();
  695. }
  696. #endregion
  697. }
  698. }