Beispiel #1
0
        /// <summary>
        /// The callback function that gets called when the configuration file changes.
        ///
        /// NOTE:
        ///		OnChanged gets fired multiple times if changes are made using notepad..
        ///		this is annoying in terms of performance but otherwise doesn't affect the correctness of
        ///		the program.
        /// </summary>
        /// <param name="a"></param>
        /// <param name="file"></param>
        public void ConfigurationFileChangedCallBack
            (object a,
            FileSystemEventArgs file)
        {
            try
            {
                //Read the configuration information using External Storage Reader
                //Read the entire XML file and get our part from the file
                Global.WriteInfo("Configuration file changed externally...");

                ReloadActivatorConfiguration();
            }
            catch (Exception e)
            {
                EAException ea = e as EAException;

                // if the exception was warning then just report it and ignore the update
                if (ea != null && (int)ea.Error < 0)
                {
                    EAException.Report(e);
                    Global.WriteWarning(
                        "Configuration file update was ignored because of bad data in it.");
                }
                else
                {
                    Global.DoHardKill(e);
                }
            }
        }
        /// <summary>
        /// Recycles the existing log file
        /// </summary>
        public static void RecycleLog()
        {
            lock (ms_hardKill)
            {
                if (ms_outputFile == null)
                {
                    return;
                }

                // Generate the new file name
                DateTime dt          = DateTime.Now;
                string   ext         = "." + dt.Year + "." + dt.Month + "." + dt.Day + "." + dt.Hour + "." + dt.Minute + "." + dt.Second + "." + dt.Millisecond;
                string   NewFileName = ms_appName + ext + OUTPUTEXT;
                try
                {
                    // copy the log file to the new log file
                    File.Copy(ms_outputLogName, NewFileName);
                    WriteToConsole("The output file was saved as: " + NewFileName);
                }
                catch (Exception e)
                {
                    WriteToConsole("Cannot save the existing output file as: " + NewFileName + ". The output file is preserved");
                    EAException.Report(e);
                }

                //  truncate the current log file
                ms_outputFile.SetLength(0);
            }
        }
        /// <summary>
        //	Installs the Windows NT Service. Uses a transacted installer, so that
        //	if installation fails midstream for some reason, installation is rolled
        //	back. Post installation, the registry settings for the service are modified
        //	to change the command-line parameters (because currently, CLR does not allow it)
        //	If registry modification fails for some reason, uninstall is called on the service.
        /// </summary>
        /// <param name="svcname">Service to install</param>
        /// <param name="username">User name to execute under</param>
        /// <param name="password">Password of the user</param>
        public static void Install(
            string svcname,
            string username,
            string password)
        {
            bool doUninstall = false;

            try
            {
                Global.WriteStatus("External Activator is installing as NT service '" + svcname + "' ...");
                TransactedInstaller ti = new TransactedInstaller();

                // Sets information required for installing (might get username and password information from the user)
                ProjectInstaller mi = new ProjectInstaller(svcname, username, password);
                ti.Installers.Add(mi);
                String path = String.Format("/assemblypath={0}",
                                            System.Reflection.Assembly.GetExecutingAssembly().Location);
                String[]       cmdline = { path };
                InstallContext ctx     = new InstallContext(String.Format(svcname + ".InstallLog"), cmdline);
                ti.Context = ctx;

                // Starts the installation process
                ti.Install(new Hashtable());
                doUninstall = true;

                // Registry modification of Command-Line arguments to include (-svc) followed by the service name
                // to install it as a particular External Activator.
                RegistryKey key             = Registry.LocalMachine.OpenSubKey(String.Format("System\\CurrentControlSet\\Services\\{0}", svcname), true);
                object      ImagePathObject = key.GetValue("ImagePath");
                if (ImagePathObject != null)
                {
                    Global.WriteDebugInfo("Modifying the registry to include command-line parameters after installation.");
                    string ImagePath = String.Format("{0} /{1}:{2}", (string)ImagePathObject, CommandLineArgument.RunAsNTServiceArgument, svcname);
                    key.SetValue("ImagePath", ImagePath);
                }
                else
                {
                    // Calls Uninstall if registry modification not possible
                    throw new EAException("Critical Error : Could not open ImagePath key of NT service '" + svcname + "' in the registry. Uninstalling service", Error.postInstallProblem);
                }
                Global.WriteStatus("External Activator is successfully installed as NT service '" + svcname + "' ...");
            }
            catch (Exception e)
            {
                if (doUninstall)
                {
                    try
                    {
                        NTService.Uninstall(svcname);
                    }
                    catch (Exception eNested)
                    {
                        EAException.Report(eNested);
                    }
                }
                throw new EAException("External Activation Installation failed", Error.installProblem, e);
            }
        }
        public static void DoHardKill(
            Exception e)
        {
            ms_logMgr.UncleanShutdown();
            EAException.Report(e, true);
            WriteError("External activator was abruptly terminated.");

            EAException ea = e as EAException;

            if (ea != null)
            {
                System.Environment.Exit((int)ea.Error);
            }

            System.Environment.Exit((int)Error.unexpectedError);
        }
        /// <summary>
        ///		Performs necessary initialization of the External Activation NT Service so that it can start
        ///		doing its work.
        /// </summary>
        /// <param name="args"></param>
        protected override void OnStart(
            string[] args) // I		optional startup arguments
        {
            try
            {
                if (Global.Shutdown == false)
                {
                    Global.BootExternalActivator();
                    return;
                }
            }
            catch (Exception e)
            {
                Global.SetShutdown();
                EAException.Report(e);
            }

            StopService(new ServiceController(this.ServiceName), new TimeSpan(1));
            return;
        }
