PageRenderTime 26ms CodeModel.GetById 26ms RepoModel.GetById 1ms app.codeStats 0ms

/bidshelper-vsix/core/Options/BIDSHelperOptionsVersionCheckPage.cs

#
C# | 332 lines | 235 code | 31 blank | 66 comment | 28 complexity | 7d60bfca10689a1f1a80b31d1c691354 MD5 | raw file
Possible License(s): CC-BY-SA-3.0
  1. namespace BIDSHelper.Core
  2. {
  3. using System;
  4. using System.Windows.Forms;
  5. using EnvDTE;
  6. using System.Reflection;
  7. using System.Globalization;
  8. /// <summary>
  9. /// Version Check dialog for BIDS Helper, as seen under the Visual Studio menu Tools -> Options.
  10. /// </summary>
  11. public partial class BIDSHelperOptionsVersionCheckPage : UserControl //, EnvDTE.IDTToolsOptionsPage
  12. {
  13. /// <summary>
  14. /// Standard caption for message boxes shown by this options page.
  15. /// </summary>
  16. private static string DefaultMessageBoxCaption = "BIDS Helper Version Check Options";
  17. /// <summary>
  18. /// Initializes a new instance of the <see cref="BIDSHelperOptionsVersionCheckPage"/> class.
  19. /// </summary>
  20. public BIDSHelperOptionsVersionCheckPage()
  21. {
  22. InitializeComponent();
  23. }
  24. #region IDTToolsOptionsPage Members
  25. //void IDTToolsOptionsPage.OnHelp()
  26. //{
  27. // // Launch plug-in help
  28. // OpenUrl(VersionCheckPlugin.VersionCheckPluginInstance.HelpUrl);
  29. //}
  30. #endregion
  31. public void Initialize()
  32. {
  33. // TODO - should we run the page load here?
  34. }
  35. private void BIDSHelperOptionsVersionCheckPage_Load(object sender, EventArgs e)
  36. {
  37. try
  38. {
  39. // Get title from assembly info, e.g. "BIDS Helper for SQL 2008"
  40. Assembly assembly = this.GetType().Assembly;
  41. AssemblyTitleAttribute attribute = (AssemblyTitleAttribute)AssemblyTitleAttribute.GetCustomAttribute(assembly, typeof(AssemblyTitleAttribute));
  42. this.lblTitle.Text = attribute.Title;
  43. string sBIDSName = "SSDTBI";
  44. if (BIDSHelperPackage.AddInLoadException != null)
  45. {
  46. this.lblBidsHelperLoadException.Text = string.Format("BIDS Helper encountered an error when Visual Studio started:\r\n{0}\r\n{1}"
  47. , BIDSHelperPackage.AddInLoadException.Message
  48. , BIDSHelperPackage.AddInLoadException.StackTrace);
  49. ReflectionTypeLoadException ex = BIDSHelperPackage.AddInLoadException as ReflectionTypeLoadException;
  50. if (ex != null)
  51. {
  52. System.Text.StringBuilder sb = new System.Text.StringBuilder();
  53. foreach (Exception exSub in ex.LoaderExceptions)
  54. {
  55. sb.AppendLine();
  56. sb.AppendLine(exSub.Message);
  57. System.IO.FileNotFoundException exFileNotFound = exSub as System.IO.FileNotFoundException;
  58. if (exFileNotFound != null)
  59. {
  60. if (!string.IsNullOrEmpty(exFileNotFound.FusionLog))
  61. {
  62. sb.AppendLine("Fusion Log:");
  63. sb.AppendLine(exFileNotFound.FusionLog);
  64. }
  65. }
  66. sb.AppendLine();
  67. }
  68. this.lblBidsHelperLoadException.Text += sb.ToString();
  69. }
  70. this.lblBidsHelperLoadException.Visible = true;
  71. this.btnCopyError.Visible = true;
  72. }
  73. else
  74. {
  75. this.lblBidsHelperLoadException.Visible = false;
  76. this.btnCopyError.Visible = false;
  77. }
  78. try
  79. {
  80. this.lblSqlVersion.Text = sBIDSName + " " + GetFriendlySqlVersion() + " for Visual Studio " + GetFriendlyVisualStudioVersion() + " was detected";
  81. }
  82. catch
  83. {
  84. //if there's an exception it's because we couldn't find SSDTBI or BIDS installed in this Visual Studio version
  85. try
  86. {
  87. this.lblSqlVersion.Text = sBIDSName + " for Visual Studio " + GetFriendlyVisualStudioVersion() + " was NOT detected. BIDS Helper disabled.";
  88. this.lblSqlVersion.ForeColor = System.Drawing.Color.Red;
  89. if (BIDSHelperPackage.AddInLoadException != null && BIDSHelperPackage.AddInLoadException is System.Reflection.ReflectionTypeLoadException)
  90. {
  91. //this is the expected exception if SSDTBI isn't installed... if this is the exception, don't show it... otherwise, show the exception
  92. this.lblBidsHelperLoadException.Visible = false;
  93. }
  94. }
  95. catch
  96. {
  97. this.lblSqlVersion.Visible = false;
  98. }
  99. }
  100. // Set current version
  101. this.lblLocalVersion.Text = VersionCheckPlugin.LocalVersion;
  102. #if DEBUG
  103. DateTime buildDateTime = GetBuildDateTime(assembly);
  104. this.lblLocalVersion.Text += string.Format(CultureInfo.InvariantCulture, " (Debug Build {0:yyyy-MM-dd HH:mm:ss})", buildDateTime);
  105. #endif
  106. // First check we have a valid instance, the add-in may be disabled.
  107. if (VersionCheckPlugin.Instance == null)
  108. {
  109. bool bConnected = false;
  110. try
  111. {
  112. // TODO - will this code even run now that we are in an extension if the extension
  113. // is not loaded
  114. //foreach (EnvDTE.AddIn addin in Connect.Application.AddIns)
  115. //{
  116. // if (addin.ProgID.ToLower() == "BIDSHelper.Connect".ToLower())
  117. // {
  118. // if (addin.Connected)
  119. // {
  120. bConnected = true;
  121. // break;
  122. // }
  123. //}
  124. //}
  125. }
  126. catch { }
  127. if (bConnected)
  128. {
  129. // Display disabled information and exit
  130. if (BIDSHelperPackage.AddInLoadException == null)
  131. lblServerVersion.Text = "The BIDS Helper Add-in is not running because of problems loading!";
  132. else
  133. lblServerVersion.Visible = false;
  134. linkNewVersion.Visible = false;
  135. }
  136. else
  137. {
  138. // Display disabled information and exit
  139. lblLocalVersion.Text += " [Add-in Disabled]";
  140. lblServerVersion.Text = "The BIDS Helper Add-in is not currently enabled.";
  141. linkNewVersion.Visible = false;
  142. }
  143. return; //if we don't have the version check plugin loaded, then stop now and don't check version on server
  144. }
  145. try
  146. {
  147. VersionCheckPlugin.Instance.LastVersionCheck = DateTime.Today;
  148. if (!VersionCheckPlugin.VersionIsLatest(VersionCheckPlugin.LocalVersion, VersionCheckPlugin.Instance.ServerVersion))
  149. {
  150. lblServerVersion.Text = "Version " + VersionCheckPlugin.Instance.ServerVersion + " is available...";
  151. lblServerVersion.Visible = true;
  152. linkNewVersion.Visible = true;
  153. }
  154. else
  155. {
  156. lblServerVersion.Text = "BIDS Helper is up to date.";
  157. lblServerVersion.Visible = true;
  158. linkNewVersion.Visible = false;
  159. }
  160. }
  161. catch (Exception ex)
  162. {
  163. lblServerVersion.Text = "Unable to retrieve current available BIDS Helper version from Codeplex: " + ex.Message + "\r\n" + ex.StackTrace;
  164. linkNewVersion.Visible = false;
  165. }
  166. }
  167. catch (Exception ex)
  168. {
  169. MessageBox.Show(ex.Message + "\r\n" + ex.StackTrace, DefaultMessageBoxCaption);
  170. }
  171. }
  172. private string GetFriendlyVisualStudioVersion()
  173. {
  174. //TODO - get version number for VS
  175. //if (BIDSHelperPackage.Application.Version.StartsWith("8.")) //YUKON runs here
  176. // return "2005";
  177. //else if (BIDSHelperPackage.Application.Version.StartsWith("9.")) //KATMAI runs here
  178. // return "2008";
  179. //else if (BIDSHelperPackage.Application.Version.StartsWith("10.")) //DENALI runs here
  180. // return "2010";
  181. //else if (BIDSHelperPackage.Application.Version.StartsWith("11.")) //DENALI runs here
  182. // return "2012";
  183. //else if (BIDSHelperPackage.Application.Version.StartsWith("12.")) //SQL2014 runs here
  184. // return "2013";
  185. //else
  186. // return BIDSHelperPackage.Application.Version; //todo in future
  187. return "Unknown";
  188. }
  189. private string GetFriendlySqlVersion()
  190. {
  191. Assembly assemb = System.Reflection.Assembly.Load("Microsoft.DataWarehouse"); //get a sample assembly that's installed with BIDS and use that to detect if BIDS is installed
  192. string sVersion = assemb.GetName().Version.ToString();
  193. try
  194. {
  195. //if it's a SQL2008 R2 release, you need to get the informational version attribute
  196. //SQL2005 didn't have this attribute
  197. AssemblyInformationalVersionAttribute attributeVersion = (AssemblyInformationalVersionAttribute)AssemblyTitleAttribute.GetCustomAttribute(assemb, typeof(AssemblyInformationalVersionAttribute));
  198. if (attributeVersion != null) sVersion = attributeVersion.InformationalVersion;
  199. }
  200. catch { }
  201. if (sVersion.StartsWith("9."))
  202. return "2005";
  203. else if (sVersion.StartsWith("10.5"))
  204. return "2008 R2";
  205. else if (sVersion.StartsWith("10."))
  206. return "2008";
  207. else if (sVersion.StartsWith("11."))
  208. return "2012";
  209. else if (sVersion.StartsWith("12."))
  210. return "2014";
  211. else
  212. return sVersion; //todo in future post DENALI and SQL2014
  213. }
  214. /// <summary>
  215. /// Handles the LinkClicked event of the linkLabelCodePlexUrl control.
  216. /// </summary>
  217. /// <param name="sender">The source of the event.</param>
  218. /// <param name="e">The <see cref="System.Windows.Forms.LinkLabelLinkClickedEventArgs"/> instance containing the event data.</param>
  219. private void linkLabelCodePlexUrl_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
  220. {
  221. OpenUrl(linkLabelCodePlexUrl.Text);
  222. }
  223. /// <summary>
  224. /// Handles the LinkClicked event of the linkNewVersion control.
  225. /// </summary>
  226. /// <param name="sender">The source of the event.</param>
  227. /// <param name="e">The <see cref="System.Windows.Forms.LinkLabelLinkClickedEventArgs"/> instance containing the event data.</param>
  228. private void linkNewVersion_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
  229. {
  230. OpenUrl(VersionCheckPlugin.BIDS_HELPER_RELEASE_URL);
  231. }
  232. /// <summary>
  233. /// Opens a URL.
  234. /// </summary>
  235. /// <param name="url">The URL to open.</param>
  236. private void OpenUrl(string url)
  237. {
  238. try
  239. {
  240. System.Diagnostics.Process process = new System.Diagnostics.Process();
  241. process.StartInfo.UseShellExecute = true;
  242. process.StartInfo.FileName = "iexplore.exe";
  243. process.StartInfo.Arguments = url;
  244. process.Start();
  245. }
  246. catch (Exception ex)
  247. {
  248. MessageBox.Show(ex.Message + Environment.NewLine + ex.StackTrace, DefaultMessageBoxCaption);
  249. }
  250. }
  251. private void btnCopyError_Click(object sender, EventArgs e)
  252. {
  253. Clipboard.SetText(this.lblBidsHelperLoadException.Text);
  254. }
  255. #if DEBUG
  256. // Gets the build date and time (by reading the COFF header)
  257. // http://stackoverflow.com/questions/1600962/displaying-the-build-date
  258. // http://msdn.microsoft.com/en-us/library/ms680313
  259. #pragma warning disable 169
  260. #pragma warning disable 649
  261. struct IMAGE_FILE_HEADER
  262. {
  263. public ushort Machine;
  264. public ushort NumberOfSections;
  265. public uint TimeDateStamp;
  266. public uint PointerToSymbolTable;
  267. public uint NumberOfSymbols;
  268. public ushort SizeOfOptionalHeader;
  269. public ushort Characteristics;
  270. };
  271. #pragma warning restore 649
  272. #pragma warning restore 169
  273. private static DateTime GetBuildDateTime(Assembly assembly)
  274. {
  275. if (System.IO.File.Exists(assembly.Location))
  276. {
  277. var buffer = new byte[Math.Max(System.Runtime.InteropServices.Marshal.SizeOf(typeof(IMAGE_FILE_HEADER)), 4)];
  278. using (var fileStream = new System.IO.FileStream(assembly.Location, System.IO.FileMode.Open, System.IO.FileAccess.Read))
  279. {
  280. fileStream.Position = 0x3C;
  281. fileStream.Read(buffer, 0, 4);
  282. fileStream.Position = BitConverter.ToUInt32(buffer, 0); // COFF header offset
  283. fileStream.Read(buffer, 0, 4); // "PE\0\0"
  284. fileStream.Read(buffer, 0, buffer.Length);
  285. }
  286. var pinnedBuffer = System.Runtime.InteropServices.GCHandle.Alloc(buffer, System.Runtime.InteropServices.GCHandleType.Pinned);
  287. try
  288. {
  289. var coffHeader = (IMAGE_FILE_HEADER)System.Runtime.InteropServices.Marshal.PtrToStructure(pinnedBuffer.AddrOfPinnedObject(), typeof(IMAGE_FILE_HEADER));
  290. return TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1) + new TimeSpan(coffHeader.TimeDateStamp * TimeSpan.TicksPerSecond));
  291. }
  292. finally
  293. {
  294. pinnedBuffer.Free();
  295. }
  296. }
  297. return new DateTime();
  298. }
  299. #endif
  300. }
  301. }