cmIISConfig MainForm

<< Click to Display Table of Contents >>

Navigation:  Deployment > Deployment Targets > IIS\ISAPI > cmIISConfig – IIS configuration program >

cmIISConfig MainForm

using System;

using System.Collections;

using System.Diagnostics;

using System.Drawing;

using System.IO;

using System.IO.Compression;

using System.Linq;

using System.Security.AccessControl;

using System.Security.Principal;

using System.Windows.Forms;

using System.Collections.Generic;

using System.Management.Instrumentation;

using System.Net;

using System.Runtime.InteropServices;

using System.Text.RegularExpressions;

using Microsoft.Web.Administration;

using PdMagic.Windows;

 

namespace cmIISConfig

{

   public partial class MainForm : Form

   {

       private PdIISManager mIISManager;

       private CmConst mConst;

       private bool mUpdating = false;

 

       public MainForm()

       {

           InitializeComponent();

       }

 

       private string DialogTitle => $"{mConst.ApplicationName} Install and Configuration Tool v" +

                                     System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;

 

       private void Form1_Shown(object sender, EventArgs e)

       {

           mIISManager = new PdIISManager();

           mConst = new CmConst(uxConfigureInstanceList.Text);

 

           // Populate controls from default CmConst properties

           uxInstallerFolder.Text = mConst.InstallersFolder;

           uxNewInstance.Text = mConst.DefaultInstanceName;

 

           RePopulateInstallers(uxInstallerFolder.Text);

 

           RePopulateInstanceList(uxUpgradeInstanceList.Items);

           if (uxUpgradeInstanceList.Items.Count > 0)

           {

               uxUpgradeInstanceList.SelectedIndex = 0;

           }

           RePopulateInstanceList(uxConfigureInstanceList.Items);

           if (uxConfigureInstanceList.Items.Count > 0)

           {

               uxConfigureInstanceList.SelectedIndex = 0;

           }

 

           UpdateControls();

       }

 

       private void ReCreatecmConst(bool aReportChange)

       {

           if (uxConfigureInstanceList.Text != string.Empty)

           {

               if (aReportChange)

               {

                   AppendToStatusLog(

                       $"All variable names recalculated to reflect Instance={uxConfigureInstanceList.Text}");

               }

 

               mConst = new CmConst(uxConfigureInstanceList.Text);

 

               uxUser.Text = mConst.InstanceUserName;

               uxUserGroup.Text = mConst.InstanceUserGroupName;

               uxPassword.Text = "";

           }

       }

 

       private void RePopulateInstanceList(IList aList)

       {

           aList.Clear();

           

           // list all CrashMagicOnline* folders - these are instances - The suffix is the instance name.

           // No suffix is the "[Default]" instance.

 

           var lFiles = Directory.GetDirectories($@"{mConst.WindowsProgramFiles}\{mConst.CompanyFolder}",

               $"{mConst.ApplicationFolderBaseName}*");

 

           foreach (var lFile in lFiles)

           {

               var lFileName = Path.GetFileName(lFile);

               if (lFileName != null)

               {

                   var lInstance = lFileName.Substring(mConst.ApplicationFolderBaseName.Length,

                                                       lFileName.Length - mConst.ApplicationFolderBaseName.Length);

                   if (mConst.InstanceExistsP(lInstance))

                   {

                       aList.Add(lInstance == string.Empty ? mConst.DefaultInstanceName : lInstance);

                   }

               }

           }

       }

 

       private void RePopulateInstallers(string aFolder)

       {

           uxInstallerList.Items.Clear();

           List<String> lInstallers = Directory.EnumerateFiles(aFolder, "cmoInstall*.zip")

               .Select(Path.GetFileName)

               .ToList();

           foreach (var lInstaller in lInstallers)

           {

               uxInstallerList.Items.Add(lInstaller);

           }

 

           if (uxInstallerList.Items.Count > 0)

           {

               uxInstallerList.SelectedIndex = 0;

           }

       }

 

       private void ShowMessageBox(string aMessage, Exception aException = null)

       {

           var lMessage = aException == null

               ? $"{aMessage}"

               : $"{aMessage}:\n{PdActiveDirectory.CleanedException(aException)}";

           MessageBox.Show(lMessage, DialogTitle, MessageBoxButtons.OK, MessageBoxIcon.Hand);

       }

 

       private void AppendToStatusLog(string aLine)

