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 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">
<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 Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Text="Back">
<Publish Event="NewDialog" Value="LicenseAgreementDlg" Order="3">1</Publish>
@ -101,13 +103,15 @@
<Publish Dialog="LicenseAgreementDlg" Control="Next" Event="NewDialog" Value="InstallLocationDlg" Order="3">
LicenseAccepted = "1"
</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" />
</UI>
<InstallExecuteSequence>
<Custom Action="PropertyFinalizeInstall" After='InstallValidate'/>
<Custom Action="FinalizeUnInstall" After="InstallValidate">(NOT UPGRADINGPRODUCTCODE) AND (REMOVE="ALL")</Custom>
<RemoveExistingProducts After="InstallValidate" />
<Custom Action='FinalizeInstall' After='InstallFinalize'>NOT Installed or REINSTALL</Custom>
<Custom Action='FinalizeInstall' After='InstallFiles' >NOT Installed or REINSTALL</Custom>
</InstallExecuteSequence>
</Product>
<Fragment>
@ -115,9 +119,16 @@
<Binary Id="CheckConnection.CA" SourceFile="bin\WebsitePanel.SchedulerServiceInstaller.CA.dll" />
</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>
<CustomAction Id="PreInstallationAction" BinaryKey="CheckConnection.CA" DllEntry="PreInstallationAction" />
<CustomAction Id="FinalizeUnInstall" BinaryKey="CheckConnection.CA" DllEntry="FinalizeUnInstall" />
<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.' />

View file

@ -27,6 +27,7 @@
// 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;
@ -35,6 +36,9 @@ 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;
@ -42,6 +46,8 @@ namespace WebsitePanel.SchedulerServiceInstaller
{
public class CustomActions
{
public const string CustomDataDelimiter = "-=del=-";
[CustomAction]
public static ActionResult CheckConnection(Session session)
{
@ -63,9 +69,23 @@ namespace WebsitePanel.SchedulerServiceInstaller
[CustomAction]
public static ActionResult FinalizeInstall(Session session)
{
ChangeConfigString("installer.connectionstring", session["CONNECTIONSTRING"], session["INSTALLFOLDER"]);
ChangeCryptoKey(session["INSTALLFOLDER"]);
InstallService(session["INSTALLFOLDER"]);
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;
}
@ -78,6 +98,46 @@ namespace WebsitePanel.SchedulerServiceInstaller
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)
{
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");
using (var reader = new StreamReader(path))
if (!File.Exists(path))
{
content = reader.ReadToEnd();
return;
}
var re = new Regex("\\$\\{" + searchString + "\\}+", RegexOptions.IgnoreCase);
content = re.Replace(content, replaceValue);
XmlDocument xmldoc = new XmlDocument();
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)
{
var sc = new ServiceController(serviceName);
@ -184,12 +229,12 @@ namespace WebsitePanel.SchedulerServiceInstaller
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)
{
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)
@ -215,5 +260,15 @@ namespace WebsitePanel.SchedulerServiceInstaller
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();
}
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
}