C# Installer Scripting for Nexus Mod Manager
For some reason there are no information about scripting your own installer in C# for Nexus Mod Manager, but you know what? This page will teach you to do that.
If you haven't used C# before, you can read a quick introduction into it.
First, grab this template and place it in your mod's fomod
folder as script.cs
.
using System;
class Script : BaseScript
{
public bool OnActivate()
{
return true;
}
}
What is happening here? Let's see.
- You are creating a new class named
Script
. This class is absolutely essential to make script working, as well as inheriting this class fromBaseScript
and it's implementor classes (see below). Script
class containsOnActivate()
method, which is called by NMM when user starts installing process. Before this method is called, a newScript
instance is being created, so you don't need to makeOnActivate()
method static. Returningtrue
from this method indicate that your script worked out correctly,false
— something bad happened and mod should not be marked as installed in NMM.- Your script can access classes and methods from these libraries (not namespaces):
System.dll
System.Drawing.dll
System.Windows.Forms.dll
System.Xml.dll
- You can inherit your
Script
class from any of these classes:SkyrimBaseScript
,Fallout4BaseScript
,FalloutNVBaseScript
,Fallout3BaseScript
,FalloutBaseScript
. Inheriting provides additional methods (ex. checking SKSE version for Skyrim). If you don't use them, it's better to just inheritBaseScript
Down there is documentation with small samples, I hope you will understand how to use them properly. Also you can download sample installer script, which shows how to install mods from archive in NMM way, how to create user interface via Windows Forms, etc.
In next examples we will use Skyrim as game and this mod structure:
my-mod.7z
---------
fomod/images/test.png
fomod/script.cs
fomod/info.xml
README.txt
LokirsTomb.esp
Accessing your mod's files
NMM provides fewer methods to access your mod's files:
Basic installation
bool PerformBasicInstall();
This method just copies all files from your mod except fomod
directory to game's data folder. Return value indicates success of operation (get error message by calling GetLastError()
).
Example:
public bool OnActivate()
{
return PerformBasicInstall();
}
Manual installation
bool InstallFileFromMod(string file);
bool InstallFileFromMod(string file, string to);
bool InstallFolderFromMod(string folder, bool recurse);
bool InstallFolderFromMod(string folder, string to, bool recurse)
Using first method extract's file from your archive to same path in Data folder, second method allows you to change path where file will be extracted. Return value indicates successful extracting. You can get error message by calling GetLastError()
. These method can throw SecurityException
if you chose not permitted destination directory (ex. "C:/mahfile.txt"
).
Third and fourth methods installs all files from mod's specified directory.
Examples:
// my-mod.7z/LokirsTomb.esp => ../Skyrim/Data/LokirsTomb.esp
InstallFileFromMod("LokirsTomb.esp");
// my-mod.7z/README.txt => ../Skyrim/Data/Readmes/LokirsTomb_Readme.txt
InstallFileFromMod("README.txt", "Readmes/LokirsTomb_Readme.txt");
You can also generate a file on fly:
bool GenerateDataFile(string path, byte[] data);
Writes the file represented by the given byte array to the given path.
Accessing mod data
string[] GetModFileList();
string[] GetModFileList(string folder, bool recurse);
Retrieves the list of files in the specified folder in the mod. Second method allows to chose the folder whose file list should be rethieved and whether to return files that are in subdirectories of the given directory.
byte[] GetFileFromMod(string file);
Return's file content as byte array. Can return null
when file doesn't exist (get error message by calling GetLastError()
).
Example:
byte[] data = GetFileFromMod("README.txt");
string text = System.Text.Encoding.UTF8.GetString(data);
MessageBox(text, "You gotta read this.");
Game management
Game version
Version GetGameVersion();
Gets the version of the game that is installed or null if not installed.
Game data files
string[] GetExistingDataFileList(string path, string pattern, bool allFolders);
Gets a filtered list of all files in a user's Data directory.
path
: The subdirectory of the Data directory from which to get the listing.pattern
: The pattern against which to filter the file paths.allFolders
: Whether or not to search through subdirectories.
Returns a filtered list of all files in a user's Data directory.
bool DataFileExists(string path)
Determines if the specified file exists in the user's Data directory.
path
: The path of the file whose existence is to be verified.
Returns true if the specified file exists; false otherwise.
byte[] GetExistingDataFile(string path)
Gets the speified file from the user's Data directory as byte array.
path
: The path of the file to retrieve.
The specified file, or
Plugins
string[] GetAllPlugins();
string[] GetActivePlugins();
First method gets a list of all installed plugins, second retrieves a list of currently active plugins.
void SetPluginActivation(string path, bool activate);
Sets the activated status of a plugin (i.e., and esp or esm file).
- activate: Whether to activate the plugin.
Plugin load order
void SetPluginOrderIndex(string plugin, int newIndex);
Sets the load order of the specifid plugin.
void SetLoadOrder(int[] plugins);
Sets the load order of the plugins.
plugins
parameter. plugins
parameter defines new load order of the plugins. Each entry in this array contains the current index of a plugin. This array must contain all current indices.void SetLoadOrder(int[] plugins, int position);
Moves the specified plugins to the given position in the load order.
plugins
: The list of plugins to move to the given position in the load order. Each entry in this array contains the current index of a plugin.position
: The position in the load order to which to move the specified plugins.
void SetRelativeLoadOrder(string[] relativelyOrderedPlugins);
Orders the plugins such that the specified plugins are in the specified order.
relativelyOrderedPlugins
: The plugins to order relative to one another.
Mod Manager info
Version GetModManagerVersion();
Get's NMM version.
User interaction
Message dialogs
void MessageBox(string message);
void MessageBox(string message, string title);
DialogResult MessageBox(string message, string title, MessageBoxButtons buttons);
Shows a message box. First two methods shows a message with optional title and "OK" button. Third method, which returns DialogResult
(see docs), can define it's own buttons for message box with MessageBoxButtons
enumeration (see docs) and get result back.
You can also use message boxes from System.Windows.Forms
namespace (see docs).
Example:
MessageBox("Here is your pizza.", "DELIVERY");
var result = MessageBox("Give him some money?", "title",
System.Windows.Forms.MessageBoxButtons.YesNo);
if (result == System.Windows.Forms.DialogResult.Yes) {
MessageBox("Have your pizza, dude!");
} else {
MessageBox("God damn it, dude!");
}
User interface
// this is same as `Form form = new Form();`
System.Windows.Forms.Form CreateCustomForm();
Creates Windows Forms Form. This allows to create windows with textboxes, buttons, etc. Google how to use Windows Forms.
If you have Visual Studio, you can use it's visual form designer to create forms in drag-n'-drop way. You need to create new Windows Forms project, edit the form, then copy-paste form source code and code, generated by form designer into the script, and finally create your Form's instance from code.
Example:
public bool OnActivate() {
var form = CreateCustomForm();
form.Text = "Title";
var button = new System.Windows.Forms.Button();
button.Text = "hit me gently";
button.Location = new System.Drawing.Point(30, 30);
button.ClientSize = new System.Drawing.Size(100, 100);
button.Click += (sender, args) => {
MessageBox("oooh");
};
form.Controls.Add(button);
form.ShowDialog();
return true;
}
string[] Select(IList<SelectOption> options, string title, bool selectMany);
new SelectOption(string name, bool isDefault, string description, Image image);
Displays a selection form to the user (seems to be broken).
options
: The options from which to select.title
: The title of the selection form.selectMany
: Whether more than one items can be selected.
INI management
string GetIniString(string settingsFileName, string section, string key);
Retrieves the specified settings value as a string.
int GetIniInt(string settingsFileName, string section, string key);
Retrieves the specified settings value as an integer.
bool EditIni(string settingsFileName, string section, string key, string value);
Sets the specified value in the specified ini file to the given value. Returns true
if the value was set; false
if the user chose not to overwrite the existing value.
Fallout Base Script derived
You must inherit your Script
class from one of these classes to use these methods: FalloutBaseScript
, Fallout3BaseScript
, FalloutNVBaseScript
, Fallout4BaseScript
or SkyrimBaseScript
.
bool ScriptExtenderPresent();
Indicates whether or not a script extender is present. For Skyrim it is SKSE, for Fallout 3 — FOSE, for Fallout New Vegas — NVSE, for Fallout 4 — F4SE.
string[] GetBSAFileList(string bsa);
Retrieves the list of files in the specified BSA. Return list of files contained in the specified BSA.
byte[] GetDataFileFromBSA(string bsa, string file);
Gets the specified file from the specified BSA.
// Fallout.ini/Skyrim.ini/FalloutNV.ini
string GetFalloutIniString(string section, string key);
int GetFalloutIniInt(string section, string key);
// FalloutPrefs.ini/SkyrimPrefs.ini/FalloutNVPrefs.ini
string GetPrefsIniString(string section, string key);
int GetPrefsIniInt(string section, string key);
// GECKCustom.ini
string GetGeckIniString(string section, string key);
int GetGeckIniInt(string section, string key);
// GECKPrefs.ini
string GetGeckPrefsIniString(string section, string key);
int GetGeckPrefsIniString(string section, string key);
Retrieves the specified game ini value as a string/integer.
// Fallout.ini/Skyrim.ini/FalloutNV.ini
bool EditFalloutINI(string section, string key, string value, bool unused);
// FalloutPrefs.ini
bool EditPrefsINI(string section, string key, string value, bool unused);
// GECKCustom.ini
bool EditGeckINI(string section, string key, string value, bool unused);
// GECKPrefs.ini
bool EditGeckPrefsINI(string section, string key, string value, bool unused);
Sets the specified value in the game ini file to the given value. Returns true
if the value was set; false
if the user chose not to overwrite the existing value.
string GetRendererInfo(string value);
Gets the specified value from the RendererInfo.txt file. Returns specified value from the RendererInfo.txt file, or null
if the value is not found.
value
: The value to retrieve from the file.
bool IsAIActive();
Determines if archive invalidation is active.
bool EditShader(int package, string shaderName, byte[] data);
Edits the specified shader with the specified data. Returns true
if the value was set; false
if the user chose not to overwrite the existing value.
package
: The package containing the shader to edit.shaderName
: The shader to edit.data
: The value to which to edit the shader.
void SetupScriptCompiler(TesPlugin[] plugins);
Sets up the script compiler for the given plugins.
plugins
: The plugins for which to set up the script compiler.
void CompileResultScript(SubRecord subrecord, out Record record, out string message);
Compiles the result script.
void CompileScript(Record record, out string message);
Compiles a script.
Fallout 3 Base Script derived
This method is only available when you inherit from Fallout3BaseScript
.
Version GetFoseVersion();
Gets the version of FOSE that is installed. Returns null
if FOSE is not installed.
Fallout NV Base Script derived
This method is only available when you inherit from FalloutNVBaseScript
.
Version GetNvseVersion();
Gets the version of NVSE that is installed. Returns null
if NVSE is not installed.
Skyrim Base Script derived
This method is only available when you inherit from SkyrimBaseScript
.
Version GetSkseVersion();
Gets the version of SKSE that is installed. Returns null
if SKSE is not installed.