Search code examples
c#asp.netwindows-servicesregistryinstallutil

Passing parameters to Windows Service during installation


I am creating a windows service which is suppose to look up data in a specific table and then process the record based the status.

I want to pass the DB credentials while I install the service using installutill as parameters and save them inside registry. I have tried doing so using the code bellow, but I keep getting error on the event "OnBeforeInstall".

I believe either I am passing the parameters incorrectly or I am writing code in the wrong event. Need your help to figure what am I doing wrong.

protected override void OnBeforeInstall(IDictionary savedState)
{
    base.OnBeforeInstall(savedState);
    _eventLog.WriteEntry("OnBeforeInstall Started");
    try
    {
        RegistryKey key = Registry.CurrentUser.CreateSubKey(@"SOFTWARE\RyteRMS");
        if (key != null)
        {
            _eventLog.WriteEntry("Write data to registry key");
            key.SetValue("DBTYPE", this.Context.Parameters["dbtype"].ToString()); // This throws error, I am assuming as the above event entry is visible.
            key.SetValue("DATASOURCE", this.Context.Parameters["datasource"].ToString());
            key.SetValue("USERID", this.Context.Parameters["userid"].ToString());
            key.SetValue("PASSWORD", this.Context.Parameters["password"].ToString());
            key.SetValue("DBNAME", this.Context.Parameters["dbname"].ToString());
            key.Close();
        }
    }
    catch (Exception ex)
    {
        _eventLog.WriteEntry(ex.Message);
    }
    _eventLog.WriteEntry("OnBeforeInstall Finished");
}

I am writing this on the command prompt: installutil RMSBGService.exe /dbtype=sqlserver /datasource=hitin-lt /dbname=rms /userid=admin /password=passw0rd

Error: "Object reference not set to an instance of an object."

P.S. I dont know how to debug the Win Service, so I am using event log to record every thing.


Solution

  • Managed to do it on my own, this is what we are suppose to do it.

    protected override void OnBeforeInstall(IDictionary savedState)
    {
        _eventLog.WriteEntry("OnBeforeInstall Started");
        try
        {
            RegistryKey key = Microsoft.Win32.Registry.LocalMachine.CreateSubKey(@"SOFTWARE\RMS");
            if (key != null)
            {
                _eventLog.WriteEntry("Write data to registry key");
    
                Process _prc = new Process();
                _prc.StartInfo.FileName = "cmd.exe";
                _prc.StartInfo.UseShellExecute = false;
                _prc.StartInfo.RedirectStandardOutput = true;
                _prc.StartInfo.RedirectStandardInput = true;
                _prc.Start();
    
                ConsoleColor _color = Console.ForegroundColor;
                Console.ForegroundColor = ConsoleColor.DarkGreen;
                Console.WriteLine("\n\n");
                Console.WriteLine("PLEASE ENTER FOLLOWING DETAILS TO COMPLETE SETUP");
                Console.WriteLine("NOTE: if you enter wrong information, you will need to reinstall the application.");
                Console.WriteLine("\n\n");
                Console.WriteLine("Enter DBTYPE (SQLSERVER or ORACLE):");
                key.SetValue("DBTYPE", StringCipher.Encrypt(Console.ReadLine(), "@xx"));
                Console.WriteLine("Enter DATASOURCE (SERVER NAME):");
                key.SetValue("DATASOURCE", StringCipher.Encrypt(Console.ReadLine(), "@xx"));
                Console.WriteLine("Enter DATABASE USER ID:");
                key.SetValue("USERID", StringCipher.Encrypt(Console.ReadLine(), "@xx"));
                Console.WriteLine("Enter PASSWORD:");
                key.SetValue("PASSWORD", StringCipher.Encrypt(Console.ReadLine(), "@xx"));
                Console.WriteLine("Enter DATABASE NAME:");
                key.SetValue("DBNAME", StringCipher.Encrypt(Console.ReadLine(), "@xx"));
                key.Close();
                Console.ForegroundColor = _color;
                _prc.Close();
            }
        }
        catch (Exception ex)
        {
            _eventLog.WriteEntry(ex.Message);
        }
        _eventLog.WriteEntry("OnBeforeInstall Finished");
        base.OnBeforeInstall(savedState);
    }
    

    StringCipher is a custom function that I used to encrypt/decrypt my text. Later on start, I am reading these stored values from the registry, and decrypt them to pass it onto database connection code and do the needful.

    Hope this would help someone.

    NOTE

    You must install this service using "InstallUtil", if you choose to install it using a Setup project, this installation will be stuck with a cmd window open.