Phil
Phil

Reputation: 4069

C# Windows Service - this keyword error

I have the following code which works fine when I use it within a Windows Forms application, however the application I'm writing needs to run as a Windows service, and when I moved my code into the Windows Service template in Visual Studio 2015 Community Edition, I get the following error.

Cannot implicitly convert type "MyWindowsService.Main" to "System.ComponentModel.ISynchronizeVoke". An explicit conversion exists (are you missing a cast?)

Could anyone shed some light on why I am getting this error, and what I need to do to resolve it?

The code which throws the error is the line below, and it is located within the OnStart method of my main class (named Main.cs). The code is used to create an instance of the DataSubscriber class (AdvancedHMI library).

dataSubscribers[dataSubscriberIndex].SynchronizingObject = this;

It has to have something to do with the fact that the code is in a Windows service template, because using this works perfectly in my forms application running the same code.

UPDATE

Correction, I've attempted to cast this to the required type, and now get the following error on run.

Additional information: Unable to cast object of type 'MyWindowsService.Main' to type 'System.ComponentModel.ISynchronizeInvoke'.

Code:

dataSubscribers[dataSubscriberIndex].SynchronizingObject = (System.ComponentModel.ISynchronizeInvoke)this;

UPDATE

I've included the entire contents of the Main.cs file from my Windows Service application.

using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Threading.Tasks;
using MySql.Data.MySqlClient;
using AdvancedHMIDrivers;
using AdvancedHMIControls;
using MfgControl.AdvancedHMI.Drivers;
using MfgControl.AdvancedHMI.Controls;
using System.Collections.ObjectModel;

namespace PLCHistoricDataHarvester {
    public partial class Main : ServiceBase {
        private EthernetIPforCLXCom commObject = new EthernetIPforCLXCom();
        private globals globals = new globals();
        private Dictionary<String, String> operationLines = new Dictionary<String, String>();
        private Dictionary<String, String> tags = new Dictionary<String, String>();
        private Collection<DataSubscriber> dataSubscribers = new Collection<DataSubscriber>();
        private int harvesterQueueCount = 0;
        private string harvesterInsertValues = String.Empty;

        public Main() {
            InitializeComponent();
        }

        protected override void OnStart(string[] args) {
            // Initialize our harvester program
            initializeHarvester();

            Console.WriteLine("The program has started");
        }

        protected override void OnStop() {
            // Call code when the service is stopped
            Console.WriteLine("Program has stopped");
            Console.ReadLine();
        }

        public void initializeHarvester() {
            // First, we connect to the database using our global connection object
            globals.dbConn.DatabaseName = "operations";

            if (!globals.dbConn.IsConnect()) {
                // TODO: Unable to connect to database.  What do we do?
            }

            // Second, we connect to the database and pull data from the settings table
            globals.initializeSettingsMain();

            // Set IP address of PLC
            commObject.IPAddress = globals.getSettingsMain("Processor_IP");

            // Pull distinct count of our parent tags (Machines ex: Line 1, etc)
            operationLines = globals.getOperationLines();

            // If we have at least 1 operation line defined...we continue
            if (operationLines.Keys.Count > 0) {
                //Now we loop over the operation lines, and pull back the data points
                int dataSubscriberIndex = 0;

                foreach (KeyValuePair<String, String> lines in operationLines) {
                    int line_id = int.Parse(lines.Key);
                    string name = lines.Value;
                    tags = globals.getTags(line_id);

                    // If we have at least 1 tag for this operation line, we continue...
                    if (tags.Keys.Count > 0 && tags["tags"].ToString().IndexOf(",") != -1) {
                        // Create our dataSubscriber object
                        dataSubscribers.Add(new DataSubscriber());
                        dataSubscribers[dataSubscriberIndex].SynchronizingObject = (ISynchronizeInvoke)this;
                        dataSubscribers[dataSubscriberIndex].CommComponent = commObject;
                        dataSubscribers[dataSubscriberIndex].PollRate = 1000;
                        dataSubscribers[dataSubscriberIndex].PLCAddressValue = tags["tags"];
                        dataSubscribers[dataSubscriberIndex].DataChanged += new EventHandler<MfgControl.AdvancedHMI.Drivers.Common.PlcComEventArgs>(subscribeCallback);
                        // Increment our dataSubscriberIndex
                        dataSubscriberIndex++;
                    }
                }
            }
        }

        private void subscribeCallback(object sender, MfgControl.AdvancedHMI.Drivers.Common.PlcComEventArgs e) {
            // code removed as it is irrelevant 
        }
    }
}

Upvotes: 0

Views: 682

Answers (2)

DavidG
DavidG

Reputation: 118937

The error message says this:

An explicit conversion exists (are you missing a cast?)

So add a cast like this:

dataSubscribers[dataSubscriberIndex].SynchronizingObject = (ISynchronizeInvoke)this;
                                                           ^^^^^^^^^^^^^^^^^^^^
                                                           //Add this

Upvotes: 2

Steve Cooper
Steve Cooper

Reputation: 21480

If you've got a console app, the easiest way to convert it to a windows service is by using Topshelf, a nuget package which lets you run in either console mode or nt service mode.

Here's the quickstart guide.

We use it to write services all the time and it helps you avoid this kind of fragile shenanigans.

Upvotes: 1

Related Questions