As part of the security setup for your application,
you need to know whether Windows is up to date. In some cases, your
application could actually fail because it depends on a fix being in
place that the user hasn't installed yet. Many administrators and
developers alike realized the need to check the Windows Update status
and created code to perform that task.
1. Configuring the Automatic Update Example
The example begins with a Windows Forms application. It requires two buttons, Settings (btnSettings) and Updates (btnUpdates), and a list box, lstResults. You don't need to add any special references or using statements.
2. Writing the Settings Code
One of the first things you'll want to do is view
the Windows Update settings, but this task can prove difficult if you
follow the clues online. A number of Websites discuss the contents of
the HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update key. In fact, you can see this key in RegEdit as shown in Figure 1.
As you can see, accessing this key would let you detect all the Windows
Update settings and determine how the user has configured the system.
The RegEdit utility can sometimes prove deceptive. When you run the following code, you'll find that the WindowsUpdate subkey is missing from the list.
// Track the results.
Boolean NotFound = true;
// Obtain the CurrentVersion registry key.
RegistryKey WU =
Registry.LocalMachine.OpenSubKey(
@"SOFTWARE\Microsoft\Windows\CurrentVersion");
// Get all of the subkeys and process them.
String[] Subkeys = WU.GetSubKeyNames();
foreach (String KeyName in Subkeys)
{
// Look for the WindowsUpdate subkey.
if (KeyName == "WindowsUpdate")
{
// Display a success message.
MessageBox.Show("Found WindowsUpdate!");
// Update the tracking variable.
NotFound = false;
break;
}
}
// Check the tracking variable.
if (NotFound)
// Display a failure message.
MessageBox.Show("WindowsUpdate is Missing!");
As far as your .NET application is concerned, the WindowsUpdate
subkey doesn't exist. Running in administrator mode won't help.
Changing the key's permissions won't help either. This is a
circumstance where RegEdit shows something your application can't
access directly.
Fortunately, you can access the information you need using COM and the dynamic keyword. Listing 1 shows the code used to access the Windows Update settings for this example.
Example 1. Obtaining the current Windows Update settings
private void btnSettings_Click(object sender, EventArgs e) { // Clear the list box. lstResults.Items.Clear();
// Create the AutoUpdate type. Type SettingsType = Type.GetTypeFromProgID("Microsoft.Update.AutoUpdate");
// Use the AutoUpdate type to create a settings object. dynamic Settings = Activator.CreateInstance(SettingsType);
// Verify that the Windows Update service is running. if (Settings.ServiceEnabled) // Display the status. lstResults.Items.Add("Windows Update Service Enabled."); else { // Display the status and exit because the code can't // process any more information. lstResults.Items.Add("Windows Update Service Disabled."); return; }
// Determine the update mode and output data accordingly. switch ((Int32)Settings.Settings.NotificationLevel) { case 1: lstResults.Items.Add("Update Mode: Never Check"); break;
case 2: lstResults.Items.Add("Update Mode: Check for Updates"); break; case 3: lstResults.Items.Add("Update Mode: Download Updates/No Install"); break; case 4: lstResults.Items.Add("Update Mode: Automatically Install Updates");
// Get the automatic check day and time. switch ((Int32)Settings.Settings.ScheduledInstallationDay) { case 0: lstResults.Items.Add("\tEvery Day: " + Settings.Settings.ScheduledInstallationTime + ":00"); break; case 1: lstResults.Items.Add("\tSunday: " + Settings.Settings.ScheduledInstallationTime + ":00"); break; case 2: lstResults.Items.Add("\tMonday: " + Settings.Settings.ScheduledInstallationTime + ":00"); break; case 3: lstResults.Items.Add("\tTuesday: " + Settings.Settings.ScheduledInstallationTime + ":00"); break; case 4: lstResults.Items.Add("\tWednesday: " + Settings.Settings.ScheduledInstallationTime + ":00"); break; case 5: lstResults.Items.Add("\tThursday: " + Settings.Settings.ScheduledInstallationTime + ":00"); break; case 6: lstResults.Items.Add("\tFriday: " + Settings.Settings.ScheduledInstallationTime + ":00"); break; case 7: lstResults.Items.Add("\tSaturday: " + Settings.Settings.ScheduledInstallationTime + ":00"); break; } break; }
// Check the kinds of updates allowed. if (Settings.Settings.FeaturedUpdatesEnabled) lstResults.Items.Add("Featured Updates Enabled"); else lstResults.Items.Add("Featured Updates Disabled");
if (Settings.Settings.IncludeRecommendedUpdates)
lstResults.Items.Add("Include Recommended Updates"); else lstResults.Items.Add("Don't Include Recommended Updates");
if (Settings.Settings.NonAdministratorsElevated) lstResults.Items.Add("Non-administrators Automatically Elevated"); else lstResults.Items.Add("Only Administrators Can Update System");
// Get update search and installation information. lstResults.Items.Add("Last Successful Search Date:" + Settings.Results.LastSearchSuccessDate); lstResults.Items.Add("Last Successful Installation Date: " + Settings.Results.LastInstallationSuccessDate); }
|
The example begins by clearing the old results. It then creates the SettingsType by calling Type.GetTypeFromProgID() with the Microsoft.Update.AutoUpdate program identifier. The code uses the dynamic keyword to create the Settings object by calling Activator.CreateInstance() with SettingsType as an argument. At this point, you have access to all the Windows Update settings.
It's important not to assume that the user has the
Windows Update service enabled. In some cases, the administrator could
turn the service off or the user might do so. The first check verifies
that the service is enabled. If not, the code outputs text showing that
the service is disabled and exits.
A user can select four levels of update. The next
check determines the notification level — the amount of update
information the user receives. At one end of the spectrum, the user can
choose not to receive any update information at all (which means the
user will have to manually request update information), and at the
other end the updates can occur automatically without any user
notification at all. When the user chooses the automatic update option,
the system is also configured for a day and time to perform the update
(usually when it's least likely to cause problems for the user's work
schedule). The system can check for updates every day or on a specific
day and at a specified time.
The user can also select a number of update
features. The example doesn't review all these settings, but the user
can choose whether to check for recommended updates in addition to
critical updates. The most important entry for developers is whether
users can install updates. In some cases, the system will be configured
to allow only administrators to perform updates, which means that your
application may have to wait until an administrator can install the
required updates.
Finally, the example checks Settings.Results for two bits of information that help you understand system health. The LastSearchSuccessDate
should be recent if the system at least checks for updates regularly.
Of course, simply because the system checks for updates doesn't
necessarily mean that the user is installing any of them, which is why
you must also check the LastInstallationSuccessDate property
to ensure it isn't too far out of date with the last search date.
Microsoft constantly provides updates, so the two dates should be
reasonably close. Figure 2 shows typical output from this portion of the example.