Skip to content

plugin sdk overview

Andre Lafleur edited this page May 10, 2026 · 14 revisions

About the Plugin SDK

The Plugin SDK enables you to create advanced, fully embedded integrations that function as custom roles within Security Center.

Understanding roles in Security Center

Before diving into plugin development, it's important to understand the concept of Roles in Security Center, as plugins function as custom roles within the system.

What are Roles?

In Security Center, Roles are components that perform specific tasks within the system. Each role is associated with one or more servers, which host and execute the role's functions. Roles are essential for various operations such as managing video units, archiving data, or synchronizing users with corporate directories.

Core features of Roles

  • Role type: Each role has a defined type that determines its specific functions. For example, a role could be responsible for managing video units and their associated archives.
  • Role settings: These settings specify the parameters within which the role operates, such as data retention periods or database configurations.
  • Server assignment: Roles can be assigned to one or multiple servers. This allows for load balancing and failover capabilities.
  • Failover support: Roles support failover, meaning they can automatically switch to a secondary server if the primary server fails, ensuring continuous operation of critical system functions.

Plugins as custom Roles

When you develop a plugin using the Plugin SDK, you're creating a custom role within Security Center. Your plugin inherits many of the core features of roles, including:

  • The ability to define a specific role type with custom functionality
  • Configurable settings for your plugin's operation
  • Automatic server assignment and failover support
  • Built-in health monitoring and database support

This architecture allows your plugin to seamlessly integrate with Security Center's existing infrastructure and benefit from its robust server-side capabilities.

Server-side execution

Plugins execute on Security Center servers, not on client machines running Config Tool or Security Desk. This means:

  • Plugins have access to server resources and file systems
  • File paths in plugins refer to the server's file system
  • The Engine is pre-authenticated, no login required

Prerequisites

Before building plugins, you should be familiar with:

Platform SDK Foundation

Plugins are built on top of the Platform SDK. The Plugin SDK provides the hosting infrastructure and lifecycle management, but all entity operations, queries, events, and transactions use the Platform SDK through the Engine property.

Essential Platform SDK guides:

All Platform SDK concepts apply to plugins - entities, transactions, queries, events, and caching all work the same way through the Engine property.

Certificates and Licensing

Plugins require an SDK certificate to authenticate with Security Center. See:

Development Requirements

  • Security Center SDK installed
  • Visual Studio 2022 or later
  • .NET Framework 4.8 or .NET 8 (Security Center 5.13+)
  • SDK certificate from Genetec (development or production)
  • License with Plugin SDK part number

Plugin architecture

How plugins are hosted

Unlike client applications that create their own Engine and call LogOnAsync(), plugins are hosted by Security Center's plugin infrastructure:

flowchart TB
    subgraph Host[Plugin role host]
        direction TB
        S1[Load plugin assembly] --> S2[Create plugin instance]
        S2 --> S3[Validate SDK certificate]
        S3 --> S4[Create Engine]
        S4 --> S5[Initialize plugin]
        S5 --> S6[Start database layer if supported]
        S6 --> S7[Start plugin]
    end
Loading

The plugin host handles:

  • Plugin assembly loading and instantiation
  • Certificate validation against license
  • Engine creation and initialization
  • Lifecycle management (start, stop, restart)
  • Database initialization (if supported)
  • State reporting to Config Tool

Plugin Components

A plugin consists of three essential parts:

1. Plugin Class - Your implementation inheriting from Genetec.Sdk.Plugin.Plugin

  • Receives a fully-initialized Engine instance
  • Implements abstract OnQueryReceived() method
  • Implements abstract Dispose(bool disposing) method
  • Overrides lifecycle methods (OnPluginLoaded(), OnPluginStart())

2. PluginDescriptor Class - Metadata and registration information

  • Defines plugin name, description, and unique GUID
  • Specifies default configuration
  • Optional: Defines images for UI representation
  • Optional: Specifies if plugin is single-instance
  • Optional: Specifies 64-bit execution requirement
  • Optional: Defines plugin category (ServiceDomain)
  • Optional: Lists certificate application IDs

PluginDescriptor properties:

Property Type Required Description
Name string Yes Plugin display name shown in Config Tool
Description string Yes Plugin description
PluginGuid Guid Yes Unique identifier for the plugin type
SpecificDefaultConfig string Yes Default XML configuration for new instances
ServiceDomain string No Plugin category for grouping. Defaults to Name
Supports64Bits bool No Whether plugin requires 64-bit process. Defaults to true
IsSingleInstance bool No Whether only one instance can exist. Defaults to false
SmallImage Bitmap No 64x64 PNG icon for entity browsers
LargeImage Bitmap No 256x256 PNG icon for configuration pages
ApplicationId List<string> No Certificate application IDs for authentication
public class MyPluginDescriptor : PluginDescriptor
{
    public override string Name => "My Integration Plugin";
    public override string Description => "Integrates with external system";
    public override Guid PluginGuid => new Guid("{12345678-1234-1234-1234-123456789012}");
    public override string SpecificDefaultConfig => "<Config />";

    // Optional: Plugins with the same ServiceDomain share a host process
    public override string ServiceDomain => "External Integrations";

    // Optional: Set to false if plugin must run in 32-bit process
    public override bool Supports64Bits => true;

    // Optional: Prevent multiple instances
    public override bool IsSingleInstance => true;

    // Optional: Must match the ApplicationId in your .cert file
    public override List<string> ApplicationId => new List<string>
    {
        "KxsD11z743Hf5Gq9mv3+5ekxzemlCiUXkTFY5ba1NOGcLCmGstt2n0zYE9NsNimv"
    };
}

Supports64Bits property

Controls whether the plugin runs in a 64-bit or 32-bit process.

Value Effect
true (default) Plugin runs in a 64-bit process
false Plugin runs in a 32-bit process

Set to false when:

  • Plugin uses 32-bit native DLLs that have no 64-bit version
  • Plugin depends on 32-bit COM components
  • Plugin integrates with legacy hardware SDKs that are 32-bit only

Keep as true (default) when:

  • Plugin has no native dependencies
  • Plugin uses 64-bit native libraries
  • Plugin can run in 64-bit mode (recommended for performance and memory)

ServiceDomain property

Groups plugin roles into process hosting containers. Roles with the same ServiceDomain value share a single RoleController process and a single Directory proxy connection.

Default: Returns Name property value

How it affects hosting:

Same ServiceDomain Different ServiceDomain
Roles share same process Roles run in separate processes
Roles share same Directory proxy Each role has its own proxy
Lower resource usage Higher isolation

Impact of failures:

Failure Type Impact on Other Plugins in Same ServiceDomain
Process crash All plugins stop and restart together
Deactivate plugin (Config Tool) Only that plugin stops, others continue
Plugin throws exception Usually isolated, others continue
Delete plugin role Only that plugin stops, others continue

The host process manages each plugin role independently. Administrative actions like deactivation or deletion only affect the targeted plugin. However, if the host process itself crashes, all plugins sharing that ServiceDomain are affected since they run in the same process.

When to customize:

  • Use the same value across related plugin types if they should share resources
  • Use unique values if plugins should be completely isolated
  • Keep the default for most cases

Tip

Spaces are automatically stripped from ServiceDomain values.

Memory optimization: Plugins sharing the same ServiceDomain also share the same entity cache. In systems with hundreds of thousands of entities (cardholders, cameras, doors), this can save gigabytes of memory. Instead of each plugin instance loading and caching the same entities separately, they share a single cache. Consider using a shared ServiceDomain when multiple plugin instances need access to the same large entity sets.

ApplicationId property

Provides certificate-based authentication by specifying which certificate ApplicationIds are valid for this plugin. Acts as a whitelist for certificate validation during plugin initialization.

Default: Empty list (validation skipped for backward compatibility)

How it works:

  1. When the plugin starts, Security Center reads the ApplicationId from the plugin's .cert file
  2. The certificate's ApplicationId is compared against each entry in this list
  3. If a match is found, the plugin continues to license validation
  4. If no match is found, the plugin fails with IllegitimateCertificate error

When ApplicationId is empty (default):

  • Certificate legitimacy check is skipped
  • Only license registration is validated
  • Provides backward compatibility for older plugins

When ApplicationId contains values:

  • The .cert file's ApplicationId must match one of the entries in this list
  • If no match is found, plugin initialization fails with IllegitimateCertificate error
  • This ensures the deployed certificate file is one specifically issued for this plugin

Why it is a list: The list structure allows a plugin to accept multiple valid certificates. This supports scenarios where:

  • Different deployment environments use different certificates
  • Multiple partners deploy the same plugin with their own certificates

3. Certificate File - Authentication and licensing

  • Must be named {Namespace}.{ClassName}.cert (e.g., Genetec.Dap.MyPlugin.cert)
  • Placed in a Certificates folder next to the plugin DLL
  • Contains ApplicationId that validates against license
  • See Plugin SDK Certificates for details

Understanding plugin GUIDs and role instances

This is a critical concept: There are TWO different GUIDs to understand:

PluginDescriptor.PluginGuid - the plugin type ID

public class MyPluginDescriptor : PluginDescriptor
{
    public override Guid PluginGuid => new Guid("{12345678-1234-1234-1234-123456789012}");
    public override string Name => "My Plugin";
}

This GUID identifies:

  • The type of plugin (like a class definition)
  • The plugin DLL and its capabilities
  • What appears in Config Tool when adding a new role
  • Hardcoded in your PluginDescriptor - same for all instances

Analogy: Like a product SKU - identifies WHAT the plugin is.

Plugin.PluginGuid - the role instance ID

public class MyPlugin : Plugin
{
    protected override void OnPluginLoaded()
    {
        // This is the ROLE INSTANCE GUID - different for each instance!
        Logger.TraceInformation($"My role instance GUID: {PluginGuid}");
        
        // Access the Role entity
        var role = Engine.GetEntity<Role>(PluginGuid);
        Logger.TraceInformation($"Role name: {role.Name}");
    }
}

This GUID identifies:

  • A specific instance of the plugin type (object instance)
  • The Role entity in the Security Center database
  • Unique for each role - even if same plugin type
  • Generated by Security Center when administrator adds the role

Analogy: Like a serial number - identifies THIS specific instance.

The Relationship

flowchart TB
    A["PluginDescriptor.PluginGuid = AAAA-AAAA
    (Plugin Type)"]

    A --> B[Administrator adds plugin role in Config Tool]
    B --> C[Security Center creates Role entity]
    C --> D["Role.Guid = BBBB-BBBB
    (Instance 1)"]
    D --> E[Plugin host creates Plugin instance]
    E --> F["Plugin.PluginGuid = BBBB-BBBB
    (Role instance GUID)"]

    A --> H[Administrator adds ANOTHER instance of SAME plugin]
    H --> I[Security Center creates ANOTHER Role entity]
    I --> J["Role.Guid = CCCC-CCCC
    (Instance 2)"]
    J --> K[Plugin host creates ANOTHER Plugin instance]
    K --> L["Plugin.PluginGuid = CCCC-CCCC
    (Different role instance GUID)"]
Loading

Practical Usage

Use Plugin.PluginGuid (role instance GUID) for:

  • Accessing your role's configuration
  • Checking entity ownership
  • Identifying your specific instance
  • Inter-role communication
protected override void OnPluginLoaded()
{
    // Access THIS role instance's configuration
    var role = Engine.GetEntity<Role>(PluginGuid);
    var config = role.SpecificConfiguration;
    
    // Check if an entity belongs to THIS instance
    var entity = Engine.GetEntity(entityGuid);
    if (entity.OwnerRole == PluginGuid)
    {
        // This entity belongs to THIS plugin instance
    }
}

Use PluginDescriptor.PluginGuid (plugin type ID) for:

  • Finding ALL instances of your plugin type
  • Type-level operations
  • Rarely used in plugin code
// Find all instances of this plugin type
// Note: This requires the GUID from your PluginDescriptor class
var myPluginTypeGuid = new Guid("{12345678-1234-1234-1234-123456789012}");
// This is NOT directly accessible from Plugin.PluginGuid - that's the role instance GUID

Key Takeaways

  1. Plugin.PluginGuid is a ROLE instance GUID - it's different for each instance
  2. PluginDescriptor.PluginGuid is a PLUGIN TYPE GUID - same for all instances
  3. Role entity GUID == Plugin.PluginGuid - they're the same thing
  4. Multiple instances of the same plugin have different Plugin.PluginGuid but same PluginDescriptor.PluginGuid
  5. Use Plugin.PluginGuid for 99% of operations - it identifies YOUR specific instance

Plugin discovery and loading

When a plugin role starts:

  1. Descriptor resolution - Loads the plugin descriptor for the role subtype
  2. Assembly loading - Loads the plugin assembly and dependencies
  3. Plugin instantiation - Creates the plugin class instance
  4. Certificate validation - Validates the SDK certificate against the license
  5. Engine creation - Creates the Engine instance
  6. Initialization - Calls Initialize(engine, roleGuid, culture) and runs OnPluginLoaded()
  7. Database setup - If IPluginDatabaseSupport, starts the database layer
  8. Plugin start - Calls OnPluginStart()

Key Points:

  • Engine is pre-authenticated - no LogOnAsync() needed
  • Multiple instances of the same plugin can run if IsSingleInstance = false
  • Each plugin role instance gets its own Engine and Plugin instance

The Engine property

Your plugin receives a fully-initialized IEngine instance through the Initialize() method:

protected internal IEngine Engine { get; private set; }

This Engine provides access to all Platform SDK functionality:

  • Entity operations (CreateEntity, GetEntity, DeleteEntity)
  • Transaction management (TransactionManager)
  • Query processing (ReportManager)
  • Event subscriptions (SetEventFilter, EventReceived)
  • Action handling (ActionReceived)
  • Request/response communication (RequestManager)
  • Entity change notifications (EntitiesInvalidated)

Critical difference from client applications:

  • No login required - Engine is already authenticated
  • Server context - Runs under admin account

For all entity operations, queries, events, and transactions, refer to the Platform SDK guides. The Plugin SDK adds hosting and lifecycle management on top of the Platform SDK foundation.

Plugin capabilities

Plugins can implement various capabilities by overriding methods and implementing interfaces:

Core Capabilities

Optional Capabilities

Each capability is covered in detail in its dedicated guide.

Development workflow

  1. Create the plugin class. Inherit from Plugin and implement abstract methods.
  2. Create the PluginDescriptor. Define metadata and default configuration.
  3. Implement the lifecycle. Override OnPluginLoaded() for initialization.
  4. Register the plugin. Add registry entries or XML configuration.
  5. Deploy the certificate. Place the .cert file in the Certificates folder.
  6. Test in development. Add the plugin role in Config Tool.
  7. Handle queries and events. Implement business logic.
  8. Deploy to production. Register on production servers with the production certificate.

For deployment details, see Deploying plugins.

See also

Plugin SDK guides

Platform SDK guides

Platform SDK

Plugin SDK

Workspace SDK

Media SDK

Macro SDK

Web SDK

Media Gateway

Genetec Web Player

Clone this wiki locally