       {

           uxStatusLog.AppendText(aLine + System.Environment.NewLine);

       }

       private void AppendToStatusLog(List<string> aList)

       {

           foreach (string lLine in aList)

           {

               uxStatusLog.AppendText(lLine + System.Environment.NewLine);

           }

       }

 

       public void AppendToStatusLog(string text, Color color)

       {

           uxStatusLog.SelectionStart = uxStatusLog.TextLength;

           uxStatusLog.SelectionLength = 0;

 

           uxStatusLog.SelectionColor = color;

           uxStatusLog.AppendText(text);

           uxStatusLog.SelectionColor = uxStatusLog.ForeColor;

       }

 

 

       private void ShowException(string aLine, Exception aException)

       {

           AppendToStatusLog("Exception: " + aLine + System.Environment.NewLine, Color.Crimson);

           var lCurEx = aException;

           while (lCurEx != null)

           {

               AppendToStatusLog(lCurEx.Message, Color.Crimson);

               lCurEx = lCurEx.InnerException;

           }

       }

 

       private void UpdateControls()

       {

           if (mUpdating)

           {

               return;

           }

 

           try

           {

               mUpdating = true;

               Text = DialogTitle;

               try

               {

                   int lIndex;

 

                   // Remember prior selections

                   string lWebSite = uxWebSite.Text;

                   string lApplication = uxApplication.Text;

 

                   uxWebSite.Items.Clear();

                   uxWebSite.Items.Add("");

                   uxApplication.Items.Clear();

                   uxApplicationPool.Items.Clear();

                   uxApplicationPool.Items.Add("");

 

                   try

                   {

                       uxWebSite.Items.AddRange(mIISManager.Sites.ToArray());

                       // Reset prior webSite selection

                       lIndex = uxWebSite.FindStringExact(lWebSite);

                       if (lIndex >= 0)

                       {

                           uxWebSite.SelectedIndex = lIndex;

                       }

                   }

                   catch (Exception lException)

                   {

                       ShowException($"Add websites and set current ({lWebSite})", lException);

                   }

 

                   try

                   {

                       if (lWebSite != string.Empty)

                       {

                           uxApplication.Items.AddRange(mIISManager.Sites[lWebSite].Applications.ToArray());

                           lIndex = uxApplication.FindStringExact(lApplication);

                           uxApplication.SelectedIndex = lIndex >= 0 ? lIndex : 0;

                       }

                   }

                   catch (Exception lException)

                   {

                       ShowException($"Add applications and select current ({lApplication})", lException);

                   }

 

                   string lPool = "";

                   try

                   {

                       foreach (ApplicationPool lAp in mIISManager.ApplicationPools)

                       {

                           uxApplicationPool.Items.Add(lAp.Name);

                       }

 

                       var lSlashPos = uxApplication.Text.IndexOf("/");

                       if (lSlashPos >= 0)

                       {

                           var lApplicationPath = uxApplication.Text.Substring(lSlashPos);

                           if (lWebSite != string.Empty)

                           {

                               lPool = mIISManager.Sites[lWebSite].Applications[lApplicationPath].ApplicationPoolName;

                               if (lPool != string.Empty)

                               {

                                   lIndex = uxApplicationPool.FindStringExact(lPool);

                                   if (lIndex >= 0)

                                   {

                                       uxApplicationPool.SelectedIndex = lIndex;

                                   }

                               }

                           }

                       }

                   }

                   catch (Exception lException)

                   {

                       ShowException($"List application pools and set current ({lPool})", lException);

                   }

               }

 

               finally

               {

                   mUpdating = false;

               }

           }

           catch (Exception lUpdateControls)

           {

               ShowException("UpdateControls", lUpdateControls);

           }

       }

 

       private bool ReportMissingParameters()

       {

           bool lMissing = false;

 

           if ((uxUserGroup.Text.Trim() == string.Empty) | (uxUser.Text.Trim() == string.Empty) |

               (uxPassword.Text.Trim() == string.Empty))

           {

               ShowMessageBox("Please enter a group, login and password before executing this operation");

               lMissing = true;

           }

 

           return lMissing;

       }

 

       private void PrepareSiteAndApplication(string aSiteName, string aApplicationPath)

