Initial project's source code check-in.

This commit is contained in:
ptsurbeleu 2011-07-13 16:07:32 -07:00
commit b03b0b373f
4573 changed files with 981205 additions and 0 deletions

View file

@ -0,0 +1,28 @@
<?xml version="1.0"?>
<configuration>
<configSections>
<section name="moduleSettings" type="WebsitePanel.VmConfig.ModuleSettingsSection, WebsitePanel.VmConfig"/>
</configSections>
<appSettings>
<!-- Start-up delay in milliseconds - time to wait before tasks execution -->
<add key="Service.StartupDelay" value="0"/>
<!-- Interval in milliseconds to poll registry keys. 1 - read registry only once -->
<add key="Service.RegistryPollInterval" value="30000"/>
<!-- Interval in milliseconds to poll system summary (RAM and HDD). -->
<add key="Service.SystemSummaryInterval" value="15000"/>
<!-- Stop service after idle interval in milliseconds. 1 - service never stops -->
<add key="Service.ExitIdleInterval" value="1"/>
</appSettings>
<moduleSettings>
<modules>
<add key="ChangeComputerName" value="WebsitePanel.VmConfig.ChangeComputerNameModule, WebsitePanel.VmConfig.Common"/>
<add key="ChangeAdministratorPassword" value="WebsitePanel.VmConfig.ChangeAdministratorPasswordModule, WebsitePanel.VmConfig.Common"/>
<add key="SetupNetworkAdapter" value="WebsitePanel.VmConfig.SetupNetworkAdapterModule, WebsitePanel.VmConfig.Common"/>
</modules>
</moduleSettings>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration>

View file

@ -0,0 +1,124 @@
// Copyright (c) 2011, Outercurve Foundation.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// - Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// - Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// - Neither the name of the Outercurve Foundation nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
using System;
using System.IO;
using System.Security.Policy;
using System.Diagnostics;
using System.Reflection;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Remoting.Lifetime;
namespace WebsitePanel.VmConfig
{
[Serializable]
internal class ModuleLoader : MarshalByRefObject
{
internal ExecutionResult RemoteRun(string typeName, ref ExecutionContext context)
{
if (string.IsNullOrEmpty(typeName))
throw new ArgumentNullException("typeName");
string[] parts = typeName.Split(',');
if (parts == null || parts.Length != 2)
throw new ArgumentException("Incorrect type name " + typeName);
Assembly assembly = typeof(ModuleLoader).Assembly;
string fileName = parts[1].Trim();
if (!fileName.EndsWith(".dll"))
fileName = fileName + ".dll";
string path = Path.Combine(Path.GetDirectoryName(assembly.Location), fileName);
assembly = Assembly.LoadFrom(path);
Type type = assembly.GetType(parts[0].Trim());
//Type type = Type.GetType(typeName);
if (type == null)
{
throw new Exception(string.Format("Type {0} not found", typeName));
}
IProvisioningModule module = Activator.CreateInstance(type) as IProvisioningModule;
if (module == null)
{
throw new Exception(string.Format("Module {0} not found", typeName));
}
return module.Run(ref context);
}
internal void AddTraceListener(TraceListener traceListener)
{
Trace.Listeners.Add(traceListener);
}
internal static ExecutionResult Run(string typeName, ref ExecutionContext context)
{
AppDomain domain = null;
try
{
Evidence securityInfo = AppDomain.CurrentDomain.Evidence;
AppDomainSetup info = new AppDomainSetup();
info.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory;
domain = AppDomain.CreateDomain("Remote Domain", securityInfo, info);
ILease lease = domain.GetLifetimeService() as ILease;
if (lease != null)
{
lease.InitialLeaseTime = TimeSpan.Zero;
}
domain.UnhandledException += new UnhandledExceptionEventHandler(OnDomainUnhandledException);
ModuleLoader loader = (ModuleLoader)domain.CreateInstanceAndUnwrap(
typeof(ModuleLoader).Assembly.FullName,
typeof(ModuleLoader).FullName);
foreach (TraceListener listener in Trace.Listeners)
{
loader.AddTraceListener(listener);
}
ExecutionResult ret = loader.RemoteRun(typeName, ref context);
AppDomain.Unload(domain);
return ret;
}
catch (Exception)
{
if (domain != null)
{
AppDomain.Unload(domain);
}
throw;
}
}
static void OnDomainUnhandledException(object sender, UnhandledExceptionEventArgs e)
{
ServiceLog.WriteError("Remote application domain error", (Exception)e.ExceptionObject);
}
}
}

