PageRenderTime 48ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/Installers/MPExtended.Installers.CustomActions/WifiRemote.cs

https://github.com/MPExtended/MPExtended
C# | 258 lines | 208 code | 28 blank | 22 comment | 22 complexity | b921572550570c1aa728a8c8e8f1d08c MD5 | raw file
  1. #region Copyright (C) 2011-2013 MPExtended
  2. // Copyright (C) 2011-2013 MPExtended Developers, http://www.mpextended.com/
  3. //
  4. // The use and distribution terms for this software are covered by the
  5. // Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php)
  6. // which can be found in the file CPL.TXT at the root of this distribution.
  7. // By using this software in any fashion, you are agreeing to be bound by
  8. // the terms of this license.
  9. //
  10. // You must not remove this notice, or any other, from this software.
  11. #endregion
  12. using System;
  13. using System.Collections.Generic;
  14. using System.Diagnostics;
  15. using System.IO;
  16. using System.Linq;
  17. using System.Net;
  18. using System.Text;
  19. using System.Xml.Linq;
  20. using Microsoft.Deployment.WindowsInstaller;
  21. using Microsoft.Win32;
  22. namespace MPExtended.Installers.CustomActions
  23. {
  24. internal static class WifiRemote
  25. {
  26. private const string UPDATE_FILE = @"https://raw.githubusercontent.com/MPExtended/WifiRemote/master/Installer/update.xml";
  27. private static Version installedVersion;
  28. private static Version onlineVersion;
  29. public static ActionResult Install(Session session)
  30. {
  31. // fail very early if we can't find MPEI
  32. string mpei = LookupMPEI();
  33. if (mpei == null)
  34. {
  35. Log.Write("WifiRemote: MPEI not available");
  36. return ActionResult.NotExecuted;
  37. }
  38. Log.Write("WifiRemote: Found MPEI at {0}", mpei);
  39. // download version information
  40. session.Message(InstallMessage.ActionStart, new Record("callAddProgressInfo", "Downloading WifiRemote update information...", ""));
  41. Uri downloadUri;
  42. InitializeVersionInformation(session, out downloadUri);
  43. // fail early if we couldn't find the online version
  44. if (onlineVersion == null)
  45. {
  46. Log.Write("WifiRemote: Online version unavailable, aborting installation...");
  47. return ActionResult.Success;
  48. }
  49. // don't do anything if installed version is the newest one
  50. if (installedVersion != null && installedVersion >= onlineVersion)
  51. {
  52. Log.Write("WifiRemote: Installed version is the last one, doing nothing...");
  53. return ActionResult.Success;
  54. }
  55. // setup for installation
  56. string mpeiPackagePath = Path.GetTempFileName();
  57. session.Message(InstallMessage.ActionStart, new Record("callAddProgressInfo", "Downloading WifiRemote installer...", ""));
  58. if (!DownloadWifiRemote(downloadUri, mpeiPackagePath))
  59. {
  60. Log.Write("WifiRemote: Failed to download version from internet, aborting installation...");
  61. return ActionResult.Success;
  62. }
  63. Log.Write("WifiRemote: Got WifiRemote installer in {0}", mpeiPackagePath);
  64. // execute
  65. session.Message(InstallMessage.ActionStart, new Record("callAddProgressInfo", "Installing WifiRemote MediaPortal plugin with MPEI...", ""));
  66. ProcessStartInfo param = new ProcessStartInfo();
  67. param.FileName = mpei;
  68. param.Arguments = mpeiPackagePath + " /S";
  69. Log.Write("WifiRemote: Starting MPEI with arguments {0}", param.Arguments);
  70. Process proc = new Process();
  71. proc.StartInfo = param;
  72. proc.Start();
  73. proc.WaitForExit();
  74. Log.Write("WifiRemote: MPEI finished with exit code {0}", proc.ExitCode);
  75. // cleanup
  76. File.Delete(mpeiPackagePath);
  77. return ActionResult.Success;
  78. }
  79. private static void InitializeVersionInformation(Session session, out Uri downloadUri)
  80. {
  81. onlineVersion = GetOnlineVersion(out downloadUri);
  82. installedVersion = GetCurrentlyInstalledVersion();
  83. Log.Write("WifiRemote: {0} is available online and {1} is installed", onlineVersion, installedVersion);
  84. }
  85. private static Version GetOnlineVersion(out Uri downloadUri)
  86. {
  87. downloadUri = null;
  88. string xmlData;
  89. // download update.xml
  90. try
  91. {
  92. Log.Write("WifiRemote: Downloading update.xml from {0}", UPDATE_FILE);
  93. using (WebClient client = new WebClient())
  94. {
  95. xmlData = client.DownloadString(UPDATE_FILE);
  96. }
  97. }
  98. catch (Exception ex)
  99. {
  100. Log.Write("WifiRemote: Failed to download update.xml: {0}", ex.Message);
  101. return null;
  102. }
  103. // parse it
  104. try
  105. {
  106. XElement updateFile = XElement.Parse(xmlData);
  107. Version latest = null;
  108. foreach (XElement e in updateFile.Element("Items").Elements("PackageClass"))
  109. {
  110. // get wifiremote version
  111. XElement versionNode = e.Element("GeneralInfo").Element("Version");
  112. Version v = new Version(
  113. Int32.Parse(versionNode.Element("Major").Value),
  114. Int32.Parse(versionNode.Element("Minor").Value),
  115. Int32.Parse(versionNode.Element("Build").Value),
  116. Int32.Parse(versionNode.Element("Revision").Value)
  117. );
  118. if (latest == null || v > latest)
  119. {
  120. downloadUri = new Uri(e.Element("GeneralInfo").Element("OnlineLocation").Value.ToString());
  121. latest = v;
  122. }
  123. }
  124. return latest;
  125. }
  126. catch (Exception ex)
  127. {
  128. Log.Write("WifiRemote: Failed to parse update.xml: {0}\r\n{1}\r\n{2}", ex.Message, ex.ToString(), ex.StackTrace.ToString());
  129. return null;
  130. }
  131. }
  132. private static bool DownloadWifiRemote(Uri url, string tempPath)
  133. {
  134. // download it
  135. try
  136. {
  137. Log.Write("WifiRemote: Downloading from {0}", url.ToString());
  138. using (WebClient client = new WebClient())
  139. {
  140. client.DownloadFile(url, tempPath);
  141. }
  142. return true;
  143. }
  144. catch (Exception ex)
  145. {
  146. Log.Write("WifiRemote: Failed to download WifiRemote", ex.Message);
  147. return false;
  148. }
  149. }
  150. private static Version GetCurrentlyInstalledVersion()
  151. {
  152. try
  153. {
  154. string path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData),
  155. "Team MediaPortal", "MediaPortal", "Installer", "V2", "InstalledExtensions.xml");
  156. if (!File.Exists(path))
  157. {
  158. Log.Write("WifiRemote: Did not find MPEI database at {0}", path);
  159. return null;
  160. }
  161. // load file
  162. XElement file = XElement.Load(path);
  163. var nodes = file.Element("Items").Elements("PackageClass").Where(x => x.Element("GeneralInfo").Element("Name").Value == "WifiRemote");
  164. if (nodes.Count() == 0)
  165. {
  166. Log.Write("WifiRemote: No local installation found");
  167. return null;
  168. }
  169. // create version
  170. XElement versionNode = nodes.First().Element("GeneralInfo").Element("Version");
  171. Version version = new Version(
  172. Int32.Parse(versionNode.Element("Major").Value),
  173. Int32.Parse(versionNode.Element("Minor").Value),
  174. Int32.Parse(versionNode.Element("Build").Value),
  175. Int32.Parse(versionNode.Element("Revision").Value)
  176. );
  177. Log.Write("WifiRemote: Version {0} currently installed", version);
  178. return version;
  179. }
  180. catch (Exception ex)
  181. {
  182. Log.Write("WifiRemote: Failed to load currently installed version", ex.Message);
  183. return null;
  184. }
  185. }
  186. private static string LookupMPEI()
  187. {
  188. try
  189. {
  190. string[] keys = new string[] {
  191. @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\MediaPortal",
  192. @"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\MediaPortal"
  193. };
  194. RegistryKey key = null;
  195. foreach (var keyPath in keys)
  196. {
  197. key = Registry.LocalMachine.OpenSubKey(keyPath);
  198. if (key != null)
  199. {
  200. break;
  201. }
  202. }
  203. if (key == null)
  204. {
  205. Log.Write("WifiRemote: Could not find MediaPortal installation path key");
  206. return null;
  207. }
  208. object value = key.GetValue("InstallPath", null);
  209. if (value == null)
  210. {
  211. Log.Write("WifiRemote: Could not find MediaPortal installation path value");
  212. return null;
  213. }
  214. string path = value.ToString();
  215. string mpei = Path.Combine(path, "MpeInstaller.exe");
  216. if (!File.Exists(mpei))
  217. {
  218. Log.Write("WifiRemote: MPEI path {0} does not exists", mpei);
  219. return null;
  220. }
  221. return mpei;
  222. }
  223. catch (Exception ex)
  224. {
  225. Log.Write("WifiRemote: Failed to lookup MPEI path", ex);
  226. return null;
  227. }
  228. }
  229. }
  230. }