       {

           if (ReportMissingParameters())

               return;

 

           var lStatus = new List<string>();

           try

           {

               mIISManager.CreateISAPIHandler(aSiteName, aApplicationPath, aSiteName + "_Handler",

                   mConst.IsapiFolder + $@"\{mConst.DllFileName}", lStatus);

               AppendToStatusLog(lStatus);

           }

           catch (Exception lException)

           {

               ShowException("CreateISAPIHandler - Note: Editing this section of IIS configuration " +

                             "requires that Windows feature 'ASP.NET 4.x' be installed.", lException);

           }

 

           try

           {

               lStatus.Clear();

               mIISManager.VerifyDLLAllowed("Crash Magic", $@"{mConst.IsapiFolder}\{mConst.DllFileName}",

                   $"{mConst.ApplicationName} {mConst.InstanceName}", lStatus);

               AppendToStatusLog(lStatus);

           }

           catch (Exception lException)

           {

               ShowException("VerifyDLLAllowed", lException);

           }

 

           try

           {

               lStatus.Clear();

               mIISManager.SetApplicationUser(aSiteName, aApplicationPath, uxUser.Text, uxPassword.Text,lStatus);

               AppendToStatusLog(lStatus);

           }

           catch (Exception lException)

           {

               ShowException("SetApplicationUser", lException);

           }

 

           try

           {

               lStatus.Clear();

               mIISManager.VerifyMimeTypes(aSiteName, aApplicationPath, mConst.MimeEntries, lStatus);

               AppendToStatusLog(lStatus);

           }

           catch (Exception lException)

           {

               ShowException("Add Mime Types", lException);

           }

 

           try

           {

               lStatus.Clear();

               mIISManager.VerifyDefaultDocument(aSiteName, aApplicationPath, $"{mConst.DllFileName}", lStatus);

               AppendToStatusLog(lStatus);

           }

           catch (Exception lException)

           {

               ShowException("AddDefaultDocument", lException);

           }

 

           try

           {

               lStatus.Clear();

               mIISManager.SetMaxAllowedContentLength(aSiteName, 524288000, lStatus);

               AppendToStatusLog(lStatus);

           }

           catch (Exception lException)

           {

               ShowException("Set MaxAllowedContentLength", lException);

           }

 

           try

           {

               lStatus.Clear();

               mIISManager.SetServerRuntimeValues(aSiteName, 2147483647, 4294967295, lStatus);

               AppendToStatusLog( lStatus);

           }

           catch (Exception lException)

           {

               ShowException("Set uploadReadAheadSize, maxRequestEntityAllowed", lException);

           }

 

           try

           {

               lStatus.Clear();

               mIISManager.VerifyVirtualFolders(aSiteName, aApplicationPath, mConst.VirtualFolders, lStatus);

               AppendToStatusLog(lStatus);

           }

           catch (Exception lException)

           {

               

               ShowException("VerifyVirtualDirectory", lException);

           }

 

           UpdateControls();

       }

 

 

       private void uxAddNewSite_Click(object sender, EventArgs e)

       {

           try

           {

               var lNewSiteName = mConst.InstanceSiteName;

               if (PdInput.Show(this, "New site name", DialogTitle, ref lNewSiteName) != DialogResult.OK)

                   return;

 

               var lStatus = new List<string>();

               mIISManager.AddNewSite(lNewSiteName, mConst.IsapiFolder, lStatus);

               AppendToStatusLog( lStatus);

 

               UpdateControls();

               uxWebSite.SelectedIndex = uxWebSite.FindStringExact(lNewSiteName);

               UpdateControls();

           }

           catch (Exception lException)

           {

               ShowMessageBox("Failed to add new site", lException);

           }

       }

 

       private void uxCreateNewApp_Click(object sender, EventArgs e)

       {

           try

           {

               var lNewAppName = mConst.InstanceAppName;

               if (PdInput.Show(this, "New application name", DialogTitle, ref lNewAppName) != DialogResult.OK)

                   return;

 

               var lStatus = new List<string>();

               mIISManager.AddNewApplication(uxWebSite.Text, lNewAppName, mConst.IsapiFolder, lStatus);

               UpdateControls();

               uxApplication.SelectedIndex = uxApplication.FindStringExact(uxWebSite.Text + lNewAppName);

               UpdateControls();

 

               AppendToStatusLog(lStatus);

           }

           catch (Exception lException)

           {

               ShowMessageBox("Failed to add new application", lException);

           }

       }

 

       private void uxCreateNewAppPool_Click(object sender, EventArgs e)

