diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/AgentShell.csproj b/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/AgentShell.csproj
index 39fef1606a2..a4c6b1fc073 100644
--- a/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/AgentShell.csproj
+++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/AgentShell.csproj
@@ -70,6 +70,7 @@
..\packages\NSubstitute.1.6.1.0\lib\NET40\NSubstitute.dll
+
@@ -101,6 +102,12 @@
+
+ Component
+
+
+ ProjectInstaller.cs
+
True
@@ -137,4 +144,4 @@
-->
-
+
\ No newline at end of file
diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/Program.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/Program.cs
index 10663708508..e84350020c4 100644
--- a/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/Program.cs
+++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/Program.cs
@@ -21,12 +21,15 @@ 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));
+ private static string serviceName = "CloudStack ServerResource";
///
/// Application entry point allows service to run in console application or as a Windows service.
@@ -34,25 +37,174 @@ namespace CloudStack.Plugin.AgentShell
///
static void Main(params string[] args)
{
- string arg1 = string.Empty;
-
- if (args.Length > 0)
- {
- arg1 = args[0];
- logger.DebugFormat("CloudStack ServerResource arg is ", arg1);
- }
-
- if (string.Compare(arg1, "--console", true) == 0)
- {
- logger.InfoFormat("CloudStack ServerResource running as console app");
- new AgentService().RunConsole(args);
- }
- else
+ if (args.Length == 0)
{
logger.InfoFormat("CloudStack ServerResource running as Windows Service");
ServiceBase[] ServicesToRun = new ServiceBase[] { new AgentService() };
ServiceBase.Run(ServicesToRun);
}
+ else if (args.Length == 1)
+ {
+ logger.DebugFormat("CloudStack ServerResource arg is ", args[0]);
+ switch (args[0])
+ {
+ case "--install":
+ logger.InfoFormat("Installing and running CloudStack ServerResource ");
+ InstallService();
+ StartService();
+ break;
+ case "--uninstall":
+ logger.InfoFormat("stopping and uninstalling CloudStack ServerResource ");
+ StopService();
+ UninstallService();
+ break;
+ case "--console":
+ logger.InfoFormat("CloudStack ServerResource running as console app");
+ new AgentService().RunConsole(args);
+ break;
+ default:
+ throw new NotImplementedException();
+ }
+ }
+ }
+
+ 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 occured 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 occured 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 occured 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 occured in stopping service " + ex.Message);
+ throw;
+ }
+ }
}
}
}
diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/ProjectInstaller.Designer.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/ProjectInstaller.Designer.cs
new file mode 100644
index 00000000000..9b9dbb6edb9
--- /dev/null
+++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/ProjectInstaller.Designer.cs
@@ -0,0 +1,60 @@
+namespace CloudStack.Plugin.AgentShell
+{
+ partial class ProjectInstaller
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Component Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.serviceProcessInstaller1 = new System.ServiceProcess.ServiceProcessInstaller();
+ this.serviceInstaller1 = new System.ServiceProcess.ServiceInstaller();
+ //
+ // serviceProcessInstaller1
+ //
+ this.serviceProcessInstaller1.Account = System.ServiceProcess.ServiceAccount.LocalSystem;
+ this.serviceProcessInstaller1.Password = null;
+ this.serviceProcessInstaller1.Username = null;
+ //
+ // serviceInstaller1
+ //
+ this.serviceInstaller1.Description = "CloudStack Agent";
+ this.serviceInstaller1.DisplayName = "CloudStack ServerResource";
+ this.serviceInstaller1.ServiceName = "CloudStack ServerResource";
+ this.serviceInstaller1.StartType = System.ServiceProcess.ServiceStartMode.Automatic;
+ //
+ // ProjectInstaller
+ //
+ this.Installers.AddRange(new System.Configuration.Install.Installer[] {
+ this.serviceProcessInstaller1,
+ this.serviceInstaller1});
+
+ }
+
+ #endregion
+
+ private System.ServiceProcess.ServiceProcessInstaller serviceProcessInstaller1;
+ private System.ServiceProcess.ServiceInstaller serviceInstaller1;
+ }
+}
\ No newline at end of file
diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/ProjectInstaller.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/ProjectInstaller.cs
new file mode 100644
index 00000000000..c3a225f540a
--- /dev/null
+++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/ProjectInstaller.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Configuration.Install;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace CloudStack.Plugin.AgentShell
+{
+ [RunInstaller(true)]
+ public partial class ProjectInstaller : System.Configuration.Install.Installer
+ {
+ public ProjectInstaller()
+ {
+ InitializeComponent();
+ }
+ }
+}