View file

@ -0,0 +1,60 @@
// Copyright (c) 2011, Outercurve Foundation.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// - Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// - Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// - Neither the name of the Outercurve Foundation nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
using System;
using System.Collections.Generic;
using System.Text;
using System.Configuration;
namespace WebsitePanel.VmConfig
{
/// <summary>
/// Provides configuration system support for the <studioSettings> configuration section.
/// </summary>
internal class ModuleSettingsSection : ConfigurationSection
{
/// <summary>
/// Creates a new instance of the StudioSection class.
/// </summary>
public ModuleSettingsSection()
{
}
[ConfigurationProperty("modules", IsDefaultCollection = true)]
public KeyValueConfigurationCollection Modules
{
get
{
return (KeyValueConfigurationCollection)base["modules"];
}
}
}
}

View file

@ -0,0 +1,46 @@
// Copyright (c) 2011, Outercurve Foundation.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// - Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// - Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// - Neither the name of the Outercurve Foundation nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
using System;
using System.ServiceProcess;
namespace WebsitePanel.VmConfig
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main()
{
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[] { new VmConfigService() };
ServiceBase.Run(ServicesToRun);
}
}
}

View file

@ -0,0 +1,63 @@
namespace WebsitePanel.VmConfig
{
partial class ProjectInstaller
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.serviceProcessInstaller = new System.ServiceProcess.ServiceProcessInstaller();
this.serviceInstaller = new System.ServiceProcess.ServiceInstaller();
//
// serviceProcessInstaller
//
this.serviceProcessInstaller.Account = System.ServiceProcess.ServiceAccount.LocalSystem;
this.serviceProcessInstaller.Password = null;
this.serviceProcessInstaller.Username = null;
//
// serviceInstaller
//
this.serviceInstaller.Description = "Performs provisioning operations in the quest operating system.";
this.serviceInstaller.DisplayName = "WebsitePanel Virtual Machine Configuration Service";
this.serviceInstaller.ServiceName = "WSPVmConfig";
this.serviceInstaller.StartType = System.ServiceProcess.ServiceStartMode.Automatic;
this.serviceInstaller.ServicesDependedOn = new string[] { "vmickvpexchange" };
//
// ProjectInstaller
//
this.Installers.AddRange(new System.Configuration.Install.Installer[] {
this.serviceProcessInstaller,
this.serviceInstaller});
}
#endregion
private System.ServiceProcess.ServiceProcessInstaller serviceProcessInstaller;
private System.ServiceProcess.ServiceInstaller serviceInstaller;
}
}

View file

@ -0,0 +1,45 @@
// Copyright (c) 2011, Outercurve Foundation.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// - Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// - Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// - Neither the name of the Outercurve Foundation nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration.Install;
namespace WebsitePanel.VmConfig
{
[RunInstaller(true)]
public partial class ProjectInstaller : Installer
{
public ProjectInstaller()
{
InitializeComponent();
}
}
}

View file

@ -0,0 +1,129 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="serviceProcessInstaller.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 54</value>
</metadata>
<metadata name="serviceInstaller.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>196, 17</value>
</metadata>
<metadata name="$this.TrayLargeIcon" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
</root>

View file

@ -0,0 +1,21 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("WebsitePanel Virtual Machine Configuration Service")]
[assembly: AssemblyDescription("Performs provisioning operations in the guest operating system.")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyProduct("WebsitePanel VPS Solution")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("52e42d75-bcac-406f-b3ed-31d19265ea22")]

View file