       {

           if (ReportMissingParameters())

               return;

 

           try

           {

               var lNewAppPoolName = mConst.InstanceAppPoolName;

               if (PdInput.Show(this, "New application pool name", DialogTitle, ref lNewAppPoolName) != DialogResult.OK)

                   return;

 

               var lApplicationPath = uxApplication.Text.Substring(uxApplication.Text.IndexOf("/", StringComparison.Ordinal));

               var lStatus = new List<string>();

               mIISManager.AddNewApplicationPool(lNewAppPoolName, lStatus);

               AppendToStatusLog(lStatus);

 

               lStatus.Clear();

               mIISManager.AttachSiteToApplicationPool(uxWebSite.Text, lApplicationPath, lNewAppPoolName, lStatus);

               AppendToStatusLog(lStatus);

 

               UpdateControls();

           }

           catch (Exception lException)

           {

               ShowMessageBox("Failed to add and associate new application pool", lException);

           }

       }

 

       private void uxSetupPool_Click(object sender, EventArgs e)

       {

           try

           {

               var lStatus = new List<string>();

 

               mIISManager.SetUpApplicationPool(uxApplicationPool.Text, uxUser.Text, uxPassword.Text, lStatus);

               AppendToStatusLog(lStatus);

 

               UpdateControls();

           }

           catch (Exception lException)

           {

               ShowMessageBox("Failed to set up application pool", lException);

           }

       }

 

       private void uxCreateUserAndGroup_Click(object sender, EventArgs e)

       {

           if (ReportMissingParameters())

               return;

 

           var lAd = new PdActiveDirectory();

 

           try

           {

               AppendToStatusLog("CREATE USER AND GROUP");

               var lUserGroup = uxUserGroup.Text;

               var lUser = uxUser.Text;

 

               lAd.CreateLocalUserGroup(lUserGroup, $"{mConst.ApplicationName} User Group");

               AppendToStatusLog($"* Created user group ({lUserGroup})");

 

               var lPassword = uxPassword.Text;

               lAd.CreateLocalUser(lUser, lPassword, $"{mConst.ApplicationName} User");

               AppendToStatusLog($"* Created user ({lUser})");

 

               lAd.AddUserToGroup(lUser, lUserGroup);

               AppendToStatusLog($"* Added user ({lUser}) to group ({lUserGroup})");

 

               const string lIUSRS = "IIS_IUSRS";

               if (lAd.GroupExists(lIUSRS))

               {

                   lAd.AddUserToGroup(lUser, lIUSRS);

                   AppendToStatusLog($"* Added user ({lUser}) to group ({lIUSRS})");

               }

               else

               {

                   AppendToStatusLog($"* ({lIUSRS}) group not found.  (Is IIS installed?)");

               }

 

               if (lAd.GroupExists("DB2USERS"))

               {

                   lAd.AddUserToGroup(lUser, "DB2USERS");

                   AppendToStatusLog("* Added user ({lUser}) to group DB2USERS");

               }

 

           }

           catch (Exception lException)

           {

               ShowMessageBox("cmAddAccounts Failed", lException);

           }

       }

 

       private void StatusCallback(string aStatus)

       {

           uxStatus.Text = aStatus;

           uxStatus.Update();

       }

 

       private void uxAssignFolderSecurity_Click(object sender, EventArgs e)

       {

           var lAd = new PdActiveDirectory();

           var lOldCursor = Cursor.Current;

           Cursor.Current = Cursors.WaitCursor;

           try

           {

               try

               {

                   var lUserGroup = uxUserGroup.Text;

                   AppendToStatusLog("ASSIGN FOLDER SECURITY");

 

                   try

                   {

                       lAd.AddDirectorySecurity(mConst.PubFolder, lUserGroup,

                           FileSystemRights.Modify | FileSystemRights.ListDirectory |

                           FileSystemRights.Read | FileSystemRights.Write,

                           AccessControlType.Allow, StatusCallback);

                       AppendToStatusLog($"* Gave group {lUserGroup} modify/list/read/write permissions to {mConst.PubFolder}");

                   }

                   catch (Exception ePubFolder)

                   {

                       ShowException(

                           $"Failed to gave group {lUserGroup} modify/list/read/write permissions to {mConst.PubFolder}",

                           ePubFolder);

                       throw;

                   }

                   try

                   {

                       lAd.AddDirectorySecurity(mConst.IsapiFolder, lUserGroup,

                           FileSystemRights.ListDirectory | FileSystemRights.ReadAndExecute,

                           AccessControlType.Allow, StatusCallback);

                       AppendToStatusLog($"* Gave group {lUserGroup} read .&. execute permissions to {mConst.IsapiFolder}");

                   }

                   catch (Exception eIsapiFolder)

                   {

                       ShowException(

                           $"Failed to gave group {lUserGroup} modify/list/read/write permissions to {mConst.IsapiFolder}",

                           eIsapiFolder);

                       throw;

                   }

               }

               catch (Exception lException)

               {

                   ShowMessageBox("cmAddAccounts Failed", lException);

               }

           }

           finally

           {

               Cursor.Current = lOldCursor;

           }

       }

 

 