Beispiel #6
0
        /// <summary>
        /// Connects to the sql server and database and run the service
        /// </summary>
        public static void Start(
            ConfigurationManager configMgr)
        {
            Global.WriteDebugInfo("Starting up the Notification service...");

            configMgr.GetNotificationService(
                ref ms_notificationSQLServer,
                ref ms_notificationDatabase,
                ref ms_notificationService);
            ms_connected  = false;
            ms_connecting = false;
            ms_error      = null;

            NotificationService ns         = null;
            SqlConnection       connection = null;
            int waiting_time = 1000;
            int retry        = 0;

            while (true)
            {
                bool fFailedToConnect = false;

                //  define a connection if needed
                if (connection == null)
                {
                    connection = new SqlConnection(
                        String.Format("server={0};Integrated security=true;database={1};Connect Timeout=10;Application Name=External activator",
                                      ms_notificationSQLServer,
                                      ms_notificationDatabase));
                    ns = null;
                }

                // if connection is up, do not establish again. Else, establish a connection
                // Always started the first time
                if (connection.State != ConnectionState.Open)
                {
                    try
                    {
                        ms_connecting = true;
                        connection.Open();
                    }
                    catch (SqlException e)
                    {
                        if (ms_error != e.Message)
                        {
                            ms_error = e.Message;
                            Global.WriteWarning(
                                "Failed to connect to Notification SQL Server '" + ms_notificationSQLServer + "' and Database: '" + ms_notificationDatabase +
                                "' because: " + e.Message);
                        }
                        else
                        {
                            Global.WriteDebugInfo(
                                "Failed to connect to Notification SQL Server '" + ms_notificationSQLServer + "' and Database: '" + ms_notificationDatabase +
                                "' because: " + e.Message);
                        }
                        connection.Dispose();
                        connection       = null;
                        fFailedToConnect = true;
                    }
                    ms_connecting = false;

                    if (fFailedToConnect)
                    {
                        // Implement an exponential back-off rate of connecting (else this might
                        // overflow the EventLog and other logs
                        waiting_time *= 2;
                        if (waiting_time > Global.MAX_WAITING_TIME)
                        {
                            waiting_time = Global.MAX_WAITING_TIME;
                        }
                        Thread.Sleep(waiting_time);

                        continue;
                    }

                    Global.WriteInfo("Connection to notification SQL server '" + ms_notificationSQLServer + "' and database '" + ms_notificationDatabase + "' is established.");
                    waiting_time = 1000;
                    ms_error     = null;
                    ms_connected = true;
                }

                //  create a notification service is one does not exist
                if (ns == null)
                {
                    try
                    {
                        ns = new NotificationService(
                            ms_notificationService,
                            connection,
                            configMgr);
                    }
                    catch (ArgumentException e)
                    {
                        //  if bad parameters were provided then
                        //  report the problem and retry later
                        if (ms_error != e.Message)
                        {
                            Global.WriteWarning(e.Message);
                            ms_error = e.Message;
                        }
                        else
                        {
                            Global.WriteDebugInfo(e.Message);
                        }

                        fFailedToConnect = true;
                    }

                    if (fFailedToConnect)
                    {
                        waiting_time *= 2;
                        if (waiting_time > Global.MAX_WAITING_TIME)
                        {
                            waiting_time = Global.MAX_WAITING_TIME;
                        }
                        Thread.Sleep(waiting_time);
                        continue;
                    }
                    waiting_time = 1000;
                }

                //  now receive all the messages for this service and
                //  end the application
                ns.WaitforTimeout = TimeSpan.FromSeconds(-1);
                ns.FetchSize      = 1;
                bool fRestart = false;
                Global.WriteInfo("Notification service '" + ms_notificationService + "' is started.");
                try
                {
                    ns.Run(true, connection, null);
                }
                catch (ServiceException e)
                {
                    Global.WriteWarning("Service exception occured while running. External activator will try to reconnect.");
                    if (retry == 3)
                    {
                        Global.DoHardKill(e);
                    }

                    EAException.Report(e);
                    fRestart = true;
                }
                catch (SqlException e)
                {
                    Global.WriteWarning("Service exception occured while running. External activator will try to reconnect.");
                    if (retry == 3)
                    {
                        Global.DoHardKill(e);
                    }

                    EAException.Report(e);
                    fRestart = true;
                }
                catch (Exception e)
                {
                    Global.DoHardKill(e);
                }

                if (fRestart)
                {
                    retry++;
                    //  reset the state and retry again
                    ms_connected  = false;
                    ms_connecting = false;
                    ms_error      = null;
                    waiting_time  = 1000;
                    ns            = null;
                    connection.Close();
                    connection = null;
                    continue;
                }

                connection.Close();
                return;
            }
        }