/// <summary> /// This executes the install script. /// </summary> /// <param name="p_tfmFileManager">The transactional file manager to use to interact with the file system.</param> /// <returns><c>true</c> if the script completed successfully; /// <c>false</c> otherwise.</returns> protected bool RunScript(TxFileManager p_tfmFileManager) { IModFileInstaller mfiFileInstaller = CreateFileInstaller(p_tfmFileManager, m_dlgOverwriteConfirmationDelegate); bool booResult = false; if (Mod.HasInstallScript) { IDataFileUtil dfuDataFileUtility = new DataFileUtil(GameMode.GameModeEnvironmentInfo.InstallationPath); IIniInstaller iniIniInstaller = CreateIniInstaller(p_tfmFileManager, m_dlgOverwriteConfirmationDelegate); IGameSpecificValueInstaller gviGameSpecificValueInstaller = CreateGameSpecificValueInstaller(p_tfmFileManager, m_dlgOverwriteConfirmationDelegate); InstallerGroup ipgInstallers = new InstallerGroup(dfuDataFileUtility, mfiFileInstaller, iniIniInstaller, gviGameSpecificValueInstaller, PluginManager); IScriptExecutor sexScript = Mod.InstallScript.Type.CreateExecutor(Mod, GameMode, EnvironmentInfo, ipgInstallers, UIContext); sexScript.TaskStarted += new EventHandler <EventArgs <IBackgroundTask> >(ScriptExecutor_TaskStarted); sexScript.TaskSetCompleted += new EventHandler <TaskSetCompletedEventArgs>(ScriptExecutor_TaskSetCompleted); booResult = sexScript.Execute(Mod.InstallScript); iniIniInstaller.FinalizeInstall(); if (gviGameSpecificValueInstaller != null) { gviGameSpecificValueInstaller.FinalizeInstall(); } } else { booResult = RunBasicInstallScript(mfiFileInstaller, ActiveMods); } mfiFileInstaller.FinalizeInstall(); return(booResult); }
/// <summary> /// Runs the basic uninstall script. /// </summary> /// <remarks> /// A basic uninstall uninstalls all of the changes made when the mod was installed. /// </remarks> /// <param name="p_tfmFileManager">The transactional file manager to use to interact with the file system.</param> /// <returns><c>true</c> if the uninstallation was successful; /// <c>false</c> otherwise.</returns> protected bool RunBasicUninstallScript(TxFileManager p_tfmFileManager, out string p_strErrorMessage) { p_strErrorMessage = null; IDataFileUtil dfuDataFileUtility = new DataFileUtil(GameMode.GameModeEnvironmentInfo.InstallationPath); IModFileInstaller mfiFileInstaller = new ModFileInstaller(GameMode.GameModeEnvironmentInfo, Mod, ModInstallLog, PluginManager, dfuDataFileUtility, p_tfmFileManager, null, GameMode.UsesPlugins, m_mmModManager); IIniInstaller iniIniInstaller = new IniInstaller(Mod, ModInstallLog, p_tfmFileManager, null); IGameSpecificValueInstaller gviGameSpecificValueInstaller = GameMode.GetGameSpecificValueInstaller(Mod, ModInstallLog, p_tfmFileManager, new NexusFileUtil(EnvironmentInfo), null); InstallerGroup ipgInstallers = new InstallerGroup(dfuDataFileUtility, mfiFileInstaller, iniIniInstaller, gviGameSpecificValueInstaller, PluginManager); BasicUninstallTask butTask = new BasicUninstallTask(Mod, ipgInstallers, ModInstallLog, GameMode, ActiveMods); OnTaskStarted(butTask); bool booResult = butTask.Execute(); if (mfiFileInstaller.InstallErrors.Count > 0) { p_strErrorMessage = Environment.NewLine + "The manager was unable to remove these files:" + Environment.NewLine; foreach (string strPath in mfiFileInstaller.InstallErrors) { p_strErrorMessage += strPath + Environment.NewLine; } } mfiFileInstaller.FinalizeInstall(); iniIniInstaller.FinalizeInstall(); if (gviGameSpecificValueInstaller != null) { gviGameSpecificValueInstaller.FinalizeInstall(); } return(booResult); }
/// <summary> /// A simple constructor that initializes the object with the given values. /// </summary> /// <param name="p_modMod">The mod being installed.</param> /// <param name="p_igpInstallers">The utility class to use to install the mod items.</param> /// <param name="p_ilgModInstallLog">The install log that tracks mod install info /// for the current game mode</param> /// <param name="p_gmdGameMode">The the current game mode.</param> /// <param name="p_rolActiveMods">The list of active mods.</param> public BasicUninstallTask(IMod p_modMod, InstallerGroup p_igpInstallers, IInstallLog p_ilgModInstallLog, IGameMode p_gmdGameMode, ReadOnlyObservableList <IMod> p_rolActiveMods) { Mod = p_modMod; Installers = p_igpInstallers; ModInstallLog = p_ilgModInstallLog; GameMode = p_gmdGameMode; ActiveMods = p_rolActiveMods; }
/// <summary> /// A simple constructor that initializes the object with the given values. /// </summary> /// <param name="p_modMod">The mod being installed.</param> /// <param name="p_igpInstallers">The utility class to use to install the mod items.</param> /// <param name="p_ilgModInstallLog">The install log that tracks mod install info /// for the current game mode</param> /// <param name="p_gmdGameMode">The the current game mode.</param> /// <param name="p_rolActiveMods">The list of active mods.</param> public BasicUninstallTask(IMod p_modMod, InstallerGroup p_igpInstallers, IInstallLog p_ilgModInstallLog, IGameMode p_gmdGameMode, ReadOnlyObservableList<IMod> p_rolActiveMods) { Mod = p_modMod; Installers = p_igpInstallers; ModInstallLog = p_ilgModInstallLog; GameMode = p_gmdGameMode; ActiveMods = p_rolActiveMods; }
/// <summary> /// This executes the install script. /// </summary> /// <param name="p_tfmFileManager">The transactional file manager to use to interact with the file system.</param> /// <returns><c>true</c> if the script completed successfully; /// <c>false</c> otherwise.</returns> protected bool RunScript(TxFileManager p_tfmFileManager) { IModFileInstaller mfiFileInstaller = CreateFileInstaller(p_tfmFileManager, m_dlgOverwriteConfirmationDelegate); bool booResult = false; IIniInstaller iniIniInstaller = null; IGameSpecificValueInstaller gviGameSpecificValueInstaller = null; if (Mod.HasInstallScript) { if (CheckScriptedModLog()) { booResult = RunBasicInstallScript(mfiFileInstaller, ActiveMods, LoadXMLModFilesToInstall()); } else { try { IDataFileUtil dfuDataFileUtility = new DataFileUtil(GameMode.GameModeEnvironmentInfo.InstallationPath); iniIniInstaller = CreateIniInstaller(p_tfmFileManager, m_dlgOverwriteConfirmationDelegate); gviGameSpecificValueInstaller = CreateGameSpecificValueInstaller(p_tfmFileManager, m_dlgOverwriteConfirmationDelegate); InstallerGroup ipgInstallers = new InstallerGroup(dfuDataFileUtility, mfiFileInstaller, iniIniInstaller, gviGameSpecificValueInstaller, PluginManager); IScriptExecutor sexScript = Mod.InstallScript.Type.CreateExecutor(Mod, GameMode, EnvironmentInfo, VirtualModActivator, ipgInstallers, UIContext); sexScript.TaskStarted += new EventHandler <EventArgs <IBackgroundTask> >(ScriptExecutor_TaskStarted); sexScript.TaskSetCompleted += new EventHandler <TaskSetCompletedEventArgs>(ScriptExecutor_TaskSetCompleted); booResult = sexScript.Execute(Mod.InstallScript); } catch (Exception ex) { PopupErrorMessage = ex.Message; PopupErrorMessageType = "Error"; } iniIniInstaller.FinalizeInstall(); if (gviGameSpecificValueInstaller != null) { gviGameSpecificValueInstaller.FinalizeInstall(); } } } else { booResult = RunBasicInstallScript(mfiFileInstaller, ActiveMods, null); } mfiFileInstaller.FinalizeInstall(); return(booResult); }
/// <summary> /// Runs the basic uninstall script. /// </summary> /// <remarks> /// A basic uninstall uninstalls all of the changes made when the mod was installed. /// </remarks> /// <param name="p_tfmFileManager">The transactional file manager to use to interact with the file system.</param> /// <returns><c>true</c> if the uninstallation was successful; /// <c>false</c> otherwise.</returns> protected bool RunBasicUninstallScript(TxFileManager p_tfmFileManager, out string p_strErrorMessage) { p_strErrorMessage = null; IDataFileUtil dfuDataFileUtility = new DataFileUtil(GameMode.GameModeEnvironmentInfo.InstallationPath); IModFileInstaller mfiFileInstaller = new ModFileInstaller(GameMode.GameModeEnvironmentInfo, Mod, ModInstallLog, PluginManager, dfuDataFileUtility, p_tfmFileManager, null, GameMode.UsesPlugins, EnvironmentInfo); IIniInstaller iniIniInstaller = new IniInstaller(Mod, ModInstallLog, VirtualModActivator, p_tfmFileManager, null); IGameSpecificValueInstaller gviGameSpecificValueInstaller = GameMode.GetGameSpecificValueInstaller(Mod, ModInstallLog, p_tfmFileManager, new NexusFileUtil(EnvironmentInfo), null); InstallerGroup ipgInstallers = new InstallerGroup(dfuDataFileUtility, mfiFileInstaller, iniIniInstaller, gviGameSpecificValueInstaller, PluginManager); BasicUninstallTask butTask = new BasicUninstallTask(Mod, VirtualModActivator, ipgInstallers, ModInstallLog, GameMode, ActiveMods); OnTaskStarted(butTask); bool booResult = butTask.Execute(); if (mfiFileInstaller.InstallErrors.Count > 0) { p_strErrorMessage = Environment.NewLine + "There were issues while installing/uninstalling this mod:" + Environment.NewLine; foreach (string strPath in mfiFileInstaller.InstallErrors) { DetailsErrorMessage += strPath + Environment.NewLine; } PopupErrorMessage = p_strErrorMessage; PopupErrorMessageType = butTask.strPopupErrorMessageType; } mfiFileInstaller.FinalizeInstall(); iniIniInstaller.FinalizeInstall(); if (gviGameSpecificValueInstaller != null) { gviGameSpecificValueInstaller.FinalizeInstall(); } return(booResult); }
/// <summary> /// Returns a proxy that implements the functions available to C# scripts. /// </summary> /// <param name="p_modMod">The mod being installed.</param> /// <param name="p_gmdGameMode">The game mode currently bieng managed.</param> /// <param name="p_eifEnvironmentInfo">The application's envrionment info.</param> /// <param name="p_igpInstallers">The utility class to use to install the mod items.</param> /// <param name="p_scxUIContext">The <see cref="SynchronizationContext"/> to use to marshall UI interactions to the UI thread.</param> /// <returns>A proxy that implements the functions available to C# scripts.</returns> protected override CSharpScriptFunctionProxy GetScriptFunctionProxy(IMod p_modMod, IGameMode p_gmdGameMode, IEnvironmentInfo p_eifEnvironmentInfo, InstallerGroup p_igpInstallers, SynchronizationContext p_scxUIContext) { BsaManager bmgBsaManager = new BsaManager((SkyrimGameMode)p_gmdGameMode); UIUtil uitUiUtilities = new UIUtil(p_gmdGameMode, p_eifEnvironmentInfo, p_scxUIContext); return new SkyrimCSharpScriptFunctionProxy(p_modMod, p_gmdGameMode, p_eifEnvironmentInfo, p_igpInstallers, bmgBsaManager, uitUiUtilities); }
/// <summary> /// A simple constructor that initializes the object with the given values. /// </summary> /// <param name="p_modMod">The mod for which the script is running.</param> /// <param name="p_gmdGameMode">The game mode currently being managed.</param> /// <param name="p_eifEnvironmentInfo">The application's envrionment info.</param> /// <param name="p_igpInstallers">The utility class to use to install the mod items.</param> /// <param name="p_uipUIProxy">The UI manager to use to interact with UI elements.</param> public WoTModScriptFunctionProxy(IMod p_modMod, IGameMode p_gmdGameMode, IEnvironmentInfo p_eifEnvironmentInfo, InstallerGroup p_igpInstallers, ModScriptUIUtil p_uipUIProxy) : base(p_modMod, p_gmdGameMode, p_eifEnvironmentInfo, p_igpInstallers, p_uipUIProxy) { }
/// <summary> /// Returns a proxy that implements the functions available to Mod Script scripts. /// </summary> /// <param name="p_modMod">The mod being installed.</param> /// <param name="p_gmdGameMode">The game mode currently bieng managed.</param> /// <param name="p_eifEnvironmentInfo">The application's envrionment info.</param> /// <param name="p_igpInstallers">The utility class to use to install the mod items.</param> /// <param name="p_scxUIContext">The <see cref="SynchronizationContext"/> to use to marshall UI interactions to the UI thread.</param> /// <returns>A proxy that implements the functions available to Mod Script scripts.</returns> protected override ModScriptFunctionProxy GetScriptFunctionProxy(IMod p_modMod, IGameMode p_gmdGameMode, IEnvironmentInfo p_eifEnvironmentInfo, InstallerGroup p_igpInstallers, SynchronizationContext p_scxUIContext) { return new WoTModScriptFunctionProxy(p_modMod, p_gmdGameMode, p_eifEnvironmentInfo, p_igpInstallers, new ModScriptUIUtil(p_gmdGameMode, p_eifEnvironmentInfo, p_scxUIContext)); }
/// <summary> /// A simple constructor that initialies the object with the given values. /// </summary> /// <param name="p_modMod">The mod for which the script is running.</param> /// <param name="p_gmdGameMode">The game mode currently being managed.</param> /// <param name="p_eifEnvironmentInfo">The application's envrionment info.</param> /// <param name="p_igpInstallers">The utility class to use to install the mod items.</param> /// <param name="p_bamBsaManager">The manager to use to work with BSA files.</param> /// <param name="p_uipUIProxy">The UI manager to use to interact with UI elements.</param> public FalloutNVCSharpScriptFunctionProxy(IMod p_modMod, IGameMode p_gmdGameMode, IEnvironmentInfo p_eifEnvironmentInfo, InstallerGroup p_igpInstallers, BsaManager p_bamBsaManager, UIUtil p_uipUIProxy) : base(p_modMod, p_gmdGameMode, p_eifEnvironmentInfo, p_igpInstallers, p_bamBsaManager, p_uipUIProxy) { }
/// <summary> /// This executes the install script. /// </summary> /// <param name="p_tfmFileManager">The transactional file manager to use to interact with the file system.</param> /// <returns><c>true</c> if the script completed successfully; /// <c>false</c> otherwise.</returns> protected bool RunScript(TxFileManager p_tfmFileManager) { IModFileInstaller mfiFileInstaller = CreateFileInstaller(p_tfmFileManager, m_dlgOverwriteConfirmationDelegate); bool booResult = false; IIniInstaller iniIniInstaller = null; IGameSpecificValueInstaller gviGameSpecificValueInstaller = null; if (Mod.HasInstallScript) { try { IDataFileUtil dfuDataFileUtility = new DataFileUtil(GameMode.GameModeEnvironmentInfo.InstallationPath); iniIniInstaller = CreateIniInstaller(p_tfmFileManager, m_dlgOverwriteConfirmationDelegate); gviGameSpecificValueInstaller = CreateGameSpecificValueInstaller(p_tfmFileManager, m_dlgOverwriteConfirmationDelegate); InstallerGroup ipgInstallers = new InstallerGroup(dfuDataFileUtility, mfiFileInstaller, iniIniInstaller, gviGameSpecificValueInstaller, PluginManager); IScriptExecutor sexScript = Mod.InstallScript.Type.CreateExecutor(Mod, GameMode, EnvironmentInfo, ipgInstallers, UIContext); sexScript.TaskStarted += new EventHandler<EventArgs<IBackgroundTask>>(ScriptExecutor_TaskStarted); sexScript.TaskSetCompleted += new EventHandler<TaskSetCompletedEventArgs>(ScriptExecutor_TaskSetCompleted); booResult = sexScript.Execute(Mod.InstallScript); } catch (Exception ex) { PopupErrorMessage = ex.Message; PopupErrorMessageType = "Error"; } iniIniInstaller.FinalizeInstall(); if (gviGameSpecificValueInstaller != null) gviGameSpecificValueInstaller.FinalizeInstall(); } else booResult = RunBasicInstallScript(mfiFileInstaller, ActiveMods); mfiFileInstaller.FinalizeInstall(); return booResult; }
/// <summary> /// Runs the basic uninstall script. /// </summary> /// <remarks> /// A basic uninstall uninstalls all of the changes made when the mod was installed. /// </remarks> /// <param name="p_tfmFileManager">The transactional file manager to use to interact with the file system.</param> /// <returns><c>true</c> if the uninstallation was successful; /// <c>false</c> otherwise.</returns> protected bool RunBasicUninstallScript(TxFileManager p_tfmFileManager, out string p_strErrorMessage) { p_strErrorMessage = null; IDataFileUtil dfuDataFileUtility = new DataFileUtil(GameMode.GameModeEnvironmentInfo.InstallationPath); IModFileInstaller mfiFileInstaller = new ModFileInstaller(GameMode.GameModeEnvironmentInfo, Mod, ModInstallLog, PluginManager, dfuDataFileUtility, p_tfmFileManager, null, GameMode.UsesPlugins, m_mmModManager); IIniInstaller iniIniInstaller = new IniInstaller(Mod, ModInstallLog, p_tfmFileManager, null); IGameSpecificValueInstaller gviGameSpecificValueInstaller = GameMode.GetGameSpecificValueInstaller(Mod, ModInstallLog, p_tfmFileManager, new NexusFileUtil(EnvironmentInfo), null); InstallerGroup ipgInstallers = new InstallerGroup(dfuDataFileUtility, mfiFileInstaller, iniIniInstaller, gviGameSpecificValueInstaller, PluginManager); BasicUninstallTask butTask = new BasicUninstallTask(Mod, ipgInstallers, ModInstallLog, GameMode, ActiveMods); OnTaskStarted(butTask); bool booResult = butTask.Execute(); if (mfiFileInstaller.InstallErrors.Count > 0) { p_strErrorMessage = Environment.NewLine + "There were issues while installing/uninstalling this mod:" + Environment.NewLine; foreach (string strPath in mfiFileInstaller.InstallErrors) DetailsErrorMessage += strPath + Environment.NewLine; PopupErrorMessage = p_strErrorMessage; PopupErrorMessageType = butTask.strPopupErrorMessageType; } mfiFileInstaller.FinalizeInstall(); iniIniInstaller.FinalizeInstall(); if (gviGameSpecificValueInstaller != null) gviGameSpecificValueInstaller.FinalizeInstall(); return booResult; }
static int DoInstall(string game, string filename, string installationPath, string profilePath, string gamePath, List<string> additionalSearchPaths, string seVersion, ref string errorString) { if (game == null) { errorString = "no game specified"; return 1; } if (filename == null) { errorString = "no file specified"; return 1; } if (profilePath == null) { errorString = "no profile path specified"; return 1; } if (gamePath == null) { errorString = "no game path specified"; return 1; } try { EnvironmentInfo environmentInfo = new EnvironmentInfo(Properties.Settings.Default); string exeLocation = Assembly.GetExecutingAssembly().Location; string exePath = System.IO.Path.GetDirectoryName(exeLocation); string[] gameModes = Directory.GetFiles(Path.Combine(exePath, "GameModes"), String.Format("{0}.dll", game)); if (gameModes.Count() == 0) { errorString = "unknown game"; return 1; } Assembly gameAssembly = Assembly.LoadFrom(gameModes[0]); IGameModeFactory gameModeFactory = null; Type[] exportedTypes = gameAssembly.GetExportedTypes(); foreach (Type type in exportedTypes) { if (typeof(IGameModeFactory).IsAssignableFrom(type) && !type.IsAbstract) { ConstructorInfo constructor = type.GetConstructor(new Type[] { typeof(EnvironmentInfo) }); gameModeFactory = (IGameModeFactory)constructor.Invoke(new Object[] { environmentInfo }); } } if (gameModeFactory == null) { errorString = "invalid game"; return 1; } string str7zPath = Path.Combine(environmentInfo.ProgrammeInfoDirectory, environmentInfo.Is64BitProcess ? "7z-64bit.dll" : "7z-32bit.dll"); SevenZipCompressor.SetLibraryPath(str7zPath); FileUtil fileUtil = new NexusFileUtil(environmentInfo); environmentInfo.Settings.InstallationPaths[gameModeFactory.GameModeDescriptor.ModeId] = installationPath; environmentInfo.Settings.ModFolder[gameModeFactory.GameModeDescriptor.ModeId] = installationPath; // environmentInfo.Settings.InstallInfoFolder[gameModeFactory.GameModeDescriptor.ModeId] = environmentInfo.TemporaryPath; environmentInfo.Settings.InstallInfoFolder[gameModeFactory.GameModeDescriptor.ModeId] = Path.Combine(installationPath, "temp"); if (environmentInfo.Settings.DelayedSettings[gameModeFactory.GameModeDescriptor.ModeId] == null) environmentInfo.Settings.DelayedSettings[gameModeFactory.GameModeDescriptor.ModeId] = new KeyedSettings<string>(); if (environmentInfo.Settings.DelayedSettings["ALL"] == null) environmentInfo.Settings.DelayedSettings["ALL"] = new KeyedSettings<string>(); ViewMessage warning = null; IGameMode gameMode = gameModeFactory.BuildGameMode(fileUtil, out warning); IModCacheManager cacheManager = new NexusModCacheManager(environmentInfo.TemporaryPath, gameMode.GameModeEnvironmentInfo.ModDirectory, fileUtil); IScriptTypeRegistry scriptTypeRegistry = ScriptTypeRegistry.DiscoverScriptTypes(Path.Combine(Path.GetDirectoryName(exeLocation), "ScriptTypes"), gameMode, new List<string>()); if (scriptTypeRegistry.Types.Count == 0) { errorString = "No script types were found."; return 2; } // use a proxy so we can intercept accesses to the IGameMode interface. This allows us to make the additional search paths accessible from // the sandbox and feed in the script extender version even though the nmm lib won't find it. // This has to happen after DiscoverScriptTypes becaus that function tries to localize the assembly which fails for the dynamic assembly // of the proxy. Fortunately DiscoverScriptTypes has no side-effects on the gameMode. // This recreates the gamemode object so it's important no code above modifies gameMode ProxyGenerator generator = new ProxyGenerator(); GameModeInterceptor interceptor = new GameModeInterceptor(additionalSearchPaths, seVersion != null ? new Version(seVersion) : null); gameMode = (IGameMode)generator.CreateClassProxy(gameMode.GetType(), new object[] { environmentInfo, fileUtil }, new IInterceptor[] { interceptor }); IModFormatRegistry formatRegistry = ModFormatRegistry.DiscoverFormats(cacheManager, gameMode.SupportedFormats, scriptTypeRegistry, Path.Combine(Path.GetDirectoryName(exeLocation), "ModFormats")); if (formatRegistry.Formats.Count == 0) { errorString = "No formats were found."; return 2; } // we install the mod from the temporary path. Unfortunately this requires the archive to be copied, otherwise the sandbox will // prevent the installer script from accessing the archive in its original location string fileNameTemporary = Path.Combine(environmentInfo.TemporaryPath, Path.GetFileName(filename)); File.Copy(filename, fileNameTemporary); IMod mod = CreateMod(fileNameTemporary, formatRegistry, gameMode); if (mod == null) { errorString = "failed to initialize mod"; return 3; } System.IO.File.WriteAllText(installationPath + "/__installInfo.txt", mod.ModName + "\n" + mod.HumanReadableVersion + "\n" + mod.Id); if (mod.HasInstallScript) { DummyDataFileUtilFactory dummyFactory = null; IDataFileUtil dataFileUtility; Logger.Info("Detected C# script that relies on files in the actual data folder"); string modlistFile = Path.Combine(profilePath, "modlist.txt"); // ASSUMED mods path is the parent directory of the gameMode.InstallationPath string modsPath = Directory.GetParent(gameMode.InstallationPath).FullName; // Prepare dummy data directory dummyFactory = new DummyDataFileUtilFactory(gameMode.GameModeEnvironmentInfo.InstallationPath, modlistFile, modsPath, gamePath, additionalSearchPaths); dataFileUtility = dummyFactory.CreateDummyDataFileUtil(); TxFileManager fileManager = new TxFileManager(); IInstallLog installLog = new DummyInstallLog(); IIniInstaller iniIniInstaller = new IniInstaller(mod, installLog, fileManager, delegate { return OverwriteResult.No; }); IPluginManager pluginManager = new DummyPluginManager(Path.Combine(profilePath, "plugins.txt"), gameMode, mod); IGameSpecificValueInstaller gameSpecificValueInstaller = gameMode.GetGameSpecificValueInstaller(mod, installLog, fileManager, new NexusFileUtil(environmentInfo), delegate { return OverwriteResult.No; }); IModFileInstaller fileInstaller = new ModFileInstaller(gameMode.GameModeEnvironmentInfo, mod, installLog, pluginManager, dataFileUtility, fileManager, delegate { return OverwriteResult.No; }, false); InstallerGroup installers = new InstallerGroup(dataFileUtility, fileInstaller, iniIniInstaller, gameSpecificValueInstaller, pluginManager); IVirtualModActivator modActivator = new DummyVirtualModActivator(gameMode, environmentInfo); IScriptExecutor executor = mod.InstallScript.Type.CreateExecutor(mod, gameMode, environmentInfo, modActivator, installers, SynchronizationContext.Current); // read-only transactions are waaaay faster, especially for solid archives) because the extractor isn't recreated for every extraction (why exactly would it be otherwise?) mod.BeginReadOnlyTransaction(fileUtil); // run the script in a second thread and start the main loop in the main thread to ensure we can handle message boxes and the like ScriptRunner runner = new ScriptRunner(executor, mod.InstallScript); runner.Execute(); runner.TaskEnded += delegate { iniIniInstaller.FinalizeInstall(); gameSpecificValueInstaller.FinalizeInstall(); mod.EndReadOnlyTransaction(); Application.Exit(); }; Application.Run(); switch (runner.Status) { case BackgroundTasks.TaskStatus.Cancelled: return 11; case BackgroundTasks.TaskStatus.Error: return 6; case BackgroundTasks.TaskStatus.Incomplete: return 10; default: return 0; } } else { errorString = "no install script"; return 4; } } catch (Exception e) { Console.WriteLine("exception: " + e.Message); MessageBox.Show(e.Message, "Installation failed", MessageBoxButtons.OK, MessageBoxIcon.Error); return 5; } }