       private void uxRefresh_Click(object sender, EventArgs e)

       {

           mIISManager.ReLoad();

           UpdateControls();

       }

 

       private void uxPrepareSiteAndApplication_Click(object sender, EventArgs e)

       {

           try

           {

               PrepareSiteAndApplication(uxWebSite.Text, uxApplication.Text.Substring(uxApplication.Text.IndexOf("/", StringComparison.Ordinal)));

           }

           catch (Exception lException)

           {

               var lCurEx = lException;

               while (lCurEx != null)

               {

                   AppendToStatusLog(lCurEx.Message);

                   lCurEx = lCurEx.InnerException;

               }

           }

 

       }

 

       private void uxWebSite_SelectedIndexChanged(object sender, EventArgs e)

       {

           UpdateControls();

       }

 

       private void uxApplication_SelectedIndexChanged(object sender, EventArgs e)

       {

           UpdateControls();

       }

 

       private void uxClear_Click(object sender, EventArgs e)

       {

           uxStatusLog.Clear();

       }

 

       private void uxInstanceName_Leave(object sender, EventArgs e)

       {

           ReCreatecmConst(true);

       }

 

       private void uxInstanceName_TextChanged(object sender, EventArgs e)

       {

           ReCreatecmConst(true);

       }

       private bool RunningAsAdmin()

       {

           try

           {

               var lIdentity = WindowsIdentity.GetCurrent();

               var lPrincipal = new WindowsPrincipal(lIdentity);

               return lPrincipal.IsInRole(WindowsBuiltInRole.Administrator);

           }

           catch

           {

               return false;

           }

       }

 

       private void uxInstanceName_DropDown(object sender, EventArgs e)

       {

           RePopulateInstanceList(uxConfigureInstanceList.Items);

       }

 

       private void uxInstallerFolder_Click(object sender, EventArgs e)

       {

           uxSelectInstallerFolder.RootFolder = Environment.SpecialFolder.CommonApplicationData;

 

           uxSelectInstallerFolder.SelectedPath = mConst.DefaultInstallersFolder;

           if (uxSelectInstallerFolder.ShowDialog() == DialogResult.OK)

           {

               mConst.InstallersFolder = uxSelectInstallerFolder.SelectedPath;

               uxInstallerFolder.Text = mConst.InstallersFolder;

           }

       }

 

       private void uxInstallerFolder_TextChanged(object sender, EventArgs e)

       {

           mConst.InstallersFolder = uxInstallerFolder.Text;

 

           RePopulateInstallers( mConst.InstallersFolder);

           if (uxInstallerList.Items.Count > 0)

           {

               uxInstallerList.SelectedIndex = 0;

           }

       }

 

       private void InstallUpgradeChanged(object sender, EventArgs e)

       {

           if (uxSelectNewInstance.Checked)

           {

               uxNewInstanceControls.Show();

               uxNewInstanceNameControls.Show();

               uxUpgradeInstanceNameControls.Hide();

           }

           else

           {

               RePopulateInstanceList(uxUpgradeInstanceList.Items);

               if (uxUpgradeInstanceList.Items.Count > 0)

               {

                   uxUpgradeInstanceList.SelectedIndex = 0;

               }

 

               uxNewInstanceControls.Hide();

               uxNewInstanceNameControls.Hide();

               uxUpgradeInstanceNameControls.Show();

           }

           UpdateCopyFilesDescription();

       }

 

       private void uxUseDefaultInstance_CheckedChanged(object sender, EventArgs e)

       {

           if (uxUseDefaultInstance.Checked)

           {

 

               uxNewInstance.Text = mConst.DefaultInstanceName;

               uxNewInstance.Visible = false;

           }

           else

           {

               uxNewInstance.Text = string.Empty;

               uxNewInstance.Visible = true;

           }

 

           UpdateCopyFilesDescription();

       }

 

