Provides the functionality needed to update the ATC voicepack of Flight Simulator X.
Namespace:
Bevelstone.EditVoicepack.InstallerApiAssembly: Bevelstone.EditVoicepack.InstallerApi (in Bevelstone.EditVoicepack.InstallerApi.dll) Version: 4.0.7.0 (4.0.7.0)
Syntax
| C# |
|---|
public class VoicepackUpdater : INotifyPropertyChanged, IDisposable |
| Visual Basic (Declaration) |
|---|
Public Class VoicepackUpdater _ Implements INotifyPropertyChanged, IDisposable |
| Visual C++ |
|---|
public ref class VoicepackUpdater : INotifyPropertyChanged, IDisposable |
Remarks
When integrating the VoicepackUpdater with an application or installer, the
typical flow is as follows:
- Instantiate the VoicepackUpdater.
- If IsProcessElevationRequired returns true display the UAC shield on any user interface menu item or button used to start the update.
- Call Execute(IntPtr) to start the ATC voicepack update.
- Monitor the progress events through the PropertyChanged event and provide feedback to the user:
-
Allow the user to cancel the update, as long as:
- IsCancelAllowed is true
- IsCanceled is false
-
Once IsCompleted is true, check if UpdateError is null. If this is not the case, display the error text to the user.
Notice that in case the error is an UpdateVoicepackException, the real course of the error can be retreived through the ExceptionMessages and BaseExceptionMessage properties.
The full stack trace is available for debugging purpose through the DebugInformation property.
- Dispose()()() the VoicepackUpdater.
Examples
A WinForm based installer application. The full set of source files including Visual Studio 2008 project
files are included with the API.
CopyC#
using System; using System.ComponentModel; using System.Windows.Forms; using Bevelstone.EditVoicepack.InstallerApi; using Microsoft.Win32; namespace Bevelstone.EditVoicepack.ExampleInstaller { public partial class MainForm : Form { private VoicepackUpdater updater; public MainForm() { InitializeComponent(); } /// <summary> /// Called once the form is shown on the screen. /// </summary> /// <param name="sender"> /// The sender. /// </param> /// <param name="e"> /// The EventArgs instance containing the event data. /// </param> /// <remarks> /// Waiting until the form is shown allows it to be used /// as the parent window for the UAC dialog in case /// it needs to be displayed. /// </remarks> private void FormShownHandler(object sender, EventArgs e) { string flightSimFolder = FindFlightSimDirectoryFromRegistry(); if (flightSimFolder == null) { MessageBox.Show(this, "Unable to locate Flight Simulator X from the registry.", "ATC Voicepack Installer", MessageBoxButtons.OK, MessageBoxIcon.Error); Close(); return; } // Instantiate and start the update process. updater = new VoicepackUpdater(flightSimFolder); updater.PropertyChanged += PropertyChangedHandler; try { updater.Execute(Handle); } catch (Win32Exception ex) { updater.Dispose(); updater = null; // Check if it is a normal UAC cancel if (ex.NativeErrorCode == 1223) Close(); else throw; } } /// <summary> /// Called when the user click the cancel button. /// </summary> /// <param name="sender"> /// The sender. /// </param> /// <param name="e"> /// The EventArgs instance containing the event data. /// </param> /// <remarks> /// If the update is already completed close the form. /// If the update is not completed request the updater to cancel /// but do not close the form until the cancelation is completed. /// </remarks> private void CancelButtonClickHandler(object sender, EventArgs e) { if (updater == null || updater.IsCompleted) Close(); else updater.Cancel(); } /// <summary> /// Called by the VoicepackUpdater as it's properties are changed. /// </summary> /// <param name="sender"> /// The sender. /// </param> /// <param name="e"> /// The PropertyChangedEventArgs instance containing the event data. /// </param> void PropertyChangedHandler(object sender, PropertyChangedEventArgs e) { switch (e.PropertyName) { case "ProgressText": progressTextLabel.Text = updater.ProgressText; break; case "ProgressPercentage": progressBar.Value = updater.ProgressPercentage; break; case "IsCancelAllowed": // Ensure the user can use the cancel button to close once the // update is completed. cancelButton.Enabled = updater.IsCancelAllowed || updater.IsCompleted; break; case "IsCompleted": if (updater.IsCompleted) UpdateCompleted(); break; } } /// <summary> /// Executed once the voicepack update is completed. /// </summary> private void UpdateCompleted() { if (updater.IsCanceled) { // The user requested a cancel, so close the window. Close(); } else if (updater.UpdateError == null) { // Normal termination cancelButton.Text = "Close"; cancelButton.Enabled = true; } else { // Termination with error string errorMsg = "Updating the ATC voicepack failed with the following error:" + Environment.NewLine; if (updater.UpdateError is UpdateVoicepackException) { errorMsg += ((UpdateVoicepackException)updater.UpdateError).BaseExceptionMessage; } else { errorMsg += updater.UpdateError.GetBaseException().Message; } MessageBox.Show(this, errorMsg, "ATC Voicepack Installer", MessageBoxButtons.OK, MessageBoxIcon.Error); Close(); } } /// <summary> /// Called when the Form is being closed. /// </summary> /// <param name="sender"> /// The sender. /// </param> /// <param name="e"> /// The FormClosingEventArgs instance containing the event data. /// </param> /// <remarks> /// If the update is in progress cancel it but keep the window open. /// </remarks> private void FormClosingHandler(object sender, FormClosingEventArgs e) { if (updater != null && !updater.IsCompleted) { updater.Cancel(); e.Cancel = true; } } /// <summary> /// Called when the form has been closed /// </summary> /// <param name="sender"> /// The sender. /// </param> /// <param name="e"> /// The FormClosedEventArgs instance containing the event data. /// </param> /// <remarks> /// Ensure Dispose is called on the VoicepackUpdater. /// </remarks> private void FormCloseHandler(object sender, FormClosedEventArgs e) { if (updater != null) updater.Dispose(); } /// <summary> /// Finds the root directory of Flight Simulator X based on the registry /// key created by the installer. /// </summary> /// <returns> /// The location of the root folder; or <c>null</c> if the registry key /// indicating the root folder could not be found. /// </returns> /// <remarks> /// Supports both 32 and 64 bit environments. /// </remarks> private static string FindFlightSimDirectoryFromRegistry() { string result; RegistryKey key = null; string keyPath = @"SOFTWARE\Microsoft\Microsoft Games\Flight Simulator\10.0"; if (IntPtr.Size == 8) keyPath = @"SOFTWARE\Wow6432Node\Microsoft\Microsoft Games\Flight Simulator\10.0"; try { key = Registry.LocalMachine.OpenSubKey(keyPath, false); if (key == null) return null; result = (string)key.GetValue("SetupPath"); } finally { if (key != null) key.Close(); } return result; } } }