Skip to main content

Overview

IExposedPlugin represents an installed plugin as exposed to other plugins. It provides read-only access to plugin metadata, state information, and UI operations. This interface is used when accessing the list of installed plugins through IDalamudPluginInterface.InstalledPlugins.

Interface Definition

public interface IExposedPlugin
{
    // Properties
    string Name { get; }
    string InternalName { get; }
    bool IsLoaded { get; }
    bool IsOutdated { get; }
    bool IsTesting { get; }
    bool IsOrphaned { get; }
    bool IsDecommissioned { get; }
    bool IsBanned { get; }
    bool IsDev { get; }
    bool IsThirdParty { get; }
    ILocalPluginManifest Manifest { get; }
    Version Version { get; }
    bool HasMainUi { get; }
    bool HasConfigUi { get; }
    
    // Methods
    void OpenMainUi();
    void OpenConfigUi();
}

Properties

Basic Information

Name
string
Gets the display name of the plugin.
string Name { get; }
This is the user-friendly name shown in the plugin installer and plugin list.
InternalName
string
Gets the internal name of the plugin.
string InternalName { get; }
This is the unique identifier used internally by Dalamud to identify the plugin.
Version
Version
Gets the version of the plugin.
Version Version { get; }
This represents the current installed version of the plugin.
Manifest
ILocalPluginManifest
Gets the plugin manifest containing metadata.
ILocalPluginManifest Manifest { get; }
The manifest contains additional metadata such as description, author, and other plugin information.

State Flags

IsLoaded
bool
Gets whether the plugin is currently loaded.
bool IsLoaded { get; }
A plugin can be installed but not loaded if it’s disabled or encountered an error.
IsOutdated
bool
Gets whether this plugin’s API level is out of date.
bool IsOutdated { get; }
Outdated plugins may not function correctly with the current version of Dalamud.
IsTesting
bool
Gets whether the plugin is marked for testing use only.
bool IsTesting { get; }
Testing plugins are pre-release versions that users can opt into.
IsOrphaned
bool
Gets whether this plugin is orphaned (belongs to a repository that still exists, but the plugin is no longer maintained).
bool IsOrphaned { get; }
IsDecommissioned
bool
Gets whether this plugin is decommissioned (repository still exists, but plugin no longer does).
bool IsDecommissioned { get; }
Decommissioned plugins are no longer available for installation but may still be installed on some systems.
IsBanned
bool
Gets whether this plugin has been banned.
bool IsBanned { get; }
Banned plugins have been blocked from loading due to policy violations or security concerns.
IsDev
bool
Gets whether this is a development plugin.
bool IsDev { get; }
Development plugins are loaded from local directories rather than the plugin repository.
IsThirdParty
bool
Gets whether this plugin was installed from a third-party repository.
bool IsThirdParty { get; }
Third-party plugins come from custom repositories rather than the official Dalamud repository.

UI Capabilities

HasMainUi
bool
Gets whether the plugin has a main UI window.
bool HasMainUi { get; }
If true, the plugin provides a main UI that can be opened via OpenMainUi().
HasConfigUi
bool
Gets whether the plugin has a configuration UI window.
bool HasConfigUi { get; }
If true, the plugin provides a configuration UI that can be opened via OpenConfigUi().

Methods

OpenMainUi
void
Opens the main UI of the plugin.
void OpenMainUi()
Throws: InvalidOperationException if HasMainUi is falseAlways check HasMainUi before calling this method.
OpenConfigUi
void
Opens the configuration UI of the plugin.
void OpenConfigUi()
Throws: InvalidOperationException if HasConfigUi is falseAlways check HasConfigUi before calling this method.

Usage Examples

Listing All Installed Plugins

using Dalamud.Plugin;

public class MyPlugin : IDalamudPlugin
{
    public MyPlugin(IDalamudPluginInterface pluginInterface)
    {
        foreach (var plugin in pluginInterface.InstalledPlugins)
        {
            Console.WriteLine($"Plugin: {plugin.Name} v{plugin.Version}");
            Console.WriteLine($"  Loaded: {plugin.IsLoaded}");
            Console.WriteLine($"  Internal Name: {plugin.InternalName}");
        }
    }

    public void Dispose() { }
}

Finding a Specific Plugin

public bool IsPluginInstalled(IDalamudPluginInterface pluginInterface, string internalName)
{
    return pluginInterface.InstalledPlugins
        .Any(p => p.InternalName == internalName && p.IsLoaded);
}

public IExposedPlugin? GetPlugin(IDalamudPluginInterface pluginInterface, string internalName)
{
    return pluginInterface.InstalledPlugins
        .FirstOrDefault(p => p.InternalName == internalName);
}

Opening Another Plugin’s UI

public void OpenPluginConfig(IDalamudPluginInterface pluginInterface, string internalName)
{
    var plugin = pluginInterface.InstalledPlugins
        .FirstOrDefault(p => p.InternalName == internalName);
    
    if (plugin == null)
    {
        // Plugin not found
        return;
    }
    
    if (!plugin.IsLoaded)
    {
        // Plugin is installed but not loaded
        return;
    }
    
    if (plugin.HasConfigUi)
    {
        try
        {
            plugin.OpenConfigUi();
        }
        catch (InvalidOperationException)
        {
            // Handle error
        }
    }
}

Checking Plugin States

public void AnalyzePluginStates(IDalamudPluginInterface pluginInterface)
{
    var plugins = pluginInterface.InstalledPlugins;
    
    var loadedCount = plugins.Count(p => p.IsLoaded);
    var outdatedCount = plugins.Count(p => p.IsOutdated);
    var devCount = plugins.Count(p => p.IsDev);
    var thirdPartyCount = plugins.Count(p => p.IsThirdParty);
    
    Console.WriteLine($"Loaded: {loadedCount}/{plugins.Count()}");
    Console.WriteLine($"Outdated: {outdatedCount}");
    Console.WriteLine($"Dev Plugins: {devCount}");
    Console.WriteLine($"Third Party: {thirdPartyCount}");
}

Monitoring Plugin Changes

public class MyPlugin : IDalamudPlugin
{
    private IDalamudPluginInterface pluginInterface;

    public MyPlugin(IDalamudPluginInterface pluginInterface)
    {
        this.pluginInterface = pluginInterface;
        pluginInterface.ActivePluginsChanged += OnPluginsChanged;
    }

    private void OnPluginsChanged(IActivePluginsChangedEventArgs args)
    {
        foreach (var internalName in args.AffectedInternalNames)
        {
            var plugin = pluginInterface.InstalledPlugins
                .FirstOrDefault(p => p.InternalName == internalName);
            
            if (plugin != null)
            {
                Console.WriteLine($"Plugin {plugin.Name} changed: {args.Kind}");
                Console.WriteLine($"  Is Loaded: {plugin.IsLoaded}");
            }
        }
    }

    public void Dispose()
    {
        pluginInterface.ActivePluginsChanged -= OnPluginsChanged;
    }
}

Best Practices

  • Always check HasMainUi or HasConfigUi before calling the respective Open*Ui() methods
  • Check IsLoaded before attempting to interact with a plugin’s UI
  • Handle the InvalidOperationException that may be thrown by UI methods
  • Use the ActivePluginsChanged event to stay updated on plugin state changes
  • Cache plugin lookups if you need to reference the same plugin multiple times

Build docs developers (and LLMs) love