/// <summary> /// This starts the <see cref="BackgroundWorkerProgressDialog" /> to build the fomod. /// </summary> /// <remarks> /// This method is called by implementers of this abstract class to instantiate the /// <see cref="BackgroundWorkerProgressDialog" /> that will be used to generate the fomod. The /// <see cref="BackgroundWorkerProgressDialog" /> calls <see cref="DoGenerateFomod(object)" />, /// which must be overridden in the implementer, to actually do the work. /// </remarks> /// <param name="p_gfaArgs"> /// The arguments to pass the the <see cref="DoGenerateFomod(object)" /> /// method. /// </param> /// <returns>The atual path of the generated fomod.</returns> protected string GenerateFomod(GenerateFomodArgs p_gfaArgs) { var strPackedPath = p_gfaArgs.PackedPath; if (!CheckFileName(ref strPackedPath)) { return(null); } p_gfaArgs.PackedPath = strPackedPath; try { using (ProgressDialog = new BackgroundWorkerProgressDialog(DoGenerateFomod)) { ProgressDialog.OverallMessage = OverallProgressMessage; ProgressDialog.ShowItemProgress = true; ProgressDialog.OverallProgressStep = 1; ProgressDialog.WorkMethodArguments = p_gfaArgs; if (ProgressDialog.ShowDialog() == DialogResult.Cancel) { FileUtil.ForceDelete(strPackedPath); return(null); } } } finally { foreach (var strFolder in m_lltTempFolders) { FileUtil.ForceDelete(strFolder); } } return(strPackedPath); }
/// <summary> /// Displays the option form and starts the background worker to do the install. /// </summary> /// <returns><lang langref="true" /> if the mod installed correctly; <lang langref="false" /> otherwise.</returns> public bool Install() { var xmlConfig = new XmlDocument(); var strConfig = m_misInstallScript.Fomod.GetInstallScript().Text; xmlConfig.LoadXml(strConfig); //remove comments so we don't have to deal with them later var xnlComments = xmlConfig.SelectNodes("//comment()"); foreach (XmlNode xndComment in xnlComments) { xndComment.ParentNode.RemoveChild(xndComment); } m_dsmStateManager = Program.GameMode.CreateDependencyStateManager(m_misInstallScript); var prsParser = Parser.GetParser(xmlConfig, m_misInstallScript.Fomod, m_dsmStateManager); var cpdModDependencies = prsParser.GetModDependencies(); if ((cpdModDependencies != null) && !cpdModDependencies.IsFufilled) { throw new DependencyException(cpdModDependencies.Message); } var lstSteps = prsParser.GetInstallSteps(); var hifHeaderInfo = prsParser.GetHeaderInfo(); var ofmOptions = new OptionsForm(this, hifHeaderInfo, m_dsmStateManager, lstSteps); bool booPerformInstall; if (lstSteps.Count == 0) { booPerformInstall = true; } else { booPerformInstall = (ofmOptions.ShowDialog() == DialogResult.OK); } if (booPerformInstall) { using (m_bwdProgress = new BackgroundWorkerProgressDialog(InstallFiles)) { m_bwdProgress.WorkMethodArguments = new InstallFilesArguments(prsParser, ofmOptions); m_bwdProgress.OverallMessage = "Installing " + hifHeaderInfo.Title; m_bwdProgress.OverallProgressStep = 1; m_bwdProgress.ItemProgressStep = 1; if (m_bwdProgress.ShowDialog() == DialogResult.Cancel) { return(false); } } return(true); } return(false); }
/// <summary> /// Checks for conflicts with mod-author specified critical records. /// </summary> public void CheckForConflicts() { using (m_bwdProgress = new BackgroundWorkerProgressDialog(CheckForCriticalRecordConflicts)) { m_bwdProgress.ShowItemProgress = false; m_bwdProgress.OverallProgressStep = 1; m_bwdProgress.OverallMessage = "Checking for conflicts..."; if (m_bwdProgress.ShowDialog() == DialogResult.Cancel) m_pfpFormatProvider.Clear(); } }
/// <summary> /// Checks for conflicts with mod-author specified critical records. /// </summary> public void CheckForConflicts() { using (m_bwdProgress = new BackgroundWorkerProgressDialog(CheckForCriticalRecordConflicts)) { m_bwdProgress.ShowItemProgress = false; m_bwdProgress.OverallProgressStep = 1; m_bwdProgress.OverallMessage = "Checking for conflicts..."; if (m_bwdProgress.ShowDialog() == DialogResult.Cancel) { m_pfpFormatProvider.Clear(); } } }
/// <summary> /// Displays the option form and starts the background worker to do the install. /// </summary> /// <returns><lang cref="true"/> if the mod installed correctly; <lang cref="false"/> otherwise.</returns> public bool Install() { XmlDocument xmlConfig = new XmlDocument(); string strConfig = m_misInstallScript.Fomod.GetInstallScript().Text; xmlConfig.LoadXml(strConfig); //remove comments so we don't have to deal with them later XmlNodeList xnlComments = xmlConfig.SelectNodes("//comment()"); foreach (XmlNode xndComment in xnlComments) xndComment.ParentNode.RemoveChild(xndComment); m_dsmStateManager = Program.GameMode.CreateDependencyStateManager(m_misInstallScript); Parser prsParser = Parser.GetParser(xmlConfig, m_misInstallScript.Fomod, m_dsmStateManager); CompositeDependency cpdModDependencies = prsParser.GetModDependencies(); if ((cpdModDependencies != null) && !cpdModDependencies.IsFufilled) throw new DependencyException(cpdModDependencies.Message); IList<InstallStep> lstSteps = prsParser.GetInstallSteps(); HeaderInfo hifHeaderInfo = prsParser.GetHeaderInfo(); OptionsForm ofmOptions = new OptionsForm(this, hifHeaderInfo, m_dsmStateManager, lstSteps); bool booPerformInstall = false; if (lstSteps.Count == 0) booPerformInstall = true; else booPerformInstall = (ofmOptions.ShowDialog() == DialogResult.OK); if (booPerformInstall) { using (m_bwdProgress = new BackgroundWorkerProgressDialog(InstallFiles)) { m_bwdProgress.WorkMethodArguments = new InstallFilesArguments(prsParser, ofmOptions); m_bwdProgress.OverallMessage = "Installing " + hifHeaderInfo.Title; m_bwdProgress.OverallProgressStep = 1; m_bwdProgress.ItemProgressStep = 1; if (m_bwdProgress.ShowDialog() == DialogResult.Cancel) return false; } return true; } return false; }
/// <summary> /// Runs the basic install script. /// </summary> /// <param name="p_strMessage">The message to display in the progress dialog.</param> /// <returns> /// <lang langref="true" /> if the installation was successful; /// <lang langref="false" /> otherwise. /// </returns> protected bool RunBasicInstallScript(string p_strMessage) { try { using (ProgressDialog = new BackgroundWorkerProgressDialog(PerformBasicInstall)) { ProgressDialog.OverallMessage = p_strMessage; ProgressDialog.ShowItemProgress = false; ProgressDialog.OverallProgressStep = 1; if (ProgressDialog.ShowDialog() == DialogResult.Cancel) { return(false); } } } finally { ProgressDialog = null; } return(true); }
/// <summary> /// Runs the basic uninstall script. /// </summary> /// <returns> /// <lang langref="true" /> if the installation was successful; /// <lang langref="false" /> otherwise. /// </returns> protected bool RunBasicUninstallScript() { try { using (m_bwdProgress = new BackgroundWorkerProgressDialog(PerformBasicUninstall)) { m_bwdProgress.OverallMessage = "Uninstalling Fomod"; m_bwdProgress.ItemProgressStep = 1; m_bwdProgress.OverallProgressStep = 1; if (m_bwdProgress.ShowDialog() == DialogResult.Cancel) { return(false); } } } finally { m_bwdProgress = null; } return(true); }
/// <summary> /// Called to perform the upgrade. /// </summary> /// <remarks> /// Sets up the resources required to upgrade the install log, and then /// call <see cref="DoUpgrade()" /> so implementers can do the upgrade. /// </remarks> /// <returns> /// <lang langref="true" /> if the upgrade completed; <lang langref="false" /> /// if the user cancelled. /// </returns> internal bool PerformUpgrade() { FileManager = new TxFileManager(); var booComplete = false; using (var tsTransaction = new TransactionScope()) { FileManager.Snapshot(InstallLog.Current.InstallLogPath); using (ProgressWorker = new BackgroundWorkerProgressDialog(DoUpgrade)) { ProgressWorker.OverallMessage = "Upgrading FOMM Files"; if (ProgressWorker.ShowDialog() == DialogResult.OK) { booComplete = true; tsTransaction.Complete(); } } FileManager = null; } return booComplete; }
/// <summary> /// Handles the <see cref="Control.Click" /> event of the auto-detect button. /// </summary> /// <remarks> /// This launches the auto-detection algorithm on another process using the /// <see cref="BackgroundWorkerProgressDialog" /> class. /// </remarks> /// <param name="sender">The object that raised the event.</param> /// <param name="e">An <see cref="EventArgs" /> describing the event arguments.</param> private void butAutoDetect_Click(object sender, EventArgs e) { using (m_bwdProgress = new BackgroundWorkerProgressDialog(AutoDetectWokringDirectory)) { m_bwdProgress.ShowItemProgress = false; m_bwdProgress.OverallProgressMarquee = true; m_strFoundWorkingDirectory = null; if (m_bwdProgress.ShowDialog(this) == DialogResult.Cancel) { m_strFoundWorkingDirectory = null; } } if (!String.IsNullOrEmpty(m_strFoundWorkingDirectory)) { tbxWorkingDirectory.Text = m_strFoundWorkingDirectory; } else { MessageBox.Show(this, "Could not find Fallout 3.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } }
/// <summary> /// Called to perform the upgrade. /// </summary> /// <remarks> /// Sets up the resources required to upgrade the install log, and then /// call <see cref="DoUpgrade()" /> so implementers can do the upgrade. /// </remarks> /// <returns> /// <lang langref="true" /> if the upgrade completed; <lang langref="false" /> /// if the user cancelled. /// </returns> internal bool PerformUpgrade() { FileManager = new TxFileManager(); var booComplete = false; using (var tsTransaction = new TransactionScope()) { FileManager.Snapshot(InstallLog.Current.InstallLogPath); using (ProgressWorker = new BackgroundWorkerProgressDialog(DoUpgrade)) { ProgressWorker.OverallMessage = "Upgrading FOMM Files"; if (ProgressWorker.ShowDialog() == DialogResult.OK) { booComplete = true; tsTransaction.Complete(); } } FileManager = null; } return(booComplete); }
/// <summary> /// Handles the <see cref="Button.Click" /> event of the extract button. /// </summary> /// <remarks> /// This queries the user for the destinations directory, and then launches the /// background process to extract the fomod. /// </remarks> /// <param name="sender">The object that raised the event.</param> /// <param name="e">An <see cref="EventArgs" /> describing the event arguments.</param> private void butExtractFomod_Click(object sender, EventArgs e) { if (lvModList.SelectedItems.Count != 1) { return; } var fomodMod = (fomod)lvModList.SelectedItems[0].Tag; if (fbdExtractFomod.ShowDialog(this) == DialogResult.OK) { using (m_bwdProgress = new BackgroundWorkerProgressDialog(UnpackFomod)) { var strOutput = Path.Combine(fbdExtractFomod.SelectedPath, Path.GetFileNameWithoutExtension(fomodMod.filepath)); if (!Directory.Exists(strOutput)) { Directory.CreateDirectory(strOutput); } m_bwdProgress.WorkMethodArguments = new Pair <fomod, string>(fomodMod, strOutput); m_bwdProgress.ShowDialog(); } m_bwdProgress = null; } }
/// <summary> /// Runs the basic uninstall script. /// </summary> /// <returns> /// <lang langref="true" /> if the installation was successful; /// <lang langref="false" /> otherwise. /// </returns> protected bool RunBasicUninstallScript() { try { using (m_bwdProgress = new BackgroundWorkerProgressDialog(PerformBasicUninstall)) { m_bwdProgress.OverallMessage = "Uninstalling Fomod"; m_bwdProgress.ItemProgressStep = 1; m_bwdProgress.OverallProgressStep = 1; if (m_bwdProgress.ShowDialog() == DialogResult.Cancel) { return false; } } } finally { m_bwdProgress = null; } return true; }
/// <summary> /// Starts the migration, if necessary. /// </summary> /// <returns> /// <lang langref="false" /> if the migration failed; /// <lang langref="true" /> otherwise. /// </returns> public bool Migrate() { if (Properties.Settings.Default.migratedFromPre0130) { return(true); } var strOldFOMMLocation = (Registry.GetValue( @"HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\Fallout Mod Manager_is1", "InstallLocation", "") ?? "").ToString(); if (String.IsNullOrEmpty(strOldFOMMLocation)) { strOldFOMMLocation = (Registry.GetValue( @"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Fallout Mod Manager_is1", "InstallLocation", "") ?? "").ToString(); } if (String.IsNullOrEmpty(strOldFOMMLocation)) { return(true); } var strMessage = "An older version of the mod manager was detected. Would you like to migrate your mods into the new programme?" + Environment.NewLine + "If you answer \"No\", you will have to manually copy your mods into: " + Environment.NewLine + Program.GameMode.ModDirectory + Environment.NewLine + "You will also have to reinstall the mods, so make sure you deactivate them in the old FOMM first." + Environment.NewLine + "Clicking \"Cancel\" will close the programme so you can deactivate the mods in the old FOMM, if you so choose." + Environment.NewLine + "If you are confused, click \"Yes\"."; switch (MessageBox.Show(strMessage, "Migrate", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question)) { case DialogResult.Cancel: return(false); case DialogResult.No: Properties.Settings.Default.migratedFromPre0130 = true; Properties.Settings.Default.Save(); return(true); } using (var tsTransaction = new TransactionScope()) { using (m_bwdProgress = new BackgroundWorkerProgressDialog(DoMigration)) { m_bwdProgress.OverallProgressMaximum = 3; m_bwdProgress.OverallProgressStep = 1; m_bwdProgress.ItemProgressStep = 1; m_bwdProgress.OverallMessage = "Migrating..."; m_bwdProgress.WorkMethodArguments = strOldFOMMLocation; if (m_bwdProgress.ShowDialog() == DialogResult.Cancel) { return(false); } } tsTransaction.Complete(); } Properties.Settings.Default.migratedFromPre0130 = true; Properties.Settings.Default.Save(); return(true); }
/// <summary> /// Performs an in-place upgrade of the <see cref="fomod" />. /// </summary> protected override bool DoScript() { foreach (var strSettingsFile in Program.GameMode.SettingsFiles.Values) { TransactionalFileManager.Snapshot(strSettingsFile); } foreach (var strAdditionalFile in Program.GameMode.AdditionalPaths.Values) { if (File.Exists(strAdditionalFile)) { TransactionalFileManager.Snapshot(strAdditionalFile); } } TransactionalFileManager.Snapshot(InstallLog.Current.InstallLogPath); var booUpgraded = false; try { MergeModule = new InstallLogMergeModule(); if (Fomod.HasInstallScript) { var fscInstallScript = Fomod.GetInstallScript(); switch (fscInstallScript.Type) { case FomodScriptType.CSharp: booUpgraded = RunCustomInstallScript(); break; case FomodScriptType.XMLConfig: booUpgraded = RunXmlInstallScript(); break; } } else { booUpgraded = RunBasicInstallScript(ProgressMessage); } if (booUpgraded) { using (m_bwdProgress = new BackgroundWorkerProgressDialog(ReconcileDifferences)) { m_bwdProgress.OverallMessage = "Finalizing Upgrade"; m_bwdProgress.ItemProgressStep = 1; m_bwdProgress.OverallProgressStep = 1; if (m_bwdProgress.ShowDialog() == DialogResult.Cancel) { return(false); } } var strOldBaseName = Fomod.BaseName; ((UpgradeFomod)Fomod).SetBaseName(((UpgradeFomod)Fomod).OriginalBaseName); InstallLog.Current.MergeUpgrade(Fomod, strOldBaseName, MergeModule); ((UpgradeFomod)Fomod).SetBaseName(strOldBaseName); Script.CommitActivePlugins(); } } catch (Exception e) { throw e; } m_fomodOriginalMod.IsActive = DetermineFomodActiveStatus(booUpgraded); return(booUpgraded); }
/// <summary> /// Runs the install script. /// </summary> /// <remarks> /// This contains the boilerplate code that needs to be done for all install-type /// scripts. Implementers must override the <see cref="DoScript()" /> method to /// implement their script-specific functionality. /// </remarks> /// <param name="p_booSuppressSuccessMessage"> /// Indicates whether to /// supress the success message. This is useful for batch installs. /// </param> /// <seealso cref="DoScript()" /> protected bool Run(bool p_booSuppressSuccessMessage, bool p_booSetFOModReadOnly) { var booSuccess = false; if (CheckAlreadyDone()) { booSuccess = true; } if (!booSuccess) { try { //the install process modifies INI and config files. // if multiple sources (i.e., installs) try to modify // these files simultaneously the outcome is not well known // (e.g., one install changes SETTING1 in a config file to valueA // while simultaneously another install changes SETTING1 in the // file to value2 - after each install commits its changes it is // not clear what the value of SETTING1 will be). // as a result, we only allow one mod to be installed at a time, // hence the lock. lock (objInstallLock) { using (var tsTransaction = new TransactionScope()) { m_tfmFileManager = new TxFileManager(); using (Script = CreateInstallScript()) { var booCancelled = false; if (p_booSetFOModReadOnly && (Fomod != null)) { if (Fomod.ReadOnlyInitStepCount > 1) { using (m_bwdProgress = new BackgroundWorkerProgressDialog(BeginFOModReadOnlyTransaction)) { m_bwdProgress.OverallMessage = "Preparing FOMod..."; m_bwdProgress.ShowItemProgress = false; m_bwdProgress.OverallProgressMaximum = Fomod.ReadOnlyInitStepCount; m_bwdProgress.OverallProgressStep = 1; try { Fomod.ReadOnlyInitStepStarted += Fomod_ReadOnlyInitStepStarted; Fomod.ReadOnlyInitStepFinished += Fomod_ReadOnlyInitStepFinished; if (m_bwdProgress.ShowDialog() == DialogResult.Cancel) { booCancelled = true; } } finally { Fomod.ReadOnlyInitStepStarted -= Fomod_ReadOnlyInitStepStarted; Fomod.ReadOnlyInitStepFinished -= Fomod_ReadOnlyInitStepFinished; } } } else { Fomod.BeginReadOnlyTransaction(); } } if (!booCancelled) { booSuccess = DoScript(); if (booSuccess) { tsTransaction.Complete(); } } } } } } catch (Exception e) { var stbError = new StringBuilder(e.Message); if (e is FileNotFoundException) { stbError.Append(" (" + ((FileNotFoundException) e).FileName + ")"); } if (e is IllegalFilePathException) { stbError.Append(" (" + ((IllegalFilePathException) e).Path + ")"); } if (e.InnerException != null) { stbError.AppendLine().AppendLine(e.InnerException.Message); } if (e is RollbackException) { foreach (var erm in ((RollbackException) e).ExceptedResourceManagers) { stbError.AppendLine(erm.ResourceManager.ToString()); stbError.AppendLine(erm.Exception.Message); if (erm.Exception.InnerException != null) { stbError.AppendLine(erm.Exception.InnerException.Message); } } } var strMessage = String.Format(ExceptionMessage, stbError); MessageBox.Show(strMessage, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return false; } finally { m_tfmFileManager = null; m_ilmModInstallLog = null; if (Fomod != null) { Fomod.EndReadOnlyTransaction(); } } } if (booSuccess && !p_booSuppressSuccessMessage && !String.IsNullOrEmpty(SuccessMessage)) { MessageBox.Show(SuccessMessage, "Success", MessageBoxButtons.OK, MessageBoxIcon.Information); } else if (!booSuccess && !String.IsNullOrEmpty(FailMessage)) { MessageBox.Show(FailMessage, "Failure", MessageBoxButtons.OK, MessageBoxIcon.Error); } return booSuccess; }
/// <summary> /// Handles the <see cref="Control.Click" /> event of the auto-detect button. /// </summary> /// <remarks> /// This launches the auto-detection algorithm on another process using the /// <see cref="BackgroundWorkerProgressDialog" /> class. /// </remarks> /// <param name="sender">The object that raised the event.</param> /// <param name="e">An <see cref="EventArgs" /> describing the event arguments.</param> private void butAutoDetect_Click(object sender, EventArgs e) { using (m_bwdProgress = new BackgroundWorkerProgressDialog(AutoDetectWokringDirectory)) { m_bwdProgress.ShowItemProgress = false; m_bwdProgress.OverallProgressMarquee = true; m_strFoundWorkingDirectory = null; if (m_bwdProgress.ShowDialog(this) == DialogResult.Cancel) { m_strFoundWorkingDirectory = null; } } if (!String.IsNullOrEmpty(m_strFoundWorkingDirectory)) { tbxWorkingDirectory.Text = m_strFoundWorkingDirectory; } else { MessageBox.Show(this, "Could not find Fallout 3.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } }
/// <summary> /// Starts the migration, if necessary. /// </summary> /// <returns><lang cref="false"/> if the migration failed; /// <lang cref="true"/> otherwise.</returns> public bool Migrate() { if (Properties.Settings.Default.migratedFromPre0130) return true; #if TRACE Trace.WriteLine("Check for old FOMM to migrate from..."); Trace.Indent(); #endif string strOldFOMMLocation = (Registry.GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\Fallout Mod Manager_is1", "InstallLocation", "") ?? "").ToString(); #if TRACE Trace.WriteLine("First guess: " + strOldFOMMLocation); #endif if (String.IsNullOrEmpty(strOldFOMMLocation)) { strOldFOMMLocation = (Registry.GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Fallout Mod Manager_is1", "InstallLocation", "") ?? "").ToString(); #if TRACE Trace.WriteLine("Second guess: " + strOldFOMMLocation); #endif } if (String.IsNullOrEmpty(strOldFOMMLocation)) { #if TRACE Trace.WriteLine("No need to migrate"); Trace.Unindent(); #endif return true; } string strMessage = "An older version of the mod manager was detected. Would you like to migrate your mods into the new programme?" + Environment.NewLine + "If you answer \"No\", you will have to manually copy your mods into: " + Environment.NewLine + Program.GameMode.ModDirectory + Environment.NewLine + "You will also have to reinstall the mods, so make sure you deactivate them in the old FOMM first." + Environment.NewLine + "Clicking \"Cancel\" will close the programme so you can deactivate the mods in the old FOMM, if you so choose." + Environment.NewLine + "If you are confused, click \"Yes\"."; switch (MessageBox.Show(strMessage, "Migrate", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question)) { case DialogResult.Cancel: return false; case DialogResult.No: Properties.Settings.Default.migratedFromPre0130 = true; Properties.Settings.Default.Save(); return true; } using (TransactionScope tsTransaction = new TransactionScope()) { using (m_bwdProgress = new BackgroundWorkerProgressDialog(DoMigration)) { m_bwdProgress.OverallProgressMaximum = 3; m_bwdProgress.OverallProgressStep = 1; m_bwdProgress.ItemProgressStep = 1; m_bwdProgress.OverallMessage = "Migrating..."; m_bwdProgress.WorkMethodArguments = strOldFOMMLocation; if (m_bwdProgress.ShowDialog() == DialogResult.Cancel) return false; } tsTransaction.Complete(); } Properties.Settings.Default.migratedFromPre0130 = true; Properties.Settings.Default.Save(); return true; }
/// <summary> /// Runs the install script. /// </summary> /// <remarks> /// This contains the boilerplate code that needs to be done for all install-type /// scripts. Implementers must override the <see cref="DoScript()" /> method to /// implement their script-specific functionality. /// </remarks> /// <param name="p_booSuppressSuccessMessage"> /// Indicates whether to /// supress the success message. This is useful for batch installs. /// </param> /// <seealso cref="DoScript()" /> protected bool Run(bool p_booSuppressSuccessMessage, bool p_booSetFOModReadOnly) { var booSuccess = false; if (CheckAlreadyDone()) { booSuccess = true; } if (!booSuccess) { try { //the install process modifies INI and config files. // if multiple sources (i.e., installs) try to modify // these files simultaneously the outcome is not well known // (e.g., one install changes SETTING1 in a config file to valueA // while simultaneously another install changes SETTING1 in the // file to value2 - after each install commits its changes it is // not clear what the value of SETTING1 will be). // as a result, we only allow one mod to be installed at a time, // hence the lock. lock (objInstallLock) { using (var tsTransaction = new TransactionScope()) { m_tfmFileManager = new TxFileManager(); using (Script = CreateInstallScript()) { var booCancelled = false; if (p_booSetFOModReadOnly && (Fomod != null)) { if (Fomod.ReadOnlyInitStepCount > 1) { using (m_bwdProgress = new BackgroundWorkerProgressDialog(BeginFOModReadOnlyTransaction)) { m_bwdProgress.OverallMessage = "Preparing FOMod..."; m_bwdProgress.ShowItemProgress = false; m_bwdProgress.OverallProgressMaximum = Fomod.ReadOnlyInitStepCount; m_bwdProgress.OverallProgressStep = 1; try { Fomod.ReadOnlyInitStepStarted += Fomod_ReadOnlyInitStepStarted; Fomod.ReadOnlyInitStepFinished += Fomod_ReadOnlyInitStepFinished; if (m_bwdProgress.ShowDialog() == DialogResult.Cancel) { booCancelled = true; } } finally { Fomod.ReadOnlyInitStepStarted -= Fomod_ReadOnlyInitStepStarted; Fomod.ReadOnlyInitStepFinished -= Fomod_ReadOnlyInitStepFinished; } } } else { Fomod.BeginReadOnlyTransaction(); } } if (!booCancelled) { booSuccess = DoScript(); if (booSuccess) { tsTransaction.Complete(); } } } } } } catch (Exception e) { var stbError = new StringBuilder(e.Message); if (e is FileNotFoundException) { stbError.Append(" (" + ((FileNotFoundException)e).FileName + ")"); } if (e is IllegalFilePathException) { stbError.Append(" (" + ((IllegalFilePathException)e).Path + ")"); } if (e.InnerException != null) { stbError.AppendLine().AppendLine(e.InnerException.Message); } if (e is RollbackException) { foreach (var erm in ((RollbackException)e).ExceptedResourceManagers) { stbError.AppendLine(erm.ResourceManager.ToString()); stbError.AppendLine(erm.Exception.Message); if (erm.Exception.InnerException != null) { stbError.AppendLine(erm.Exception.InnerException.Message); } } } var strMessage = String.Format(ExceptionMessage, stbError); MessageBox.Show(strMessage, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return(false); } finally { m_tfmFileManager = null; m_ilmModInstallLog = null; if (Fomod != null) { Fomod.EndReadOnlyTransaction(); } } } if (booSuccess && !p_booSuppressSuccessMessage && !String.IsNullOrEmpty(SuccessMessage)) { MessageBox.Show(SuccessMessage, "Success", MessageBoxButtons.OK, MessageBoxIcon.Information); } else if (!booSuccess && !String.IsNullOrEmpty(FailMessage)) { MessageBox.Show(FailMessage, "Failure", MessageBoxButtons.OK, MessageBoxIcon.Error); } return(booSuccess); }
/// <summary> /// This starts the <see cref="BackgroundWorkerProgressDialog" /> to build the fomod. /// </summary> /// <remarks> /// This method is called by implementers of this abstract class to instantiate the /// <see cref="BackgroundWorkerProgressDialog" /> that will be used to generate the fomod. The /// <see cref="BackgroundWorkerProgressDialog" /> calls <see cref="DoGenerateFomod(object)" />, /// which must be overridden in the implementer, to actually do the work. /// </remarks> /// <param name="p_gfaArgs"> /// The arguments to pass the the <see cref="DoGenerateFomod(object)" /> /// method. /// </param> /// <returns>The atual path of the generated fomod.</returns> protected string GenerateFomod(GenerateFomodArgs p_gfaArgs) { var strPackedPath = p_gfaArgs.PackedPath; if (!CheckFileName(ref strPackedPath)) { return null; } p_gfaArgs.PackedPath = strPackedPath; try { using (ProgressDialog = new BackgroundWorkerProgressDialog(DoGenerateFomod)) { ProgressDialog.OverallMessage = OverallProgressMessage; ProgressDialog.ShowItemProgress = true; ProgressDialog.OverallProgressStep = 1; ProgressDialog.WorkMethodArguments = p_gfaArgs; if (ProgressDialog.ShowDialog() == DialogResult.Cancel) { FileUtil.ForceDelete(strPackedPath); return null; } } } finally { foreach (var strFolder in m_lltTempFolders) { FileUtil.ForceDelete(strFolder); } } return strPackedPath; }
/// <summary> /// Called to perform the upgrade. /// </summary> /// <remarks> /// Sets up the resources required to upgrade the install log, and then /// call <see cref="DoUpgrade()"/> so implementers can do the upgrade. /// </remarks> /// <returns><lang cref="true"/> if the upgrade completed; <lang cref="false"/> /// if the user cancelled.</returns> internal bool PerformUpgrade() { #if TRACE Trace.WriteLine("Beginning Install Log Upgrade."); #endif m_tfmFileManager = new TxFileManager(); bool booComplete = false; using (TransactionScope tsTransaction = new TransactionScope()) { m_tfmFileManager.Snapshot(InstallLog.Current.InstallLogPath); using (m_pgdProgress = new BackgroundWorkerProgressDialog(DoUpgrade)) { m_pgdProgress.OverallMessage = "Upgrading FOMM Files"; if (m_pgdProgress.ShowDialog() == DialogResult.OK) { booComplete = true; tsTransaction.Complete(); } } m_tfmFileManager = null; } return booComplete; }
/// <summary> /// Performs an in-place upgrade of the <see cref="fomod" />. /// </summary> protected override bool DoScript() { foreach (var strSettingsFile in Program.GameMode.SettingsFiles.Values) { TransactionalFileManager.Snapshot(strSettingsFile); } foreach (var strAdditionalFile in Program.GameMode.AdditionalPaths.Values) { if (File.Exists(strAdditionalFile)) { TransactionalFileManager.Snapshot(strAdditionalFile); } } TransactionalFileManager.Snapshot(InstallLog.Current.InstallLogPath); var booUpgraded = false; try { MergeModule = new InstallLogMergeModule(); if (Fomod.HasInstallScript) { var fscInstallScript = Fomod.GetInstallScript(); switch (fscInstallScript.Type) { case FomodScriptType.CSharp: booUpgraded = RunCustomInstallScript(); break; case FomodScriptType.XMLConfig: booUpgraded = RunXmlInstallScript(); break; } } else { booUpgraded = RunBasicInstallScript(ProgressMessage); } if (booUpgraded) { using (m_bwdProgress = new BackgroundWorkerProgressDialog(ReconcileDifferences)) { m_bwdProgress.OverallMessage = "Finalizing Upgrade"; m_bwdProgress.ItemProgressStep = 1; m_bwdProgress.OverallProgressStep = 1; if (m_bwdProgress.ShowDialog() == DialogResult.Cancel) { return false; } } var strOldBaseName = Fomod.BaseName; ((UpgradeFomod) Fomod).SetBaseName(((UpgradeFomod) Fomod).OriginalBaseName); InstallLog.Current.MergeUpgrade(Fomod, strOldBaseName, MergeModule); ((UpgradeFomod) Fomod).SetBaseName(strOldBaseName); Script.CommitActivePlugins(); } } catch (Exception e) { throw e; } m_fomodOriginalMod.IsActive = DetermineFomodActiveStatus(booUpgraded); return booUpgraded; }
/// <summary> /// Runs the basic install script. /// </summary> /// <param name="p_strMessage">The message to display in the progress dialog.</param> /// <returns> /// <lang langref="true" /> if the installation was successful; /// <lang langref="false" /> otherwise. /// </returns> protected bool RunBasicInstallScript(string p_strMessage) { try { using (ProgressDialog = new BackgroundWorkerProgressDialog(PerformBasicInstall)) { ProgressDialog.OverallMessage = p_strMessage; ProgressDialog.ShowItemProgress = false; ProgressDialog.OverallProgressStep = 1; if (ProgressDialog.ShowDialog() == DialogResult.Cancel) { return false; } } } finally { ProgressDialog = null; } return true; }
/// <summary> /// Handles the <see cref="Button.Click"/> event of the extract button. /// </summary> /// <remarks> /// This queries the user for the destinations directory, and then launches the /// background process to extract the fomod. /// </remarks> /// <param name="sender">The object that raised the event.</param> /// <param name="e">An <see cref="EventArgs"/> describing the event arguments.</param> private void butExtractFomod_Click(object sender, EventArgs e) { if (lvModList.SelectedItems.Count != 1) return; fomod fomodMod = (fomod)lvModList.SelectedItems[0].Tag; if (fbdExtractFomod.ShowDialog(this) == DialogResult.OK) { using (m_bwdProgress = new BackgroundWorkerProgressDialog(UnpackFomod)) { string strOutput = Path.Combine(fbdExtractFomod.SelectedPath, Path.GetFileNameWithoutExtension(fomodMod.filepath)); if (!Directory.Exists(strOutput)) Directory.CreateDirectory(strOutput); m_bwdProgress.WorkMethodArguments = new Pair<fomod, string>(fomodMod, strOutput); m_bwdProgress.ShowDialog(); } m_bwdProgress = null; } }