topbanner_forum
  *

avatar image

Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length
  • Friday March 29, 2024, 3:04 am
  • Proudly celebrating 15+ years online.
  • Donate now to become a lifetime supporting member of the site and get a non-expiring license key for all of our programs.
  • donate

Author Topic: C# Updater class for DcuHelper  (Read 7032 times)

worstje

  • Honorary Member
  • Joined in 2009
  • **
  • Posts: 588
  • The Gent with the White Hat
    • View Profile
    • Donate to Member
C# Updater class for DcuHelper
« on: July 12, 2011, 08:17 PM »
Way back, around the time of the previous NANY release times, I once said to mouser that I would share the class I wrote to make use of dcuhelper.exe with the rest of DoCo. And then I forgot. Bad bad me. :-[

Anyhow, here it goes. I took this straight from JottiQ, so do with it what you wish.

Supported features of this class:
  • Properties to abstract settings storage; by default it uses the WPF Settings store to remember whether it should automatically check for updates (Properties.Settings.Default.UpdaterEnabled) and when it last checked (Properties.Settings.Default.UpdaterLastCheck)
  • Supports silent checking.
  • Silent checking supports an interval, the default being one check every two days.
  • Supports feeding additional parameters (JottiQ uses it to hide the Dcupdater button)
  • Supports label name option.
  • Supports custom captions for the dialogs (for when you hate mouser's addiction to default of an all caps UPDATE CHECK window caption).

Code of Updater class: (save in Updater.cs)
Code: C# [Select]
  1. using System;
  2. using System.Windows;
  3. using System.Diagnostics;
  4. using System.Reflection;
  5.  
  6. namespace JottiQ
  7. {
  8.     public static class Updater
  9.     {
  10.         /* Settings - adjust as necessary. */
  11.         private static string FileUpdater = "dcuhelper.exe";
  12.         private static string FileConfig = "JottiQ.dcupdate";
  13.  
  14.         private static string UpdaterLabelName = "JottiQ";
  15.         private static string UpdaterDialogCaption = "Update check";
  16.         private static string UpdaterAdditionalFlags = "-dontofferdcupdaterpage";
  17.  
  18.         private static int UpdaterCheckingInterval = 2;    /* days since last check */
  19.  
  20.         private static string UpdaterNotAvailableCaption = "You silly monkey.";
  21.         private static string UpdaterNotAvailableMessage = "Updater support is not present.";
  22.  
  23.         /* Interface for persistent storage so we don't litter the rest of the code
  24.          * with hard-coded references to the Settings stuff.
  25.          */
  26.         private static bool UpdaterEnabled
  27.         {
  28.             get { return Properties.Settings.Default.UpdaterEnabled; }
  29.         }
  30.  
  31.         private static DateTime UpdaterLastCheck
  32.         {
  33.             get { return Properties.Settings.Default.UpdaterLastCheck; }
  34.             set
  35.             {
  36.                 Properties.Settings.Default.UpdaterLastCheck = value;
  37.                 Properties.Settings.Default.Save();
  38.             }
  39.         }
  40.  
  41.         /* Implementation of the class goes below here - no changes needed. */
  42.         private static String GetInstallationLocation()
  43.         {
  44.             string appDir = Assembly.GetExecutingAssembly().Location;
  45.             appDir = System.IO.Path.GetDirectoryName(appDir);
  46.             if (!appDir.EndsWith(@"\"))
  47.                 appDir = appDir + @"\";
  48.  
  49.             return appDir;
  50.         }
  51.  
  52.         public static bool IsUpdaterAvailable()
  53.         {
  54.             bool dcUpdaterAvailable =
  55.                 System.IO.File.Exists(GetInstallationLocation() + FileUpdater) &&
  56.                 System.IO.File.Exists(GetInstallationLocation() + FileConfig);
  57.  
  58.             return dcUpdaterAvailable;
  59.         }
  60.  
  61.         public static void CheckForUpdates(bool explicitCheck)
  62.         {
  63.             if (!explicitCheck)
  64.             {
  65.                 /* See if we are allowed to do automatic checks. */
  66.                 if (UpdaterEnabled == false)
  67.                     return;
  68.  
  69.                 /* See if last check was less than X days ago. */
  70.                 TimeSpan ts = DateTime.Now.Subtract(UpdaterLastCheck);
  71.                 if (ts.Days < UpdaterCheckingInterval)
  72.                     return;
  73.             }
  74.  
  75.             if (IsUpdaterAvailable())
  76.             {
  77.                 System.Diagnostics.ProcessStartInfo updater =
  78.                     new System.Diagnostics.ProcessStartInfo();
  79.                 updater.FileName = GetInstallationLocation() + FileUpdater;
  80.                 updater.WorkingDirectory = GetInstallationLocation();
  81.                 updater.Arguments = "-i \"" + UpdaterLabelName + "\" \".\" \"" + (explicitCheck ? UpdaterDialogCaption : ".") + "\" " + UpdaterAdditionalFlags;
  82.  
  83.                 /* Old versions of dcuhelper.exe pop up an ugly command-line window. Setting the WindowStyle to Hidden hides that ugly monstrosity.
  84.                  *
  85.                  * PLEASE REMOVE this line if you have a recent version of dcuhelper.exe (later than ~January 1, 2011), since at some point
  86.                  * mouser redesigned the dialog in dcuhelper.exe, which actually broke the Hidden trick. At July 12, this bug was found and fixed,
  87.                  * so the Hidden switch can once again safely be used with dcuhelper.exe - although it is pointless as the ugly monstrosity has
  88.                  * been amputated somewhere along the way. Oh joy.
  89.                  *
  90.                  * Short story: safe for dcuhelper.exe versions: <= v1.05.01 (Oct 8, 2010) && >= v1.10.01 (July 12, 2011)
  91.                  */
  92.                 updater.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
  93.  
  94.                 /* Finally start dcuhelper.exe to do our check. */
  95.                 Process.Start(updater);
  96.  
  97.                 /* Make sure to note down that we checked for an update. */
  98.                 UpdaterLastCheck = DateTime.Now;
  99.             }
  100.             else if (explicitCheck)
  101.                 MessageBox.Show(UpdaterNotAvailableMessage, UpdaterNotAvailableCaption, MessageBoxButton.OK, MessageBoxImage.Error);
  102.         }
  103.     }
  104. }

To use it, you basically want to adjust the top parameters. Sadly enough, dcuhelper.exe is a total mess for as far its commandline interface goes, which is why I hope the above settings are a good example for people to start out with. If you want to urge your users to use dcupdater, by all means remove the additional parameter -dontofferdcupdaterpage that I once upon a time forced mouser to add. Likewise, you may (or may not) want to change the implementation of the properties the Updater class uses to implement its logic.

From there on forth, it is simple. On application start (or preferably MainWindow_Loaded given that that means you've gotten through to a visual interface), call:

Code: C# [Select]
  1. /* Check for updates. */
  2. Updater.CheckForUpdates(false);

The false parameter means it is not an explicit check. In comparison, the JottiQ Updates? button is rigged the opposite way to indicate that the user initiated the update check:

Code: C# [Select]
  1. private void checkForUpdatesButton_Click(object sender, RoutedEventArgs e)
  2. {
  3.     Updater.CheckForUpdates(true);
  4. }

And prior to that, we make sure the button is only enabled when the appropriate files are in place. (In case some required files are not present.)

Code: C# [Select]
  1. private void Window_Loaded(object sender, RoutedEventArgs e)
  2. {
  3.     /* If we have update functionality, enable the button. */
  4.     checkForUpdatesButton.IsEnabled = JottiQ.Updater.IsUpdaterAvailable();
  5. }

Any comments and suggestions, please share. :)

Ath

  • Supporting Member
  • Joined in 2006
  • **
  • Posts: 3,612
    • View Profile
    • Donate to Member
Re: C# Updater class for DcuHelper
« Reply #1 on: July 13, 2011, 01:43 AM »
Hey, that's nice code, thanks :Thmbsup:
I'll be using that in a DC-related project soon, I hope. :tellme: