Search code examples
kofax

Run Custom Module as Service instead of launching a WinForms application


I created a custom module for Kofax. This module is a WinForms application with a runtime Form and a setup form (administration module).

For the runtime application I use this code


Program.cs - launch the runtime form

internal static class Program
{
    [STAThread]
    private static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new FrmMain());
    }
}

FrmMain.cs - initialize the UI and create the required instances

public partial class FrmMain : Form
{
    private BatchProcessor batchProcessor;
    private BatchManager batchManager;
    private SessionManager sessionManager;

    public FrmMain()
    {
        InitializeComponent();
    }

    private void FrmMain_Load(object sender, EventArgs e)
    {
        try
        {
            batchProcessor = new BatchProcessor();
            sessionManager = new SessionManager();
            batchManager = new BatchManager(batchProcessor, sessionManager);
            // UpdateUI();              
            timerBatchPolling.Enabled = true;
        }
        catch (Exception exception)
        {
            throw exception;
        }
    }

    private void FrmMain_FormClosed(object sender, FormClosedEventArgs e)
    {
        timerBatchPolling.Enabled = false;

        try
        {
            sessionManager.Logout();
        }
        catch (Exception exception)
        {
            throw exception;
        }
    }

    private void timerBatchPolling_Tick(object sender, EventArgs e)
    {
        timerBatchPolling.Enabled = false;
        batchManager.BatchPolling();
        // UpdateUI();
        timerBatchPolling.Enabled = true;
    }
}

BatchManager.cs - ask for the next batch to process

internal class BatchManager
{
    private BatchProcessor batchProcessor;
    private SessionManager sessionManager;

    public IBatch CurrentActiveBatch { get; private set; }

    public BatchManager(BatchProcessor batchProcessor, SessionManager sessionManager)
    {
        this.batchProcessor = batchProcessor;
        this.sessionManager = sessionManager;
        this.sessionManager.LoginToRuntimeSession();
    }

    public void BatchPolling()
    {
        CurrentActiveBatch = sessionManager.GetNextBatch();

        if (CurrentActiveBatch != null)
        {
            batchProcessor.ProcessBatch(CurrentActiveBatch);
        }
        else
        {
            sessionManager.Logout();
        }
    }
}

BatchProcessor.cs - process the batch

internal class BatchProcessor
{
    public void ProcessBatch(IBatch batch)
    {
        // ...
    }
}

I just saw that it is also possible to run custom modules as services. I don't know how to register them or how to setup the code so I'm asking if there is a way to change my code to turn the module into a service instead of a forms application.

Thanks for help!


Solution

  • Create a new class derived from ServiceBase. The two relevant methods are OnStart and OnStop, read more about them here. Here is one example, note that CustomModule is one of my custom classes that takes care of logging into KC, processing batches, and more.

    protected override void OnStart(string[] args)
    {
        // TODO: Add code here to start your service.
        cm = new CustomModule();
        cm.Login("", "");
    
        if (CustomModule.BatchNotificationEnabled == true)
        {
            cm.ListenForNewBatches();
        }
        else
        {
            cm.PollForNewBatches();
        }
    }
    

    For installing the service, you can add another class that derives from Installer, but this is purely optional. However, I would recommend going the extra mile as this would allow you to install and uninstall your CM in the same style as all Kofax modules: MyCustomModule.exe -install.

    Finally, in your Program.cs, check whether the user launched the module interactively or not:

    if (Environment.UserInteractive)
    {
        // run as module
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new RuntimeForm(args));
    }
    else
    {
        // run as service
        ServiceBase.Run(new CustomModuleService());
    }