diff --git a/Solutions/Endjin.Templify.Client/Endjin.Templify.Client.csproj b/Solutions/Endjin.Templify.Client/Endjin.Templify.Client.csproj
index 7c6f2f5..44e1a08 100644
--- a/Solutions/Endjin.Templify.Client/Endjin.Templify.Client.csproj
+++ b/Solutions/Endjin.Templify.Client/Endjin.Templify.Client.csproj
@@ -158,6 +158,10 @@
{9E8B79ED-9C17-485B-B1F9-8D33D8BB4BD2}
Endjin.Templify.Domain
+
+ {D8F709BA-1E52-48FB-A917-7C3A40445F7F}
+ Endjin.Templify.WizardFramework
+
diff --git a/Solutions/Endjin.Templify.Client/ViewModel/DeployPackageViewModel.cs b/Solutions/Endjin.Templify.Client/ViewModel/DeployPackageViewModel.cs
index 903de51..2755ff6 100644
--- a/Solutions/Endjin.Templify.Client/ViewModel/DeployPackageViewModel.cs
+++ b/Solutions/Endjin.Templify.Client/ViewModel/DeployPackageViewModel.cs
@@ -19,6 +19,7 @@ namespace Endjin.Templify.Client.ViewModel
using Endjin.Templify.Domain.Framework;
using Endjin.Templify.Domain.Framework.Threading;
using Endjin.Templify.Domain.Infrastructure;
+ using Endjin.Templify.WizardFramework;
#endregion
@@ -250,7 +251,11 @@ private void ExecutePackageComplete(RunWorkerCompletedEventArgs e)
private void ExecutePackageCore(Package package)
{
this.packageDeploymentProcessor.Execute(package);
- this.packageProcessor.Process(this.CommandOptions.Path, this.Name);
+
+ // TODO: Due to the WizardFramework being a WinForm, the WPF app does not show anything :-(
+ this.ExecuteWizard(package);
+
+ this.packageProcessor.Process(this.CommandOptions.Path, this.Name, package.Manifest.Configuration);
}
private void Initialise()
@@ -269,5 +274,24 @@ private void RetrievePackages()
{
this.Packages = new PackageCollection(this.packageRepository.FindAll());
}
+
+ private void ExecuteWizard(Package package)
+ {
+ // TODO: Run the wizard to collect the token info
+ // Instantiate the command list
+ var cmdList = new CommandList();
+
+ // Add the WizardCommand objects in order to the list to provide
+ // the application workflow
+ cmdList.Add(new PackageConfigurationDataWizardFormCommand(package.Manifest.Configuration));
+
+ // The wizard simply uses a flow of objects in order until we
+ // reach the last command, so loop until that condition is
+ // detected
+ while (cmdList.CmdPointer > -1 && !cmdList.IsLastCommand())
+ {
+ cmdList.ExecuteNext();
+ }
+ }
}
}
\ No newline at end of file
diff --git a/Solutions/Endjin.Templify.Domain/Contracts/Packager/Processors/IPackageProcessor.cs b/Solutions/Endjin.Templify.Domain/Contracts/Packager/Processors/IPackageProcessor.cs
index 77160fb..29a172c 100644
--- a/Solutions/Endjin.Templify.Domain/Contracts/Packager/Processors/IPackageProcessor.cs
+++ b/Solutions/Endjin.Templify.Domain/Contracts/Packager/Processors/IPackageProcessor.cs
@@ -3,6 +3,7 @@
#region Using Directives
using System;
+ using System.Collections.Generic;
using Endjin.Templify.Domain.Domain.Packages;
@@ -10,6 +11,6 @@
public interface IPackageProcessor
{
- void Process(string path, string name);
+ void Process(string path, string name, List tokens);
}
}
\ No newline at end of file
diff --git a/Solutions/Endjin.Templify.Domain/Contracts/Packager/Tokeniser/ITemplateTokeniser.cs b/Solutions/Endjin.Templify.Domain/Contracts/Packager/Tokeniser/ITemplateTokeniser.cs
index c9c10d5..5616323 100644
--- a/Solutions/Endjin.Templify.Domain/Contracts/Packager/Tokeniser/ITemplateTokeniser.cs
+++ b/Solutions/Endjin.Templify.Domain/Contracts/Packager/Tokeniser/ITemplateTokeniser.cs
@@ -1,9 +1,13 @@
namespace Endjin.Templify.Domain.Contracts.Packager.Tokeniser
{
+ using System.Collections.Generic;
+
+ using Endjin.Templify.Domain.Domain.Packages;
+
public interface ITemplateTokeniser
{
- void TokeniseFileContent(string file, string token);
+ void TokeniseFileContent(string file, List tokens);
- void TokeniseDirectoryAndFilePaths(string file, string token);
+ void TokeniseDirectoryAndFilePaths(string file, List tokens);
}
}
\ No newline at end of file
diff --git a/Solutions/Endjin.Templify.Domain/Domain/Packager/Processors/PackageProcessor.cs b/Solutions/Endjin.Templify.Domain/Domain/Packager/Processors/PackageProcessor.cs
index 004f195..9109400 100644
--- a/Solutions/Endjin.Templify.Domain/Domain/Packager/Processors/PackageProcessor.cs
+++ b/Solutions/Endjin.Templify.Domain/Domain/Packager/Processors/PackageProcessor.cs
@@ -43,9 +43,9 @@ public PackageProcessor(
this.templateTokeniser = templateTokeniser;
}
- public void Process(string path, string name)
+ public void Process(string path, string name, List tokens)
{
- this.ProcessFiles(path, name);
+ this.ProcessFiles(path, tokens);
this.ProcessDirectories(path);
}
@@ -67,28 +67,28 @@ private void ProcessDirectories(string path)
}
}
- private void ProcessFiles(string path, string name)
+ private void ProcessFiles(string path, List tokens)
{
var files = this.artefactProcessor.RetrieveFiles(path);
-
- this.ProcessFileContents(files, name);
- this.ProcessDirectoryAndFilePaths(files, name);
+
+ this.ProcessFileContents(files, tokens);
+ this.ProcessDirectoryAndFilePaths(files, tokens);
}
- private void ProcessDirectoryAndFilePaths(IEnumerable files, string name)
+ private void ProcessDirectoryAndFilePaths(IEnumerable files, List tokens)
{
int fileCount = files.Count();
int progress = 0;
foreach (var file in files)
{
- this.templateTokeniser.TokeniseDirectoryAndFilePaths(file, name);
+ this.templateTokeniser.TokeniseDirectoryAndFilePaths(file, tokens);
this.progressNotifier.UpdateProgress(ProgressStage.TokenisePackageStructure, fileCount, progress);
progress++;
}
}
- private void ProcessFileContents(IEnumerable files, string name)
+ private void ProcessFileContents(IEnumerable files, List tokens)
{
var filteredFiles = this.binaryFileFilter.Filter(files);
@@ -97,7 +97,7 @@ private void ProcessFileContents(IEnumerable files, string name)
foreach (var file in filteredFiles)
{
- this.templateTokeniser.TokeniseFileContent(file, name);
+ this.templateTokeniser.TokeniseFileContent(file, tokens);
this.progressNotifier.UpdateProgress(ProgressStage.TokenisePackageContents, fileCount, progress);
progress++;
}
diff --git a/Solutions/Endjin.Templify.Domain/Domain/Packager/Tokeniser/TemplateTokeniser.cs b/Solutions/Endjin.Templify.Domain/Domain/Packager/Tokeniser/TemplateTokeniser.cs
index efeb937..9a546f0 100644
--- a/Solutions/Endjin.Templify.Domain/Domain/Packager/Tokeniser/TemplateTokeniser.cs
+++ b/Solutions/Endjin.Templify.Domain/Domain/Packager/Tokeniser/TemplateTokeniser.cs
@@ -2,11 +2,13 @@ namespace Endjin.Templify.Domain.Domain.Packager.Tokeniser
{
#region Using Directives
+ using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Text.RegularExpressions;
using Endjin.Templify.Domain.Contracts.Packager.Processors;
using Endjin.Templify.Domain.Contracts.Packager.Tokeniser;
+ using Endjin.Templify.Domain.Domain.Packages;
using Endjin.Templify.Domain.Infrastructure;
#endregion
@@ -24,22 +26,43 @@ public TemplateTokeniser(IRenameFileProcessor renameFileProcessor, IFileContentP
this.fileContentProcessor = fileContentProcessor;
}
- public void TokeniseDirectoryAndFilePaths(string file, string token)
+ private void TokeniseDirectoriesAndFiles(string file, List tokens)
{
- var tokenisedName = Replace(token, file);
+ var tokenisedName = Replace(tokens, file);
this.renameFileProcessor.Process(file, tokenisedName);
}
- public void TokeniseFileContent(string file, string token)
+ private void TokeniseFileContent(string file, List tokens)
{
var contents = this.fileContentProcessor.ReadContents(file);
- contents = Replace(token, contents);
+ contents = Replace(tokens, contents);
this.fileContentProcessor.WriteContents(file, contents);
}
- private static string Replace(string token, string value)
+ private static string Replace(List tokens, string value)
{
- return Regex.Replace(value, Tokens.TokenName, match => token);
+ string replaced = value;
+ foreach (var token in tokens)
+ {
+ replaced = Regex.Replace(replaced, token.Token, match => token.Value);
+ }
+
+ // TODO: Probably need a more meaningful return value?
+ return replaced;
+ }
+
+ #region ITemplateTokeniser Members
+
+ void ITemplateTokeniser.TokeniseFileContent(string file, List tokens)
+ {
+ throw new System.NotImplementedException();
}
+
+ void ITemplateTokeniser.TokeniseDirectoryAndFilePaths(string file, List tokens)
+ {
+ throw new System.NotImplementedException();
+ }
+
+ #endregion
}
}
\ No newline at end of file
diff --git a/Solutions/Endjin.Templify.Domain/Domain/Packages/Manifest.cs b/Solutions/Endjin.Templify.Domain/Domain/Packages/Manifest.cs
index 2e07f84..795d251 100644
--- a/Solutions/Endjin.Templify.Domain/Domain/Packages/Manifest.cs
+++ b/Solutions/Endjin.Templify.Domain/Domain/Packages/Manifest.cs
@@ -16,6 +16,7 @@ public class Manifest : IPackageMetaData
public Manifest()
{
this.Files = new List();
+ this.Configuration = new List();
}
public string Author { get; set; }
@@ -40,5 +41,9 @@ public string Title
{
get { return this.Name + " - " + this.Version; }
}
+
+ [XmlArray]
+ [XmlArrayItem("Setting")]
+ public List Configuration { get; set; }
}
}
\ No newline at end of file
diff --git a/Solutions/Endjin.Templify.Domain/Domain/Packages/PackageConfigurationData.cs b/Solutions/Endjin.Templify.Domain/Domain/Packages/PackageConfigurationData.cs
new file mode 100644
index 0000000..2f44655
--- /dev/null
+++ b/Solutions/Endjin.Templify.Domain/Domain/Packages/PackageConfigurationData.cs
@@ -0,0 +1,27 @@
+namespace Endjin.Templify.Domain.Domain.Packages
+{
+ using System.Xml.Serialization;
+
+ public class PackageConfigurationData
+ {
+ [XmlAttribute]
+ public string Token { get; set; }
+
+ [XmlText]
+ public string Description { get; set; }
+
+ [XmlAttribute]
+ public PackageConfigurationDataKind Kind { get; set; }
+
+ [XmlIgnore]
+ public string Value { get; set; }
+ }
+
+ public enum PackageConfigurationDataKind
+ {
+ text = 0,
+ flag = 1,
+ choice = 2,
+ password = 3
+ }
+}
diff --git a/Solutions/Endjin.Templify.Domain/Endjin.Templify.Domain.csproj b/Solutions/Endjin.Templify.Domain/Endjin.Templify.Domain.csproj
index a2a4b49..4d9eac2 100644
--- a/Solutions/Endjin.Templify.Domain/Endjin.Templify.Domain.csproj
+++ b/Solutions/Endjin.Templify.Domain/Endjin.Templify.Domain.csproj
@@ -99,6 +99,7 @@
+
diff --git a/Solutions/Endjin.Templify.Domain/Tasks/PackageDeployerTasks.cs b/Solutions/Endjin.Templify.Domain/Tasks/PackageDeployerTasks.cs
index 4d45fea..b4bfa1d 100644
--- a/Solutions/Endjin.Templify.Domain/Tasks/PackageDeployerTasks.cs
+++ b/Solutions/Endjin.Templify.Domain/Tasks/PackageDeployerTasks.cs
@@ -71,7 +71,7 @@ private void RunPackageComplete(RunWorkerCompletedEventArgs e)
private void RunDeployPackage(Package package)
{
this.packageDeploymentProcessor.Execute(package);
- this.packageProcessor.Process(this.Path, this.Name);
+ this.packageProcessor.Process(this.Path, this.Name, package.Manifest.Configuration);
}
private void OnProgressUpdate(object sender, PackageProgressEventArgs e)
diff --git a/Solutions/Endjin.Templify.WizardFramework/Command.cs b/Solutions/Endjin.Templify.WizardFramework/Command.cs
new file mode 100644
index 0000000..e1b7e99
--- /dev/null
+++ b/Solutions/Endjin.Templify.WizardFramework/Command.cs
@@ -0,0 +1,33 @@
+namespace Endjin.Templify.WizardFramework
+{
+ using System;
+ using System.Collections.Generic;
+
+ using Endjin.Templify.Domain.Domain.Packages;
+
+ public class PackageConfigurationDataWizardFormCommand : FormWizardCommand
+ {
+ private List settings;
+
+ public PackageConfigurationDataWizardFormCommand(List Settings)
+ {
+ this.settings = Settings;
+ }
+
+ ///
+ /// Sets the form to use as the command form
+ ///
+ public override void InitialiseCommand()
+ {
+ this.CommandForm = new PackageConfigurationDataWizardForm(this.settings);
+ }
+
+ ///
+ /// Implements any cleanup required
+ ///
+ public override void CleanupCommand()
+ {
+
+ }
+ }
+}
diff --git a/Solutions/Endjin.Templify.WizardFramework/CommandList.cs b/Solutions/Endjin.Templify.WizardFramework/CommandList.cs
new file mode 100644
index 0000000..205da99
--- /dev/null
+++ b/Solutions/Endjin.Templify.WizardFramework/CommandList.cs
@@ -0,0 +1,30 @@
+namespace Endjin.Templify.WizardFramework
+{
+ using System;
+
+ ///
+ /// Summary description for CommandList.
+ ///
+ public class CommandList : WizardCommandList
+ {
+ public CommandList()
+ {
+ //
+ // TODO: Add constructor logic here
+ //
+ }
+
+ public void ExecuteNext()
+ {
+
+ // Get the WizardCommand object to execute
+ WizardCommand formCmd = this[this.CmdPointer];
+
+ // Execute the WizardCommand object and set the current command
+ // pointer to that which is returned
+ this.CmdPointer = formCmd.Execute(this.CmdPointer, this.LastCmdPointer);
+
+
+ }
+ }
+}
diff --git a/Solutions/Endjin.Templify.WizardFramework/ConfigHelper.cs b/Solutions/Endjin.Templify.WizardFramework/ConfigHelper.cs
new file mode 100644
index 0000000..1b42d6b
--- /dev/null
+++ b/Solutions/Endjin.Templify.WizardFramework/ConfigHelper.cs
@@ -0,0 +1,49 @@
+using System;
+using System.Configuration;
+
+namespace Conchango.Fusion.InstallerWizard
+{
+ ///
+ /// Summary description for ConfigHelper.
+ ///
+ public class ConfigHelper
+ {
+
+ private static string _wizardTitle = ConfigurationSettings.AppSettings["WizardTitle"];
+ private static string _wizardTitleText = ConfigurationSettings.AppSettings["WizardTitleText"];
+ private static string _parameterConfigFile = ConfigurationSettings.AppSettings["ParameterConfigFile"];
+ private static string _onlineConfigPath = ConfigurationSettings.AppSettings["CfgSrcOnlinePath"];
+ private static string _localConfigPath = ConfigurationSettings.AppSettings["CfgSrcLocalPath"];
+
+
+ private ConfigHelper()
+ {
+
+ }
+
+ public static string GetWizardTitle
+ {
+ get { return _wizardTitle; }
+ }
+
+ public static string GetWizardTitleText
+ {
+ get { return _wizardTitleText; }
+ }
+
+ public static string GetParameterConfigFile
+ {
+ get { return _parameterConfigFile; }
+ }
+
+ public static string GetOnlineConfigPath
+ {
+ get { return _onlineConfigPath; }
+ }
+
+ public static string GetLocalConfigPath
+ {
+ get { return _localConfigPath; }
+ }
+ }
+}
diff --git a/Solutions/Endjin.Templify.WizardFramework/Endjin.Templify.WizardFramework.csproj b/Solutions/Endjin.Templify.WizardFramework/Endjin.Templify.WizardFramework.csproj
new file mode 100644
index 0000000..8952ef6
--- /dev/null
+++ b/Solutions/Endjin.Templify.WizardFramework/Endjin.Templify.WizardFramework.csproj
@@ -0,0 +1,91 @@
+
+
+
+ Debug
+ AnyCPU
+ 8.0.30703
+ 2.0
+ {D8F709BA-1E52-48FB-A917-7C3A40445F7F}
+ Library
+ Properties
+ Endjin.Templify.WizardFramework
+ Endjin.Templify.WizardFramework
+ v4.0
+ 512
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Form
+
+
+
+ Form
+
+
+
+
+
+ Form
+
+
+
+
+
+ BaseWizardForm.cs
+
+
+ StartupForm.cs
+
+
+ WizardCommand.cs
+
+
+ InstallParametersForm.cs
+
+
+
+
+ {9E8B79ED-9C17-485B-B1F9-8D33D8BB4BD2}
+ SharpArch.PackageManagement
+
+
+
+
+
\ No newline at end of file
diff --git a/Solutions/Endjin.Templify.WizardFramework/Forms/BaseWizardForm.cs b/Solutions/Endjin.Templify.WizardFramework/Forms/BaseWizardForm.cs
new file mode 100644
index 0000000..d4ea04a
--- /dev/null
+++ b/Solutions/Endjin.Templify.WizardFramework/Forms/BaseWizardForm.cs
@@ -0,0 +1,80 @@
+namespace Endjin.Templify.WizardFramework
+{
+ using System;
+ using System.Windows.Forms;
+
+ ///
+ /// Base Form for use with forms that wish to implement the Wizard
+ /// Command
+ ///
+ public class BaseWizardForm : Form {
+
+ #region Constructors
+
+ ///
+ /// Default constructor
+ ///
+ public BaseWizardForm() {
+ }
+
+ #endregion
+
+ #region Private Variables
+
+ //CommandIndex starts at 0
+ private int _commandIndex = 0;
+ private int _originCommandIndex = 0;
+
+ #endregion
+
+ #region Public Properties
+ public int CommandIndex {
+ get { return _commandIndex; }
+ set { _commandIndex = value; }
+ }
+
+ public int OriginCommandIndex {
+ get { return _originCommandIndex; }
+ set { _originCommandIndex = value; }
+ }
+ #endregion
+
+ #region Public Methods
+
+ // Go back to the OriginCommandIndex - who sent the form to the particular index
+ public void MoveToSender()
+ {
+ CommandIndex = OriginCommandIndex;
+ this.Close();
+
+ }
+
+ // Move to a specific CommandIndex
+ public void MoveTo(int index)
+ {
+ OriginCommandIndex = CommandIndex;
+ CommandIndex = index;
+ this.Close();
+ }
+ // Move to the next CommandIndex in the list
+ public void MoveNext() {
+ CommandIndex++;
+ this.Close();
+ }
+
+ // Move to the previous CommandIndex in the list
+ public void MovePrevious() {
+ CommandIndex--;
+ this.Close();
+ }
+
+ //
+ public void MoveExit() {
+ CommandIndex = -1;
+ }
+
+ #endregion
+
+ }
+}
+
diff --git a/Solutions/Endjin.Templify.WizardFramework/Forms/BaseWizardForm.resx b/Solutions/Endjin.Templify.WizardFramework/Forms/BaseWizardForm.resx
new file mode 100644
index 0000000..3f337e0
--- /dev/null
+++ b/Solutions/Endjin.Templify.WizardFramework/Forms/BaseWizardForm.resx
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 1.0.0.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
diff --git a/Solutions/Endjin.Templify.WizardFramework/Forms/FormWizardCommand.cs b/Solutions/Endjin.Templify.WizardFramework/Forms/FormWizardCommand.cs
new file mode 100644
index 0000000..515889b
--- /dev/null
+++ b/Solutions/Endjin.Templify.WizardFramework/Forms/FormWizardCommand.cs
@@ -0,0 +1,61 @@
+namespace Endjin.Templify.WizardFramework
+{
+ using System;
+
+ ///
+ /// Abstract class that defines a wizard command for Windows Forms. Implements
+ /// the abstract wizard command class.
+ ///
+ public abstract class FormWizardCommand : WizardCommand {
+
+ #region Private Variables
+
+ ///
+ /// The Windows Form used for this command
+ ///
+ private BaseWizardForm _commandForm = null;
+
+ #endregion
+
+ #region Properties
+
+ ///
+ /// he Windows Form used for this command
+ ///
+ public BaseWizardForm CommandForm {
+ get { return _commandForm; }
+ set { _commandForm = value; }
+ }
+
+ #endregion
+
+ #region Methods
+
+ ///
+ /// Executes the WizardCommand object
+ ///
+ /// TODO
+ public override int Execute(int cmdPointer, int lastCmdPointer) {
+
+ // Setup the template - this is implemented within the sub class
+ InitialiseCommand();
+
+ // Show the command form
+ this.CommandForm.CommandIndex = cmdPointer;
+ this.CommandForm.OriginCommandIndex = lastCmdPointer;
+ //this.CommandForm.Visible = true;
+ var res = this.CommandForm.ShowDialog();
+
+
+ // Cleanup the template data - this is implemented within the
+ // sub class
+ CleanupCommand();
+
+ return this.CommandForm.CommandIndex;
+
+ }
+
+ #endregion
+
+ }
+}
diff --git a/Solutions/Endjin.Templify.WizardFramework/Forms/InstallParametersForm.cs b/Solutions/Endjin.Templify.WizardFramework/Forms/InstallParametersForm.cs
new file mode 100644
index 0000000..f5e2158
--- /dev/null
+++ b/Solutions/Endjin.Templify.WizardFramework/Forms/InstallParametersForm.cs
@@ -0,0 +1,377 @@
+namespace Endjin.Templify.WizardFramework
+{
+ using System;
+ using System.Collections.Generic;
+ using System.ComponentModel;
+ using System.Linq;
+ using System.Diagnostics;
+ //using System.DirectoryServices;
+ //using System.Drawing;
+ using System.IO;
+ using System.Text;
+ using System.Windows.Forms;
+
+ using Endjin.Templify.Domain.Domain.Packages;
+
+ public class PackageConfigurationDataWizardForm : BaseWizardForm
+ {
+ private const int MAX_SETTINGS_PER_PAGE = 5;
+
+ private int currentPage = 0;
+ //private InstallerBootstrapConfigPage[] pages;
+ //private IisHostHeaderConfigCollection webInfoForComboBox;
+
+
+ #region UI cordinates
+ // These values are used to derive the positions of the
+ // dynamically generated controls
+ private int firstLabelX = 8;
+ private int firstLabelY = 31;
+ private int labelWidth = 152;
+ private int labelHeight = 20;
+
+ private int firstControlX = 167;
+ private int firstControlY = 29;
+ private int controlWidth = 216;
+ private int controlHeight = 20;
+
+ #endregion
+
+
+ private System.Windows.Forms.Label lblTitle;
+ private System.Windows.Forms.Button btnNext;
+ private System.Windows.Forms.Button btnBack;
+ private System.Windows.Forms.Button btnCancel;
+ private System.Windows.Forms.GroupBox groupParameters;
+ private System.Windows.Forms.Label lblText;
+ private System.Windows.Forms.ToolTip toolTip1;
+ private System.ComponentModel.IContainer components = null;
+
+ public PackageConfigurationDataWizardForm(List settings)
+ {
+ // This call is required by the Windows Form Designer.
+ InitializeComponent();
+
+ //pages = (InstallerBootstrapConfigPage[])WizardState.Instance.RequiredParameters.ToArray(typeof(InstallerBootstrapConfigPage) );
+ this.Settings = settings;
+ }
+
+ public List Settings { get; set; }
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing)
+ {
+ if (components != null)
+ {
+ components.Dispose();
+ }
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Designer generated code
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.components = new System.ComponentModel.Container();
+ System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(PackageConfigurationDataWizardForm));
+ this.lblTitle = new System.Windows.Forms.Label();
+ this.btnNext = new System.Windows.Forms.Button();
+ this.btnBack = new System.Windows.Forms.Button();
+ this.btnCancel = new System.Windows.Forms.Button();
+ this.groupParameters = new System.Windows.Forms.GroupBox();
+ this.lblText = new System.Windows.Forms.Label();
+ this.toolTip1 = new System.Windows.Forms.ToolTip(this.components);
+ this.SuspendLayout();
+ //
+ // lblTitle
+ //
+ this.lblTitle.BackColor = System.Drawing.SystemColors.Window;
+ this.lblTitle.Font = new System.Drawing.Font("Microsoft Sans Serif", 14.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
+ this.lblTitle.Location = new System.Drawing.Point(24, 5);
+ this.lblTitle.Name = "lblTitle";
+ this.lblTitle.Size = new System.Drawing.Size(384, 40);
+ this.lblTitle.TabIndex = 10;
+ this.lblTitle.Text = "Pre-Installation Parameters";
+ this.lblTitle.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+ //
+ // btnNext
+ //
+ this.btnNext.Location = new System.Drawing.Point(304, 320);
+ this.btnNext.Name = "btnNext";
+ this.btnNext.TabIndex = 1;
+ this.btnNext.Text = "&Next";
+ this.btnNext.Click += new System.EventHandler(this.btnNext_Click);
+ //
+ // btnBack
+ //
+ this.btnBack.Location = new System.Drawing.Point(216, 320);
+ this.btnBack.Name = "btnBack";
+ this.btnBack.TabIndex = 12;
+ this.btnBack.Text = "&Back";
+ this.btnBack.Click += new System.EventHandler(this.btnBack_Click);
+ //
+ // btnCancel
+ //
+ this.btnCancel.Location = new System.Drawing.Point(392, 320);
+ this.btnCancel.Name = "btnCancel";
+ this.btnCancel.TabIndex = 14;
+ this.btnCancel.Text = "&Cancel";
+ this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
+ //
+ // groupParameters
+ //
+ this.groupParameters.BackColor = System.Drawing.SystemColors.Window;
+ this.groupParameters.Location = new System.Drawing.Point(32, 112);
+ this.groupParameters.Name = "groupParameters";
+ this.groupParameters.Size = new System.Drawing.Size(416, 184);
+ this.groupParameters.TabIndex = 0;
+ this.groupParameters.TabStop = false;
+ this.groupParameters.Text = "";
+ //
+ // lblText
+ //
+ this.lblText.BackColor = System.Drawing.SystemColors.Window;
+ this.lblText.Location = new System.Drawing.Point(40, 72);
+ this.lblText.Name = "lblText";
+ this.lblText.Size = new System.Drawing.Size(408, 32);
+ this.lblText.TabIndex = 16;
+ this.lblText.Text = "Enter the correct settings for the following parameters required by this installa" +
+ "tion package.";
+ //
+ // InstallParametersForm
+ //
+ this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
+ this.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("$this.BackgroundImage")));
+ this.ClientSize = new System.Drawing.Size(478, 348);
+ this.Controls.Add(this.lblText);
+ this.Controls.Add(this.groupParameters);
+ this.Controls.Add(this.btnNext);
+ this.Controls.Add(this.btnBack);
+ this.Controls.Add(this.btnCancel);
+ this.Controls.Add(this.lblTitle);
+ this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.Fixed3D;
+ this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
+ this.Name = "InstallParametersForm";
+ this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
+ this.Load += new System.EventHandler(this.InstallParametersForm_Load);
+ this.ResumeLayout(false);
+
+ }
+ #endregion
+
+ private void btnBack_Click(object sender, System.EventArgs e)
+ {
+ this.MovePrevious();
+ }
+
+ private void btnNext_Click(object sender, System.EventArgs e)
+ {
+ // Save the parameter info from the current screen
+ saveCurrentParameters();
+
+ currentPage++;
+
+ if (currentPage <= Settings.Count / MAX_SETTINGS_PER_PAGE)
+ {
+ // Display theh UI to obtain values for the required parameters
+ renderParameterPage(currentPage);
+ }
+ else
+ {
+ // Generate the set of Windows Installer properties that map to the
+ // parameters that the user has just supplied
+ //buildMsiPropertyList();
+
+ // Proceed to next stage in the Wizard
+ this.MoveNext();
+ }
+ }
+
+ private void btnCancel_Click(object sender, System.EventArgs e)
+ {
+ this.MoveExit();
+ this.Close();
+ }
+
+ private void InstallParametersForm_Load(object sender, System.EventArgs e)
+ {
+ // Set some title text based on the config file
+ this.Text = "*** TO BE REPLACED ***";
+
+ renderParameterPage(currentPage);
+ }
+
+
+
+
+
+ private void renderParameterPage(int pageNumber)
+ {
+ clearControls();
+
+ //var settingsToRender = from s in this.settings
+ // select s;
+ var settingsToRender = this.Settings.Skip((pageNumber - 1) * MAX_SETTINGS_PER_PAGE).Take(MAX_SETTINGS_PER_PAGE).ToList();
+
+ // set the variables
+ int numControlsReqd = settingsToRender.Count();
+
+ // setup the groupbox title
+ //groupParameters.Text = string.Format("{0} of {1} - {2}", currentPage + 1, pages.Length, this.pages[currentPage].Title);
+ groupParameters.Text = "Page " + pageNumber;
+
+ #region setup the label controls
+ for (int i = 1; i <= numControlsReqd; i++)
+ {
+ // create a new label
+ Label lbl = new Label();
+
+ // position the label
+ lbl.Left = firstLabelX;
+ lbl.Top = firstLabelY * i;
+ lbl.Width = labelWidth;
+ lbl.Height = labelHeight;
+
+ // setup the control
+ lbl.Text = settingsToRender[i].Description + ":";
+
+ // Set the tooltip using the supplied description
+ toolTip1.SetToolTip(lbl, settingsToRender[i].Description);
+
+ lbl.Visible = true;
+
+ groupParameters.Controls.Add(lbl);
+
+ }
+ #endregion
+
+ #region setup the input controls
+ for (int i = 1; i <= numControlsReqd; i++)
+ {
+
+ if (settingsToRender[i].Kind == PackageConfigurationDataKind.choice)
+ {
+ ComboBox inputControl = new ComboBox();
+
+ // TODO: populate combo box
+ // inputControl.DataSource = settingsToRender[i].Default.Split('|');
+
+ // postition the control
+ inputControl.Left = firstControlX;
+ inputControl.Top = firstControlY * i;
+ inputControl.Width = controlWidth;
+ inputControl.Height = controlHeight;
+
+ inputControl.Visible = true;
+
+ groupParameters.Controls.Add(inputControl);
+ }
+ else
+ {
+ TextBox inputControl = new TextBox();
+
+ // Set the tooltip using the supplied description
+ //inputControl.Text = this.pages[currentPage].Parameters[i - 1].DefaultValue;
+ toolTip1.SetToolTip(inputControl, settingsToRender[i].Description);
+
+ if (settingsToRender[i].Kind == PackageConfigurationDataKind.password)
+ {
+ inputControl.PasswordChar = '*';
+ }
+
+ // position the control
+ inputControl.Left = firstControlX;
+ inputControl.Top = firstControlY * i;
+ inputControl.Width = controlWidth;
+ inputControl.Height = controlHeight;
+
+ inputControl.Visible = true;
+
+ groupParameters.Controls.Add(inputControl);
+ }
+ }
+ #endregion
+ }
+
+ private void saveCurrentParameters()
+ {
+ var settingsToRender = this.Settings.Skip((currentPage - 1) * MAX_SETTINGS_PER_PAGE).Take(MAX_SETTINGS_PER_PAGE).ToList();
+
+ for (int i = 0; i < settingsToRender.Count(); i++)
+ {
+ string paramName = settingsToRender[i].Token;
+ string paramValue = GetControlValue(i);
+
+ if (paramValue != null)
+ {
+ settingsToRender[i].Value = paramValue;
+
+ //if (this.pages[currentPage].Parameters[i].ParamType == InstallerBootstrapConfigPageParameterParamType.path)
+ //{
+ // // Ensure that path parameters have a trailing
+ // // '\' - as this is required by MSI
+ // if (!paramValue.EndsWith(@"\"))
+ // {
+ // paramValue = string.Concat(paramValue, @"\");
+ // }
+ //}
+
+ // Get the parameter's unique ID, we use this to differentiate between parameters
+ // of the same name
+ //string paramId = this.pages[currentPage].Parameters[i].id + ".";
+
+ //if (this.pages[currentPage].Parameters[i].ParamType == InstallerBootstrapConfigPageParameterParamType.website)
+ //{
+ // // If dealing with a web site parameter, the this actually requires three
+ // // bits of information - which (for the moment?) has to be handled using this hack.
+
+ // // Such parameters must be defined in the parameter WizardState.Instance.Config as 3 comma seperated
+ // // strings which we split below and return as seperate parameters to the bootstrapper
+ // string[] splitParameterNames = paramName.Split(",".ToCharArray(), 3);
+ // WizardState.Instance.ParameterValues.Add(string.Concat(paramId, splitParameterNames[0]), paramValue);
+ // WizardState.Instance.ParameterValues.Add(string.Concat(paramId, splitParameterNames[1]), webInfoForComboBox[paramValue].Address);
+ // WizardState.Instance.ParameterValues.Add(string.Concat(paramId, splitParameterNames[2]), webInfoForComboBox[paramValue].Port);
+ //}
+ //else
+ //{
+ // otherwise just assign the value to the parameter
+ //WizardState.Instance.Settings.Add(string.Concat(paramId, paramName), paramValue);
+ //}
+ }
+ }
+ }
+
+ private void clearControls()
+ {
+ // Clear all the existing intput controls
+ if (groupParameters.HasChildren)
+ {
+ //foreach ( Control control in grpParamTitle.Controls )
+ //{
+ // control.Dispose();
+ //}
+ groupParameters.Controls.Clear();
+ }
+
+ }
+
+ private string GetControlValue(int i)
+ {
+ // skip the labels
+ int firstInputControl = (groupParameters.Controls.Count / 2);
+
+ int requiredInputControl = firstInputControl + i;
+
+ return groupParameters.Controls[requiredInputControl].Text;
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/Solutions/Endjin.Templify.WizardFramework/Forms/InstallParametersForm.resx b/Solutions/Endjin.Templify.WizardFramework/Forms/InstallParametersForm.resx
new file mode 100644
index 0000000..9c4eff0
--- /dev/null
+++ b/Solutions/Endjin.Templify.WizardFramework/Forms/InstallParametersForm.resx
@@ -0,0 +1,317 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 1.3
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ False
+
+
+ Private
+
+
+ Private
+
+
+ False
+
+
+ Private
+
+
+ Private
+
+
+ False
+
+
+ Private
+
+
+ Private
+
+
+ False
+
+
+ Private
+
+
+ Private
+
+
+ Private
+
+
+ 8, 8
+
+
+ True
+
+
+ False
+
+
+ True
+
+
+ Private
+
+
+ False
+
+
+ Private
+
+
+ Private
+
+
+ Private
+
+
+ 17, 17
+
+
+ Private
+
+
+ False
+
+
+ (Default)
+
+
+ False
+
+
+ False
+
+
+ 8, 8
+
+
+ True
+
+
+ InstallParametersForm
+
+
+ 80
+
+
+ True
+
+
+ Private
+
+
+
+ /9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEPERET
+ FhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4eHh4eHh4e
+ Hh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7/wAARCAFiAe4DASIAAhEBAxEB/8QA
+ HwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIh
+ MUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVW
+ V1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXG
+ x8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQF
+ BgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAV
+ YnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOE
+ hYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq
+ 8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD7LooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiig
+ AooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiig
+ AooooAKKKKAE7dKbuHqopc+lcx468W6R4SsYLnV7h4o55vKi2QPKzNtLY2ryeFbmjXYcIObtHc6LzEzz
+ IB364oaaIA/vUz/vCvGtT+L+m3oSz8PTSve3UscMcl1azRRRb2C72LOMgZB6dxVvxZo/ifw54Mn1PTfG
+ V5dGRVFx9pO7BdlUtEQfkwTnHzVy4jFeycopXcd+lj1MPlMqih7Sai5u0ez+aIfin43aG+tdL0fV7+wC
+ 3iR3t/bRo8ajy5CsQdyVDFtmeM4B5rCSTXpUDR/EXXmU9Ck1pg/rXZ6BcTeCNJXSfEegKlgR82pWUZmh
+ lJ6tMpBdWI6k5XrzXnXxI1/wzpXiK3XwVLLEryLJei0lY2rqeu1FIy3+7ivBzOpXhH2vtLf3e3oej/Zm
+ Ixj9lgG1yrfRxlbq9NH0Rpj/AISAHI+IXiAn3mtP8a6X4Z6hri/EC30298TX+rWs2m3EpS58g7XR4AGB
+ j6ffbg1yQ8W2BGQuuEH00y8/+LrpfhbcvqPxHtbqK01RbeHSrtWlurKeFAzy25VQ0hIJ+Vv1rDL6+Ili
+ YRm3Y+aw/wDaXO/rPwWfbs7fiezUUUV9eIKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooo
+ oAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooo
+ oAKKKKACiiigBgwCa8p/aEkMdp4bbzDF/wATNhkSbB/x7zf9NE/n/gfVumeM1yfxG8Jx+K7O0gl1G/09
+ rWfz45bN1V92xk/i4xh2/H9boz5KkZvo0/uYuRThKDdrxkvvTR5b8NfsF945gttQkhuoHs50Mc0wlVsm
+ PA2tLIOxxjaev3q7nxB8O5n0yXTfD2sTafZzMrSWUxMsAAYN8meUPHbI9q5O/wDhE1xgSeL/ABBKE+55
+ ht22/wC6SwIrc+2eK/BGmC4uNSPiDSonRJftjIlxGrMF+V1Ztx5H3ueetY5tUp18ROrKHuvr8kv0PQyO
+ lPC4Sjh6NX95G65Xs3zNpq+l9T0+REMJikwy7cMGHWvk/SfDOseIPiXqcOi2yN9k1GWRmdikce2RiAzA
+ cdAMDtX1mmGA3AHPTIrj/wDhE73Rr641LwneR27XMrTXFldAvBK56sGHzIfpkdeK87MMD9acL7R3XU9T
+ h/OZZaqyj8U1ZX2uVtL8S2hvItM1xL3Qr88JHeTSKkpHZJBJtf8AOu1s4ghDBy2RjO8t/MmvG/i/8QXs
+ tBOhaj4aaHVLgY/0hUmtwvTeh/i9sge9dz8FneT4b6KZZGd/JOSzEngkck9auhjIzxDoXu0rmWPymdLB
+ RxrjyqTta90/NPsdrRRRXonghRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUU
+ UUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUU
+ UUAFJjPXn6ilooAiMYz/ABf99GuT+Klnc3XgLUIrSGaaYeW4SPcWYLIrEADknANdh2psihkKlcg9jUVI
+ KpFxfU1oVnRqxqro0/uMfQPEGj63ZedpeoQz7RtdA2HRhxhl6g+xrwi3+MXiTw94u1a01FF1WwjvZVSN
+ wEljRZCMKQMH8a6L45xLp1zpOr6ZN/Z+otfGB7yB1R2TyJX2kmQAjKg4bA/PB8rhEcd5cXr3iTXM7s8k
+ 3mxI2Sck4S4Uc189mmLrU6ihHRrr0+4++4byrBVaM6tWPPGa0T3Tv3Nb42eK9G8Yato+o6bLKkUds0cy
+ yQsHjO/uBz+VevfBHxd4YvLCy8J6NqNxc3NnaNIwls5IdyhgGbJ4zucceleKi6Axi94/6+//ALqrtfgP
+ KJfihHifzQNJuuku/H72D/ptJ/7L+Nc+WYiTxjnJayO7PcFR/spUVflpXcdfXc+haKKK+sPy4KKKKACi
+ iigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACi
+ iigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAMDxR4V0vxLbwwarFPI
+ kE3nRbLqSIo+0rkMjA9GYfjWGPhT4T6mLVP/AAcXf/xyu7orGVCnN3lG7OuljsTRjy05tLyZwg+FXhPG
+ DFqv/g5u/wD45Wl4X8C6B4d1b+09Pt7v7V5DQiSe+mn2oSpKgSO2MlF6eldTRRDD0oO8YodTMMVUi4zq
+ Np+bCiiitjjCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiig
+ AooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiig
+ AooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiig
+ AooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiig
+ AooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiig
+ AooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiig
+ AooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiig
+ AooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiig
+ AooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiig
+ AooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiig
+ AooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiig
+ AooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiig
+ AooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiig
+ AooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiig
+ AooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiig
+ AooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiig
+ AooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiig
+ AooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiig
+ AooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiig
+ AooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiig
+ AooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiig
+ AooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiig
+ AooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiig
+ AooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiig
+ AooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiig
+ AooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiig
+ AooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiig
+ AooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiig
+ AooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiig
+ AooooAKKKKACiiigAooooAKKKKACik5o5oAWik596TJ96AHUUnPvRzQAtFFFABRRRQAUUUUAFFFFABRR
+ RQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRR
+ RQAUUUUAFFFFABRRRQAUUUUAJ+FH4VwP9o6p/wBBvUv++bf/AOMUf2jqn/Qb1L/vm3/+MVx/Wodjq+q1
+ Dvvwo/CuB/tHVP8AoN6l/wB82/8A8Yo/tHVP+g3qX/fNv/8AGKPrUOwfVah334UfhXA/2jqn/Qb1L/vm
+ 3/8AjFH9o6p/0G9S/wC+bf8A+MUfWodg+q1Dvvwo/CuB/tHVP+g3qX/fNv8A/GKP7R1T/oN6l/3zb/8A
+ xij61DsH1Wod9+FH4VwP9o6p/wBBvUv++bf/AOMUf2jqn/Qb1L/vm3/+MUfWodg+q1Dvvwo/CuB/tHVP
+ +g3qX/fNv/8AGKP7R1T/AKDepf8AfNv/APGKPrUOwfVah334UfhXA/2jqn/Qb1L/AL5t/wD4xR/aOqf9
+ BvUv++bf/wCMUfWodg+q1Dvvwo/CuB/tHVP+g3qX/fNv/wDGKP7R1T/oN6l/3zb/APxij61DsH1Wod9+
+ FH4VwP8AaOqf9BvUv++bf/4xR/aOqf8AQb1L/vm3/wDjFH1qHYPqtQ778KPwrgf7R1T/AKDepf8AfNv/
+ APGKP7R1T/oN6l/3zb//ABij61DsH1Wod9+FH4VwP9o6p/0G9S/75t//AIxR/aOqf9BvUv8Avm3/APjF
+ H1qHYPqtQ778KPwrgf7R1T/oN6l/3zb/APxij+0dU/6Depf982//AMYo+tQ7B9VqHffhR+FcD/aOqf8A
+ Qb1L/vm3/wDjFH9o6p/0G9S/75t//jFH1qHYPqtQ778KPwrgf7R1T/oN6l/3zb//ABij+0dU/wCg3qX/
+ AHzb/wDxij61DsH1Wod9+FH4VwP9o6p/0G9S/wC+bf8A+MUf2jqn/Qb1L/vm3/8AjFH1qHYPqtQ778KP
+ wrgf7R1T/oN6l/3zb/8Axij+0dU/6Depf982/wD8Yo+tQ7B9VqHffhR+FcD/AGjqn/Qb1L/vm3/+MUf2
+ jqn/AEG9S/75t/8A4xR9ah2D6rUO+/Cj8K4H+0dU/wCg3qX/AHzb/wDxij+0dU/6Depf982//wAYo+tQ
+ 7B9VqHffhR+FcD/aOqf9BvUv++bf/wCMUf2jqn/Qb1L/AL5t/wD4xR9ah2D6rUO+/Cj8K4H+0dU/6Dep
+ f982/wD8Yo/tHVP+g3qX/fNv/wDGKPrUOwfVah334UfhXA/2jqn/AEG9S/75t/8A4xR/aOqf9BvUv++b
+ f/4xR9ah2D6rUO+/Cj8K4H+0dU/6Depf982//wAYo/tHVP8AoN6l/wB82/8A8Yo+tQ7B9VqHffhR+FcD
+ /aOqf9BvUv8Avm3/APjFH9o6p/0G9S/75t//AIxR9ah2D6rUO+/Cj8K4H+0dU/6Depf982//AMYo/tHV
+ P+g3qX/fNv8A/GKPrUOwfVah334UfhXA/wBo6p/0G9S/75t//jFH9o6p/wBBvUv++bf/AOMUfWodg+q1
+ Dvvwo/CuB/tHVP8AoN6l/wB82/8A8Yo/tHVP+g3qX/fNv/8AGKPrUOwfVah334UfhXA/2jqn/Qb1L/vm
+ 3/8AjFH9o6p/0G9S/wC+bf8A+MUfWodg+q1Dvvwo/CuB/tHVP+g3qX/fNv8A/GKP7R1T/oN6l/3zb/8A
+ xij61DsH1Wod9+FH4VwP9o6p/wBBvUv++bf/AOMUf2jqn/Qb1L/vm3/+MUfWodg+q1Dvvworgf7R1T/o
+ N6l/3zb/APxij+0dU/6Depf982//AMYo+tQ7B9VqHfY9qMe1cD/aGqf9BzUvyt//AIzVa6vtfaJRaeIL
+ 1HDcmSG3bI/BBT+uR7B9Un3EooorgPQCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAC
+ iiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAC
+ iiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAC
+ iiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAC
+ iiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAC
+ iiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAC
+ iiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA//2Q==
+
+
+
+
+ AAABAAEAEBAQAAAAAAAoAQAAFgAAACgAAAAQAAAAIAAAAAEABAAAAAAAgAAAAAAAAAAAAAAAEAAAABAA
+ AAAAAAAAAACAAACAAAAAgIAAgAAAAIAAgACAgAAAgICAAMDAwAAAAP8AAP8AAAD//wD/AAAA/wD/AP//
+ AAD///8AAAAAAAAAAAAAAAAzMzMAAAAAAzMzMzAAAAeP/4MzMwAACP///zMzMAA/////+DMzAz//////
+ MzMDj/////8zMwOP/////4MzAz//////gzMDOP////+DMwMzj////4MzAAMzOIiIMzAAAzMzMzMzMAAA
+ MzMzMzMAAAADMzMzAAD//wAA/A8AAPgHAADgAwAA4AEAAMAAAACAAAAAgAAAAIAAAACAAAAAgAAAAIAA
+ AADgAQAA4AEAAPADAAD4DwAA
+
+
+
\ No newline at end of file
diff --git a/Solutions/Endjin.Templify.WizardFramework/Forms/StartupForm.cs b/Solutions/Endjin.Templify.WizardFramework/Forms/StartupForm.cs
new file mode 100644
index 0000000..76443a6
--- /dev/null
+++ b/Solutions/Endjin.Templify.WizardFramework/Forms/StartupForm.cs
@@ -0,0 +1,292 @@
+namespace Endjin.Templify.WizardFramework
+{
+ using System;
+ using System.Collections;
+ using System.ComponentModel;
+ using System.Drawing;
+ using System.Windows.Forms;
+
+ public class StartupForm : BaseWizardForm
+ {
+
+ private System.Windows.Forms.Button btnNext;
+ private System.Windows.Forms.Button btnBack;
+ private System.Windows.Forms.Button btnCancel;
+ private System.Windows.Forms.Label lblIntro;
+ private System.Windows.Forms.Label lblTitle;
+ private System.Windows.Forms.Label label1;
+ private System.Windows.Forms.RadioButton radioCfgSrcDefault;
+ private System.Windows.Forms.RadioButton radioCfgSrcOnline;
+ private System.Windows.Forms.RadioButton radioCfgSrcCustom;
+ private System.Windows.Forms.TextBox txtCfgSrcCustomPath;
+ private System.Windows.Forms.Button btnCfgSrcCustomBrowse;
+ private System.Windows.Forms.GroupBox groupCfgSrc;
+ private System.Windows.Forms.OpenFileDialog openFileDialog1;
+ private System.ComponentModel.IContainer components = null;
+
+
+
+ public StartupForm()
+ {
+ // This call is required by the Windows Form Designer.
+ InitializeComponent();
+
+ // TODO: Add any initialization after the InitializeComponent call
+ }
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ protected override void Dispose( bool disposing )
+ {
+ if( disposing )
+ {
+ if (components != null)
+ {
+ components.Dispose();
+ }
+ }
+ base.Dispose( disposing );
+ }
+
+ #region Designer generated code
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(StartupForm));
+ this.lblIntro = new System.Windows.Forms.Label();
+ this.btnNext = new System.Windows.Forms.Button();
+ this.btnBack = new System.Windows.Forms.Button();
+ this.btnCancel = new System.Windows.Forms.Button();
+ this.groupCfgSrc = new System.Windows.Forms.GroupBox();
+ this.txtCfgSrcCustomPath = new System.Windows.Forms.TextBox();
+ this.btnCfgSrcCustomBrowse = new System.Windows.Forms.Button();
+ this.radioCfgSrcDefault = new System.Windows.Forms.RadioButton();
+ this.radioCfgSrcOnline = new System.Windows.Forms.RadioButton();
+ this.radioCfgSrcCustom = new System.Windows.Forms.RadioButton();
+ this.lblTitle = new System.Windows.Forms.Label();
+ this.label1 = new System.Windows.Forms.Label();
+ this.openFileDialog1 = new System.Windows.Forms.OpenFileDialog();
+ this.groupCfgSrc.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // lblIntro
+ //
+ this.lblIntro.BackColor = System.Drawing.SystemColors.Window;
+ this.lblIntro.Location = new System.Drawing.Point(168, 72);
+ this.lblIntro.Name = "lblIntro";
+ this.lblIntro.Size = new System.Drawing.Size(288, 32);
+ this.lblIntro.TabIndex = 0;
+ this.lblIntro.Text = "This wizard will guide you through installing the module(s) defined within this i" +
+ "nstallation package.";
+ //
+ // btnNext
+ //
+ this.btnNext.Location = new System.Drawing.Point(304, 320);
+ this.btnNext.Name = "btnNext";
+ this.btnNext.TabIndex = 0;
+ this.btnNext.Text = "&Next";
+ this.btnNext.Click += new System.EventHandler(this.btnNext_Click);
+ //
+ // btnBack
+ //
+ this.btnBack.Enabled = false;
+ this.btnBack.Location = new System.Drawing.Point(216, 320);
+ this.btnBack.Name = "btnBack";
+ this.btnBack.TabIndex = 1;
+ this.btnBack.Text = "&Back";
+ //
+ // btnCancel
+ //
+ this.btnCancel.Location = new System.Drawing.Point(392, 320);
+ this.btnCancel.Name = "btnCancel";
+ this.btnCancel.TabIndex = 2;
+ this.btnCancel.Text = "&Cancel";
+ this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
+ //
+ // groupCfgSrc
+ //
+ this.groupCfgSrc.BackColor = System.Drawing.SystemColors.Window;
+ this.groupCfgSrc.Controls.Add(this.txtCfgSrcCustomPath);
+ this.groupCfgSrc.Controls.Add(this.btnCfgSrcCustomBrowse);
+ this.groupCfgSrc.Controls.Add(this.radioCfgSrcDefault);
+ this.groupCfgSrc.Controls.Add(this.radioCfgSrcOnline);
+ this.groupCfgSrc.Controls.Add(this.radioCfgSrcCustom);
+ this.groupCfgSrc.Location = new System.Drawing.Point(168, 168);
+ this.groupCfgSrc.Name = "groupCfgSrc";
+ this.groupCfgSrc.Size = new System.Drawing.Size(296, 120);
+ this.groupCfgSrc.TabIndex = 1;
+ this.groupCfgSrc.TabStop = false;
+ this.groupCfgSrc.Text = "Configuration Management Source";
+ //
+ // txtCfgSrcCustomPath
+ //
+ this.txtCfgSrcCustomPath.Enabled = false;
+ this.txtCfgSrcCustomPath.Location = new System.Drawing.Point(112, 92);
+ this.txtCfgSrcCustomPath.Name = "txtCfgSrcCustomPath";
+ this.txtCfgSrcCustomPath.Size = new System.Drawing.Size(152, 20);
+ this.txtCfgSrcCustomPath.TabIndex = 3;
+ this.txtCfgSrcCustomPath.Text = "";
+ //
+ // btnCfgSrcCustomBrowse
+ //
+ this.btnCfgSrcCustomBrowse.BackColor = System.Drawing.SystemColors.Control;
+ this.btnCfgSrcCustomBrowse.Enabled = false;
+ this.btnCfgSrcCustomBrowse.Location = new System.Drawing.Point(266, 93);
+ this.btnCfgSrcCustomBrowse.Name = "btnCfgSrcCustomBrowse";
+ this.btnCfgSrcCustomBrowse.Size = new System.Drawing.Size(22, 16);
+ this.btnCfgSrcCustomBrowse.TabIndex = 4;
+ this.btnCfgSrcCustomBrowse.Text = "...";
+ this.btnCfgSrcCustomBrowse.Click += new System.EventHandler(this.btnCfgSrcCustomBrowse_Click);
+ //
+ // radioCfgSrcDefault
+ //
+ this.radioCfgSrcDefault.Checked = true;
+ this.radioCfgSrcDefault.Location = new System.Drawing.Point(8, 24);
+ this.radioCfgSrcDefault.Name = "radioCfgSrcDefault";
+ this.radioCfgSrcDefault.Size = new System.Drawing.Size(112, 24);
+ this.radioCfgSrcDefault.TabIndex = 0;
+ this.radioCfgSrcDefault.TabStop = true;
+ this.radioCfgSrcDefault.Text = "Package Defaults";
+ //
+ // radioCfgSrcOnline
+ //
+ this.radioCfgSrcOnline.Location = new System.Drawing.Point(8, 56);
+ this.radioCfgSrcOnline.Name = "radioCfgSrcOnline";
+ this.radioCfgSrcOnline.TabIndex = 1;
+ this.radioCfgSrcOnline.Text = "Online Source";
+ //
+ // radioCfgSrcCustom
+ //
+ this.radioCfgSrcCustom.Location = new System.Drawing.Point(8, 89);
+ this.radioCfgSrcCustom.Name = "radioCfgSrcCustom";
+ this.radioCfgSrcCustom.TabIndex = 2;
+ this.radioCfgSrcCustom.Text = "Custom Source";
+ this.radioCfgSrcCustom.CheckedChanged += new System.EventHandler(this.radioCfgSrcCustom_CheckedChanged);
+ //
+ // lblTitle
+ //
+ this.lblTitle.BackColor = System.Drawing.SystemColors.Window;
+ this.lblTitle.Font = new System.Drawing.Font("Microsoft Sans Serif", 14.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
+ this.lblTitle.Location = new System.Drawing.Point(168, 16);
+ this.lblTitle.Name = "lblTitle";
+ this.lblTitle.Size = new System.Drawing.Size(288, 40);
+ this.lblTitle.TabIndex = 0;
+ this.lblTitle.Text = "Welcome to the GPP Installation Wizard";
+ this.lblTitle.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+ //
+ // label1
+ //
+ this.label1.BackColor = System.Drawing.SystemColors.Window;
+ this.label1.Location = new System.Drawing.Point(168, 120);
+ this.label1.Name = "label1";
+ this.label1.Size = new System.Drawing.Size(288, 32);
+ this.label1.TabIndex = 0;
+ this.label1.Text = "First you must select a source of configuration management data to drive the inst" +
+ "allation.";
+ //
+ // StartupForm
+ //
+ this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
+ this.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("$this.BackgroundImage")));
+ this.ClientSize = new System.Drawing.Size(480, 350);
+ this.Controls.Add(this.groupCfgSrc);
+ this.Controls.Add(this.btnNext);
+ this.Controls.Add(this.lblIntro);
+ this.Controls.Add(this.btnBack);
+ this.Controls.Add(this.btnCancel);
+ this.Controls.Add(this.lblTitle);
+ this.Controls.Add(this.label1);
+ this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.Fixed3D;
+ this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
+ this.Name = "StartupForm";
+ this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
+ this.Text = "Conchango Fusion Installer Wizard";
+ this.Load += new System.EventHandler(this.StartupForm_Load);
+ this.groupCfgSrc.ResumeLayout(false);
+ this.ResumeLayout(false);
+
+ }
+ #endregion
+
+
+ private void btnNext_Click(object sender, System.EventArgs e)
+ {
+ Utils helper = new Utils();
+
+ // The configuration file selected as this stage is used in 2 ways:
+ // 1) Provide a list of environments
+ // 2) A path to it is passed to all installations via a defined MSI property
+
+ //foreach ( Control rad in groupCfgSrc.Controls )
+ for ( int i=0; i
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 1.3
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ False
+
+
+ Private
+
+
+ Private
+
+
+ False
+
+
+ Private
+
+
+ Private
+
+
+ False
+
+
+ Private
+
+
+ Private
+
+
+ False
+
+
+ Private
+
+
+ Private
+
+
+ Private
+
+
+ 8, 8
+
+
+ True
+
+
+ False
+
+
+ True
+
+
+ Private
+
+
+ Private
+
+
+ False
+
+
+ Private
+
+
+ False
+
+
+ Private
+
+
+ Private
+
+
+ False
+
+
+ Private
+
+
+ Private
+
+
+ False
+
+
+ Private
+
+
+ Private
+
+
+ False
+
+
+ Private
+
+
+ Private
+
+
+ False
+
+
+ Private
+
+
+ Private
+
+
+ False
+
+
+ Private
+
+
+ Private
+
+
+ Private
+
+
+ Private
+
+
+ 17, 17
+
+
+ False
+
+
+ (Default)
+
+
+ False
+
+
+ False
+
+
+ StartupForm
+
+
+ 8, 8
+
+
+ True
+
+
+ 80
+
+
+ True
+
+
+ Private
+
+
+
+ /9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwg
+ JC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIy
+ MjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCAFiAe4DASIAAhEBAxEB/8QA
+ HwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIh
+ MUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVW
+ V1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXG
+ x8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQF
+ BgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAV
+ YnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOE
+ hYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq
+ 8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD3+iikZgqlmICgZJJ4AoAWisWw8WaLqV29tb3qeapIAf5d/upP
+ Wsy51G88T6g+naNcPb2EDYur6M4Zj/cQ/wBf8nF14WvF3v2OuOCq8zVRcqWrb0sv627nW0Vyx/4STQDw
+ f7asR6/LcIP5N/OtTSfEOn6zlLeUrcKPnt5RtkT6g041ot8r0fZ/1qKphJxjzwfNHuv1W6+Zq0UUVqco
+ UUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQA
+ UUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAVxPjPUJn1OHSZRcJ
+ pfkrPey2ybn2liAD6LleTXSf8JFof/QZ0/8A8Ck/xrOsb20vvG1xJaXUNwg06NS0MgcA+Y/GR9RXNWca
+ kVCMt2ejg4TozdWcH7qv2/p9vMkSw8Oa7oqQ28VtcWka4j8vgx/iOQa53wp4caXwzY6lpd/NYX7qxdlO
+ +OXDEDch47DpXR3/AIUsrmdruykk06+P/Le1O3P+8vRqt+H9KbRdDttPeUStCCC4XAOWJ6fjUex5qic4
+ rRPVfK3mjX64qeHapVG7tOz16O9+jT0/yMO88Waj4ftZBrulkuBiK4tWzDK3YHPKk+9ch4R1W51n4iw3
+ 10wMkiycAYCjYcAV1nxO/wCRS/7eI/51x3gfRtaW5Gu2NpFLHBlVjlk2GbIIIQ4xx6nA/WuLEOp9ZhTu
+ 2lZnsYGGHeXVa9lGUrx3026X2v8A1oex0Vg2fi/Sp2aG8l/s66T78F7+6I/E8Grn/CRaH/0GdP8A/ApP
+ 8a9VVqbV1JHzMsJXi7OD+40qKo2+taVdzrBbanZzTNnbHHOrMcDJwAfSr1WpKWqZjKEoO0lYKKKKZIUU
+ UUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUU
+ UUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAeceT/ANMf/IP/ANqqvPp3mTJPEZ7e
+ 5QYSaDcjD8oxkVY8n/pj/wCQf/tVHk/9Mf8AyD/9qr5c8qjWqUZ89N2ZbsvFOsaZtj1S1e/tx/y8QRMs
+ ij/aUgA/hiuzsL+31OxivLSTzIJRlGxjPauAaH5T+57f88v/ALVXS+A/+RL07/df/wBDavUwOIqTnySd
+ 1Y9qnWWJw8qsopSi0tNE7qXTZPTpZeRe8Q6FD4h0prCaV4gWDq6DJBHSs6DUtS8PxJb6rp6yWUShVu7B
+ CVVR03R9R+GR7Vp69rlt4e04Xt0krxeYqERgE89+TT9L1vTdag82wuo5l7qDhl+oPIrtkoOp7rtI6abr
+ LD+/Dmp3fyfWz6P108jnfFXiLwzLoYlmFrqbSDEESt8wPHORynv0PauS8Nb59J3OpkxIQCU3ccd/Lb+d
+ V/iRbw2/izEMSRh4Fdgi4y2Tz9an8MQMNIBaE/M5IJjzkcf9Mz/OvCxVWU67UraaaHoZphaVHJozi2+Z
+ p69N9F+vc6HS49niPSj5e398/Pl7f+WMn+wv867+uA0uPZ4j0o+Xt/fPz5e3/ljJ/sL/ADrv69TLv4T9
+ f0R8/S/gw9H+bCiiivQKCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAK
+ KKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigDzjyf8A
+ pj/5B/8AtVHk/wDTH/yD/wDaqPJ/6Y/+Qf8A7VR5P/TH/wAg/wD2qvlzxQMGQR5P/kL/AO1UaRqmr+G4
+ EtUtvt+noTtjVGWWME5PJUBupo8n/pj/AOQf/tVHk/8ATH/yD/8AaquFSVOXNF2Z2YXGTw94pJxdrp+X
+ 4p6vYPG/iLTdb8IstrNidbiPfbyDbInPdT/SuU0DRLtmF/vuLY4/dNGHVj75Cniukn0y3uWVpbQMVOQf
+ KI/lFU/kY6Qf+Qf/ALVRWqSq1FOW57j4h9jg/q2Ei4tttt2dvJd/mv8AMyLrSL/VdVS61Wb7QI4wgZYn
+ UuATjPyYrXEAUACDAHAHk/8A2qjyf+mP/kH/AO1UeT/0x/8AIP8A9qqOt2eJjMwr4vlVV6RVklol8kWN
+ Lj2eI9KPl7f3z8+Xt/5Yyf7C/wA67+uA0uPZ4j0o+Xt/fPz5e3/ljJ/sL/Ou/r2Mu/hP1/RHXS/gw9H+
+ bCiiivQKCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAoo
+ ooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigDj/APhDL7/oK2n/AILV
+ /wDi6P8AhDL7/oK2n/gtX/4uuworj+oYf+X8X/mP3f5V9y/yOP8A+EMvv+graf8AgtX/AOLo/wCEMvv+
+ graf+C1f/i67Cij6hh/5fxf+Ye7/ACr7l/kcf/whl9/0FbT/AMFq/wDxdH/CGX3/AEFbT/wWr/8AF12F
+ FH1DD/y/i/8AMPd/lX3L/I4//hDL7/oK2n/gtX/4uj/hDL7/AKCtp/4LV/8Ai67Cij6hh/5fxf8AmHu/
+ yr7l/kcxp3hS5s9VtbybUYJVgZm2R2QjLEoy/eDH+9munooropUYUlywWg3JtJdvK35BRRRWhIUUUUAF
+ FFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAF
+ FFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAF
+ FFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAF
+ FFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABmioRIP7w/P/AOvTg49R+f8A9egZ
+ JRTQw9f1p2aBBRRRQAUUUUAVNQ1O00uFJbuRkWR/LXbGzktgnGFBPQH8qz/+Es0f/nrc/wDgFN/8RWd4
+ +XfpViu3dm8HG3d/yzk7bW/ka4f7N/07f+S//wBortweCeJjKXNaztt5J9/M48bjoYRxi4N3V97dWuz7
+ HpP/AAlmj/8APW5/8Apv/iKP+Es0f/nrc/8AgFN/8RXm32b/AKdv/Jf/AO0UfZv+nb/yX/8AtFdf9kP+
+ f8P+Ccf9tU/+fb/8C/8AtT0n/hLNH/563P8A4BTf/EUf8JZo/wDz1uf/AACm/wDiK82+zf8ATt/5L/8A
+ 2ij7N/07f+S//wBoo/sh/wA/4f8ABD+2qf8Az7f/AIF/9qek/wDCWaP/AM9bn/wCm/8AiKP+Es0f/nrc
+ /wDgFN/8RXm32b/p2/8AJf8A+0UfZv8Ap2/8l/8A7RR/ZD/n/D/gh/bVP/n2/wDwL/7U9J/4SzR/+etz
+ /wCAU3/xFWbDXtO1K6NtbSymbYZNrwSR/KCATllHdh+deW/Zv+nb/wAl/wD7RW/4Jj8vxOf3ezNnL/yz
+ 25+eP/pmn9fwrnxWXuhSdTmva3Tu0u504PMYYmsqXI1dPW99k328j0WiiivPO8KKKKACiiigAooooAKK
+ KKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKK
+ KKACiiigAooooAzxcr/z0H/fwf8AxdSCdf74/wC+x/8AFVgaZ4isNXtluLHUI5oz6TAEfUGbI/GtFbxT
+ /wAt1/7+j/47TGaQlH94f99D/wCKp4kHqPz/APr1QW6H/PVf+/g/+OVMtwD/AMtB/wB9j/4ugC4GHqPz
+ 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
+ AFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUU
+ AFFFFABRRRQAhFRsD6n8/wD69S0hFAFZ8/3j/wB9H/4qq75/56H/AL+H/wCOVeI9z+f/ANeo2B/vH/vo
+ /wDxVMZl3EazRPFK4eNhhlaQkEe482vOPEHwb8K6yzS26f2ZOTktasm0/VWlI/LFerMD/fP/AH2f/i6j
+ YH/nof8Av4f/AI5QB843/wAA9RjJ/s/W7KYdhcFYv5O1Z3/CifFP/P8AaJ/4G/8A2NfTZ3f89W/7+n/4
+ 5Rz/AM9W/wC/p/8AjlID51sPgFqEjD+0Ncs4R3FuVk/m6133h74OeFdFdZZ0/tKdTkPdMmAfZVlA/PNe
+ mgN/z1b/AL+H/wCOU9Qf+eh/7+H/AOOUAVYUWKNY432oowqrKQAPQDzatJn/AJ6H/v4f/jlSKD/fP/fZ
+ /wDi6lUH+8f++j/8VTAaoOPvH/vo/wDxVTKD6/r/APXoAPr+v/16eBQACloopCCiiigAooooAKKKKACi
+ iigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACi
+ iigAooooAKKKKACiiigAooooAKKKKACmke9OooAjI9z+f/16YQfU/wDfR/xqekxQMgIP94/99H/4qkwf
+ 7x/76P8A8VVjH1/Okx9fzpgQ4P8AeP8A30f/AIqnAH1P/fR/xqXH1/OjFIBgB9T+f/16cB7/AK06igQU
+ UUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAU
+ UUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRXMfbLz/oIXX5Rf/G6Ptl5/wBBC6/KL/43WPto
+ 9jb2Mjp6K5j7Zef9BC6/KL/43R9svP8AoIXX5Rf/ABuj20ewexkdPRXMfbLz/oIXX5Rf/G6Ptl5/0ELr
+ 8ov/AI3R7aPYPYyOnormPtl5/wBBC6/KL/43R9svP+ghdflF/wDG6PbR7B7GR09Fcx9svP8AoIXX5Rf/
+ ABuj7Zef9BC6/KL/AON0e2j2D2Mjp6K5j7Zef9BC6/KL/wCN0fbLz/oIXX5Rf/G6PbR7B7GR09Fcx9sv
+ P+ghdflF/wDG6Ptl5/0ELr8ov/jdHto9g9jI6eiuY+2Xn/QQuvyi/wDjdH2y8/6CF1+UX/xuj20ewexk
+ dPRXMfbLz/oIXX5Rf/G6Ptl5/wBBC6/KL/43R7aPYPYyOnormPtl5/0ELr8ov/jdH2y8/wCghdflF/8A
+ G6PbR7B7GR09Fcx9svP+ghdflF/8bo+2Xn/QQuvyi/8AjdHto9g9jI6eiuY+2Xn/AEELr8ov/jdH2y8/
+ 6CF1+UX/AMbo9tHsHsZHT0VzH2y8/wCghdflF/8AG6Ptl5/0ELr8ov8A43R7aPYPYyOnormPtl5/0ELr
+ 8ov/AI3R9svP+ghdflF/8bo9tHsHsZHT0VzH2y8/6CF1+UX/AMbo+2Xn/QQuvyi/+N0e2j2D2Mjp6K5j
+ 7Zef9BC6/KL/AON0fbLz/oIXX5Rf/G6PbR7B7GR09Fcx9svP+ghdflF/8bo+2Xn/AEELr8ov/jdHto9g
+ 9jI6eiuY+2Xn/QQuvyi/+N0fbLz/AKCF1+UX/wAbo9tHsHsZHT0VzH2y8/6CF1+UX/xuj7Zef9BC6/KL
+ /wCN0e2j2D2Mjp6K5j7Zef8AQQuvyi/+N0fbLz/oIXX5Rf8Axuj20ewexkdPRXMfbLz/AKCF1+UX/wAb
+ o+2Xn/QQuvyi/wDjdHto9g9jI6eiuY+2Xn/QQuvyi/8AjdH2y8/6CF1+UX/xuj20ewexkdPRXMfbLz/o
+ IXX5Rf8Axuj7Zef9BC6/KL/43R7aPYPYyOnormPtl5/0ELr8ov8A43R9svP+ghdflF/8bo9tHsHsZHT0
+ VzH2y8/6CF1+UX/xuj7Zef8AQQuvyi/+N0e2j2D2Mjp6K5j7Zef9BC6/KL/43R9svP8AoIXX5Rf/ABuj
+ 20ewexkdPRXMfbLz/oIXX5Rf/G6Ptl5/0ELr8ov/AI3R7aPYPYyOnormPtl5/wBBC6/KL/43R9svP+gh
+ dflF/wDG6PbR7B7GR09Fcx9svP8AoIXX5Rf/ABuj7Zef9BC6/KL/AON0e2j2D2Mjp6K5j7Zef9BC6/KL
+ /wCN0fbLz/oIXX5Rf/G6PbR7B7GR09Fcx9svP+ghdflF/wDG6imu9TZAINUmRs8l4omGPoFFHt12D2Mu
+ 42iiiuc6AooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKK
+ KKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKK
+ KKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKK
+ KKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKK
+ KKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKK
+ KKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKK
+ KKACiiigAooooAKKKKAP/9k=
+
+
+
+
+ AAABAAEAEBAQAAAAAAAoAQAAFgAAACgAAAAQAAAAIAAAAAEABAAAAAAAgAAAAAAAAAAAAAAAEAAAABAA
+ AAAAAAAAAACAAACAAAAAgIAAgAAAAIAAgACAgAAAgICAAMDAwAAAAP8AAP8AAAD//wD/AAAA/wD/AP//
+ AAD///8AAAAAAAAAAAAAAAAzMzMAAAAAAzMzMzAAAAeP/4MzMwAACP///zMzMAA/////+DMzAz//////
+ MzMDj/////8zMwOP/////4MzAz//////gzMDOP////+DMwMzj////4MzAAMzOIiIMzAAAzMzMzMzMAAA
+ MzMzMzMAAAADMzMzAAD//wAA/A8AAPgHAADgAwAA4AEAAMAAAACAAAAAgAAAAIAAAACAAAAAgAAAAIAA
+ AADgAQAA4AEAAPADAAD4DwAA
+
+
+
\ No newline at end of file
diff --git a/Solutions/Endjin.Templify.WizardFramework/Properties/AssemblyInfo.cs b/Solutions/Endjin.Templify.WizardFramework/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..4683eb6
--- /dev/null
+++ b/Solutions/Endjin.Templify.WizardFramework/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Endjin.Templify.WizardFramework")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Microsoft")]
+[assembly: AssemblyProduct("Endjin.Templify.WizardFramework")]
+[assembly: AssemblyCopyright("Copyright © Microsoft 2010")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("f51fa27b-18a5-4c8a-ad67-e4eeae7b454c")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/Solutions/Endjin.Templify.WizardFramework/WizardCommand.cs b/Solutions/Endjin.Templify.WizardFramework/WizardCommand.cs
new file mode 100644
index 0000000..52fc5b6
--- /dev/null
+++ b/Solutions/Endjin.Templify.WizardFramework/WizardCommand.cs
@@ -0,0 +1,32 @@
+namespace Endjin.Templify.WizardFramework
+{
+ using System;
+
+ ///
+ /// Abstract class that defines a Wziard Command object. This is used
+ /// to implement the command pattern.
+ ///
+ public abstract class WizardCommand {
+
+ ///
+ /// Executes the wizard command object. The index of the current
+ /// command is passed so that the related state can be updated.
+ ///
+ /// Index of the current command pointer
+ /// Index of the next command pointer
+ public abstract int Execute(int cmdPointer, int lastCmdPointer);
+
+ ///
+ /// Initialises the command object
+ ///
+ public abstract void InitialiseCommand();
+
+ ///
+ /// Cleans up the command object
+ ///
+ public abstract void CleanupCommand();
+ }
+
+
+}
+
diff --git a/Solutions/Endjin.Templify.WizardFramework/WizardCommand.resx b/Solutions/Endjin.Templify.WizardFramework/WizardCommand.resx
new file mode 100644
index 0000000..3f337e0
--- /dev/null
+++ b/Solutions/Endjin.Templify.WizardFramework/WizardCommand.resx
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 1.0.0.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
diff --git a/Solutions/Endjin.Templify.WizardFramework/WizardCommandList.cs b/Solutions/Endjin.Templify.WizardFramework/WizardCommandList.cs
new file mode 100644
index 0000000..5bebefd
--- /dev/null
+++ b/Solutions/Endjin.Templify.WizardFramework/WizardCommandList.cs
@@ -0,0 +1,101 @@
+namespace Endjin.Templify.WizardFramework
+{
+ using System;
+
+ ///
+ /// Base class that defines a WizardCommandList
+ ///
+ ///
+ public abstract class WizardCommandList {
+
+ #region Private Variables
+
+ ///
+ /// Internal array list that stores the WizardCommand objects
+ ///
+ private System.Collections.ArrayList _cmdList = null;
+
+ ///
+ /// Integer that returns the pointer to the current WizardCommand
+ ///
+ private int _cmdPointer = 0;
+ private int _lastCmdPointer = 0;
+
+ #endregion
+
+ #region Properties
+
+ public int LastCmdPointer {
+ get { return _lastCmdPointer; }
+ }
+
+ ///
+ /// Integer that returns the pointer to the current WizardCommand
+ ///
+ public int CmdPointer {
+ get { return _cmdPointer; }
+ set {
+ _lastCmdPointer = _cmdPointer;
+ _cmdPointer = value;
+ }
+ }
+
+ ///
+ /// Integer that returns the number of WizardCommand objects in the
+ /// list
+ ///
+ public int CmdLength {
+ get { return _cmdList.Count; }
+ }
+
+ #endregion
+
+ #region Constructors
+
+ ///
+ /// Default constructor
+ ///
+ public WizardCommandList() {
+ _cmdList = new System.Collections.ArrayList();
+ }
+
+ #endregion
+
+ #region Methods
+
+ ///
+ /// Adds the WizardCommand object to the internal array list
+ ///
+ ///
+ public void Add(WizardCommand cmd) {
+ _cmdList.Add(cmd);
+ }
+
+ ///
+ /// Determines whether this is the last command in the list
+ ///
+ /// Boolean of true if it is the last command in the list, otherwise false
+ public bool IsLastCommand() {
+ if (this.CmdPointer == this.CmdLength) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ #endregion
+
+ #region Indexers
+
+ ///
+ /// Indexer that retrieves the WizardComand object at the specified
+ /// index within the internal array
+ ///
+ public WizardCommand this[int index] {
+ get { return (WizardCommand)_cmdList[index]; }
+ }
+
+ #endregion
+ }
+
+}
diff --git a/Solutions/Endjin.Templify.WizardFramework/WizardState.cs b/Solutions/Endjin.Templify.WizardFramework/WizardState.cs
new file mode 100644
index 0000000..56b442a
--- /dev/null
+++ b/Solutions/Endjin.Templify.WizardFramework/WizardState.cs
@@ -0,0 +1,24 @@
+namespace Endjin.Templify.WizardFramework
+{
+ using System;
+ using System.Collections.Generic;
+
+ using Endjin.Templify.Domain.Domain.Packages;
+
+ ///
+ /// Summary description for WizardState.
+ ///
+ public class WizardState
+ {
+ public List Settings { get; set; }
+
+
+ // Public instance member
+ public static WizardState Instance = new WizardState();
+
+
+ private WizardState()
+ {
+ }
+ }
+}
diff --git a/Solutions/Endjin.Templify.sln b/Solutions/Endjin.Templify.sln
index ca23881..5eb0db5 100644
--- a/Solutions/Endjin.Templify.sln
+++ b/Solutions/Endjin.Templify.sln
@@ -24,6 +24,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build", "Build", "{324E1002
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Endjin.Templify.CommandLine", "Endjin.Templify.CommandLine\Endjin.Templify.CommandLine.csproj", "{585FCA37-58D1-4E7C-93BB-30C1FC755437}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Endjin.Templify.WizardFramework", "Endjin.Templify.WizardFramework\Endjin.Templify.WizardFramework.csproj", "{D8F709BA-1E52-48FB-A917-7C3A40445F7F}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -36,7 +38,6 @@ Global
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{56BE3D9C-686D-426A-A49C-BC83FCAB670E}.Debug|Any CPU.ActiveCfg = Debug
{56BE3D9C-686D-426A-A49C-BC83FCAB670E}.Debug|Mixed Platforms.ActiveCfg = Debug
- {56BE3D9C-686D-426A-A49C-BC83FCAB670E}.Debug|Mixed Platforms.Build.0 = Debug
{56BE3D9C-686D-426A-A49C-BC83FCAB670E}.Debug|x86.ActiveCfg = Debug
{56BE3D9C-686D-426A-A49C-BC83FCAB670E}.Debug|x86.Build.0 = Debug
{56BE3D9C-686D-426A-A49C-BC83FCAB670E}.Release|Any CPU.ActiveCfg = Release
@@ -87,6 +88,16 @@ Global
{585FCA37-58D1-4E7C-93BB-30C1FC755437}.Release|Mixed Platforms.Build.0 = Release|x86
{585FCA37-58D1-4E7C-93BB-30C1FC755437}.Release|x86.ActiveCfg = Release|x86
{585FCA37-58D1-4E7C-93BB-30C1FC755437}.Release|x86.Build.0 = Release|x86
+ {D8F709BA-1E52-48FB-A917-7C3A40445F7F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D8F709BA-1E52-48FB-A917-7C3A40445F7F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D8F709BA-1E52-48FB-A917-7C3A40445F7F}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {D8F709BA-1E52-48FB-A917-7C3A40445F7F}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {D8F709BA-1E52-48FB-A917-7C3A40445F7F}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {D8F709BA-1E52-48FB-A917-7C3A40445F7F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D8F709BA-1E52-48FB-A917-7C3A40445F7F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D8F709BA-1E52-48FB-A917-7C3A40445F7F}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {D8F709BA-1E52-48FB-A917-7C3A40445F7F}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {D8F709BA-1E52-48FB-A917-7C3A40445F7F}.Release|x86.ActiveCfg = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -94,6 +105,7 @@ Global
GlobalSection(NestedProjects) = preSolution
{56BE3D9C-686D-426A-A49C-BC83FCAB670E} = {6C3DEE68-6633-4899-B980-64339AB62651}
{9E8B79ED-9C17-485B-B1F9-8D33D8BB4BD2} = {59A31D18-9067-4B4D-930C-54113BAD4A83}
+ {D8F709BA-1E52-48FB-A917-7C3A40445F7F} = {59A31D18-9067-4B4D-930C-54113BAD4A83}
{AB83608F-1457-4EC7-B9CD-82813A222347} = {4799185A-AFB0-428D-9B2C-29BCDFDF0B3C}
{585FCA37-58D1-4E7C-93BB-30C1FC755437} = {4799185A-AFB0-428D-9B2C-29BCDFDF0B3C}
{1491A90A-6AC9-4EF4-A959-E0F0439A1D6E} = {AF81571B-C5FB-4073-A8EC-8C912EA07100}