       private void uxNewInstance_TextChanged(object sender, EventArgs e)

       {

           if (mConst.InstanceExistsP(uxNewInstance.Text))

           {

               uxNewInstance.BackColor = Color.LightPink;

           }

           else if (!mConst.ValidNewInstanceNameP(uxNewInstance.Text))

           {

               uxNewInstance.BackColor = Color.LightPink;

           }

           else

           {

               uxNewInstance.BackColor = Color.LightGreen;

           }

           UpdateCopyFilesDescription();

       }

 

       private void uxConfigureInstanceList_DropDownClosed(object sender, EventArgs e)

       {

           if (uxConfigureInstanceList.Text == string.Empty)

           {

               uxConfigureInstanceList.Text = mConst.DefaultInstanceName;

           }

       }

 

       private void UpdateCopyFilesDescription()

       {

           var lInstanceName = uxSelectNewInstance.Checked

               ? uxNewInstance.Text

               : uxUpgradeInstanceList.Text;

           var lNewVersion = ExtractZipVersion($@"{uxInstallerFolder.Text}\{uxInstallerList.Text}");

 

           var lIsapiFileName = $@"{mConst.IsapiFolderP(lInstanceName)}\CrashMagicOnline_ISAPI.dll";

           string lExistingVersion;

           if (File.Exists(lIsapiFileName))

           {

               var lFileVersion = FileVersionInfo.GetVersionInfo(lIsapiFileName);

               lExistingVersion = lFileVersion.FileVersion;

           }

           else

           {

               lExistingVersion = "Existing program version not available";

           }

 

 

           uxCopyFilesDescription.Text = uxSelectNewInstance.Checked

               ? $"Install new instance of Crash Magic (v{lNewVersion}) named '{mConst.FullInstanceNameP(lInstanceName)}'"

               : $"Upgrade existing (v{lExistingVersion}) instance of Crash Magic named '{mConst.FullInstanceNameP(lInstanceName)}' to v{lNewVersion}";

       }

 

       private bool ValidControlValues()

       {

           string lInstanceName = uxSelectNewInstance.Checked ? uxNewInstance.Text : uxUpgradeInstanceList.Text;

           string lInstallerPackage = uxInstallerList.Text;

 

           if (lInstallerPackage == string.Empty)

           {

               MessageBox.Show("Please select an install package and try again.", "Crash Magic Online Installation",

                   MessageBoxButtons.OK, MessageBoxIcon.Error);

               return false;

           }

 

           if (uxSelectNewInstance.Checked)

           {

               if (mConst.InstanceExistsP(lInstanceName))

               {

                   MessageBox.Show(

                       "The specified instance already exists.  Please select a different instance name or upgrade an existing one.",

                       "Crash Magic Online Installation", MessageBoxButtons.OK, MessageBoxIcon.Error);

                   return false;

               }

               else if (!mConst.ValidNewInstanceNameP(lInstanceName))

               {

                   MessageBox.Show("Instance names may only contain letters and numbers, no special characters.",

                       "Crash Magic Online Installation", MessageBoxButtons.OK, MessageBoxIcon.Error);

                   return false;

               }

 

           }

           else if (uxSelectUpgradeInstance.Checked)

           {

               if (uxUpgradeInstanceList.SelectedIndex < 0)

               {

                   MessageBox.Show(

                       "Please select an instance to upgrade, or choose to Install a New Crash Magic Instance.",

                       "Crash Magic Online Installation", MessageBoxButtons.OK, MessageBoxIcon.Error);

                   return false;

               }

           }

 

 

           if (uxSelectNewInstance.Checked)

           {

               if (MessageBox.Show($"Install {uxInstallerList.Text} as a new instanced called {lInstanceName}?",

                       "Crash Magic Online Installation", MessageBoxButtons.YesNo) != DialogResult.Yes)

               {

                   return false;

               }

           }

           else //(uxSelectUpgradeInstance.Checked)

           {

               if (MessageBox.Show($"Upgrade existing instance {lInstanceName} to {uxInstallerList.Text}?",

                       "Crash Magic Online Installation", MessageBoxButtons.YesNo) != DialogResult.Yes)

               {

                   return false;

               }

           }

 

           return true;

       }

 

       private string ExtractZipVersion(string aFileName)

