scheduler installer fix

This commit is contained in:
a.skorina 2014-12-18 17:50:06 +03:00
parent 53aff75c14
commit 75ccdbb916
3 changed files with 121 additions and 36 deletions

View file

@ -82,7 +82,9 @@
</Dialog> </Dialog>
<Dialog Id="InstallLocationDlg" Width="370" Height="270" Title="[ProductName] Setup"> <Dialog Id="InstallLocationDlg" Width="370" Height="270" Title="[ProductName] Setup">
<Control Id="Next" Type="PushButton" X="236" Y="243" Width="56" Height="17" Default="yes" Text="Next"> <Control Id="Next" Type="PushButton" X="236" Y="243" Width="56" Height="17" Default="yes" Text="Next">
<Publish Event="NewDialog" Value="DatabaseConnectionDlg" Order="3">1</Publish> <Publish Event="DoAction" Value="PreInstallationAction">1</Publish>
<Publish Event="NewDialog" Value="DatabaseConnectionDlg" Order="3">SKIPCONNECTIONSTRINGSTEP = "0"</Publish>
<Publish Event="NewDialog" Value="VerifyReadyDlg" Order="3">SKIPCONNECTIONSTRINGSTEP = "1"</Publish>
</Control> </Control>
<Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Text="Back"> <Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Text="Back">
<Publish Event="NewDialog" Value="LicenseAgreementDlg" Order="3">1</Publish> <Publish Event="NewDialog" Value="LicenseAgreementDlg" Order="3">1</Publish>
@ -101,13 +103,15 @@
<Publish Dialog="LicenseAgreementDlg" Control="Next" Event="NewDialog" Value="InstallLocationDlg" Order="3"> <Publish Dialog="LicenseAgreementDlg" Control="Next" Event="NewDialog" Value="InstallLocationDlg" Order="3">
LicenseAccepted = "1" LicenseAccepted = "1"
</Publish> </Publish>
<Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="DatabaseConnectionDlg">1</Publish> <Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="DatabaseConnectionDlg">SKIPCONNECTIONSTRINGSTEP = "0"</Publish>
<Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="InstallLocationDlg">SKIPCONNECTIONSTRINGSTEP = "1"</Publish>
<TextStyle Id="DlgTitleFont" FaceName="Tahoma" Size="8" Bold="yes" /> <TextStyle Id="DlgTitleFont" FaceName="Tahoma" Size="8" Bold="yes" />
</UI> </UI>
<InstallExecuteSequence> <InstallExecuteSequence>
<Custom Action="PropertyFinalizeInstall" After='InstallValidate'/>
<Custom Action="FinalizeUnInstall" After="InstallValidate">(NOT UPGRADINGPRODUCTCODE) AND (REMOVE="ALL")</Custom> <Custom Action="FinalizeUnInstall" After="InstallValidate">(NOT UPGRADINGPRODUCTCODE) AND (REMOVE="ALL")</Custom>
<RemoveExistingProducts After="InstallValidate" /> <RemoveExistingProducts After="InstallValidate" />
<Custom Action='FinalizeInstall' After='InstallFinalize'>NOT Installed or REINSTALL</Custom> <Custom Action='FinalizeInstall' After='InstallFiles' >NOT Installed or REINSTALL</Custom>
</InstallExecuteSequence> </InstallExecuteSequence>
</Product> </Product>
<Fragment> <Fragment>
@ -115,9 +119,16 @@
<Binary Id="CheckConnection.CA" SourceFile="bin\WebsitePanel.SchedulerServiceInstaller.CA.dll" /> <Binary Id="CheckConnection.CA" SourceFile="bin\WebsitePanel.SchedulerServiceInstaller.CA.dll" />
</Fragment> </Fragment>
<Fragment> <Fragment>
<CustomAction Id="FinalizeInstall" BinaryKey="CheckConnection.CA" DllEntry="FinalizeInstall" /> <!-- immediate CA -->
<CustomAction Id='PropertyFinalizeInstall' Property='FinalizeInstall' Value='ConnectionString=[CONNECTIONSTRING];PreviousConnectionString=[PREVIOUSCONNECTIONSTRING];ServiceFolder=[SERVICEFOLDER];PreviousCryptoKey=[PREVIOUSCRYPTOKEY]' Return="check"/>
<!-- deferred CA -->
<CustomAction Id='FinalizeInstall' BinaryKey ='CheckConnection.CA' DllEntry='FinalizeInstall' Impersonate='no' Execute='deferred' Return='check' HideTarget='yes'/>
<!--<CustomAction Id="FinalizeInstall" BinaryKey="CheckConnection.CA" DllEntry="FinalizeInstall" />-->
</Fragment> </Fragment>
<Fragment> <Fragment>
<CustomAction Id="PreInstallationAction" BinaryKey="CheckConnection.CA" DllEntry="PreInstallationAction" />
<CustomAction Id="FinalizeUnInstall" BinaryKey="CheckConnection.CA" DllEntry="FinalizeUnInstall" /> <CustomAction Id="FinalizeUnInstall" BinaryKey="CheckConnection.CA" DllEntry="FinalizeUnInstall" />
<CustomAction Id='AlreadyUpdated' Error='Product has already been updated to $(var.VERSION) or newer.' /> <CustomAction Id='AlreadyUpdated' Error='Product has already been updated to $(var.VERSION) or newer.' />
<CustomAction Id='NoDowngrade' Error='A later version of [ProductName] is already installed.' /> <CustomAction Id='NoDowngrade' Error='A later version of [ProductName] is already installed.' />

View file

