using System; using System.Collections; using System.Collections.Specialized; using System.ComponentModel; using System.Data; using System.Drawing; using System.IO; using System.Globalization; using System.Threading; using System.Windows.Forms; using HakInstaller.Utilities; using NWN; namespace HakInstaller { /// /// Summary description for InstallFormBase. /// public class InstallFormBase: Form { #region public properties/methods /// /// Default constructur /// public InstallFormBase() { // Wire up event handlers Load += new EventHandler(InstallFormBase_Load); } #endregion #region protected fields/properties/methods /// /// Sets the proper values for the string labels. /// /// The version string /// The path string protected void SetLabels(Label labelVersion, Label labelPath) { // Load strings for XP1 and XP2 installed if they are otherwise use // nothing. string xp1 = NWNInfo.IsXP1Installed ? StringResources.GetString("VersionFormatXP1") : string.Empty; string xp2 = NWNInfo.IsXP1Installed ? StringResources.GetString("VersionFormatXP2") : string.Empty; labelVersion.Text = StringResources.GetString("VersionFormat", NWNInfo.Version, xp1, xp2); labelPath.Text = StringResources.GetString("PathFormat", NWNInfo.InstallPath); } /// /// Loads all of the hack info files into the hak check list box. /// protected void LoadHakInfoList(CheckedListBox checkedHaks) { // Get all of the modules in the module directory and add them to // the list box. string[] haks = Directory.GetFiles(NWNInfo.GetPathForFile("foo.hif"), "*.hif"); foreach (string hak in haks) { // Load the HIF now and perform validation before adding it to the // list of HIFs. HakInfo hif = new HakInfo(hak); string error; if (hif.Validate(out error)) checkedHaks.Items.Add(hif); else MessageBox.Show(error, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } if (0 == checkedHaks.Items.Count) { MessageBox.Show(StringResources.GetString("NoHIFS"), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); Close(); Hide(); Application.Exit(); } } /// /// Loads all of the modules in the NWN modules directory into the module /// check list box. /// protected void LoadModuleList(CheckedListBox checkedModules) { // Turn sorting on so all of the user modules get added alphabetically checkedModules.Sorted = true; // Get all of the modules in the module directory and add them to // the list box. string[] modules = Directory.GetFiles(NWNInfo.ModulesPath, "*.mod"); foreach (string module in modules) { checkedModules.Items.Add(new Module(Path.GetFileName(module))); } // Turn off sorting so we can add the OC/XP1/XP2 at the top. checkedModules.Sorted = false; // Add the OC/XP1/XP2 modules if appropriate. if (NWNInfo.IsXP2ModsInstalled) checkedModules.Items.Insert(0, new Module(StringResources.GetString("XP2Name"), NWNInfo.XP2Modules)); if (NWNInfo.IsXP1ModsInstalled) checkedModules.Items.Insert(0, new Module(StringResources.GetString("XP1Name"), NWNInfo.XP1Modules)); if (NWNInfo.IsOCModsInstalled) checkedModules.Items.Insert(0, new Module(StringResources.GetString("OCName"), NWNInfo.OCModules)); } /// /// Checks the modules to see if any of the specified hifs are installed already, /// if they are it prompts the user to see if we should continue. /// /// The list of hifs /// The list of modules /// True if the user cancels the operation, false if they do not protected bool CheckForHifConflicts(HakInfo[] hifs, string[] modules) { // Get the list of conflicts if there aren't any then just return false. HifConflictCollection conflicts = HakInstaller.CheckInstalledHifs(hifs, modules); if (null == conflicts) return false; // There are conflicts, prompt the user for what to do. HifConflictsForm form = new HifConflictsForm(conflicts); return DialogResult.Cancel == form.ShowDialog(this); } private void InitializeComponent() { // // InstallFormBase // this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); this.ClientSize = new System.Drawing.Size(292, 266); this.Name = "InstallFormBase"; this.Load += new System.EventHandler(this.InstallFormBase_Load); } /// /// Handler for the install button click event. It installs the selected /// haks in the selected modules. /// /// /// public void PerformInstall(HakInfo[] hifs, string[] modules) { try { // Before starting check for hif conflicts and ask the user if they really want to // continue. if (CheckForHifConflicts(hifs, modules)) return; // Create a progress control, InstallProgressForm progress = new InstallProgressForm(); ThreadPool.QueueUserWorkItem(new WaitCallback(DoHakInstall), new InstallInfo(hifs, modules, progress)); progress.ShowDialog(this); } finally { } } #endregion #region private nested classes private class InstallInfo { #region public properties/methods /// /// Gets the list of haks to add. /// public HakInfo[] Hifs { get { return hifs; } } /// /// Gets the list of modules to add haks to. /// public string[] Modules { get { return modules; } } /// /// Gets the object used to display progress information. /// public InstallProgressForm Progress { get { return progress; } } /// /// Class constructor /// /// The list of haks to add /// The list of modules to add haks to /// The object used to show progress public InstallInfo(HakInfo[] hifs, string[]modules, InstallProgressForm progress) { this.hifs = hifs; this.modules = modules; this.progress = progress; } #endregion #region private fields/properties/methods private InstallProgressForm progress; private HakInfo[] hifs; private string[] modules; #endregion } #endregion #region private fields/properties/methods private SystemMenu systemMenu; /// /// This function performs the install of the haks into the modules. It is /// intended to be called in a background thread using the thread pool, allowing /// a progress dialog to be displayed to the user while the work is being done. /// /// InstallInfo object containing the install data. protected void DoHakInstall(object o) { // Force the thread to use the invariant culture to make the install // code work on foreign language versions of windows. Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture; // Do the hak install and when we're done close the progress form. InstallInfo info = (InstallInfo) o; try { // The OC/XP1/XP2 files can be marked as read only, so we have to undo that // for all modules in the list. foreach (string module in info.Modules) { string file = NWNInfo.GetFullFilePath(module); FileAttributes attrs = File.GetAttributes(file); attrs &= ~FileAttributes.ReadOnly; File.SetAttributes(file, attrs); } HakInstaller.InstallHaks(info.Hifs, info.Modules, info.Progress); } catch(Exception e) { MessageBox.Show(info.Progress, e.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } finally { info.Progress.Close(); // Reset any .nwm files back to read only to leave them as we found them, // in case the engine wants them marked read only. foreach (string module in info.Modules) { if (0 == string.Compare(".nwm", Path.GetExtension(module), true, CultureInfo.InvariantCulture)) { string file = NWNInfo.GetFullFilePath(module); FileAttributes attrs = File.GetAttributes(file); attrs |= FileAttributes.ReadOnly; File.SetAttributes(file, attrs); } } } } #endregion #region menu handlers /// /// Event handler for the system menu About menu item. /// /// /// private void OnAbout(object sender, EventArgs args) { AboutForm form = new AboutForm(); form.ShowDialog(this); } #endregion #region form event handlers /// /// Event handler for the forms' load event, it wires up our system menu items. Doing /// these in the constructor breaks CenterWindow. /// /// /// private void InstallFormBase_Load(object sender, System.EventArgs e) { systemMenu = new SystemMenu(this); SystemMenuItem item = new SystemMenuItem("-", systemMenu); systemMenu.Add(item); item = new SystemMenuItem("&About", systemMenu); item.Click += new EventHandler(OnAbout); systemMenu.Add(item); } #endregion } /// /// This object defines a 'module' that is displayed in the right checked list box in /// the form. For most modules it refers to a single module, but for the bioware modules /// it refers to a group of modules. /// public class Module { #region public properties/methods /// /// Gets the name of the module object, this is the text that should be /// displayed to the user. /// public string Name { get { return name; } } /// /// Gets the list of modules that make up this module object. /// public string[] Modules { get { return modules; } } /// /// Constructor to create a module object for a single module on disk. /// /// The module public Module(string module) { name = Path.GetFileNameWithoutExtension(module); modules = new string[] { module }; } /// /// Constructor to create a module object for a collection of modules /// /// The display name for the collection /// The list of modules. public Module(string name, string[] modules) { this.name = name; this.modules = modules; } /// /// Override of ToString() to use the Name property. /// /// public override string ToString() { return Name; } #endregion #region private fields/properties/methods string name; private string[] modules; #endregion } }