Question Need help by creating an WindowsForm App with ServiceInstaller on button click

wolk_tambowskij

New member
Joined
Sep 25, 2015
Messages
4
Programming Experience
Beginner
Hello, coding gurus!

I'm new to programming with visual studio and programming in general...
I need an advice how to get the following scenario working.

What I have:
Visual C# 2008 Pro
A WindowsForm App (MyApp) created with it to store some info
An external console application (AnyApp.exe)

Design of MyApp contains:
5 TextBoxes, 3 CheckBoxes and a SubmitButton:
TextBox 4 has a password hint, the Enable.State of TextBox5 is controled by CheckBox1 (if Checked = Enable.True, Unchecked = Enable.False by default)

What I want to achieve:
On pushing the SubmitButton MyApp
1. should install a service wich should start from AnyApp.exe with command line parameters containing the user infos from the form like '\%PROGRAMFILES%\PathTo_AnyApp.exe --[some static parameter 1] TextBox2.Text@TextBox1.Text, TextBox4.Text --[some static parameter 2] TextBox1.Text:TextBox2.Text --[some static parameter 3]' and so on;
1.a) when CheckBox1 is checked the command line parameters should contain also '--[some static parameter 4] TextBox5.Text', else nor the TextBox5.Text nor the static parameter 4;
1.b) when CheckBox2 is checked '--[some static parameter 3]' should be removed from the service start options;
2. when CheckBox3 is checked (checked by default) there should be imported some registry keys to system registry;
3. if some of the required fields are empty, should popup a warn message with submit and cancel possibilities;
4. the MyApp should exit

Thank you very much for any advices!
 

jmcilhinney

C# Forum Moderator
Staff member
Joined
Apr 23, 2011
Messages
2,471
Location
Sydney, Australia
Programming Experience
10+
It's not really clear what you're asking for. Are you saying that you want to install a service that will then run your console app or that you want to install the console app as a service? To be honest, neither really makes sense. What is this service and/or console app actually supposed to achieve?
 

wolk_tambowskij

New member
Joined
Sep 25, 2015
Messages
4
Programming Experience
Beginner
Dear jmcilhinney, thank you for your reply.
Ideally I want to install the console app as a service - I don't need a second process. The console app is a simple SIP client that is supposed to register at a SIP server with the credentials and options defined by user input in MyApp and should run in the background so that a backend could send and receive voice data through its connection.
 

jmcilhinney

C# Forum Moderator
Staff member
Joined
Apr 23, 2011
Messages
2,471
Location
Sydney, Australia
Programming Experience
10+
You can't just install any old console app as a Windows service. It has to actually be written to behave as a Windows service. I've written some projects that can be run as a console app in order to facilitate easy debugging (services must be installed before debugging) but then installed as a Windows services. I start by creating a Windows Service project, which automatically adds a class that inherits System.ServiceProcess.ServiceBase. The code for the task performed by the service then goes in the OnStart method. I then modify the Main method in the Program class to detect a specific commandline argument that I only use while debugging and run as a console app if it's detected and as a Windows service otherwise. Running as a console app means basically running the same code as in the OnStart method of the derived service class. Here's an example of such a service class:
using System;
using System.IO;
using System.ServiceProcess;
using ApplicationLogger = SI.Moh.Phisco_Periph.Global.ApplicationLogger;

namespace SI.Moh.Phisco.Submissions.Service
{
    public partial class SubmissionService : ServiceBase
    {
        private const string ERROR_LOG_NAME = "PhiscoErrorLog";
        private const string INFO_LOG_NAME = "PhiscoInfoLog";

        private SubmissionProcessor processor;

        public SubmissionService()
        {
            InitializeComponent();
        }

