Cinchoo – Turn your app to Windows Tray app

In this article, I’ll show you how to turn your console / winform application to Windows System Tray application. Cinchoo framework provides a single hosting infrastructure to turn your application either Windows Service or Windows Tray application through configuration.

Console Application

Here is how you can do it for console application

1. Create a new ‘Console Application‘ from VS.NET

2. Add reference to Cinchoo.Core.dll

3. Add namespace Cinchoo.Core

4. Create a class derived from ChoApplicationHost as below

[RunInstaller(true)]
public class AppHost : ChoApplicationHost
{
    protected override void OnStart(string[] args)
    {
        //TODO: Application Startup code goes here
        base.OnStart(args);
    }
}

Decorating the above class with RunInstallerAttribute will make the application to be run as Windows Service. And override OnStart method, where application start up code placed there.

5. In the main entry, do as below.

public class Program
{
    static void Main(string[] args)
    {
        ChoApplication.Run(new AppHost(), args);
    }
}

That’s all, you application is now ready to run as self installable windows service application or Windows Tray application.

Here is how to turn your application to Windows Tray application. In ChoCoreFrx.xml file, set ‘turnOn’ flag to ‘true’ in trayApplicationBehaviourSettings element.

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <globalApplicationSettings applicationId="TestApplication.exe" eventLogSourceName="TestApplication.exe" turnOnConsoleOutput="false">
    <behaviourSettings hideWindow="false" bringWindowToTop="false" alwaysOnTop="false" runAtStartup="false" runOnceAtStartup="false" singleInstanceApp="false" activateFirstInstance="false" />
    <trayApplicationBehaviourSettings turnOn="true" showInTaskbar="true" hideMainWindowAtStartup="true" hideTrayIconWhenMainWindowShown="false" trayAppTurnOnMode="OnMinimize" />
    <appConfigPath />
  </globalApplicationSettings>
</configuration>

Other parameters

  • showInTaskbar – true, will show the application in Taskbar. false, otherwise.
  • hideMainWindowAtStartup – true, will hide the window at the application startup. Otherwise false.
  • hideTrayIconWhenMainWindowShown – true, tray application icon will hidden when the main windows shown. Otherwise false.
  • trayAppTurnOnMode – This option is applicable to WinForm application only. Possible options are OnMinimize, OnClose, OnMinimizeOrClose.

WinForm Application

Below are the steps to turn your winform application into Windows Tray application

1. Create a new ‘WinForm Application‘ from VS.NET

2. Add reference to Cinchoo.Core.dll

3. Add namespace Cinchoo.Core

4. Create a class derived from ChoApplicationHost and IChoWinFormApp as below

[RunInstaller(true)]
public class AppHost : ChoApplicationHost, IChoWinFormApp
{
    MainForm form = new MainForm();
    public AppHost()
    {
    }

    public Form MainFormWindow
    {
        get { return form; }
    }

    public ContextMenu GetContextMenu(ContextMenu contextMenu)
    {
        //Build the context menu items
        return contextMenu;
    }

    public string TooltipText
    {
        get { return null; }
    }

    public System.Drawing.Icon TrayIcon
    {
        get { return null; }
    }

    public string BalloonTipText
    {
        get { return null; }
    }

    protected override void OnStart(string[] args)
    {
        base.OnStart(args);
    }
}

Decorating the above class with RunInstallerAttribute will make the application to be run as Windows Service. And override OnStart method, where application start up code placed there.

5. In the main entry, do as below.

public class Program
{
    static void Main(string[] args)
    {
        ChoApplication.Run(new AppHost(), args);
    }
}

Thats all. Try it.

Cinchoo – Windows Service made easy

Cinchoo framework simplifies the Windows service development. An application developed in this approach is ready to run as Console application as well as self install-able Service application. In this article, I’m going to walk over the steps of creating service development.

1. Create a new ‘Console Application‘ from VS.NET

2. Add reference to Cinchoo.Core.dll

3. Add namespace Cinchoo.Core

4. Create a class derived from ChoApplicationHost as below

[RunInstaller(true)]
public class AppHost : ChoApplicationHost
{
    protected override void OnStart(string[] args)
    {
        //TODO: Application Startup code goes here
    }
}

Make sure the type is decorated with RunInstallerAttribute. And override OnStart method, where application start up code placed there. Implement any other service related (OnStop, OnShutdown etc) methods by overriding them.

5. In the main entry, do as below.

public class Program
{
    static void Main(string[] args)
    {
        ChoApplication.Run(new AppHost(), args);
    }
}

That’s all, you application is self install able windows service application.

You can run it as console application or install it as Windows service also.

To Install as windows service, pass /@i command line argument

[AppExeName].exe /@i

To uninstall as windows service, pass /@u command line argument

[AppExeName].exe /@u

To start the service, pass /@s command line argument

[AppExeName].exe /@s

To stop the service, pass /@t command line argument

[AppExeName].exe /@t

To pause the service, pass /@p command line argument

[AppExeName].exe /@p

To continue the service, pass /@c command line argument

[AppExeName].exe /@c

To execute a command in the service, pass /@e:{command_id} command line argument

[AppExeName].exe /@e:2

To get the help on Windows service commands, pass /@?

C:\>TestServiceApp.exe /@?
TestServiceApp [Version 1.0.0.0]
Copyright c  2014

TESTSERVICEAPP [/@SN:<string>] [/@SD:<string>] [/@I] [/@U] [/@S] [/@T] [/@P]
[/@C] [/@E:<int>] [/@SP:<string>]

        /@SN    Service Name.
        /@SD    Service Description.
        /@I     Install Service.
        /@U     Uninstall Service.
        /@S     Start Service.
        /@T     Stop Service.
        /@P     Pause Service.
        /@C     Continue Service.
        /@E     Execute Command.
        /@SP    Command Line Parameters.

Controlling Service Installation

There are couple of settings classes which controls the service process behavior during installation. It can configured through configuration file or can be overridden programmatically. They are

  • ChoServiceInstallerSettings – service process parameters used during installation of service.
  • ChoServiceProcessInstallerSettings – service credential parameters used during installation of the service.

First, let take a look at the way configuring them through configuration file.

ChoServiceProcessInstallerSettings

These setting can be maintained in ChoServiceProcessInstallerSettings.xml file. If the file not exists, it will created by Cinchoo framework in application configuration directory. The file look as below

&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;configuration&gt;
  &lt;serviceProcessInstallerSettings account=&quot;LocalSystem&quot; userName=&quot;&quot; password=&quot;&quot;&gt;
    &lt;helpText /&gt;
  &lt;/serviceProcessInstallerSettings&gt;
&lt;/configuration&gt;

If you want more information about each attribute/element in the above xml section, please visit ServiceProcessInstaller Class in MSDN.

ChoServiceInstallerSettings

These setting can be maintained in ChoServiceInstallerSettings.xml file. If the file not exists, it will created by Cinchoo framework in application configuration directory. The file look as below

&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;configuration&gt;
  &lt;serviceInstallerSettings delayedAutoStart=&quot;false&quot; displayName=&quot;ChoServiceHost.Test&quot; serviceName=&quot;ChoServiceHost.Test&quot; serviceStartMode=&quot;Automatic&quot; /&gt;
&lt;/configuration&gt;

If you want more information about each attribute/element in the above xml section, please visit ServiceInstaller Class in MSDN.

Next, let take a look at the way of overriding them programmatically.

Override ApplyServiceInstallParamsOverrides method in your ApplicationHost class, where you can changes service installation parameters.

[RunInstaller(true)]
public class AppHost : ChoApplicationHost
{
    protected override void OnStart(string[] args)
    {
        Console.WriteLine(&quot;Application started...&quot;);
    }