       {

           var lVersion = "INSTALL PACKAGE VERSION NOT FOUND";

 

           try

           {

               using (ZipArchive lArchive = ZipFile.OpenRead(aFileName))

               {

                   var lResult = from currEntry in lArchive.Entries

                       where Path.GetDirectoryName(currEntry.FullName) == "ProgramData"

                       where currEntry.Name == "cmVersionNumber.txt"

                       select currEntry;

                   foreach (ZipArchiveEntry lEntry in lResult)

                   {

                       var lFileName = Path.GetTempFileName();

                       lEntry.ExtractToFile(lFileName, true);

                       lVersion = File.ReadAllText(lFileName);

                       File.Delete(lFileName);

                   }

               }

           }

           catch( Exception lExtract)

           {

               lVersion = "ERROR READING INSTALL PACKAGE: " + lExtract.Message;

           }

 

           return lVersion;

       }

       private void uxExtractFiles_Click(object sender, EventArgs e)

       {

           if (!ValidControlValues())

           {

               return;

           }

 

           string lInstanceName = uxSelectNewInstance.Checked ? uxNewInstance.Text : uxUpgradeInstanceList.Text;

           lInstanceName = mConst.NameWithInstanceP("", lInstanceName );

 

           string lInstallerPackage = uxInstallerList.Text;

 

           string lZipFileName = $@"{uxInstallerFolder.Text}\{uxInstallerList.Text}";

 

           try

           {

               using (var lArchive = ZipFile.OpenRead(lZipFileName))

               {

                   uxProgress.Minimum = 0;

                   uxProgress.Maximum = lArchive.Entries.Count;

                   uxProgress.Step = 1;

 

                   var lDestinationBasePath = string.Empty;

 

 

                   foreach (var lEntry in lArchive.Entries)

                   {

                       uxProgress.PerformStep();

                       uxProgress.Text = lEntry.Name;

 

                       var lCleanedFullName = lEntry.FullName.Replace("/", "\\");

 

                       if (lEntry.FullName.StartsWith("Common"))

                       {

                           lDestinationBasePath =

                               $@"{Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86)}\PdMagic\Common";

                           lCleanedFullName = lCleanedFullName.Substring("Common".Length + 1);

                       }

                       else if (lEntry.FullName.StartsWith("ProgramData"))

                       {

                           lDestinationBasePath =

                               $@"{Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData)}\PdMagic\CrashMagicOnline{lInstanceName}";

                           lCleanedFullName = lCleanedFullName.Substring("ProgramData".Length + 1);

                       }

                       else if (lEntry.FullName.StartsWith("ProgramFiles"))

                       {

                           lDestinationBasePath =

                               $@"{Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86)}\PdMagic\CrashMagicOnline{lInstanceName}";

                           lCleanedFullName = lCleanedFullName.Substring("ProgramFiles".Length + 1);

                       }

                       else if (lEntry.FullName.StartsWith("System32"))

                       {

                           lDestinationBasePath = $@"{Environment.GetFolderPath(Environment.SpecialFolder.SystemX86)}";

                           lCleanedFullName = lCleanedFullName.Substring("System32".Length + 1);

                       }

 

                       var lFullFileName = Path.Combine(lDestinationBasePath, lCleanedFullName);

                       var lJustPath = Path.GetDirectoryName(lFullFileName);

 

                       if ((lJustPath != null) .&. (lJustPath != string.Empty))

                       {

                           Directory.CreateDirectory(lJustPath);

                       }

 

                       lEntry.ExtractToFile(lFullFileName, true);

                   }

               }

               MessageBox.Show("File copy completed");

           }

           catch (Exception eZip)

           {

               MessageBox.Show("File copy failed: " + eZip.Message);

           }

           uxProgress.Value = 0;

       }

 

       private void uxVersions_Click(object sender, EventArgs e)

       {

           var lVersionsDlg = new NewVersionDownloads();

           lVersionsDlg.Initialize( mConst );

           lVersionsDlg.ShowDialog();

           RePopulateInstallers( mConst.InstallersFolder );

       }

 

       private void uxInstallerList_SelectedValueChanged(object sender, EventArgs e)

       {

           UpdateCopyFilesDescription();

       }

 

       private void uxUpgradeInstanceList_SelectedValueChanged(object sender, EventArgs e)

       {

           UpdateCopyFilesDescription();

       }

 

       private void uxInstallerList_DropDown(object sender, EventArgs e)

       {

           RePopulateInstallers(mConst.InstallersFolder);

       }

   }

}