@ -0,0 +1,214 @@
// Copyright (c) 2011, Outercurve Foundation.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// - Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// - Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// - Neither the name of the Outercurve Foundation nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
using System;
using System.Configuration;
using System.Diagnostics;
using System.IO;
using System.Reflection;
namespace WebsitePanel.VmConfig
{
/// <summary>
/// Log.
/// </summary>
internal sealed class ServiceLog
{
/// <summary>
/// Initializes a new instance of the class.
/// </summary>
private ServiceLog()
{
}
/// <summary>
/// Initializes trace listeners.
/// </summary>
static ServiceLog()
{
string fileName = LogFile;
FileStream fileLog = new FileStream(fileName, FileMode.Append);
TextWriterTraceListener fileListener = new TextWriterTraceListener(fileLog);
fileListener.TraceOutputOptions = TraceOptions.DateTime;
Trace.UseGlobalLock = true;
Trace.Listeners.Clear();
Trace.Listeners.Add(fileListener);
TextWriterTraceListener consoleListener = new TextWriterTraceListener(Console.Out);
Trace.Listeners.Add(consoleListener);
Trace.AutoFlush = true;
}
private static string LogFile
{
get
{
Assembly assembly = typeof(ServiceLog).Assembly;
return Path.Combine(Path.GetDirectoryName(assembly.Location), assembly.GetName().Name + ".log");
}
}
/// <summary>
/// Write error to the log.
/// </summary>
/// <param name="message">Error message.</param>
/// <param name="ex">Exception.</param>
internal static void WriteError(string message, Exception ex)
{
try
{
string line = string.Format("[{0:G}] ERROR: {1}", DateTime.Now, message);
Trace.WriteLine(line);
Trace.WriteLine(ex);
}
catch { }
}
/// <summary>
/// Write error to the log.
/// </summary>
/// <param name="message">Error message.</param>
internal static void WriteError(string message)
{
try
{
string line = string.Format("[{0:G}] ERROR: {1}", DateTime.Now, message);
Trace.WriteLine(line);
}
catch { }
}
/// <summary>
/// Write to log
/// </summary>
/// <param name="message"></param>
internal static void Write(string message)
{
try
{
string line = string.Format("[{0:G}] {1}", DateTime.Now, message);
Trace.Write(line);
}
catch { }
}
/// <summary>
/// Write line to log
/// </summary>
/// <param name="message"></param>
internal static void WriteLine(string message)
{
try
{
string line = string.Format("[{0:G}] {1}", DateTime.Now, message);
Trace.WriteLine(line);
}
catch { }
}
/// <summary>
/// Write info message to log
/// </summary>
/// <param name="message"></param>
internal static void WriteInfo(string message)
{
try
{
string line = string.Format("[{0:G}] INFO: {1}", DateTime.Now, message);
Trace.WriteLine(line);
}
catch { }
}
/// <summary>
/// Write start message to log
/// </summary>
/// <param name="message"></param>
internal static void WriteStart(string message)
{
try
{
string line = string.Format("[{0:G}] START: {1}", DateTime.Now, message);
Trace.WriteLine(line);
}
catch { }
}
/// <summary>
/// Write end message to log
/// </summary>
/// <param name="message"></param>
internal static void WriteEnd(string message)
{
try
{
string line = string.Format("[{0:G}] END: {1}", DateTime.Now, message);
Trace.WriteLine(line);
}
catch { }
}
internal static void WriteApplicationStart()
{
try
{
string name = typeof(ServiceLog).Assembly.GetName().Name;
string version = typeof(ServiceLog).Assembly.GetName().Version.ToString();
string line = string.Format("[{0:G}] APP: {1} {2} started successfully", DateTime.Now, name, version);
Trace.WriteLine(line);
}
catch { }
}
internal static void WriteApplicationStop()
{
try
{
string name = typeof(ServiceLog).Assembly.GetName().Name;
string version = typeof(ServiceLog).Assembly.GetName().Version.ToString();
string line = string.Format("[{0:G}] APP: {1} {2} stopped successfully", DateTime.Now, name, version);
Trace.WriteLine(line);
}
catch { }
}
/// <summary>
/// Opens notepad to view log file.
/// </summary>
public static void ShowLogFile()
{
try
{
string path = LogFile;
path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, path);
Process.Start("notepad.exe", path);
}
catch { }
}
}
}

View file

@ -0,0 +1,37 @@
namespace WebsitePanel.VmConfig
{
partial class VmConfigService
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
this.ServiceName = "WSPVmConfig";
}
#endregion
}
}