@ -27,6 +27,7 @@
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
using System; using System;
using System.Collections.Generic;
using System.Configuration.Install; using System.Configuration.Install;
using System.Data; using System.Data;
using System.Data.SqlClient; using System.Data.SqlClient;
@ -35,6 +36,9 @@ using System.Linq;
using System.ServiceProcess; using System.ServiceProcess;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Threading; using System.Threading;
using System.Windows.Forms;
using System.Windows.Forms.VisualStyles;
using System.Xml;
using Microsoft.Deployment.WindowsInstaller; using Microsoft.Deployment.WindowsInstaller;
using WebsitePanel.Setup; using WebsitePanel.Setup;
@ -42,6 +46,8 @@ namespace WebsitePanel.SchedulerServiceInstaller
{ {
public class CustomActions public class CustomActions
{ {
public const string CustomDataDelimiter = "-=del=-";
[CustomAction] [CustomAction]
public static ActionResult CheckConnection(Session session) public static ActionResult CheckConnection(Session session)
{ {
@ -63,9 +69,23 @@ namespace WebsitePanel.SchedulerServiceInstaller
[CustomAction] [CustomAction]
public static ActionResult FinalizeInstall(Session session) public static ActionResult FinalizeInstall(Session session)
{ {
ChangeConfigString("installer.connectionstring", session["CONNECTIONSTRING"], session["INSTALLFOLDER"]); var connectionString = GetCustomActionProperty(session, "ConnectionString").Replace(CustomDataDelimiter, ";");
ChangeCryptoKey(session["INSTALLFOLDER"]); var serviceFolder = GetCustomActionProperty(session, "ServiceFolder");
InstallService(session["INSTALLFOLDER"]); 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; return ActionResult.Success;
} }
@ -78,6 +98,46 @@ namespace WebsitePanel.SchedulerServiceInstaller
return ActionResult.Success; 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(@"(?<=<add key=""WebsitePanel.CryptoKey"" .*?value\s*=\s*"")[^""]+(?="".*?>)");
Match match = pattern.Match(content);
session["PREVIOUSCRYPTOKEY"] = match.Value;
var connectionStringPattern = new Regex(@"(?<=<add name=""EnterpriseServer"" .*?connectionString\s*=\s*"")[^""]+(?="".*?>)");
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) private static void InstallService(string installFolder)
{ {
try try
@ -122,44 +182,29 @@ namespace WebsitePanel.SchedulerServiceInstaller
} }
} }
private static void ChangeCryptoKey(string installFolder) private static void ChangeConfigString(string nodePath, string attrToChange, string value, string installFolder)
{ {
string path = Path.Combine(installFolder.Replace("SchedulerService", "Enterprise Server"), "web.config");
string cryptoKey = "0123456789";
if (File.Exists(path))
{
using (var reader = new StreamReader(path))
{
string content = reader.ReadToEnd();
var pattern = new Regex(@"(?<=<add key=""WebsitePanel.CryptoKey"" .*?value\s*=\s*"")[^""]+(?="".*?>)");
Match match = pattern.Match(content);
cryptoKey = match.Value;
}
}
ChangeConfigString("installer.cryptokey", cryptoKey, installFolder);
}
private static void ChangeConfigString(string searchString, string replaceValue, string installFolder)
{
string content;
string path = Path.Combine(installFolder, "WebsitePanel.SchedulerService.exe.config"); string path = Path.Combine(installFolder, "WebsitePanel.SchedulerService.exe.config");
using (var reader = new StreamReader(path)) if (!File.Exists(path))
{ {
content = reader.ReadToEnd(); return;
} }
var re = new Regex("\\$\\{" + searchString + "\\}+", RegexOptions.IgnoreCase); XmlDocument xmldoc = new XmlDocument();
content = re.Replace(content, replaceValue); xmldoc.Load(path);
using (var writer = new StreamWriter(path)) XmlElement node = xmldoc.SelectSingleNode(nodePath) as XmlElement;
if (node != null)
{ {
writer.Write(content); node.SetAttribute(attrToChange, value);
xmldoc.Save(path);
} }
} }
private static void StopService(string serviceName) private static void StopService(string serviceName)
{ {
var sc = new ServiceController(serviceName); var sc = new ServiceController(serviceName);
@ -184,12 +229,12 @@ namespace WebsitePanel.SchedulerServiceInstaller
private static string GetConnectionString(string serverName, string databaseName) private static string GetConnectionString(string serverName, string databaseName)
{ {
return string.Format("Server={0};database={1};Trusted_Connection=true;", serverName, 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) 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); return string.Format("Server={0};database={1};uid={2};password={3};", serverName, databaseName, login, password).Replace(";", CustomDataDelimiter);
} }
private static bool CheckConnection(string connectionString) private static bool CheckConnection(string connectionString)
@ -215,5 +260,15 @@ namespace WebsitePanel.SchedulerServiceInstaller
return result; return result;
} }
private static string GetCustomActionProperty(Session session, string key)
{
if (session.CustomActionData.ContainsKey(key))
{
return session.CustomActionData[key].Replace("-=-", ";");
}
return string.Empty;
}
} }
} }

View file

@ -1110,6 +1110,25 @@ namespace WebsitePanel.Setup
wmiService.Delete(); wmiService.Delete();
} }
public static string GetServicePath(string serviceName)
{
var mc = new ManagementClass("Win32_Service");
foreach (var mo in mc.GetInstances())
{
if (mo.GetPropertyValue("Name").ToString() == serviceName)
{
var path = mo.GetPropertyValue("PathName").ToString().Trim('"');
var directory = Path.GetDirectoryName(path);
return directory;
}
}
return string.Empty;
}
#endregion #endregion
} }