// Licensed to the Apache Software Foundation (ASF) under one // or more contributor license agreements. See the NOTICE file // distributed with this work for additional information // regarding copyright ownership. The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. using log4net; using System; using System.Collections.Generic; using System.Linq; using System.ServiceProcess; using System.Text; using System.Threading.Tasks; using System.Configuration.Install; using System.Collections; namespace CloudStack.Plugin.AgentShell { static class Program { private static ILog logger = LogManager.GetLogger(typeof(Program)); public const string serviceName = "CloudStack Hyper-V Agent"; private static string option = null; private static string user = null; private static string password = null; private const string install = "--install"; private const string uninstall = "--uninstall"; private const string console = "--console"; /// /// Application entry point allows service to run in console application or as a Windows service. /// Add '--console' to the commandline for the former, the latter is the default. /// static void Main(params string[] args) { if (args.Length == 0) { logger.InfoFormat(serviceName + " running as Windows Service"); ServiceBase[] ServicesToRun = new ServiceBase[] { new AgentService() }; ServiceBase.Run(ServicesToRun); } else if (ParseArguments(args)) { switch (option) { case install: logger.InfoFormat("Installing and running " + serviceName); InstallService(); StartService(); break; case uninstall: logger.InfoFormat("Stopping and uninstalling " + serviceName); StopService(); UninstallService(); break; case console: logger.InfoFormat(serviceName + " is running as console application"); new AgentService().RunConsole(args); break; default: throw new NotImplementedException(); } } else { string argumentExample = "--(install/uninstall/console) [-u ] [-p ].\n" + " For example:\n " + " --install -u domain1\\user1 -p mypwd\n"+ " --uninstall"; logger.Error("Invalid arguments passed for installing\\uninstalling the service. \n" + argumentExample); } } static private Boolean ParseArguments(string[] args) { logger.DebugFormat(serviceName + " arg is ", args[0]); int argIndex = 0; while (argIndex < args.Length) { switch (args[argIndex]) { case install: case uninstall: case console: option = args[argIndex]; argIndex++; break; case "-u": user = args[argIndex+1]; argIndex+=2; break; case "-p": password = args[argIndex+1]; argIndex+=2; break; default: argIndex++; // Unrecognised argument. Do nothing; break; } } // Validate arguments return ValidateArguments(); } private static Boolean ValidateArguments() { Boolean argsValid = false; switch (option) { case uninstall: case install: case console: argsValid = true; break; default: break; } return argsValid; } public static string GetPassword() { return password; } public static string GetUser() { return user; } private static bool IsInstalled() { using (ServiceController controller = new ServiceController(serviceName)) { try { ServiceControllerStatus status = controller.Status; } catch { return false; } return true; } } private static bool IsRunning() { using (ServiceController controller = new ServiceController(serviceName)) { if (!IsInstalled()) return false; return (controller.Status == ServiceControllerStatus.Running); } } private static AssemblyInstaller GetInstaller() { AssemblyInstaller installer = new AssemblyInstaller( typeof(Program).Assembly, null); installer.UseNewContext = true; return installer; } private static void InstallService() { if (IsInstalled()) return; try { using (AssemblyInstaller installer = GetInstaller()) { IDictionary state = new Hashtable(); try { installer.Install(state); installer.Commit(state); } catch { try { installer.Rollback(state); } catch { } throw; } } } catch (Exception ex) { logger.ErrorFormat(" Error occurred in installing service " + ex.Message); throw; } } private static void UninstallService() { if (!IsInstalled()) return; try { using (AssemblyInstaller installer = GetInstaller()) { IDictionary state = new Hashtable(); try { installer.Uninstall(state); } catch { throw; } } } catch (Exception ex) { logger.ErrorFormat(" Error occurred in uninstalling service " + ex.Message); throw; } } private static void StartService() { if (!IsInstalled()) return; using (ServiceController controller = new ServiceController(serviceName)) { try { if (controller.Status != ServiceControllerStatus.Running) { controller.Start(); controller.WaitForStatus(ServiceControllerStatus.Running, TimeSpan.FromSeconds(10)); } } catch (Exception ex) { logger.ErrorFormat(" Error occurred in starting service " + ex.Message); throw; } } } private static void StopService() { if (!IsInstalled()) return; using (ServiceController controller = new ServiceController(serviceName)) { try { if (controller.Status != ServiceControllerStatus.Stopped) { controller.Stop(); controller.WaitForStatus(ServiceControllerStatus.Stopped, TimeSpan.FromSeconds(10)); } } catch (Exception ex) { logger.ErrorFormat(" Error occurred in stopping service " + ex.Message); throw; } } } } }