Home > Software design >  Easiest way to send one-time string value from my winforms desktop app to my windows service
Easiest way to send one-time string value from my winforms desktop app to my windows service

Time:12-03

Every time my windows forms desktop app starts up, I need it to send a one-time string value to my windows service on the same pc. In most cases, the service will be running constantly even when the desktop app is not. But the desktop app will check and start the service if necessary.

What is the easiest/best mechanism for simple communication of a single string on desktop app startup to the windows service? I have no idea how communication with windows service works.

Is there any simple example of doing this?

CodePudding user response:

A Window service is a class derived from ServiceBase. This base class allows your service code to override a method OnCustomCommand.

For example, you can have something like this in the main class of your service

public enum ServiceCCommands
{ 
    ExecuteBackupNow = 128,
    DataLoader = 129
}
    
public partial class BackupService : ServiceBase
{
    .....

    protected override void OnCustomCommand(int command)
    {
        if (Enum.IsDefined(typeof(ServiceCCommands), command))
        {
            ServiceCCommands cmd = (ServiceCCommands)command;
            switch (cmd)
            {
                case ServiceCCommands.ExecuteBackupNow:
                    _logger.Info($"BackupService: Executing backup");
                    RunBackup();
                    break;
                case ServiceCCommands.DataLoader:
                    _logger.Info($"BackupService: Executing loader");
                    LoadData();
                    break;
            }
        }
        else
            _logger.Error($"BackupService: Custom Command not recognized={command}");
    }

Now, your UI code could call this CustomCommand after obtaining an instance of your service from the ServiceController class using the System.ServiceProcess namespace

private void cmdRunBackup_Click(object sender, EventArgs e)
{
    try
    {
        const int ExecuteBackupNow = 128;
        var service = new ServiceController("yourServiceNameHere");
        if (service != null)
        {
            service.ExecuteCommand(ExecuteBackupNow);
            msgUtil.Information("Started backup command!");
        }
        else
            msgUtil.Failure("The service is not available!");
    }
    catch (Exception ex)
    {
        _logger.Error(......);
    }

} // end class

However, as far as I know, there is no way to pass a string to this method. But of course you can store the string somewhere on a disk file and then trigger the appropriate command on the service to read the string or other parameters that you need to pass.

If a more complex context is required you can always host a WCF service inside the Windows Service itself. This is a more complex solution and I recommend you to evaluate the effort required against the simple file based solution.

CodePudding user response:

What I am doing and seems to be working so far is have my desktop app write my string value to a file in the CommonApplicationData special folder using:

Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData)

And then my Windows Service looks for the file and its value using the same method.

CommonApplicationData is the directory that serves as a common repository for application-specific data that is used by all users, including the SYSTEM account.

For details, see Environment.GetFolderPath Method and CommonApplicationData in Environment.SpecialFolder.

  • Related