View file

@ -0,0 +1,497 @@
// Copyright (c) 2011, Outercurve Foundation.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// - Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// - Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// - Neither the name of the Outercurve Foundation nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
using System;
using System.Configuration;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.ServiceProcess;
using System.Management;
using System.Timers;
using System.Text;
using Microsoft.Win32;
namespace WebsitePanel.VmConfig
{
public partial class VmConfigService : ServiceBase
{
internal const string RegistryInputKey = "SOFTWARE\\Microsoft\\Virtual Machine\\External";
internal const string RegistryOutputKey = "SOFTWARE\\Microsoft\\Virtual Machine\\Guest";
internal const string TaskPrefix = "WSP-";
internal const string CurrentTaskName = "WSP-CurrentTask";
internal const string RAM_SUMMARY_KEY = "VM-RAM-Summary";
internal const string HDD_SUMMARY_KEY = "VM-HDD-Summary";
private Dictionary<string, string> provisioningModules;
private Timer idleTimer;
private Timer pollTimer;
private Timer summaryTimer;
private bool rebootRequired = false;
private System.Threading.Thread mainThread;
public VmConfigService()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
//start main procedure in separate thread
mainThread = new System.Threading.Thread(new System.Threading.ThreadStart(Start));
mainThread.Start();
}
private void Start()
{
//log
ServiceLog.WriteApplicationStart();
// delay (for sync with KVP exchange service)
DelayOnStart();
//init
InitializeProvisioningModules();
InitializeTimers();
// start timer
StartSummaryTimer();
//run tasks
ProcessTasks();
}
protected override void OnStop()
{
if (this.mainThread.IsAlive)
{
this.mainThread.Abort();
}
this.mainThread.Join();
ServiceLog.WriteApplicationStop();
}
private void DelayOnStart()
{
int startupDelay = 0;
if (Int32.TryParse(ConfigurationManager.AppSettings["Service.StartupDelay"], out startupDelay)
&& startupDelay > 0)
{
ServiceLog.WriteStart("Delay on service start-up");
System.Threading.Thread.Sleep(startupDelay);
ServiceLog.WriteEnd("Delay on service start-up");
}
}
private void DeleteOldResults()
{
// get the list of input tasks
string[] strTasks = RegistryUtils.GetRegistryKeyValueNames(RegistryInputKey);
List<string> tasks = new List<string>();
foreach (string strTask in strTasks)
{
if (!string.IsNullOrEmpty(strTask) && strTask.StartsWith(TaskPrefix) && strTask != CurrentTaskName)
{
//save only WebsitePanel tasks
tasks.Add(strTask);
}
}
// get the list of task results
int deletedResults = 0;
string[] strResults = RegistryUtils.GetRegistryKeyValueNames(RegistryOutputKey);
foreach (string strResult in strResults)
{
if (!string.IsNullOrEmpty(strResult) && strResult.StartsWith(TaskPrefix) && strResult != CurrentTaskName)
{
// check if task result exists in the input tasks
if (!tasks.Contains(strResult))
{
DeleteRegistryKeyValue(RegistryOutputKey, strResult);
ServiceLog.WriteInfo(string.Format("Deleted activity result: {0}", strResult));
deletedResults++;
}
}
}
if(deletedResults > 0)
ServiceLog.WriteEnd(string.Format("{0} result(s) deleted", deletedResults));
}
private void InitializeProvisioningModules()
{
ServiceLog.WriteStart("Loading provisioning modules...");
provisioningModules = new Dictionary<string, string>();
Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
ModuleSettingsSection section = config.Sections["moduleSettings"] as ModuleSettingsSection;
if ( section != null)
{
foreach (string key in section.Modules.AllKeys)
{
provisioningModules.Add(key, section.Modules[key].Value);
}
}
else
ServiceLog.WriteError("Modules configuration section not found");
ServiceLog.WriteEnd(string.Format("{0} module(s) loaded", provisioningModules.Count));
}
private void InitializeTimers()
{
// idle timer
idleTimer = new Timer();
idleTimer.AutoReset = false;
double idleInterval;
if (!Double.TryParse(ConfigurationManager.AppSettings["Service.ExitIdleInterval"], out idleInterval))
{
ServiceLog.WriteError("Invalid configuration parameter: Service.ExitIdleInterval");
idleInterval = 600000;
}
idleTimer.Interval = idleInterval;
idleTimer.Enabled = false;
idleTimer.Elapsed += new ElapsedEventHandler(OnIdleTimerElapsed);
// poll timer
pollTimer = new Timer();
pollTimer.AutoReset = false;
double pollInterval;
if (!Double.TryParse(ConfigurationManager.AppSettings["Service.RegistryPollInterval"], out pollInterval))
{
ServiceLog.WriteError("Invalid configuration parameter: Service.RegistryPollInterval");
pollInterval = 60000;
}
pollTimer.Interval = pollInterval;
pollTimer.Enabled = false;
pollTimer.Elapsed += new ElapsedEventHandler(OnPollTimerElapsed);
// system symmary timer
summaryTimer = new Timer();
double summaryInterval;
if (!Double.TryParse(ConfigurationManager.AppSettings["Service.SystemSummaryInterval"], out summaryInterval))
{
ServiceLog.WriteError("Invalid configuration parameter: Service.SystemSummaryInterval");
summaryInterval = 15000;
}
summaryTimer.Interval = summaryInterval;
summaryTimer.Enabled = false;
summaryTimer.Elapsed += new ElapsedEventHandler(OnSummaryTimerElapsed);
}
private void OnIdleTimerElapsed(object sender, ElapsedEventArgs e)
{
base.Stop();
}
private void OnPollTimerElapsed(object sender, ElapsedEventArgs e)
{
ProcessTasks();
}
private void OnSummaryTimerElapsed(object sender, ElapsedEventArgs e)
{
GetSystemSummary();
}
private void GetSystemSummary()
{
const UInt64 Size1KB = 0x400;
const UInt64 Size1GB = 0x40000000;
// check free/total RAM
WmiUtils wmi = new WmiUtils("root\\cimv2");
ManagementObjectCollection objOses = wmi.ExecuteQuery("SELECT * FROM Win32_OperatingSystem");
foreach (ManagementObject objOs in objOses)
{
UInt64 freeRam = Convert.ToUInt64(objOs["FreePhysicalMemory"]) / Size1KB;
UInt64 totalRam = Convert.ToUInt64(objOs["TotalVisibleMemorySize"]) / Size1KB;
// write to the registry
RegistryUtils.SetRegistryKeyStringValue(RegistryOutputKey, RAM_SUMMARY_KEY,
String.Format("{0}:{1}", freeRam, totalRam));
objOs.Dispose();
}
// check local HDD logical drives
ManagementObjectCollection objDisks = wmi.ExecuteQuery("SELECT * FROM Win32_LogicalDisk WHERE DriveType = 3");
StringBuilder sb = new StringBuilder();
bool first = true;
foreach (ManagementObject objDisk in objDisks)
{
if(!first)
sb.Append(";");
sb.Append(objDisk["DeviceID"]);
sb.Append(Convert.ToInt32(Convert.ToDouble(objDisk["FreeSpace"]) / (double)Size1GB)).Append(":");
sb.Append(Convert.ToInt32(Convert.ToDouble(objDisk["Size"]) / (double)Size1GB));
first = false;
objDisk.Dispose();
}
// write HDD info
RegistryUtils.SetRegistryKeyStringValue(RegistryOutputKey, HDD_SUMMARY_KEY, sb.ToString());
// dispose resources
objOses.Dispose();
objDisks.Dispose();
}
private void ProcessTasks()
{
// delete old results
DeleteOldResults();
//process all tasks
while (true)
{
//load completed tasks results
string[] strResults = RegistryUtils.GetRegistryKeyValueNames(RegistryOutputKey);
List<string> results = new List<string>();
foreach (string strResult in strResults)
{
if (!string.IsNullOrEmpty(strResult) && strResult.StartsWith(TaskPrefix) && strResult != CurrentTaskName)
{
//save only WebsitePanel tasks
results.Add(strResult);
}
}
// sorted list of tasks - will be sorted by the TaskID (time in ticks)
SortedList<long, string> tasks = new SortedList<long, string>();
//load task definitions from input registry key
string[] strTasks = RegistryUtils.GetRegistryKeyValueNames(RegistryInputKey);
foreach (string strTask in strTasks)
{
if (results.Contains(strTask))
continue; // skip completed tasks
if (!string.IsNullOrEmpty(strTask) && strTask.StartsWith(TaskPrefix))
{
// extract Task ID parameter
int idx = strTask.LastIndexOf('-');
if(idx == -1)
continue;
string strTaskId = strTask.Substring(idx + 1);
long taskId = 0;
try
{
taskId = Int64.Parse(strTaskId);
}
catch
{
continue; // wrong task format
}
//save only WebsitePanel tasks
if(!tasks.ContainsKey(taskId))
tasks.Add(taskId, strTask);
}
}
if (tasks.Count == 0)
{
if (rebootRequired)
{
ServiceLog.WriteInfo("Reboot required");
RebootSystem();
return;
}
//start timers
StartPollTimer(); //starts task processing after poll interval
StartIdleTimer(); //stops service if idle
//no tasks - exit!
return;
}
else
{
//stop idle timer as we need to process tasks
StopIdleTimer();
}
ExecutionContext context = null;
foreach (long tid in tasks.Keys)
{
//find first correct task
string taskDefinition = tasks[tid];
string taskParameters = RegistryUtils.GetRegistryKeyStringValue(RegistryInputKey, taskDefinition);
if (taskDefinition.LastIndexOf("-") == -1 || taskDefinition.LastIndexOf('-') == taskDefinition.Length - 1)
{
ServiceLog.WriteError(string.Format("Task was deleted from queue as its definition is invalid : {0}", taskDefinition));
DeleteRegistryKeyValue(RegistryInputKey, taskDefinition);
//go to next task
continue;
}
string taskName = taskDefinition.Substring(0, taskDefinition.LastIndexOf("-")).Substring(TaskPrefix.Length);
string taskId = taskDefinition.Substring(taskDefinition.LastIndexOf('-') + 1);
if (!provisioningModules.ContainsKey(taskName))
{
ServiceLog.WriteError(string.Format("Task was deleted from queue as its definition was not found : {0}", taskName));
DeleteRegistryKeyValue(RegistryInputKey, taskDefinition);
//go to next task
continue;
}
//prepare execution context for correct task
context = new ExecutionContext();
context.ActivityID = taskId;
context.ActivityName = taskName;
ParseParameters(context.Parameters, taskParameters);
context.ActivityDefinition = taskDefinition;
break;
}
if (context != null)
{
string type = provisioningModules[context.ActivityName];
ExecutionResult res = null;
DateTime start = DateTime.Now;
try
{
//load module and run task
ServiceLog.WriteStart(string.Format("Starting '{0}' module...", context.ActivityName));
context.Progress = 0;
res = ModuleLoader.Run(type, ref context);
context.Progress = 100;
ServiceLog.WriteEnd(string.Format("'{0}' module finished.", context.ActivityName));
}
catch (Exception ex)
{
ServiceLog.WriteError("Unhandled exception:", ex);
res = new ExecutionResult();
res.ResultCode = -1;
res.ErrorMessage = string.Format("Unhandled exception : {0}", ex);
}
DateTime end = DateTime.Now;
SaveExecutionResult(context.ActivityDefinition, res, start, end);
//DeleteRegistryKeyValue(RegistryInputKey, context.ActivityDefinition);
if (res.RebootRequired)
rebootRequired = true;
}
}
}
private void ParseParameters(Dictionary<string, string> dictionary, string parameters)
{
if (dictionary == null)
throw new ArgumentNullException("dictionary");
if (string.IsNullOrEmpty(parameters))
return;
string[] pairs = parameters.Split('|');
foreach (string pair in pairs)
{
string[] parts = pair.Split(new char[] { '=' }, 2);
if (parts.Length != 2)
continue;
if (!dictionary.ContainsKey(parts[0]))
dictionary.Add(parts[0], parts[1]);
}
}
private void DeleteRegistryKeyValue(string key, string valueName)
{
try
{
RegistryUtils.DeleteRegistryKeyValue(key, valueName);
}
catch (Exception ex)
{
ServiceLog.WriteError("Registry error:", ex);
}
}
private void SaveExecutionResult(string name, ExecutionResult res, DateTime started, DateTime ended)
{
StringBuilder builder = new StringBuilder();
builder.AppendFormat("ResultCode={0}|", res.ResultCode);
builder.AppendFormat("RebootRequired={0}|", res.RebootRequired);
builder.AppendFormat("ErrorMessage={0}|", res.ErrorMessage);
builder.AppendFormat("Value={0}|", res.Value);
builder.AppendFormat("Started={0}|", started.ToString("yyyyMMddHHmmss"));
builder.AppendFormat("Ended={0}", started.ToString("yyyyMMddHHmmss"));
RegistryUtils.SetRegistryKeyStringValue(RegistryOutputKey, name, builder.ToString());
}
private void StopIdleTimer()
{
idleTimer.Stop();
}
private void StartIdleTimer()
{
if ( idleTimer.Interval > 1 )
idleTimer.Start();
}
private void StartPollTimer()
{
if ( pollTimer.Interval > 1 )
pollTimer.Start();
}
private void StartSummaryTimer()
{
if (summaryTimer.Interval > 1)
summaryTimer.Start();
}
private void RebootSystem()
{
try
{
ServiceLog.WriteStart("RebootSystem");
WmiUtils wmi = new WmiUtils("root\\cimv2");
ManagementObjectCollection objOses = wmi.ExecuteQuery("SELECT * FROM Win32_OperatingSystem");
foreach (ManagementObject objOs in objOses)
{
objOs.Scope.Options.EnablePrivileges = true;
objOs.InvokeMethod("Reboot", null);
}
ServiceLog.WriteEnd("RebootSystem");
}
catch (Exception ex)
{
ServiceLog.WriteError("Reboot System error:", ex);
}
}
}
}

