Skip to content

Instantly share code, notes, and snippets.

Created May 1, 2014 13:20
Show Gist options
  • Save anonymous/e4daa8f0a58d90411ef9 to your computer and use it in GitHub Desktop.
Save anonymous/e4daa8f0a58d90411ef9 to your computer and use it in GitHub Desktop.
Async Install Task
ModuleBase.ReportProgress() [CLTDEPAPI10] [1]% [Installing Mobile Recruiter]
ModuleBase.ReportProgress() [CLTDEPFE1] [1]% [Installing Mobile Recruiter]
ModuleBase.ReportProgress() [CLTDEPAPI11] [1]% [Installing Mobile Recruiter]
ModuleBase.ReportProgress() [CLTDEPFE1] [5]% [Invoking installer agent at net.tcp://cltdepfe1:8890/]
ModuleBase.ReportProgress() [CLTDEPAPI11] [5]% [Invoking installer agent at net.tcp://cltdepapi11:8890/]
ModuleBase.ReportProgress() [CLTDEPAPI10] [5]% [Invoking installer agent at net.tcp://cltdepapi10:8890/]
#region
using System;
using System.ComponentModel.Composition;
using System.Diagnostics;
using System.ServiceModel;
using System.Threading.Tasks;
using Cmc.Installer.Agent.Client;
using Cmc.Installer.Infrastructure;
using Cmc.Installer.Modules.MobileRecruiter.Views;
using Microsoft.Practices.Prism.MefExtensions.Modularity;
using Microsoft.Practices.Prism.Regions;
#endregion
namespace Cmc.Installer.Modules.MobileRecruiter
{
/// <summary>
/// Mobile Recruiter Module
/// </summary>
[ModuleExport(typeof (MobileRecruiterModule))]
public sealed class MobileRecruiterModule : ModuleBase, IDisposable
{
[Import] public IRegionManager Region;
/// <summary>
/// The installer agent service client. Note: If this lived in ModuleBase
/// it would create a circular dependency with Cmc.Installer.Agent.Client
/// </summary>
private InstallerAgentServiceClient _installerAgentServiceClient;
/// <summary>
/// Gets the name of the module.
/// </summary>
/// <value>
/// The name of the module.
/// </value>
public override string ModuleName
{
get { return "Mobile Recruiter"; }
}
/// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
/// </summary>
public void Dispose()
{
_installerAgentServiceClient.Dispose();
}
/// <summary>
/// Determines if module prerequisites are satisfied
/// </summary>
/// <param name="targetMachine"></param>
/// <returns></returns>
/// <exception cref="System.NotImplementedException"></exception>
public override bool PrerequisitesSatisfied(string targetMachine)
{
throw new NotImplementedException();
}
/// <summary>
/// Installs the specified target machine.
/// </summary>
/// <param name="targetMachine">The target machine.</param>
/// <param name="progress">The progress.</param>
/// <returns></returns>
public override async Task<int> Install(string targetMachine, IProgress<InstallProgress> progress)
{
Progress = progress;
ReportProgress(progress, targetMachine, 1, "Installing " + ModuleName);
LoadSettings();
var msi = Settings.MobileRecruiterModule.MSIs.MSI.Path.Value;
var msiArgs = Settings.MobileRecruiterModule.MSIs.MSI.CommandLine.Value;
//TODO make port configurable at runtime via app.config with fallback of 8890 or whatever
var uri = new Uri("net.tcp://" + targetMachine + ":8890");
var endpointAddress = new EndpointAddress(uri);
ReportProgress(Progress, targetMachine, 5, "Invoking installer agent at " + uri);
_installerAgentServiceClient = new InstallerAgentServiceClient(this, endpointAddress);
// Bubble progress events back up to WPF Shell
_installerAgentServiceClient.ProgressChanged += (sender, args) =>
{
Debug.WriteLine("InstallerAgentServiceClient.ProgressChanged: {0}", args.ProgressPercentage);
ReportProgress(Progress, targetMachine, args.ProgressPercentage, args.UserState.ToString());
};
var ret = await _installerAgentServiceClient.Install(msi, msiArgs);
return ret;
}
/// <summary>
/// Uninstalls the specified target machine.
/// </summary>
/// <param name="targetMachine">The target machine.</param>
/// <param name="progress">The progress.</param>
/// <returns></returns>
/// <exception cref="System.NotImplementedException"></exception>
public override Task<int> Uninstall(string targetMachine, IProgress<InstallProgress> progress)
{
throw new NotImplementedException();
}
/// <summary>
/// Notifies the module that it has be initialized.
/// </summary>
public override void Initialize()
{
Region.RegisterViewWithRegion(RegionNames.MainContentRegion, typeof (MobileRecruiterView));
}
}
}
#region
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Threading.Tasks;
using Microsoft.Practices.Prism.Modularity;
#endregion
namespace Cmc.Installer
{
public abstract class ModuleBase : IModule, IInstallModule
{
protected IProgress<InstallProgress> Progress;
protected dynamic Settings;
private string _targetMachine;
public event ProgressChangedEventHandler ProgressChanged;
public event InstallCompletedEventHandler InstallCompleted;
/// <summary>
/// Gets the name of the module.
/// </summary>
/// <value>
/// The name of the module.
/// </value>
public abstract string ModuleName { get; }
/// <summary>
/// Determines if module prerequisites are satisfied
/// </summary>
/// <param name="targetMachine"></param>
/// <returns></returns>
public abstract bool PrerequisitesSatisfied(string targetMachine);
/// <summary>
/// Called when [progress changed].
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="args">The <see cref="ProgressChangedEventArgs" /> instance containing the event data.</param>
public virtual void OnProgressChanged(object sender, ProgressChangedEventArgs args)
{
ReportProgress(Progress, _targetMachine, args.ProgressPercentage);
}
/// <summary>
/// Loads the settings.
/// </summary>
/// <exception cref="System.IO.FileNotFoundException"></exception>
/// <exception cref="Cmc.Installer.ModuleSettingsNotFoundException"></exception>
public virtual void LoadSettings()
{
var currentDirectory = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
if (!File.Exists(currentDirectory + @"\settings.xml"))
{
throw new FileNotFoundException(currentDirectory + @"\settings.xml");
}
Settings = SettingsReader.LoadSettings(currentDirectory + @"\settings.xml");
// Verify that settings.xml contains a <Modules><MobileRecruiterModule></MobileRecruiterModule></Modules> section
if (Settings.Modules == null || Settings.Modules.MobileRecruiterModule == null)
{
throw new ModuleSettingsNotFoundException();
}
}
/// <summary>
/// Installs the specified target machine.
/// </summary>
/// <param name="targetMachine">The target machine.</param>
/// <param name="progress">The progress.</param>
/// <returns></returns>
public abstract Task<int> Install(string targetMachine, IProgress<InstallProgress> progress);
/// <summary>
/// Uninstalls the specified target machine.
/// </summary>
/// <param name="targetMachine">The target machine.</param>
/// <param name="progress">The progress.</param>
/// <returns></returns>
public abstract Task<int> Uninstall(string targetMachine, IProgress<InstallProgress> progress);
/// <summary>
/// Notifies the module that it has be initialized.
/// </summary>
public abstract void Initialize();
/// <summary>
/// Installs the asynchronous.
/// </summary>
/// <param name="targetMachine">The target machine.</param>
/// <param name="progress">The progress.</param>
/// <returns></returns>
public virtual Task<InstallCompletedResult> InstallAsync(string targetMachine, IProgress<InstallProgress> progress = null)
{
var tcs = new TaskCompletionSource<InstallCompletedResult>();
InstallCompletedEventHandler handler = null;
handler = (s, e) =>
{
InstallCompleted -= handler;
if (e.Exception != null)
tcs.TrySetException(e.Exception);
else
tcs.TrySetResult(e.Result);
};
InstallCompleted += handler;
Install(targetMachine, progress);
return tcs.Task;
}
/// <summary>
/// Reports the progress.
/// </summary>
/// <param name="progress">The progress.</param>
/// <param name="machineName">Name of the machine.</param>
/// <param name="progressPercentage">The progress percentage.</param>
/// <param name="message">The message.</param>
protected void ReportProgress(IProgress<InstallProgress> progress, string machineName, int progressPercentage,
string message = "")
{
if (progress == null) return;
Debug.WriteLine("ModuleBase.ReportProgress() [{0}] [{1}%] [{2}]", machineName, progressPercentage,
message);
progress.Report(new InstallProgress
{
MachineName = machineName,
ProgressPercentage = progressPercentage,
Message = message
});
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment