TinyMCE: Cannot call method ‘add’ of undefined

As I was implementing TinyMCE 4.0.5 on a site I got a funny error in my console in chrome:

Uncaught TypeError: Cannot call method ‘add’ of undefined

My implementation looked something like this:

	tinyMCE.init(
	{
		selector: ".WritingArea",
		plugins: "link lists preview anchor spellchecker emoticons textcolor paste",
		toolbar1: "bold italic underline strikethrough | alignleft aligncenter alignright alignjustify | styleselect formatselect fontselect fontsizeselect",
		toolbar2: "cut copy paste | bullist numlist | undo redo | link unlink | forcolor backcolor",
		menubar: false,
        toolbar_items_size: 'small',
		height: "100%",
		resize: false,
		setup: function(ed)
		{
			ed.onInit.add(function(ed)
			{
				tinyMCE.get(ed.target.id).hide();				
			});
		}
	});

The problem turned out to be the change in event handler management. The event onInit isn’t used anymore, instead you bind it like this:

...
		setup: function(ed)
		{
			ed.on("init", function(ed)
			{
				tinyMCE.get(ed.target.id).hide();
			});
		}
...

The documentation is, as I’m writing this, a bit weak on this point but now you know 🙂

C#: create a basic windows service

The service

Creating services in C# differs a bit from creating a standard console/winform/wpf application. A service is often created to run continuously and it has no graphical interface, something which makes it hard to communicate errors to the user.
This post will show you how to create a very basic windows service which communicates with the user through the event handler!

First up, create a console project and call it something nice, such as TestService:

Add a console project
Add a console project

 

Add references to the project to System.ServiceProcess and System.Configuration.Install. Then add a new item,a windows service, called TestService.cs and let it inherit from ServiceBase:

Windows Service now, Installer for later
Windows Service now, Installer for later
namespace TestService
{
    partial class TestService: ServiceBase
    {
        public TestService()
        {
            InitializeComponent();
        }
 
        protected override void OnStart(string[] args)
        {
            // TODO: Add code here to start your service.
        }
 
        protected override void OnStop()
        {
            // TODO: Add code here to perform any tear-down necessary to stop your service.
        }
    }
}

TestService comes with a few methods you can override. You should at least override OnStart and OnStop as these let you control what happens when the service starts and stops:

namespace MyFirstService
{
    public class MyService : ServiceBase
    {
        public MyService()
        {
            InitializeComponent();
            this.ServiceName = "MyService";
        }
 
        protected override void OnStart(string[] args)
        {
            base.OnStart(args);
        }
 
        protected override void OnStop()
        {
            base.OnStop();
        }
    }
}

Call the base implementation first and then add whatever you want to do afterwards. To make sure this service in the one that’s run we go to the program.cs class and call for this service on execution:

namespace TestService
{
    class Program
    {
        static void Main(string[] args)
        {
            ServiceBase.Run(new ServiceBase[]
            {
                new TestService()
            });
        }
    }
}

The installer

Now, this won’t install as normal and the easiest way to install it is to create an installer class and then add a setup project to handle it. We start by adding a new item, an installer item (see image above), called TestServiceInstaller.cs which we let inherit from the Installer class in System.Configuration.Install. Add the code as shown below:

namespace TestServiceService
{
    [RunInstaller(true)]
    public class TestServiceInstaller : Installer
    {
        public MyServiceInstaller()
        {
            ServiceProcessInstaller serviceProcessInstaller =
                               new ServiceProcessInstaller();
            ServiceInstaller serviceInstaller = new ServiceInstaller();
 
            //Who will run this service?
            serviceProcessInstaller.Account = ServiceAccount.LocalSystem;
            //Set login credentials if needed
            //serviceProcessInstaller.Username = ?;
            //serviceProcessInstaller.Password = ?;
 
            //This is the name that is displayed in the service menu
            serviceInstaller.DisplayName = "My test service";
 
            //How will the service act on startup?
            serviceInstaller.StartType = ServiceStartMode.Manual;
 
            //The actual name of the service, must be the same
            //as in your ServiceBase
            serviceInstaller.ServiceName = "TestService";
 
            this.Installers.Add(serviceProcessInstaller);
            this.Installers.Add(serviceInstaller);
 
            this.Installers.Add(serviceProcessInstaller);
            this.Installers.Add(serviceInstaller);
 
            InitializeComponent();
        }
    }
}

This is just a basic installer class and you need to configure at least the ServiceName and the DisplayName to match your preferences. The ServiceName must match your services name or else it won’t install.

Communicate using the EventLog

The easiest way to communicate with the user is to use the EventLog. If you haven’t seen or used it before you can open it by going to Start => Control Panel => Administrative Tools => EventLog (or Event Viewer in Vista). The EventView is where services and programs can output information to a user and it is very handy.
To configure an EventLog go back to the TestService.cs and change it to this:

namespace TestService
{
    public class TestService: ServiceBase
    {
        private const string Source = "TestServiceLog";
        private const string Log = "Application";
 
        private EventLog m_EventLog;
 
        public TestService()
        {
            this.ServiceName = "TestService";
 
            ConfigureEventLog();
        }
 
        protected override void OnStart(string[] args)
        {
            base.OnStart(args);
 
            m_EventLog.WriteEntry("TestServiceis starting!");
        }
 
        protected override void OnStop()
        {
            base.OnStop();
 
            m_EventLog.WriteEntry("TestServiceis stopping!");
        }
 
        private void ConfigureEventLog()
        {
            if (!EventLog.SourceExists(Source))
            {
                EventLog.CreateEventSource(Source, Log);
            }
 
            m_EventLog.Source = Source;
            m_EventLog.Log = Log;
 
            m_EventLog.WriteEntry("EventLog configured!");
        }
    }
}

The EventLog must be configured before using and it is prudent to check if the source exists. You don’t know if it exists on another computer and the EventLog will crash if it doesn’t.

A Setup-project

Now to the installation and usage of our fine service. Add a Setup project and call it ServiceSetup:

Add setup project
Add setup project

Add the service project by right clicking on the setup project and selecting View => File System and enter the Application Folder. Right click in the application folder and select Add => Project Output :

Configuring the setup project
Configuring the setup project

Select the project as follows:

Adding the project output
Adding the project output

Now, there is one more thing to do in order to get this to work. If you just install normally now the files will be copied to the installation directory complete but the service won’t get registered and it will have been quite pointless. We need to right-click on the project once more and select View => Custom Actions and add our project output there:

Custom actions
Custom actions

Now, if you right-click on the setup project and build it (setup projects generally has to be build individually as they are not included in the building schedule, change it by right-clicking by going to Solution configurations => Configuration manager). After building the project, right-click on it and select install.

Using the installed service

Go to Start => Control Panel => Administrative Tools => Services and find your service (by its display name):

C# Setup project

To distribute a a project smoothly there is a project type in Visual Studio called Setup with which you can create an installation package with ease. I’m going to show you how it’s done.
Begin with having a project that you want someone to install (this is somewhat vital). Select File => Add => New Project and select, under “Other Project Types/Setup and Deployment“, Setup Projekt and give it a nifty name:

Setup skärmen
Chose the right type of project

A setup project behaves a little bit different from your standard project. Directly after creating the project you’ll see the “File System“-view. If you happen to screw up and close it, you’ll reach reach it again by right clicking on the setup roejct and select View => File System

Here, you can select which files to place where during the installation. All files that should be placed in the installation folder must be added to the Application Folder. If we want to add our program as output we need to select Add => Project Output:

Chose application folder and right click in the right windows

Chose Primary Output

After this you’ve added what you need for a basic installation. Before release though, you need to set the project properties. The following picture shows which properties are important:

Change the marked properties

If you want to add a short cut on the desktop select User’s Desktop in the File System tab and right click. Select ‘Create New Short Cut’ and select the output project. The same thing goes for the program menu (but in User’s Programs Menu).
But, the application we use in this example utilizes a text file. It reads the file and outputs it, like this:

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Hello World!");
 
        using (FileStream stream = new FileStream("SomeTextFile.txt", FileMode.Open))
        {
            using (StreamReader reader = new StreamReader(stream))
            {
                Console.WriteLine(reader.ReadToEnd());
            }
        }
 
        Console.Read();
    }
}

As you can see, we’re reading from a file called ‘SomeTextFile.txt’ and outputs the content. My project looks like this:

Project overview

The text file ‘SomeTextFile.txt’ is stored as Content Properties => BuildAction which is a build action you use sometimes. It means that the file, as opposed to Embedded, is not embedded but must be manually added to the project output.
Therefore, we must add the Content Files output in our Application Folder. Right click in the folder and select Add => Project Output and select Content Files instead of Primary Output.

Now we have all we need to run an installation, and we’ll do it through Visual Studio to test it. Start by right clicking on the setup project and build it. The setup projects aren’t automatically added to the Visual Studio building queue and they generally require individual building actions (you can add them yourself, but since you very seldom need to build them there is no need for us to do it).
After you’ve built it, right click on it and select install:

Install or uninstall in Visual Studio

Now we’re done…