View file

@ -0,0 +1,143 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>9.0.30729</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{58FEFE0B-A0E7-4FB3-9E60-91E18BEECDA7}</ProjectGuid>
<OutputType>WinExe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>WebsitePanel.VmConfig</RootNamespace>
<AssemblyName>WebsitePanel.VmConfig</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<StartupObject>WebsitePanel.VmConfig.Program</StartupObject>
<FileUpgradeFlags>
</FileUpgradeFlags>
<OldToolsVersion>3.5</OldToolsVersion>
<UpgradeBackupLocation />
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
<UpdateEnabled>false</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<IsWebBootstrapper>false</IsWebBootstrapper>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
<UseVSHostingProcess>false</UseVSHostingProcess>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>none</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<UseVSHostingProcess>false</UseVSHostingProcess>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.configuration" />
<Reference Include="System.Configuration.Install" />
<Reference Include="System.Management" />
<Reference Include="System.Data" />
<Reference Include="System.ServiceProcess" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\VersionInfo.cs">
<Link>VersionInfo.cs</Link>
</Compile>
<Compile Include="ModuleLoader.cs" />
<Compile Include="ModuleSettingsSection.cs" />
<Compile Include="ProjectInstaller.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="ProjectInstaller.Designer.cs">
<DependentUpon>ProjectInstaller.cs</DependentUpon>
</Compile>
<Compile Include="ServiceLog.cs" />
<Compile Include="VmConfigService.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="VmConfigService.Designer.cs">
<DependentUpon>VmConfigService.cs</DependentUpon>
</Compile>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="ProjectInstaller.resx">
<DependentUpon>ProjectInstaller.cs</DependentUpon>
<SubType>Designer</SubType>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\WebsitePanel.VmConfig.Common\WebsitePanel.VmConfig.Common.csproj">
<Project>{456AA9C9-AB1C-490D-AD33-33EADE1071C1}</Project>
<Name>WebsitePanel.VmConfig.Common</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="..\..\Resources\install.bat">
<Link>install.bat</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="..\..\Resources\uninstall.bat">
<Link>uninstall.bat</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
<Visible>False</Visible>
<ProductName>Windows Installer 3.1</ProductName>
<Install>true</Install>
</BootstrapperPackage>
</ItemGroup>
<ItemGroup>
<Content Include="..\..\..\ReleaseNotes.htm">
<Link>ReleaseNotes.htm</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>