        protected override void OnStart(string[] args)
        {
            try
            {
                processor = new SubmissionProcessor();

                var path = Properties.Settings.Default.SubmissionsRootFolder;
                var filter = Properties.Settings.Default.SubmissionFileNamePattern;

#if DEBUG
                ApplicationLogger.Inst.LogInfo(INFO_LOG_NAME, "Path: " + path);
                ApplicationLogger.Inst.LogInfo(INFO_LOG_NAME, "Filter: " + filter);
#endif

                // Process files already in the submission folder.
                foreach (var file in new DirectoryInfo(path).GetFiles(filter))
                {
                    processor.EnqueueFile(file.FullName);
                }

                processor.ProcessQueuedFilesAsync();

                // Watch for new files in the submission folder.
                submissionFolderWatcher.Path = path;
                submissionFolderWatcher.Filter = filter;
                submissionFolderWatcher.EnableRaisingEvents = true;
            }
            catch (Exception ex)
            {
                ApplicationLogger.Inst.LogException(ERROR_LOG_NAME, ex.Message, ex);
            }
        }

        protected override void OnStop()
        {
        }

        private void submissionFolderWatcher_Renamed(object sender, RenamedEventArgs e)
        {
            ApplicationLogger.Inst.LogInfo(INFO_LOG_NAME, "File detected: " + e.FullPath);

            processor.EnqueueFile(e.FullPath);
            processor.ProcessQueuedFilesAsync();
        }
    }
}
and here's the corresponding Program class:
using System.IO;
using System.Linq;
using System.ServiceProcess;
using NSWHealth.DX.Common.Web;
using SI.Moh.Phisco_Periph.Dto.Mapping;

namespace SI.Moh.Phisco.Submissions.Service
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        static void Main(string[] args)
        {
            DomainMapper.MapDomain();

            if (args.Length == 1 && args[0] == "/console")
            {
                // Run the application as a Console app.
                using (var processor = new SubmissionProcessor())
                {
                    var folder = new DirectoryInfo(Properties.Settings.Default.SubmissionsRootFolder);

                    foreach (var file in folder.GetFiles(Properties.Settings.Default.SubmissionFileNamePattern).OrderBy(fi => fi.CreationTime))
                    {
                        processor.EnqueueFile(file.FullName);
                    }

                    processor.ProcessQueuedFiles();
                }
            }
            else
            {
                // Run the application as a Windows service.
                ServiceBase[] ServicesToRun;
                ServicesToRun = new ServiceBase[]
                                    {
                                        new SubmissionService()
                                    };
                ServiceBase.Run(ServicesToRun);
            }
        }
    }
}
As for installing with commandline args, I don't think that it's possible using standard functionality. I did a little bit of searching and, while I haven't read it, I think that this may be able to help:

Install a Windows service the way YOU want to! - CodeProject
 

wolk_tambowskij

New member
Joined
Sep 25, 2015
Messages
4
Programming Experience
Beginner
Dear friend,
thank you for your explanation.
As I'm thinking right I can define the parameters by a OnStart or OnBeforeStart method...
But what I don't understand is how I can let MyApp use the input from the form to create and submit the arguments to AmyApp.
Also, as I'm very new in programming, I only partially understand the logic of your example and how to use your code in my project: for ex. if I understand you are creating an error logger and I see where to specify the pathes for the log files that will be created by the service, but I don't realize where to put the path for the AnyApp.exe that shuld be used as the service in my case...
The article from code project is helpfull, but to difficult for me, I think - I wanted to keep it simple and by possibility stay on C#...
If it isn't too difficult for you could you please explain me the logic of your service like for a dummy and a complete beginner?
I will understand if you don't have the time for it, but sometimes its really helpfull when you get a tutorial by a teacher knowing your problem... I already made a research through different forums and tried reading some general teaching materials, but I got still more confused... I'm more the "learning by doing" guy - after a successful creation of the form I seam to need a step by step guide...
 

wolk_tambowskij

New member
Joined
Sep 25, 2015
Messages
4
Programming Experience
Beginner
Dear John,
when I'm right in this way I can start the service with the given parameters using MyApp only, but my need is to register this service with that parameters once from MyApp so that after installation it starts on every boot automatically using this parameters.
 

wim sturkenboom

Well-known member
Joined
Aug 6, 2014
Messages
85
Location
Roodepoort, South Africa
Programming Experience
10+
Have you considered to place your parameters in a configuration file. When the service starts, it can read the file and get the 'parameters' that way. No need for passing. If you want to use different parameters, modify the configuration file (I guess that that would be the function of MyApp.exe) and restart the service (I think that that can also be done from MyApp.exe, but never tried it).
 
Top Bottom