    protected override void ApplyServiceInstallParamsOverrides(ChoServiceProcessInstallerSettings serviceProcessInstallerSettings, ChoServiceInstallerSettings serviceInstallerSettings)
    {
        serviceInstallerSettings.DisplayName = &quot;Test&quot;;
        serviceInstallerSettings.ServiceName = &quot;Test&quot;;
    }
}

In the above sample code, we are trying to override the ServiceName and DisplayName as ‘Test’. When you install the service, it will be created as ‘Test’ service.

Cinchoo – Framework Tips

Here I’m going to talk about couple of tips on using Cinchoo framework in your project.

At the start of the application, you must call ChoFramework.Initialize() to initialize the framework and start necessary services. Usually you must place this statement in application Main entry point as below.

Calling ChoFramework.Shutdown() method is not mandatory to call. But it is safe to make this call for graceful shutdown of all the background services.

static void Main(string[] args)
{
    ChoFramework.Initialize();
    try
    {
        ChoApplication.ApplyFrxParamsOverrides += new EventHandler<ChoFrxParamsEventArgs>(ChoApplication_ApplyFrxParamsOverrides);

        SampleConfigSection ApplicationSettings = new SampleConfigSection();
    }
    catch (Exception ex)
    {
        Console.WriteLine("ERROR: " + ex.Message);
    }
    finally
    {
        ChoFramework.Shutdown();
    }
}

ChoAppDomain.

Cinchoo – Configuration framework, part 17

Configuration Object Validation

This section is the continuation of previous articles. In here, I’ll go over seamless automatic configuration member validations,  another feature provided by Cinchoo configuration framework.

At present, Cinchoo framework supports the following family of Validation attributes

Look below the sample, where the Name property decorated with ChoStringValidator, It restricts the maximum length of the Name is 5.

[ChoSingleTagConfigurationSection("sample")]
public class SampleConfigSection : ChoConfigurableObject
{
	#region Instance Data Members (Public)

	[ChoPropertyInfo("name", DefaultValue = "Mark")]
    [ChoStringValidator(MaxLength=5)]
	public string Name;

	[ChoPropertyInfo("message", DefaultValue = "Hello World!")]
	public string Message;

	#endregion

	[ChoAfterConfigurationObjectLoadedHandler]
	void OnAfterConfigurationObjectLoaded(object sender, ChoConfigurationObjectEventArgs e)
	{
		Console.WriteLine(sender.ToString());
	}
}

During the configuration object initialization or when there is explicit assignment to Name member, if the length of value over 5, it will silently (default behavior) report the error in the log file as below. Framework will try to assign the value either DefaultValue or FallbackValue to Name.

Below code trying to assign Name value to ‘123456’

class Program
{
	static void Main(string[] args)
	{
		SampleConfigSection sampleConfigSection = new SampleConfigSection();
        sampleConfigSection.Name = "123456";

		//Shutdown the framework to stop the background services...
		//otherwise the application will not terminate
		ChoFramework.Shutdown();
	}
}

If you look at the configuration object log file (\\Logs\Settings\HelloWorld.SampleConfigSection.log), it reports the error


2012-03-29 04:53:08.0241140
  -- HelloWorld.SampleConfigSection State --
	Name: Mark
	Message: Hello World!

-- MetaData Information --
	BindingMode: TwoWay
	Defaultable: True
	Silent: True
	ConfigurationMetaDataLogInfo:
		-- Log Information --
			LogCondition: True
			LogTimeStampFormat:
			LogDirectory: Settings
			LogFileName: HelloWorld.SampleConfigSection.log

	ConfigStorageType: Cinchoo.Core.Configuration.ChoFileSingleTagConfigStorage, Cinchoo.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=b7dacd80ff3e33de

2012-03-29 04:53:08.0397395
* -- HelloWorld.SampleConfigSection State --
	Name: Mark
	Message: Hello World!

	-- Following errors produced while construction --
		Name: Failed to assign `123456` value. The string must be no more than 5 characters long.

-- MetaData Information --
	BindingMode: TwoWay
	Defaultable: True
	Silent: True
	ConfigurationMetaDataLogInfo:
		-- Log Information --
			LogCondition: True
			LogTimeStampFormat:
			LogDirectory: Settings
			LogFileName: HelloWorld.SampleConfigSection.log

	ConfigStorageType: Cinchoo.Core.Configuration.ChoFileSingleTagConfigStorage, Cinchoo.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=b7dacd80ff3e33de

Cinchoo – Configuration framework, part 16

Configuration Meta Data Information

In this section I’m going to talk about Configuration Meta Data, a self described information about individual configuration object. This data used to control the behavior of the configuration object at any time (even at run time).

It can be controlled either by declarative or configuration.

First, I’ll discuss about specifying meta-data by declarative manner

Declarative Approach

All the configuration object must be decorated by ChoConfigurationSectionAttribute or one of the derived attributes.

  • BindingMode – Direction of configuration data flow.
    • TwoWay updates the target property or the property whenever either the target property or the source property changes. Default.
    • OneWay updates the target property only when the source property changes.
    • OneTime updates the target property only when the application starts.
    • OneWayToSource updates the source property when the target property changes.
  • Defaultable – true, will create the the section in the underlying configuration file if not present. Default is true.
  • ConfigStorageType – Type of the underlying configuration storage. Please visit Available Configuration Section Handlers for list of available storages.
  • ConfigFilePath – Absolute or relative file path to configuration file used by the configuration object.
  • ConfigFileNameFromTypeName – Configuration file name from Type name.
  • ConfigFileNameFromTypeFullName – Configuration file name from Type full name.
  • LogCondition – true, to allow log anything to the underlying log file using ConfigurationObject Log() method. Default value is true.
  • LogDirectory – Absolute or related path of the log directory. Default value is [Frameworklogdirectory]\Settings folder.
  • LogFileName – Log file name. Default value is Configuration Object Type full name.
  • LogTimeStampFormat – Log entry time stamp format. Default value is “yyyy-MM-dd hh:mm:ss.fffffff”.
  • Parameters – Reserved
  • Silent – true, will ignore any error while loading configuration parameters. Default is true.

Below is the sample configuration object decorated with meta-data information

[ChoConfigurationSection("applicationSettings", ConfigFileNameFromTypeName = typeof(SampleConfigSection), BindingMode = ChoConfigurationBindingMode.OneWay, LogDirectory = @"C:\Logs")]
public class SampleConfigSection : ChoConfigurableObject
{
	#region Instance Data Members (Public)

	[ChoPropertyInfo("name", DefaultValue="Mark")]
	public string Name;

	[ChoPropertyInfo("message", DefaultValue="Hello World!")]
	public string Message;

	#endregion
}

When you instantiate and use the above configuration object in your application, Cinchoo framework creates meta-data section in the meta-data file ([appExeName].config.meta) as below

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <applicationSettings bindingMode="OneWay" defaultable="true" silent="true">
    <logInfo condition="true" directory="Settings" fileName="SampleConfigSection.log" />
  </applicationSettings>
</configuration>

Configuration Approach

Cinchoo framework creates or uses the meta-data information in [appExeName].config.meta file by default.

This file name can be overridden. Please visit Framework Configuration Parameters section on how to do it.

Once file has been created and used by the framework, you have a chance to modify them to control the configuration object at run-time. Any changes made to this file automatically picked up framework and adjust the meta-data accordingly. Do not require restart of the application.

Also for any reason you have doubt about the values in the meta-data file, you can let the framework auto correct them by simple delete the a section from the meta-data file. Try for yourself.

Cinchoo – Overriding Framework Configuration Parameters

In this section, I’ll go over the list of Cinchoo framework configuration parameters can be overridden to control the run-time environment of the framework either through configuration or programmatically.

Framework will run fine without overriding these parameters. Only when you need, you can override them. In those situation, it can be done through configuration or programmatically.

First, we will see how to override them through configuration. All the framework parameters must be stored in ChoCoreFrx.config file under application executable folder. This is the default behavior of discovering this file by the framework. But this can be overridden by specifying the path to this file through appFrxSettings custom configuration section in App.config file as below

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <configSections>
        <section name="appFrxSettings" type="Cinchoo.Core.ChoAppFrxSettings, Cinchoo.Core" />
    </configSections>
    <appFrxSettings appFrxFilePath="C:\ConfigFolder" />
</configuration>

GlobalApplicationSettings

There are the application level settings used by framework. Below are the attributes and their usages.

  • globalApplicationSettings – Global application parameters used by framework. All the variables are optional.
    • singleInstanceApp [bool] – true, to ensure there is only one instance of the application running at any point in time. false, lets you to run multiple instances of the application. Default is false.
    • applicationId [string] – the custom application name. Default value is the executable name.
    • eventLogSourceName [string] – Event log source name where all the errors are posted on this name, default value is applicationId.
    • useApplicationDataFolderAsLogFolder [bool] – true, it uses the current roaming user directory. Default is false.
    • logFolder [string] – A log directory, where all the log files are created by framework. Default is ‘[appExePath]\Logs’.
    • appConfigPath [string] – configuration file path. If not specified, this will be [appExeFolder].[appExeName].xml
    • logTimeStampFormat [string] – A time stamp format used when logging information to log files. Default value is “yyyy-MM-dd hh:mm:ss.fffffff”
    • traceLevel [int] – Specifies what message to output for the Trace/ChoTrace classes. 0-Off, 1-Error, 2-Warning, 3-Info, 4-Verbose.

Here is the sample Global Application Settings section in ChoCoreFrx.config file

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <globalApplicationSettings singleInstanceApp="false" applicationId="TestApplication" eventLogSourceName="TestApplication" useApplicationDataFolderAsLogFolder="false">
    <logFolder>C:\Logs</logFolder>
    <appConfigPath>c:\config\TestApplication.xml</appConfigPath>
    <logTimeStampFormat>yyyy-MM-dd hh:mm:ss.fffffff</logTimeStampFormat>
  </globalApplicationSettings>
</configuration>

MetaDataFilePathSettings

Cinchoo framework creates as well as uses number of Meta-Data files, these file paths can be configured through ChoCoreFrx.config file.

  • configurationMetaDataFilePath – meta data file path used by Configuration manager. By default, it’s value is [appExeName].config.meta
  • pcMetaDataFilePath – meta data file path used by Performance Counter manager. By default, its value is [appExeName].perf.meta

Here is the sample xml section looks like

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <metaDataFilePathSettings>
    <configurationMetaDataFilePath>c:\Config\configurationMetaFile.meta</configurationMetaDataFilePath>
    <pcMetaDataFilePath>c:\Config\PCMetaFile.meta</pcMetaDataFilePath>
  </metaDataFilePathSettings>
</configuration>

Run-Time approach

Lets see how we can override the system parameters at run-time in here. Cinchoo framework exposes ChoApplication.ApplyFrxParamsOverrides event. By subscribing to this event, you have a chance to override the framework parameters at run-time. See below the sample code on how to override some of the system parameters

static void Main(string[] args)
{
    try
    {
        ChoApplication.ApplyFrxParamsOverrides += new EventHandler<ChoFrxParamsEventArgs>(ChoApplication_ApplyFrxParamsOverrides);
        XmlApplicationSettings ApplicationSettings = new XmlApplicationSettings();
    }
    finally
    {
        ChoAppDomain.Exit();
    }
}

static void ChoApplication_ApplyFrxParamsOverrides(object sender, ChoFrxParamsEventArgs e)
{
    e.GlobalApplicationSettings.SingleInstanceApp = true;
    e.MetaDataFilePathSettings.ConfigurationMetaDataFilePath = @"C:\Config\MetaDataFilePath.meta";
}

Cinchoo – Binary Downloads

Developers, please bookmark this page. I’ll keep updating the state of the framework in this post.

Oct 30, 2014 / v1.0.5.6 (Latest)

Cinchoo.Framework.Dlls.Zip (Any CPU)

  • Maintenance Release

Oct 29, 2014 / v1.0.5.5

Cinchoo.Framework.Dlls.Zip (Any CPU)

  • Maintenance Release

Oct 27, 2014 / v1.0.5.4

Cinchoo.Framework.Dlls.Zip (Any CPU)

  • Maintenance Release

Oct 19, 2014 / v1.0.5.2

Cinchoo.Framework.Dlls.Zip (Any CPU)

  • Maintenance Release

Sep 07, 2014 / v1.0.5.1

Cinchoo.Framework.Dlls.Zip (Any CPU)

  • BUG FIX: Minor fixes on command line argument parser..

Aug 27, 2014 / v1.0.5.0

Cinchoo.Framework.Dlls.Zip (Any CPU)

  • BUG FIX: An stackoverflow exception reported while instantiating configuration object.

Now Cinchoo is available as NuGet package, you can download them

Install-Package Cinchoo

Please post your valuable feedback in this blog. Also if I miss anything, please email me at cinchoofrx@gmail.com. Glad to add them in future releases. Thanks for your support.

Cinchoo – Configuration framework, part 15

Available Configuration Section Handlers

Here is the list of available configuration section handlers in Cinchoo framework. This list will keep changing based on the more support to other data sources. Keep looking for new configuration section handlers.

  • ChoNameValueSectionHandler (Default)

Cinchoo – Using Performance Counters, Part 4

This is the continuation of previous articles on Performance Counters. So far you learned how to create, use and control the performance counters in your application. In this article, I’ll talk about two performance counters category attributes to control the installation of  Performance Counters.

There are

  • selfInstall – true to install the counters automatically when you instantiate the object, otherwise it won’t install the counters.
  • recreate – true to recreate the counters irrespective of their existence, otherwise skip recreating them if already exists.
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <PerformanceCounterCategory name="Random Single Instance Test" selfInstall="true" recreate="true">
    <PerformanceCounter name="Random Rate" turnOn="true" />
    <PerformanceCounter name="Random Average" turnOn="true" />
  </PerformanceCounterCategory>
  <PerformanceCounterCategory name="Random Multiple Instance Test" selfInstall="true" recreate="true">
    <PerformanceCounter name="Random Value" instanceName="Standard" turnOn="true" />
    <PerformanceCounter name="Random Value" instanceName="Inverted" turnOn="true" />
  </PerformanceCounterCategory>
</configuration>

Cinchoo – Using Performance Counters, Part 3

In this section, I’ll talk about installing and uninstalling Performance Counters using Cinchoo framework. This is the explicit way of installing and uninstalling them.

1. Add reference to Cinchoo.Core.dll assembly

2. Namespace Cinchoo.Core.Instrumentation.Performance

For a sample performance counter class defined as below

[ChoPerformanceCounterCategory("Random Single Instance Test", PerformanceCounterCategoryType.SingleInstance)]
public sealed class SingleInstancePerfCounters : ChoPerformanceCounterCategory
{
    #region Performance Counters

    [ChoPerformanceCounter("Random Rate", "", PerformanceCounterType.RateOfCountsPerSecond32)]
    public readonly ChoPerformanceCounter PCRandomRate = null;

    [ChoPerformanceCounter("Random Average", "", PerformanceCounterType.AverageCount64)]
    public readonly ChoPerformanceCounter PCRandomAverage = null;

    #endregion
}

Installing Performance Counters

This is how to install the performance counter using ChoPerformanceCounterInstaller helper class

ChoPerformanceCounterInstaller.Install(typeof(SingleInstancePerfCounters))

Uninstalling Performance Counters

Here is how to uninstall the performance counter using ChoPerformanceCounterInstaller helper class

ChoPerformanceCounterInstaller.Uninstall(typeof(SingleInstancePerfCounters))