diff --git a/WebsitePanel.Installer/Sources/Setup.WIXInstaller/Config.wxi b/WebsitePanel.Installer/Sources/Setup.WIXInstaller/Config.wxi new file mode 100644 index 00000000..9883f33b --- /dev/null +++ b/WebsitePanel.Installer/Sources/Setup.WIXInstaller/Config.wxi @@ -0,0 +1,6 @@ + + + + + + diff --git a/WebsitePanel.Installer/Sources/Setup.WIXInstaller/License.rtf b/WebsitePanel.Installer/Sources/Setup.WIXInstaller/License.rtf new file mode 100644 index 00000000..f4f781eb Binary files /dev/null and b/WebsitePanel.Installer/Sources/Setup.WIXInstaller/License.rtf differ diff --git a/WebsitePanel.Installer/Sources/Setup.WIXInstaller/Product.wxs b/WebsitePanel.Installer/Sources/Setup.WIXInstaller/Product.wxs new file mode 100644 index 00000000..aecd38f7 --- /dev/null +++ b/WebsitePanel.Installer/Sources/Setup.WIXInstaller/Product.wxs @@ -0,0 +1,162 @@ + + + + + + + + + + + + bannrbmp + + + + + + + + + + + + + + + + + + + + + + + 1 + + + 1 + CORRECTCONNECTION = "0" + CORRECTCONNECTION = "1" + + + 1 + + + + + + + + + + + + + + + + + + AUTHENTICATIONTYPE = "Windows Authentication" + NOT(AUTHENTICATIONTYPE = "Windows Authentication") + + + + + + + + + 1 + + + Connection not valid. + + + + + 1 + SKIPCONNECTIONSTRINGSTEP = "0" + SKIPCONNECTIONSTRINGSTEP = "1" + + + 1 + + + 1 + + + + + + + + + + + LicenseAccepted = "1" + + SKIPCONNECTIONSTRINGSTEP = "0" + SKIPCONNECTIONSTRINGSTEP = "1" + + + + + (NOT UPGRADINGPRODUCTCODE) AND (REMOVE="ALL") + + NOT Installed or REINSTALL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/WebsitePanel.Installer/Sources/Setup.WIXInstaller/Setup.WIXInstaller.wixproj b/WebsitePanel.Installer/Sources/Setup.WIXInstaller/Setup.WIXInstaller.wixproj new file mode 100644 index 00000000..f28cc956 --- /dev/null +++ b/WebsitePanel.Installer/Sources/Setup.WIXInstaller/Setup.WIXInstaller.wixproj @@ -0,0 +1,52 @@ + + + + Debug + x86 + 3.7 + {978f0a18-7c81-4561-8f6d-5a165484ad0a} + 2.0 + Websitepanel-SchedulerService + Package + $(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.targets + $(MSBuildExtensionsPath)\Microsoft\WiX\v3.x\Wix.targets + + + bin\ + obj\$(Configuration)\ + Debug;BUILD=debug + False + + + + + + + + + bin\$(Configuration)\ + obj\$(Configuration)\ + BUILD=release + + + + + + + + + + ..\..\..\tools\WIX\WixUIExtension.dll + WixUIExtension + + + + + \ No newline at end of file diff --git a/WebsitePanel.Installer/Sources/Setup.WIXInstaller/WebSitePanel.ico b/WebsitePanel.Installer/Sources/Setup.WIXInstaller/WebSitePanel.ico new file mode 100644 index 00000000..bf9c0b86 Binary files /dev/null and b/WebsitePanel.Installer/Sources/Setup.WIXInstaller/WebSitePanel.ico differ diff --git a/WebsitePanel.Installer/Sources/Setup.WIXInstaller/bannrbmp.bmp b/WebsitePanel.Installer/Sources/Setup.WIXInstaller/bannrbmp.bmp new file mode 100644 index 00000000..9ac7e922 Binary files /dev/null and b/WebsitePanel.Installer/Sources/Setup.WIXInstaller/bannrbmp.bmp differ diff --git a/WebsitePanel.Installer/Sources/Setup.WIXInstaller/dlgbmp.bmp b/WebsitePanel.Installer/Sources/Setup.WIXInstaller/dlgbmp.bmp new file mode 100644 index 00000000..dbf9959b Binary files /dev/null and b/WebsitePanel.Installer/Sources/Setup.WIXInstaller/dlgbmp.bmp differ diff --git a/WebsitePanel.Installer/Sources/WebsitePanel.Installer.sln b/WebsitePanel.Installer/Sources/WebsitePanel.Installer.sln index 2a9fa4c2..d238b09e 100644 --- a/WebsitePanel.Installer/Sources/WebsitePanel.Installer.sln +++ b/WebsitePanel.Installer/Sources/WebsitePanel.Installer.sln @@ -1,5 +1,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2010 +# Visual Studio 2013 +VisualStudioVersion = 12.0.30723.0 +MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{129305D5-A9E6-4DCE-BFF6-41809E13EEEE}" ProjectSection(SolutionItems) = preProject ..\..\WebsitePanel\build.xml = ..\..\WebsitePanel\build.xml @@ -31,6 +33,10 @@ Project("{930C7802-8A8C-48F9-8165-68863BCCD9DD}") = "Setup.SchedulerService", "S EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebsitePanel.SchedulerServiceInstaller", "WebsitePanel.SchedulerServiceInstaller\WebsitePanel.SchedulerServiceInstaller.csproj", "{24A4C231-73A9-4F03-ABAD-9A8FE5324495}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebsitePanel.WIXInstaller", "WebsitePanel.WIXInstaller\WebsitePanel.WIXInstaller.csproj", "{3343FFD8-7CCE-451B-95AE-3D97244313A2}" +EndProject +Project("{930C7802-8A8C-48F9-8165-68863BCCD9DD}") = "Setup.WIXInstaller", "Setup.WIXInstaller\Setup.WIXInstaller.wixproj", "{978F0A18-7C81-4561-8F6D-5A165484AD0A}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -123,6 +129,26 @@ Global {24A4C231-73A9-4F03-ABAD-9A8FE5324495}.Release|Mixed Platforms.Build.0 = Release|x86 {24A4C231-73A9-4F03-ABAD-9A8FE5324495}.Release|x86.ActiveCfg = Release|x86 {24A4C231-73A9-4F03-ABAD-9A8FE5324495}.Release|x86.Build.0 = Release|x86 + {3343FFD8-7CCE-451B-95AE-3D97244313A2}.Debug|Any CPU.ActiveCfg = Debug|x86 + {3343FFD8-7CCE-451B-95AE-3D97244313A2}.Debug|Mixed Platforms.ActiveCfg = Debug|x86 + {3343FFD8-7CCE-451B-95AE-3D97244313A2}.Debug|Mixed Platforms.Build.0 = Debug|x86 + {3343FFD8-7CCE-451B-95AE-3D97244313A2}.Debug|x86.ActiveCfg = Debug|x86 + {3343FFD8-7CCE-451B-95AE-3D97244313A2}.Debug|x86.Build.0 = Debug|x86 + {3343FFD8-7CCE-451B-95AE-3D97244313A2}.Release|Any CPU.ActiveCfg = Release|x86 + {3343FFD8-7CCE-451B-95AE-3D97244313A2}.Release|Mixed Platforms.ActiveCfg = Release|x86 + {3343FFD8-7CCE-451B-95AE-3D97244313A2}.Release|Mixed Platforms.Build.0 = Release|x86 + {3343FFD8-7CCE-451B-95AE-3D97244313A2}.Release|x86.ActiveCfg = Release|x86 + {3343FFD8-7CCE-451B-95AE-3D97244313A2}.Release|x86.Build.0 = Release|x86 + {978F0A18-7C81-4561-8F6D-5A165484AD0A}.Debug|Any CPU.ActiveCfg = Debug|x86 + {978F0A18-7C81-4561-8F6D-5A165484AD0A}.Debug|Mixed Platforms.ActiveCfg = Debug|x86 + {978F0A18-7C81-4561-8F6D-5A165484AD0A}.Debug|Mixed Platforms.Build.0 = Debug|x86 + {978F0A18-7C81-4561-8F6D-5A165484AD0A}.Debug|x86.ActiveCfg = Debug|x86 + {978F0A18-7C81-4561-8F6D-5A165484AD0A}.Debug|x86.Build.0 = Debug|x86 + {978F0A18-7C81-4561-8F6D-5A165484AD0A}.Release|Any CPU.ActiveCfg = Release|x86 + {978F0A18-7C81-4561-8F6D-5A165484AD0A}.Release|Mixed Platforms.ActiveCfg = Release|x86 + {978F0A18-7C81-4561-8F6D-5A165484AD0A}.Release|Mixed Platforms.Build.0 = Release|x86 + {978F0A18-7C81-4561-8F6D-5A165484AD0A}.Release|x86.ActiveCfg = Release|x86 + {978F0A18-7C81-4561-8F6D-5A165484AD0A}.Release|x86.Build.0 = Release|x86 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/WebsitePanel.Installer/Sources/WebsitePanel.WIXInstaller/CustomAction.config b/WebsitePanel.Installer/Sources/WebsitePanel.WIXInstaller/CustomAction.config new file mode 100644 index 00000000..233c44d7 --- /dev/null +++ b/WebsitePanel.Installer/Sources/WebsitePanel.WIXInstaller/CustomAction.config @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + diff --git a/WebsitePanel.Installer/Sources/WebsitePanel.WIXInstaller/CustomAction.cs b/WebsitePanel.Installer/Sources/WebsitePanel.WIXInstaller/CustomAction.cs new file mode 100644 index 00000000..1ce53461 --- /dev/null +++ b/WebsitePanel.Installer/Sources/WebsitePanel.WIXInstaller/CustomAction.cs @@ -0,0 +1,274 @@ +// Copyright (c) 2015, 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.Configuration.Install; +using System.Data; +using System.Data.SqlClient; +using System.IO; +using System.Linq; +using System.ServiceProcess; +using System.Text.RegularExpressions; +using System.Threading; +using System.Windows.Forms; +using System.Windows.Forms.VisualStyles; +using System.Xml; +using Microsoft.Deployment.WindowsInstaller; +using WebsitePanel.Setup; + +namespace WebsitePanel.WIXInstaller +{ + public class CustomActions + { + public const string CustomDataDelimiter = "-=del=-"; + + [CustomAction] + public static ActionResult CheckConnection(Session session) + { + string testConnectionString = session["AUTHENTICATIONTYPE"].Equals("Windows Authentication") ? GetConnectionString(session["SERVERNAME"], "master") : GetConnectionString(session["SERVERNAME"], "master", session["LOGIN"], session["PASSWORD"]); + + if (CheckConnection(testConnectionString)) + { + session["CORRECTCONNECTION"] = "1"; + session["CONNECTIONSTRING"] = session["AUTHENTICATIONTYPE"].Equals("Windows Authentication") ? GetConnectionString(session["SERVERNAME"], session["DATABASENAME"]) : GetConnectionString(session["SERVERNAME"], session["DATABASENAME"], session["LOGIN"], session["PASSWORD"]); + } + else + { + session["CORRECTCONNECTION"] = "0"; + } + + return ActionResult.Success; + } + + [CustomAction] + public static ActionResult FinalizeInstall(Session session) + { + var connectionString = GetCustomActionProperty(session, "ConnectionString").Replace(CustomDataDelimiter, ";"); + var serviceFolder = GetCustomActionProperty(session, "ServiceFolder"); + var previousConnectionString = GetCustomActionProperty(session, "PreviousConnectionString").Replace(CustomDataDelimiter, ";"); + var previousCryptoKey = GetCustomActionProperty(session, "PreviousCryptoKey"); + + if (string.IsNullOrEmpty(serviceFolder)) + { + return ActionResult.Success; + } + + connectionString = string.IsNullOrEmpty(previousConnectionString) + ? connectionString + : previousConnectionString; + + ChangeConfigString("/configuration/connectionStrings/add[@name='EnterpriseServer']", "connectionString", connectionString, serviceFolder); + ChangeConfigString("/configuration/appSettings/add[@key='WebsitePanel.CryptoKey']", "value", previousCryptoKey, serviceFolder); + InstallService(serviceFolder); + + return ActionResult.Success; + } + + [CustomAction] + public static ActionResult FinalizeUnInstall(Session session) + { + UnInstallService(); + + return ActionResult.Success; + } + + [CustomAction] + public static ActionResult PreInstallationAction(Session session) + { + session["SKIPCONNECTIONSTRINGSTEP"] = "0"; + + session["SERVICEFOLDER"] = session["INSTALLFOLDER"]; + + var servicePath = SecurityUtils.GetServicePath("WebsitePanel Scheduler"); + + if (!string.IsNullOrEmpty(servicePath)) + { + string path = Path.Combine(servicePath, "WebsitePanel.SchedulerService.exe.config"); + + if (File.Exists(path)) + { + using (var reader = new StreamReader(path)) + { + string content = reader.ReadToEnd(); + var pattern = new Regex(@"(?<=)"); + Match match = pattern.Match(content); + session["PREVIOUSCRYPTOKEY"] = match.Value; + + var connectionStringPattern = new Regex(@"(?<=)"); + match = connectionStringPattern.Match(content); + session["PREVIOUSCONNECTIONSTRING"] = match.Value.Replace(";", CustomDataDelimiter); + } + + session["SKIPCONNECTIONSTRINGSTEP"] = "1"; + + if (string.IsNullOrEmpty(session["SERVICEFOLDER"])) + { + session["SERVICEFOLDER"] = servicePath; + } + } + + } + + return ActionResult.Success; + } + + private static void InstallService(string installFolder) + { + try + { + var schedulerService = + ServiceController.GetServices().FirstOrDefault( + s => s.DisplayName.Equals("WebsitePanel Scheduler", StringComparison.CurrentCultureIgnoreCase)); + + if (schedulerService != null) + { + StopService(schedulerService.ServiceName); + + SecurityUtils.DeleteService(schedulerService.ServiceName); + } + + ManagedInstallerClass.InstallHelper(new[] { "/i", Path.Combine(installFolder, "WebsitePanel.SchedulerService.exe") }); + + StartService("WebsitePanel Scheduler"); + } + catch (Exception) + { + } + } + + private static void UnInstallService() + { + try + { + var schedulerService = + ServiceController.GetServices().FirstOrDefault( + s => s.DisplayName.Equals("WebsitePanel Scheduler", StringComparison.CurrentCultureIgnoreCase)); + + if (schedulerService != null) + { + StopService(schedulerService.ServiceName); + + SecurityUtils.DeleteService(schedulerService.ServiceName); + } + } + catch (Exception) + { + } + } + + private static void ChangeConfigString(string nodePath, string attrToChange, string value, string installFolder) + { + string path = Path.Combine(installFolder, "WebsitePanel.SchedulerService.exe.config"); + + if (!File.Exists(path)) + { + return; + } + + XmlDocument xmldoc = new XmlDocument(); + xmldoc.Load(path); + + XmlElement node = xmldoc.SelectSingleNode(nodePath) as XmlElement; + + if (node != null) + { + node.SetAttribute(attrToChange, value); + + xmldoc.Save(path); + } + } + + + private static void StopService(string serviceName) + { + var sc = new ServiceController(serviceName); + + if (sc.Status == ServiceControllerStatus.Running) + { + sc.Stop(); + sc.WaitForStatus(ServiceControllerStatus.Stopped); + } + } + + private static void StartService(string serviceName) + { + var sc = new ServiceController(serviceName); + + if (sc.Status == ServiceControllerStatus.Stopped) + { + sc.Start(); + sc.WaitForStatus(ServiceControllerStatus.Running); + } + } + + private static string GetConnectionString(string serverName, string databaseName) + { + return string.Format("Server={0};database={1};Trusted_Connection=true;", serverName, databaseName).Replace(";", CustomDataDelimiter); + } + + private static string GetConnectionString(string serverName, string databaseName, string login, string password) + { + return string.Format("Server={0};database={1};uid={2};password={3};", serverName, databaseName, login, password).Replace(";", CustomDataDelimiter); + } + + private static bool CheckConnection(string connectionString) + { + var connection = new SqlConnection(connectionString); + bool result = true; + + try + { + connection.Open(); + } + catch (Exception) + { + result = false; + } + finally + { + if (connection != null && connection.State == ConnectionState.Open) + { + connection.Close(); + } + } + + return result; + } + + private static string GetCustomActionProperty(Session session, string key) + { + if (session.CustomActionData.ContainsKey(key)) + { + return session.CustomActionData[key].Replace("-=-", ";"); + } + + return string.Empty; + } + } +} diff --git a/WebsitePanel.Installer/Sources/WebsitePanel.WIXInstaller/Properties/AssemblyInfo.cs b/WebsitePanel.Installer/Sources/WebsitePanel.WIXInstaller/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..7149ada9 --- /dev/null +++ b/WebsitePanel.Installer/Sources/WebsitePanel.WIXInstaller/Properties/AssemblyInfo.cs @@ -0,0 +1,63 @@ +// Copyright (c) 2015, 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.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.WIXInstaller")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("WebsitePanel.WIXInstaller")] +[assembly: AssemblyCopyright("Copyright © 2015")] +[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("CA494A4D-8D40-4A7D-8473-2F5E05605831")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/WebsitePanel.Installer/Sources/WebsitePanel.WIXInstaller/WebsitePanel.WIXInstaller.csproj b/WebsitePanel.Installer/Sources/WebsitePanel.WIXInstaller/WebsitePanel.WIXInstaller.csproj new file mode 100644 index 00000000..b2211e38 --- /dev/null +++ b/WebsitePanel.Installer/Sources/WebsitePanel.WIXInstaller/WebsitePanel.WIXInstaller.csproj @@ -0,0 +1,59 @@ + + + + Debug + x86 + 8.0.30703 + 2.0 + {3343FFD8-7CCE-451B-95AE-3D97244313A2} + Library + Properties + WebsitePanel.WIXInstaller + WebsitePanel.WIXInstaller + v4.0 + 512 + $(MSBuildExtensionsPath)\Microsoft\WiX\v3.x\Wix.CA.targets + + + true + full + false + ..\Setup.WIXInstaller\bin\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + ..\Setup.WIXInstaller\bin\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + + + + {3951C0EC-BD98-450E-B228-CDBE5BD4AD49} + WebsitePanel.Setup + + + + + \ No newline at end of file