From f4360130a9ad264b0b7177ba2ba59b5d8fce06c3 Mon Sep 17 00:00:00 2001 From: Virtuworks Date: Tue, 5 May 2015 09:25:33 -0400 Subject: [PATCH 01/22] Added tag build-2.1.0.700 for changeset ac35b56f9274 From 8b9ca61684a247fe22805f1db0f9ce823b0889bc Mon Sep 17 00:00:00 2001 From: Virtuworks Date: Tue, 5 May 2015 12:32:22 -0400 Subject: [PATCH 02/22] Added tag build-2.1.0.701 for changeset 52aad3cf1968 From 584b1618f988a30ae8dd7664ece51fae6442ff7a Mon Sep 17 00:00:00 2001 From: Virtuworks Date: Wed, 6 May 2015 07:40:21 -0400 Subject: [PATCH 03/22] Added tag build-2.1.0.702 for changeset 63edea4e90bf From 0f073a74579bb5107c2d900502c30a3dbd10e116 Mon Sep 17 00:00:00 2001 From: vfedosevich Date: Wed, 6 May 2015 06:28:58 -0700 Subject: [PATCH 04/22] symbol regex fix --- .../CustomAttributes/OrganizationPasswordPolicyAttribute.cs | 3 ++- .../appScripts/validation/passwordeditor.unobtrusive.js | 2 +- .../Views/Account/PasswordResetFinalStep.cshtml | 3 ++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/CustomAttributes/OrganizationPasswordPolicyAttribute.cs b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/CustomAttributes/OrganizationPasswordPolicyAttribute.cs index 6fea16be..9cffde91 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/CustomAttributes/OrganizationPasswordPolicyAttribute.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/CustomAttributes/OrganizationPasswordPolicyAttribute.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; +using System.Text.RegularExpressions; using System.Web; using System.Web.Mvc; using WebsitePanel.Providers.HostedSolution; @@ -53,9 +54,9 @@ namespace WebsitePanel.WebDavPortal.CustomAttributes if (settings.PasswordComplexityEnabled) { - var symbolsCount = valueString.Count(Char.IsSymbol); var numbersCount = valueString.Count(Char.IsDigit); var upperLetterCount = valueString.Count(Char.IsUpper); + var symbolsCount = Regex.Matches(valueString, @"[~!@#$%^&*_\-+'\|\\(){}\[\]:;\""'<>,.?/]").Count; if (upperLetterCount < settings.UppercaseLettersCount) { diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Scripts/appScripts/validation/passwordeditor.unobtrusive.js b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Scripts/appScripts/validation/passwordeditor.unobtrusive.js index 799b8f82..03d49e3e 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Scripts/appScripts/validation/passwordeditor.unobtrusive.js +++ b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Scripts/appScripts/validation/passwordeditor.unobtrusive.js @@ -45,7 +45,7 @@ $.validator.addMethod("numberscount", function (value, element, count) { $.validator.unobtrusive.adapters.addSingleVal("symbolscount", "count"); $.validator.addMethod("symbolscount", function (value, element, count) { - if (value.replace(/[a-zA-Z0-9_]/g, "").length < count) { + if (value.replace(/[^~!@#$%^&*_\-+'\|\\(){}\[\]:;\"'<>,.?/]/g, "").length < count) { return false; } diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Views/Account/PasswordResetFinalStep.cshtml b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Views/Account/PasswordResetFinalStep.cshtml index 6432a19b..2d5abbbf 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Views/Account/PasswordResetFinalStep.cshtml +++ b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Views/Account/PasswordResetFinalStep.cshtml @@ -8,7 +8,8 @@
@using (Html.BeginRouteForm(AccountRouteNames.PasswordResetFinalStep, FormMethod.Post, new { @class = "form-horizontal user-password-reset-final-step bs-val-styles col-lg-9 col-lg-offset-3", id = "user-password-reset" })) { - + @Html.HiddenFor(x=>x.Login) +

@UI.PasswordReset

From e2e351bbf623b8e8bd2860deecc3d9a0be7b7bd3 Mon Sep 17 00:00:00 2001 From: vfedosevich Date: Wed, 6 May 2015 07:41:30 -0700 Subject: [PATCH 05/22] update_db.sql fixes --- WebsitePanel/Database/update_db.sql | 2 ++ 1 file changed, 2 insertions(+) diff --git a/WebsitePanel/Database/update_db.sql b/WebsitePanel/Database/update_db.sql index 5126597e..f139c195 100644 --- a/WebsitePanel/Database/update_db.sql +++ b/WebsitePanel/Database/update_db.sql @@ -9607,6 +9607,8 @@ IF EXISTS (SELECT * FROM ResourceGroups WHERE GroupName = 'SharePoint') BEGIN DECLARE @group_id INT SELECT @group_id = GroupId FROM ResourceGroups WHERE GroupName = 'SharePoint' + DELETE FROM PackageQuotas WHERE QuotaID IN (SELECT QuotaID FROM Quotas WHERE GroupID = @group_id) + DELETE FROM HostingPlanQuotas WHERE QuotaID IN (SELECT QuotaID FROM Quotas WHERE GroupID = @group_id) DELETE FROM Providers WHERE GroupID = @group_id DELETE FROM Quotas WHERE GroupID = @group_id DELETE FROM VirtualGroups WHERE GroupID = @group_id From 01daa1a293dab5e1642bd05a95c097e890721afb Mon Sep 17 00:00:00 2001 From: Virtuworks Date: Wed, 6 May 2015 10:44:30 -0400 Subject: [PATCH 06/22] Added tag build-2.1.0.704 for changeset 41fe22fe2adf From 2e13fd4d165b253f9cdc80b6a62a5db16051b816 Mon Sep 17 00:00:00 2001 From: Virtuworks Date: Wed, 6 May 2015 16:46:28 -0400 Subject: [PATCH 07/22] Added tag build-2.1.0.705 for changeset 205d8f91935e From 4a45e05f07f08d52082a36f39fa957d1e3fcf615 Mon Sep 17 00:00:00 2001 From: Virtuworks Date: Wed, 6 May 2015 20:20:09 -0400 Subject: [PATCH 08/22] Re-Style Webdav Portal --- .../Content/Site.css | 72 +++++++++++++++++++ .../Views/FileSystem/_ResoursePartial.cshtml | 2 +- 2 files changed, 73 insertions(+), 1 deletion(-) diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Content/Site.css b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Content/Site.css index 2173c20a..2ab67ad3 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Content/Site.css +++ b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Content/Site.css @@ -455,4 +455,76 @@ div#breadcrumb_wrapper a:last-child { .navbar-right { margin-right: 0; } +} + +.navbar-inverse { + background-color: #F4F4F4; + border-color: #d4d4d4; + background: rgb(251,251,251); + background: -moz-linear-gradient(top, rgba(251,251,251,1) 0%, rgba(242,242,242,1) 100%); + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(251,251,251,1)), color-stop(100%,rgba(242,242,242,1))); + background: -webkit-linear-gradient(top, rgba(251,251,251,1) 0%,rgba(242,242,242,1) 100%); + background: -o-linear-gradient(top, rgba(251,251,251,1) 0%,rgba(242,242,242,1) 100%); + background: -ms-linear-gradient(top, rgba(251,251,251,1) 0%,rgba(242,242,242,1) 100%); + background: linear-gradient(to bottom, rgba(251,251,251,1) 0%,rgba(242,242,242,1) 100%); + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#fbfbfb', endColorstr='#f2f2f2',GradientType=0 ); + -webkit-box-shadow: 0 1px 10px rgba(0,0,0,.1); + -moz-box-shadow: 0 1px 10px rgba(0,0,0,.1); + box-shadow: 0 1px 10px rgba(0,0,0,.1); +} +.navbar-inverse .navbar-text, .navbar-inverse .navbar-brand, .navbar-text, #logout { + color: #565656; +} + +.navbar-inverse .navbar-brand:hover, .navbar-inverse .navbar-brand:focus, .navbar-text:hover, #logout:hover { + color: #565656; + background-color: transparent; + opacity: 1; +} + +div#breadcrumb_wrapper { + background-color: #F7F7F7; + border: 1px solid #d4d4d4; + margin-top: 9px; +} +.progress { + height:21px; + + background-color: #ffffff; + border: 1px solid #BBBBBB; + border-radius: 3px!important; +} +.progress-bar { + background-color: #F4C18F; + -webkit-box-shadow: none; + box-shadow: none; +} +body { + background-color: #FAFAFA; +} +p.progress-text { + position: absolute; + left: 44%; + color: #515151; +} +p.resource-subtext { + color: #AEAEAE; +} +#logout :hover { + color: #333; +} + +.file-link:hover { + text-decoration:none; +} +.file-link p { + color: #818181; + font-size: 13pt; +} +.file-link p:hover { + color: #333!important; +} +.icon-size { + width: 60px; + height: 60px; } \ No newline at end of file diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Views/FileSystem/_ResoursePartial.cshtml b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Views/FileSystem/_ResoursePartial.cshtml index 9285872a..9f5dbcdc 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Views/FileSystem/_ResoursePartial.cshtml +++ b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Views/FileSystem/_ResoursePartial.cshtml @@ -64,7 +64,7 @@

@percent%

-

@ViewDataHelper.BytesToSize(resource.ContentLength) / @ViewDataHelper.BytesToSize(resource.AllocatedSpace)

+

@ViewDataHelper.BytesToSize(resource.ContentLength) / @ViewDataHelper.BytesToSize(resource.AllocatedSpace)

}
From 4be06211a44723d9017e45032ea69e672da845c8 Mon Sep 17 00:00:00 2001 From: Virtuworks Date: Wed, 6 May 2015 20:34:00 -0400 Subject: [PATCH 09/22] Added tag build-2.1.0.706 for changeset 9577939ee17a From 3c7cc2fc8c5e860fa3a73e84832339aa3c9357cd Mon Sep 17 00:00:00 2001 From: Virtuworks Date: Wed, 6 May 2015 21:38:19 -0400 Subject: [PATCH 10/22] Update Webdav Portal Logo --- .../Content/Images/logo.png | Bin 6045 -> 6205 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Content/Images/logo.png b/WebsitePanel/Sources/WebsitePanel.WebDavPortal/Content/Images/logo.png index 8db3bf628312588c512b6d06272d3562ed109d67..bf543851b73a0f0231c68129942f7fea00524985 100644 GIT binary patch delta 5482 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 delta 5332 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 mbnOt@n;k-X`-|;A0t^5aNp`%WGN5b#0000 Date: Wed, 6 May 2015 21:50:23 -0400 Subject: [PATCH 11/22] Added tag build-2.1.0.707 for changeset 16aa24360497 From e9be91a97c803d22cfb48ad89e1d538f376040a1 Mon Sep 17 00:00:00 2001 From: vfedosevich Date: Thu, 7 May 2015 02:02:04 -0700 Subject: [PATCH 12/22] update_db.sql fixes --- WebsitePanel/Database/update_db.sql | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/WebsitePanel/Database/update_db.sql b/WebsitePanel/Database/update_db.sql index f139c195..72d95c43 100644 --- a/WebsitePanel/Database/update_db.sql +++ b/WebsitePanel/Database/update_db.sql @@ -9609,6 +9609,11 @@ BEGIN SELECT @group_id = GroupId FROM ResourceGroups WHERE GroupName = 'SharePoint' DELETE FROM PackageQuotas WHERE QuotaID IN (SELECT QuotaID FROM Quotas WHERE GroupID = @group_id) DELETE FROM HostingPlanQuotas WHERE QuotaID IN (SELECT QuotaID FROM Quotas WHERE GroupID = @group_id) + DELETE FROM HostingPlanResources WHERE GroupId = @group_id + DELETE FROM PackagesBandwidth WHERE GroupId = @group_id + DELETE FROM PackagesDiskspace WHERE GroupId = @group_id + DELETE FROM PackageResources WHERE GroupId = @group_id + DELETE FROM ResourceGroupDnsRecords WHERE GroupId = @group_id DELETE FROM Providers WHERE GroupID = @group_id DELETE FROM Quotas WHERE GroupID = @group_id DELETE FROM VirtualGroups WHERE GroupID = @group_id From 5bc6de2f5ec3e29f09f96b2b3864da74273d9b75 Mon Sep 17 00:00:00 2001 From: Virtuworks Date: Thu, 7 May 2015 13:39:11 -0400 Subject: [PATCH 13/22] Added tag build-2.1.0.708 for changeset 97a9a9f34040 From feb73de8a63e7aa40233d739a4e11f5c23db85f3 Mon Sep 17 00:00:00 2001 From: McMak Date: Fri, 8 May 2015 17:13:05 +0300 Subject: [PATCH 14/22] update update_db.sql for WiX --- WebsitePanel/Database/wix_update_db.sql | 560 +++++++++++++++++++++--- 1 file changed, 487 insertions(+), 73 deletions(-) diff --git a/WebsitePanel/Database/wix_update_db.sql b/WebsitePanel/Database/wix_update_db.sql index 4f342f1d..c44654db 100644 --- a/WebsitePanel/Database/wix_update_db.sql +++ b/WebsitePanel/Database/wix_update_db.sql @@ -8910,6 +8910,12 @@ INSERT [dbo].[Quotas] ([QuotaID], [GroupID], [QuotaOrder], [QuotaName], [QuotaDe END GO +IF NOT EXISTS (SELECT * FROM [dbo].[Quotas] WHERE [QuotaID] = '572') +BEGIN + INSERT [dbo].[Quotas] ([QuotaID], [GroupID], [QuotaOrder], [QuotaName], [QuotaDescription], [QuotaTypeID], [ServiceQuota], [ItemTypeID], [HideQuota]) VALUES (572, 33, 20, N'VPS2012.ReplicationEnabled', N'Allow user to Replication', 1, 0, NULL, NULL) +END +GO + IF NOT EXISTS (SELECT * FROM [dbo].[Providers] WHERE [ProviderName] = 'HyperV2012R2') BEGIN INSERT [dbo].[Providers] ([ProviderID], [GroupID], [ProviderName], [DisplayName], [ProviderType], [EditorControl], [DisableAutoDiscovery]) VALUES (350, 33, N'HyperV2012R2', N'Microsoft Hyper-V 2012 R2', N'WebsitePanel.Providers.Virtualization.HyperV2012R2, WebsitePanel.Providers.Virtualization.HyperV2012R2', N'HyperV2012R2', 1) @@ -9590,6 +9596,13 @@ IF EXISTS (SELECT * FROM ResourceGroups WHERE GroupName = 'SharePoint') BEGIN DECLARE @group_id INT SELECT @group_id = GroupId FROM ResourceGroups WHERE GroupName = 'SharePoint' + DELETE FROM PackageQuotas WHERE QuotaID IN (SELECT QuotaID FROM Quotas WHERE GroupID = @group_id) + DELETE FROM HostingPlanQuotas WHERE QuotaID IN (SELECT QuotaID FROM Quotas WHERE GroupID = @group_id) + DELETE FROM HostingPlanResources WHERE GroupId = @group_id + DELETE FROM PackagesBandwidth WHERE GroupId = @group_id + DELETE FROM PackagesDiskspace WHERE GroupId = @group_id + DELETE FROM PackageResources WHERE GroupId = @group_id + DELETE FROM ResourceGroupDnsRecords WHERE GroupId = @group_id DELETE FROM Providers WHERE GroupID = @group_id DELETE FROM Quotas WHERE GroupID = @group_id DELETE FROM VirtualGroups WHERE GroupID = @group_id @@ -10020,6 +10033,145 @@ UPDATE [dbo].[UserSettings] SET [PropertyValue] = @UserPasswordResetLetterTextBo GO + + +DECLARE @UserPasswordResetSMSBody nvarchar(2500) + +Set @UserPasswordResetSMSBody = N'Password reset link: +#passwordResetLink# +' + +IF NOT EXISTS (SELECT * FROM [dbo].[UserSettings] WHERE [UserID] = 1 AND [SettingsName]= N'UserPasswordResetLetter' AND [PropertyName]= N'PasswordResetLinkSmsBody' ) +BEGIN +INSERT [dbo].[UserSettings] ([UserID], [SettingsName], [PropertyName], [PropertyValue]) VALUES (1, N'UserPasswordResetLetter', N'PasswordResetLinkSmsBody', @UserPasswordResetSMSBody) +END +ELSE +UPDATE [dbo].[UserSettings] SET [PropertyValue] = @UserPasswordResetSMSBody WHERE [UserID] = 1 AND [SettingsName]= N'UserPasswordResetLetter' AND [PropertyName]= N'PasswordResetLinkSmsBody' +GO + +-- USER PASSWORD RESET EMAIL PINCODE TEMPLATE + +IF NOT EXISTS (SELECT * FROM [dbo].[UserSettings] WHERE [UserID] = 1 AND [SettingsName]= N'UserPasswordResetPincodeLetter' AND [PropertyName]= N'From' ) +BEGIN +INSERT [dbo].[UserSettings] ([UserID], [SettingsName], [PropertyName], [PropertyValue]) VALUES (1, N'UserPasswordResetPincodeLetter', N'From', N'support@HostingCompany.com') +END +GO + +DECLARE @UserPasswordResetPincodeLetterHtmlBody nvarchar(2500) + +Set @UserPasswordResetPincodeLetterHtmlBody = N' + + Password reset notification + + + +
+
+ +
+

Password reset notification

+ + +

+Hello #user.FirstName#, +

+
+ +

+We received a request to reset the password for your account. Your password reset pincode: +

+ +#passwordResetPincode# + +

+If you have any questions regarding your hosting account, feel free to contact our support department at any time. +

+ +

+Best regards +

+
+'; + +IF NOT EXISTS (SELECT * FROM [dbo].[UserSettings] WHERE [UserID] = 1 AND [SettingsName]= N'UserPasswordResetPincodeLetter' AND [PropertyName]= N'HtmlBody' ) +BEGIN +INSERT [dbo].[UserSettings] ([UserID], [SettingsName], [PropertyName], [PropertyValue]) VALUES (1, N'UserPasswordResetPincodeLetter', N'HtmlBody', @UserPasswordResetPincodeLetterHtmlBody) +END +ELSE +UPDATE [dbo].[UserSettings] SET [PropertyValue] = @UserPasswordResetPincodeLetterHtmlBody WHERE [UserID] = 1 AND [SettingsName]= N'UserPasswordResetPincodeLetter' AND [PropertyName]= N'HtmlBody' +GO + + +IF NOT EXISTS (SELECT * FROM [dbo].[UserSettings] WHERE [UserID] = 1 AND [SettingsName]= N'UserPasswordResetPincodeLetter' AND [PropertyName]= N'Priority' ) +BEGIN +INSERT [dbo].[UserSettings] ([UserID], [SettingsName], [PropertyName], [PropertyValue]) VALUES (1, N'UserPasswordResetPincodeLetter', N'Priority', N'Normal') +END +GO +IF NOT EXISTS (SELECT * FROM [dbo].[UserSettings] WHERE [UserID] = 1 AND [SettingsName]= N'UserPasswordResetPincodeLetter' AND [PropertyName]= N'Subject' ) +BEGIN +INSERT [dbo].[UserSettings] ([UserID], [SettingsName], [PropertyName], [PropertyValue]) VALUES (1, N'UserPasswordResetPincodeLetter', N'Subject', N'Password reset notification') +END +GO +IF NOT EXISTS (SELECT * FROM [dbo].[UserSettings] WHERE [UserID] = 1 AND [SettingsName]= N'UserPasswordResetPincodeLetter' AND [PropertyName]= N'LogoUrl' ) +BEGIN +INSERT [dbo].[UserSettings] ([UserID], [SettingsName], [PropertyName], [PropertyValue]) VALUES (1, N'UserPasswordResetPincodeLetter', N'LogoUrl', N'https://controlpanel.virtuworks.net/App_Themes/Default/Images/logo.png') +END +GO + + +DECLARE @UserPasswordResetPincodeLetterTextBody nvarchar(2500) + +Set @UserPasswordResetPincodeLetterTextBody = N'========================================= + Password reset notification +========================================= + + +Hello #user.FirstName#, + + +We received a request to reset the password for your account. Your password reset pincode: + +#passwordResetPincode# + +If you have any questions regarding your hosting account, feel free to contact our support department at any time. + +Best regards' + +IF NOT EXISTS (SELECT * FROM [dbo].[UserSettings] WHERE [UserID] = 1 AND [SettingsName]= N'UserPasswordResetPincodeLetter' AND [PropertyName]= N'TextBody' ) +BEGIN +INSERT [dbo].[UserSettings] ([UserID], [SettingsName], [PropertyName], [PropertyValue]) VALUES (1, N'UserPasswordResetPincodeLetter', N'TextBody', @UserPasswordResetPincodeLetterTextBody) +END +ELSE +UPDATE [dbo].[UserSettings] SET [PropertyValue] = @UserPasswordResetPincodeLetterTextBody WHERE [UserID] = 1 AND [SettingsName]= N'UserPasswordResetPincodeLetter' AND [PropertyName]= N'TextBody' +GO + +DECLARE @UserPasswordPincodeSMSBody nvarchar(2500) + +Set @UserPasswordPincodeSMSBody = N' +Your password reset pincode: +#passwordResetPincode#' + +IF NOT EXISTS (SELECT * FROM [dbo].[UserSettings] WHERE [UserID] = 1 AND [SettingsName]= N'UserPasswordResetPincodeLetter' AND [PropertyName]= N'PasswordResetPincodeSmsBody' ) +BEGIN +INSERT [dbo].[UserSettings] ([UserID], [SettingsName], [PropertyName], [PropertyValue]) VALUES (1, N'UserPasswordResetPincodeLetter', N'PasswordResetPincodeSmsBody', @UserPasswordPincodeSMSBody) +END +ELSE +UPDATE [dbo].[UserSettings] SET [PropertyValue] = @UserPasswordPincodeSMSBody WHERE [UserID] = 1 AND [SettingsName]= N'UserPasswordResetPincodeLetter' AND [PropertyName]= N'PasswordResetPincodeSmsBody' +GO + -- Exchange setup EMAIL TEMPLATE @@ -10289,79 +10441,79 @@ GO DECLARE @ExchangeMailboxSetupLetterTextBody nvarchar(2500) -Set @ExchangeMailboxSetupLetterTextBody = N' -Hello #Account.DisplayName#, - -Thanks for choosing VirtuWorks as your Exchange hosting provider. - - -User Accounts - -The following user accounts have been created for you. - -Username: #Account.UserPrincipalName# -E-mail: #Account.PrimaryEmailAddress# - -Password Reset Url: #PswResetUrl# - - - -================================= -DNS -================================= - -In order for us to accept mail for your domain, you will need to point your MX records to: - -#SmtpServer# - -================================= -Webmail (OWA, Outlook Web Access) -================================= - -https://mail.virtuworks.net/owa - -================================= -Outlook (Windows Clients) -================================= - -To configure Outlook 2010 to work with VirtuWorks servers, please reference: - -https://portal.virtuworks.net/whmcs/knowledgebase.php?action=displayarticle&id=2 - -If you need to download and install the Outlook 2010 client: - -Outlook 2010 Download URL: -32 Bit - http://www.virtuworks.net/downloads/Outlook2010-32bit.zip -64 Bit - http://www.virtuworks.net/downloads/Outlook2010-64bit.zip -KEY: HXGFV-DY3HM-4W2BQ-3R7KQ-K8P49 - -================================= -ActiveSync, iPhone, iPad -================================= - -Server: #ActiveSyncServer# -Domain: #SamDomain# -SSL: must be checked -Your username: #SamUsername# - -================================= -Password Changes -================================= - -Passwords can be changed at any time using Webmail or the Control Panel (https://controlpanel.virtuworks.net). - - -================================= -Control Panel -================================= - -If you need to change the details of your account, you can easily do this using the Control Panel (https://controlpanel.virtuworks.net). - - -================================= -Support -================================= - +Set @ExchangeMailboxSetupLetterTextBody = N' +Hello #Account.DisplayName#, + +Thanks for choosing VirtuWorks as your Exchange hosting provider. + + +User Accounts + +The following user accounts have been created for you. + +Username: #Account.UserPrincipalName# +E-mail: #Account.PrimaryEmailAddress# + +Password Reset Url: #PswResetUrl# + + + +================================= +DNS +================================= + +In order for us to accept mail for your domain, you will need to point your MX records to: + +#SmtpServer# + +================================= +Webmail (OWA, Outlook Web Access) +================================= + +https://mail.virtuworks.net/owa + +================================= +Outlook (Windows Clients) +================================= + +To configure Outlook 2010 to work with VirtuWorks servers, please reference: + +https://portal.virtuworks.net/whmcs/knowledgebase.php?action=displayarticle&id=2 + +If you need to download and install the Outlook 2010 client: + +Outlook 2010 Download URL: +32 Bit - http://www.virtuworks.net/downloads/Outlook2010-32bit.zip +64 Bit - http://www.virtuworks.net/downloads/Outlook2010-64bit.zip +KEY: HXGFV-DY3HM-4W2BQ-3R7KQ-K8P49 + +================================= +ActiveSync, iPhone, iPad +================================= + +Server: #ActiveSyncServer# +Domain: #SamDomain# +SSL: must be checked +Your username: #SamUsername# + +================================= +Password Changes +================================= + +Passwords can be changed at any time using Webmail or the Control Panel (https://controlpanel.virtuworks.net). + + +================================= +Control Panel +================================= + +If you need to change the details of your account, you can easily do this using the Control Panel (https://controlpanel.virtuworks.net). + + +================================= +Support +================================= + You have 2 options, email help@virtuworks.com or use the web interface at http://www.virtuworks.com/contact/' IF NOT EXISTS (SELECT * FROM [dbo].[UserSettings] WHERE [UserID] = 1 AND [SettingsName]= N'ExchangeMailboxSetupLetter' AND [PropertyName]= N'TextBody' ) @@ -10674,3 +10826,265 @@ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER OFF GO + + +IF EXISTS (SELECT * FROM SYS.OBJECTS WHERE type = 'P' AND name = 'GetSearchObject') +DROP PROCEDURE GetSearchObject +GO +CREATE PROCEDURE [dbo].[GetSearchObject] +( + @ActorID int, + @UserID int, + @FilterColumn nvarchar(50) = '', + @FilterValue nvarchar(50) = '', + @StatusID int, + @RoleID int, + @SortColumn nvarchar(50), + @StartRow int, + @MaximumRows int = 0, + @Recursive bit, + @ColType nvarchar(50) = '', + @FullType nvarchar(50) = '', + @OnlyFind bit +) +AS + +IF dbo.CheckActorUserRights(@ActorID, @UserID) = 0 +RAISERROR('You are not allowed to access this account', 16, 1) + +DECLARE @columnUsername nvarchar(20) +SET @columnUsername = 'Username' + +DECLARE @columnEmail nvarchar(20) +SET @columnEmail = 'Email' + +DECLARE @columnCompanyName nvarchar(20) +SET @columnCompanyName = 'CompanyName' + +DECLARE @columnFullName nvarchar(20) +SET @columnFullName = 'FullName' + +DECLARE @curUsers cursor +DECLARE @curSpace cursor + +DECLARE @sqlSpace nvarchar(2000) +DECLARE @sqlUsers nvarchar(2000) +DECLARE @sqlReturn nvarchar(4000) + +IF @FilterColumn = '' AND @FilterValue <> '' +SET @FilterColumn = 'TextSearch' + +SET @sqlUsers = ' +DECLARE @HasUserRights bit +SET @HasUserRights = dbo.CheckActorUserRights(@ActorID, @UserID) +DECLARE @Users TABLE +( + ItemPosition int IDENTITY(0,1), + UserID int +) +INSERT INTO @Users (UserID) +SELECT ' + +IF @OnlyFind = 1 +SET @sqlUsers = @sqlUsers + 'TOP ' + CAST(@MaximumRows AS varchar(12)) + ' ' + +SET @sqlUsers = @sqlUsers + 'U.UserID +FROM UsersDetailed AS U +WHERE + U.UserID <> @UserID AND U.IsPeer = 0 AND + ( + (@Recursive = 0 AND OwnerID = @UserID) OR + (@Recursive = 1 AND dbo.CheckUserParent(@UserID, U.UserID) = 1) + ) + AND ((@StatusID = 0) OR (@StatusID > 0 AND U.StatusID = @StatusID)) + AND ((@RoleID = 0) OR (@RoleID > 0 AND U.RoleID = @RoleID)) + AND @HasUserRights = 1 +SET @curValue = cursor local for +SELECT + U.ItemID, + U.TextSearch, + U.ColumnType, + ''Users'' as FullType, + 0 as PackageID, + 0 as AccountID +FROM @Users AS TU +INNER JOIN +( +SELECT ItemID, TextSearch, ColumnType +FROM( +SELECT U0.UserID as ItemID, U0.Username as TextSearch, @columnUsername as ColumnType +FROM dbo.Users AS U0 +UNION +SELECT U1.UserID as ItemID, U1.Email as TextSearch, @columnEmail as ColumnType +FROM dbo.Users AS U1 +UNION +SELECT U2.UserID as ItemID, U2.CompanyName as TextSearch, @columnCompanyName as ColumnType +FROM dbo.Users AS U2 +UNION +SELECT U3.UserID as ItemID, U3.FirstName + '' '' + U3.LastName as TextSearch, @columnFullName as ColumnType +FROM dbo.Users AS U3) as U +WHERE TextSearch<>'' '' OR ISNULL(TextSearch, 0) > 0 +) + AS U ON TU.UserID = U.ItemID' + +SET @sqlUsers = @sqlUsers + ' open @curValue' + +exec sp_executesql @sqlUsers, N'@UserID int, @FilterValue nvarchar(50), @ActorID int, @Recursive bit, @StatusID int, @RoleID int, @columnUsername nvarchar(20), @columnEmail nvarchar(20), @columnCompanyName nvarchar(20), @columnFullName nvarchar(20), @curValue cursor output', +@UserID, @FilterValue, @ActorID, @Recursive, @StatusID, @RoleID, @columnUsername, @columnEmail, @columnCompanyName, @columnFullName, @curValue=@curUsers output + +SET @sqlSpace = ' + DECLARE @ItemsService TABLE + ( + ItemID int + ) + INSERT INTO @ItemsService (ItemID) + SELECT ' + +IF @OnlyFind = 1 +SET @sqlSpace = @sqlSpace + 'TOP ' + CAST(@MaximumRows AS varchar(12)) + ' ' + +SET @sqlSpace = @sqlSpace + 'SI.ItemID + FROM ServiceItems AS SI + INNER JOIN Packages AS P ON P.PackageID = SI.PackageID + INNER JOIN UsersDetailed AS U ON P.UserID = U.UserID + WHERE + dbo.CheckUserParent(@UserID, P.UserID) = 1 + DECLARE @ItemsDomain TABLE + ( + ItemID int + ) + INSERT INTO @ItemsDomain (ItemID) + SELECT + D.DomainID + FROM Domains AS D + INNER JOIN Packages AS P ON P.PackageID = D.PackageID + INNER JOIN UsersDetailed AS U ON P.UserID = U.UserID + WHERE + dbo.CheckUserParent(@UserID, P.UserID) = 1 + + SET @curValue = cursor local for + SELECT + + SI.ItemID as ItemID, + SI.ItemName as TextSearch, + STYPE.DisplayName as ColumnType, + STYPE.DisplayName as FullType, + SI.PackageID as PackageID, + 0 as AccountID + FROM @ItemsService AS I + INNER JOIN ServiceItems AS SI ON I.ItemID = SI.ItemID + INNER JOIN ServiceItemTypes AS STYPE ON SI.ItemTypeID = STYPE.ItemTypeID + WHERE STYPE.Searchable = 1 + UNION + SELECT + D.DomainID AS ItemID, + D.DomainName as TextSearch, + ''Domain'' as ColumnType, + ''Domain'' as FullType, + D.PackageID as PackageID, + 0 as AccountID + FROM @ItemsDomain AS I + INNER JOIN Domains AS D ON I.ItemID = D.DomainID + WHERE D.IsDomainPointer=0 + UNION + SELECT + EA.ItemID AS ItemID, + EA.AccountName as TextSearch, + ''ExchangeAccount'' as ColumnType, + ''ExchangeAccount'' as FullType, + SI2.PackageID as PackageID, + EA.AccountID as AccountID + FROM @ItemsService AS I2 + INNER JOIN ServiceItems AS SI2 ON I2.ItemID = SI2.ItemID + INNER JOIN ExchangeAccounts AS EA ON I2.ItemID = EA.ItemID +'; + +SET @sqlSpace = @sqlSpace + ' open @curValue' + +exec sp_executesql @sqlSpace, N'@UserID int, @FilterValue nvarchar(50), @ActorID int, @curValue cursor output', +@UserID, @FilterValue, @ActorID, @curValue=@curSpace output + +SET @sqlReturn = ' +DECLARE @ItemID int +DECLARE @TextSearch nvarchar(500) +DECLARE @ColumnType nvarchar(50) +DECLARE @FullType nvarchar(50) +DECLARE @PackageID int +DECLARE @AccountID int +DECLARE @EndRow int +SET @EndRow = @StartRow + @MaximumRows +DECLARE @ItemsAll TABLE + ( + ItemPosition int IDENTITY(1,1), + ItemID int, + TextSearch nvarchar(500), + ColumnType nvarchar(50), + FullType nvarchar(50), + PackageID int, + AccountID int + ) + +FETCH NEXT FROM @curSpaceValue INTO @ItemID, @TextSearch, @ColumnType, @FullType, @PackageID, @AccountID +WHILE @@FETCH_STATUS = 0 +BEGIN +INSERT INTO @ItemsAll(ItemID, TextSearch, ColumnType, FullType, PackageID, AccountID) +VALUES(@ItemID, @TextSearch, @ColumnType, @FullType, @PackageID, @AccountID) +FETCH NEXT FROM @curSpaceValue INTO @ItemID, @TextSearch, @ColumnType, @FullType, @PackageID, @AccountID +END + +FETCH NEXT FROM @curUsersValue INTO @ItemID, @TextSearch, @ColumnType, @FullType, @PackageID, @AccountID +WHILE @@FETCH_STATUS = 0 +BEGIN +INSERT INTO @ItemsAll(ItemID, TextSearch, ColumnType, FullType, PackageID, AccountID) +VALUES(@ItemID, @TextSearch, @ColumnType, @FullType, @PackageID, @AccountID) +FETCH NEXT FROM @curUsersValue INTO @ItemID, @TextSearch, @ColumnType, @FullType, @PackageID, @AccountID +END + +DECLARE @ItemsReturn TABLE + ( + ItemPosition int IDENTITY(1,1), + ItemID int, + TextSearch nvarchar(500), + ColumnType nvarchar(50), + FullType nvarchar(50), + PackageID int, + AccountID int + ) +INSERT INTO @ItemsReturn(ItemID, TextSearch, ColumnType, FullType, PackageID, AccountID) +SELECT ItemID, TextSearch, ColumnType, FullType, PackageID, AccountID +FROM @ItemsAll AS IA WHERE (1 = 1) ' + + +IF @ColType <> '' +SET @sqlReturn = @sqlReturn + ' AND IA.ColumnType in ( ' + @ColType + ' ) '; + +IF @FullType <> '' +SET @sqlReturn = @sqlReturn + ' AND IA.FullType = ''' + @FullType + ''''; + +IF @FilterValue <> '' +SET @sqlReturn = @sqlReturn + ' AND IA.' + @FilterColumn + ' LIKE @FilterValue ' + +IF @SortColumn <> '' AND @SortColumn IS NOT NULL +SET @sqlReturn = @sqlReturn + ' ORDER BY ' + @SortColumn + ' ' +SET @sqlReturn = @sqlReturn + ' +SELECT COUNT(ItemID) FROM @ItemsReturn; +SELECT DISTINCT(ColumnType) FROM @ItemsReturn WHERE (1 = 1) '; +IF @FullType <> '' +SET @sqlReturn = @sqlReturn + ' AND FullType = ''' + @FullType + ''''; +SET @sqlReturn = @sqlReturn + '; '; +SET @sqlReturn = @sqlReturn + ' +SELECT ItemPosition, ItemID, TextSearch, ColumnType, FullType, PackageID, AccountID +FROM @ItemsReturn AS IR WHERE (1 = 1) +' + +IF @MaximumRows > 0 +SET @sqlReturn = @sqlReturn + ' AND IR.ItemPosition BETWEEN @StartRow AND @EndRow'; + +exec sp_executesql @sqlReturn, N'@StartRow int, @MaximumRows int, @FilterValue nvarchar(50), @curSpaceValue cursor, @curUsersValue cursor', +@StartRow, @MaximumRows, @FilterValue, @curSpace, @curUsers + +CLOSE @curSpace +DEALLOCATE @curSpace +CLOSE @curUsers +DEALLOCATE @curUsers +RETURN From b35dec4356bb7ceeaf38dfc2988d6b1a3dcbf748 Mon Sep 17 00:00:00 2001 From: McMak Date: Fri, 8 May 2015 17:15:01 +0300 Subject: [PATCH 15/22] Fix sql update script --- WebsitePanel/Database/wix_update_db.sql | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/WebsitePanel/Database/wix_update_db.sql b/WebsitePanel/Database/wix_update_db.sql index c44654db..4131b41b 100644 --- a/WebsitePanel/Database/wix_update_db.sql +++ b/WebsitePanel/Database/wix_update_db.sql @@ -8197,11 +8197,13 @@ AS INNER JOIN PackagesTreeCache AS PT ON PIP.PackageID = PT.PackageID WHERE PT.ParentPackageID = @PackageID AND IP.PoolID = 3) ELSE IF @QuotaID = 558 BEGIN -- RAM of VPS2012 - DECLARE @Result1 int = (SELECT SUM(CAST(SIP.PropertyValue AS int)) FROM ServiceItemProperties AS SIP + DECLARE @Result1 int + SET @Result1 = (SELECT SUM(CAST(SIP.PropertyValue AS int)) FROM ServiceItemProperties AS SIP INNER JOIN ServiceItems AS SI ON SIP.ItemID = SI.ItemID INNER JOIN PackagesTreeCache AS PT ON SI.PackageID = PT.PackageID WHERE SIP.PropertyName = 'RamSize' AND PT.ParentPackageID = @PackageID) - DECLARE @Result2 int = (SELECT SUM(CAST(SIP.PropertyValue AS int)) FROM ServiceItemProperties AS SIP + DECLARE @Result2 int + SET @Result2 = (SELECT SUM(CAST(SIP.PropertyValue AS int)) FROM ServiceItemProperties AS SIP INNER JOIN ServiceItems AS SI ON SIP.ItemID = SI.ItemID INNER JOIN ServiceItemProperties AS SIP2 ON SIP2.ItemID = SI.ItemID AND SIP2.PropertyName = 'DynamicMemory.Enabled' AND SIP2.PropertyValue = 'True' From 98e4ab42f3634dbdedb19a211062f2c67c3ca57e Mon Sep 17 00:00:00 2001 From: Alexander Trofimov Date: Fri, 8 May 2015 18:16:11 +0300 Subject: [PATCH 16/22] HyperV minor fix --- WebsitePanel/Database/update_db.sql | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/WebsitePanel/Database/update_db.sql b/WebsitePanel/Database/update_db.sql index 72d95c43..b4cf06cb 100644 --- a/WebsitePanel/Database/update_db.sql +++ b/WebsitePanel/Database/update_db.sql @@ -8208,11 +8208,13 @@ AS INNER JOIN PackagesTreeCache AS PT ON PIP.PackageID = PT.PackageID WHERE PT.ParentPackageID = @PackageID AND IP.PoolID = 3) ELSE IF @QuotaID = 558 BEGIN -- RAM of VPS2012 - DECLARE @Result1 int = (SELECT SUM(CAST(SIP.PropertyValue AS int)) FROM ServiceItemProperties AS SIP + DECLARE @Result1 int + SET @Result1 = (SELECT SUM(CAST(SIP.PropertyValue AS int)) FROM ServiceItemProperties AS SIP INNER JOIN ServiceItems AS SI ON SIP.ItemID = SI.ItemID INNER JOIN PackagesTreeCache AS PT ON SI.PackageID = PT.PackageID WHERE SIP.PropertyName = 'RamSize' AND PT.ParentPackageID = @PackageID) - DECLARE @Result2 int = (SELECT SUM(CAST(SIP.PropertyValue AS int)) FROM ServiceItemProperties AS SIP + DECLARE @Result2 int + SET @Result2 = (SELECT SUM(CAST(SIP.PropertyValue AS int)) FROM ServiceItemProperties AS SIP INNER JOIN ServiceItems AS SI ON SIP.ItemID = SI.ItemID INNER JOIN ServiceItemProperties AS SIP2 ON SIP2.ItemID = SI.ItemID AND SIP2.PropertyName = 'DynamicMemory.Enabled' AND SIP2.PropertyValue = 'True' From 0ffa71d0709df5d29ccac05b042757954672578d Mon Sep 17 00:00:00 2001 From: Virtuworks Date: Fri, 8 May 2015 11:45:13 -0400 Subject: [PATCH 17/22] Added tag build-2.1.0.709 for changeset 7eef364995e4 From ff7ccc7dab8f2db1bf1313d082711cde82aa7dde Mon Sep 17 00:00:00 2001 From: McMak Date: Fri, 8 May 2015 20:50:54 +0300 Subject: [PATCH 18/22] Added file logger and default values for usernames, passwords. --- .../Sources/Setup.WIXInstaller/Product.wxs | 14 +++-- .../Common/WiXLogFileListener.cs | 55 +++++++++++++++++++ .../WebsitePanel.WIXInstaller/CustomAction.cs | 28 ++++++++++ .../WebsitePanel.WIXInstaller.csproj | 1 + 4 files changed, 93 insertions(+), 5 deletions(-) create mode 100644 WebsitePanel.Installer/Sources/WebsitePanel.WIXInstaller/Common/WiXLogFileListener.cs diff --git a/WebsitePanel.Installer/Sources/Setup.WIXInstaller/Product.wxs b/WebsitePanel.Installer/Sources/Setup.WIXInstaller/Product.wxs index 82eef886..866e0a79 100644 --- a/WebsitePanel.Installer/Sources/Setup.WIXInstaller/Product.wxs +++ b/WebsitePanel.Installer/Sources/Setup.WIXInstaller/Product.wxs @@ -452,6 +452,7 @@ 1 1 + Please wait while [ProductName] Installer configures IIS & ASP.NET, this may take a few minutes. Thanks! @@ -476,7 +477,7 @@ - + @@ -503,7 +504,7 @@ - + @@ -512,7 +513,7 @@ - + @@ -522,7 +523,7 @@ - + @@ -590,9 +591,10 @@ WSP_ROOT + - + @@ -610,8 +612,10 @@ + 1 + diff --git a/WebsitePanel.Installer/Sources/WebsitePanel.WIXInstaller/Common/WiXLogFileListener.cs b/WebsitePanel.Installer/Sources/WebsitePanel.WIXInstaller/Common/WiXLogFileListener.cs new file mode 100644 index 00000000..623505fa --- /dev/null +++ b/WebsitePanel.Installer/Sources/WebsitePanel.WIXInstaller/Common/WiXLogFileListener.cs @@ -0,0 +1,55 @@ +using System; +using System.Diagnostics; +using System.IO; +using System.Text; +using Microsoft.Deployment.WindowsInstaller; + +namespace WebsitePanel.WIXInstaller.Common +{ + public class WiXLogFileListener : TraceListener + { + public const uint FileFlushSize = 4096; + public const string DefaultLogFile = "WSPInstallation.log.txt"; + public static string LogFile { get; private set; } + private StringBuilder m_Ctx; + static WiXLogFileListener() + { + LogFile = Path.Combine(Path.GetTempPath() + DefaultLogFile); + } + public WiXLogFileListener(string LogFileName = DefaultLogFile) + : base("WiXLogFileListener") + { + m_Ctx = new StringBuilder(); + } + ~WiXLogFileListener() + { + Dispose(false); + } + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + Flush(true); + } + public override void Write(string Value) + { + m_Ctx.Append(Value); + Flush(); + } + public override void WriteLine(string Value) + { + m_Ctx.AppendLine(Value); + Flush(); + } + private void Flush(bool Force = false) + { + if(m_Ctx.Length >= FileFlushSize || Force) + { + using (var FileCtx = new StreamWriter(LogFile, true)) + { + FileCtx.Write(m_Ctx.ToString()); + } + m_Ctx.Clear(); + } + } + } +} diff --git a/WebsitePanel.Installer/Sources/WebsitePanel.WIXInstaller/CustomAction.cs b/WebsitePanel.Installer/Sources/WebsitePanel.WIXInstaller/CustomAction.cs index 2f652068..726ded67 100644 --- a/WebsitePanel.Installer/Sources/WebsitePanel.WIXInstaller/CustomAction.cs +++ b/WebsitePanel.Installer/Sources/WebsitePanel.WIXInstaller/CustomAction.cs @@ -54,6 +54,32 @@ namespace WebsitePanel.WIXInstaller #region CustomActions [CustomAction] + public static ActionResult PreFillSettings(Session session) + { + PopUpDebugger(); + var Ctx = session; + Ctx.AttachToSetupLog(); + Log.WriteStart("PreFillSettings"); + TryApllyNewPassword(Ctx, "PI_SERVER_PASSWORD"); + TryApllyNewPassword(Ctx, "PI_ESERVER_PASSWORD"); + TryApllyNewPassword(Ctx, "PI_PORTAL_PASSWORD"); + TryApllyNewPassword(Ctx, "SERVER_ACCESS_PASSWORD"); + TryApllyNewPassword(Ctx, "SERVERADMIN_PASSWORD"); + Log.WriteEnd("PreFillSettings"); + return ActionResult.Success; + } + private static void TryApllyNewPassword(Session Ctx, string Id) + { + var Pass = Ctx[Id]; + if(string.IsNullOrWhiteSpace(Pass)) + { + Pass = Guid.NewGuid().ToString(); + Ctx[Id] = Pass; + Ctx[Id + "_CONFIRM"] = Pass; + Log.WriteInfo("New password was applied to " + Id); + } + } + [CustomAction] public static ActionResult InstallWebFeatures(Session session) { var Msg = string.Empty; @@ -406,6 +432,7 @@ namespace WebsitePanel.WIXInstaller [CustomAction] public static ActionResult FillIpListUI(Session session) { + PopUpDebugger(); var Ctrls = new[]{ new ComboBoxCtrl(session, "PI_SERVER_IP"), new ComboBoxCtrl(session, "PI_ESERVER_IP"), new ComboBoxCtrl(session, "PI_PORTAL_IP") }; @@ -758,6 +785,7 @@ namespace WebsitePanel.WIXInstaller { WiXSetup.InstallLogListener(new WiXLogListener(Ctx)); WiXSetup.InstallLogListener(new InMemoryStringLogListener("WIX CA IN MEMORY")); + WiXSetup.InstallLogListener(new WiXLogFileListener()); } } diff --git a/WebsitePanel.Installer/Sources/WebsitePanel.WIXInstaller/WebsitePanel.WIXInstaller.csproj b/WebsitePanel.Installer/Sources/WebsitePanel.WIXInstaller/WebsitePanel.WIXInstaller.csproj index 59ae4596..1a4b44b7 100644 --- a/WebsitePanel.Installer/Sources/WebsitePanel.WIXInstaller/WebsitePanel.WIXInstaller.csproj +++ b/WebsitePanel.Installer/Sources/WebsitePanel.WIXInstaller/WebsitePanel.WIXInstaller.csproj @@ -63,6 +63,7 @@ + From 5ab109df9a05e0d107f3c9ac199672a6934ff75f Mon Sep 17 00:00:00 2001 From: McMak Date: Fri, 8 May 2015 21:55:14 +0300 Subject: [PATCH 19/22] Fix WSP registry locator. --- .../Sources/Setup.WIXInstaller/Product.wxs | 12 +++++----- .../WebsitePanel.WIXInstaller/CustomAction.cs | 23 +++++++++---------- 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/WebsitePanel.Installer/Sources/Setup.WIXInstaller/Product.wxs b/WebsitePanel.Installer/Sources/Setup.WIXInstaller/Product.wxs index 866e0a79..c22fd509 100644 --- a/WebsitePanel.Installer/Sources/Setup.WIXInstaller/Product.wxs +++ b/WebsitePanel.Installer/Sources/Setup.WIXInstaller/Product.wxs @@ -540,8 +540,8 @@ - - + + - WSP_ROOT + WSP_BASE @@ -684,9 +684,9 @@ - - + diff --git a/WebsitePanel.Installer/Sources/WebsitePanel.WIXInstaller/CustomAction.cs b/WebsitePanel.Installer/Sources/WebsitePanel.WIXInstaller/CustomAction.cs index 726ded67..e14b3ce4 100644 --- a/WebsitePanel.Installer/Sources/WebsitePanel.WIXInstaller/CustomAction.cs +++ b/WebsitePanel.Installer/Sources/WebsitePanel.WIXInstaller/CustomAction.cs @@ -68,17 +68,6 @@ namespace WebsitePanel.WIXInstaller Log.WriteEnd("PreFillSettings"); return ActionResult.Success; } - private static void TryApllyNewPassword(Session Ctx, string Id) - { - var Pass = Ctx[Id]; - if(string.IsNullOrWhiteSpace(Pass)) - { - Pass = Guid.NewGuid().ToString(); - Ctx[Id] = Pass; - Ctx[Id + "_CONFIRM"] = Pass; - Log.WriteInfo("New password was applied to " + Id); - } - } [CustomAction] public static ActionResult InstallWebFeatures(Session session) { @@ -778,6 +767,17 @@ namespace WebsitePanel.WIXInstaller { Debugger.Launch(); } + private static void TryApllyNewPassword(Session Ctx, string Id) + { + var Pass = Ctx[Id]; + if (string.IsNullOrWhiteSpace(Pass)) + { + Pass = Guid.NewGuid().ToString(); + Ctx[Id] = Pass; + Ctx[Id + "_CONFIRM"] = Pass; + Log.WriteInfo("New password was applied to " + Id); + } + } } public static class SessionExtension { @@ -788,7 +788,6 @@ namespace WebsitePanel.WIXInstaller WiXSetup.InstallLogListener(new WiXLogFileListener()); } } - internal enum WiXInstallType: byte { InstallServer, From 473fd3c3ef2f75fc62660aa849defb64dae81ab9 Mon Sep 17 00:00:00 2001 From: McMak Date: Tue, 12 May 2015 23:44:49 +0300 Subject: [PATCH 20/22] WiX Update fixes. --- .../Sources/Setup.WIXInstaller/Product.wxs | 71 ++++++-- .../Common/InstallAction.cs | 3 +- .../Sources/WebsitePanel.Setup/Common/OS.cs | 18 ++ .../WebsitePanel.Setup/Internal/Adapter.cs | 160 ++++++++++++++---- .../Internal/BackupRestore.cs | 122 +++++++++++++ .../Internal/XmlDocumentMerge.cs | 139 +++++++++++++++ .../WebsitePanel.Setup.csproj | 2 + .../WebsitePanel.WIXInstaller/CustomAction.cs | 41 ++++- 8 files changed, 500 insertions(+), 56 deletions(-) create mode 100644 WebsitePanel.Installer/Sources/WebsitePanel.Setup/Internal/BackupRestore.cs create mode 100644 WebsitePanel.Installer/Sources/WebsitePanel.Setup/Internal/XmlDocumentMerge.cs diff --git a/WebsitePanel.Installer/Sources/Setup.WIXInstaller/Product.wxs b/WebsitePanel.Installer/Sources/Setup.WIXInstaller/Product.wxs index c22fd509..273fbfaf 100644 --- a/WebsitePanel.Installer/Sources/Setup.WIXInstaller/Product.wxs +++ b/WebsitePanel.Installer/Sources/Setup.WIXInstaller/Product.wxs @@ -331,11 +331,14 @@ 1 1 - &ServerFeature=3 - &EnterpriseServerFeature=3 - &PortalFeature=3 - &SchedulerServiceFeature=3 - &WDPortalFeature=3 + + + + + + + + 1 1 @@ -357,7 +360,10 @@ ""]]> "" AND DSOP_UPN = ""]]> - 1 + + 1 + + &EnterpriseServerFeature=3 AND VALIDATE_OK = "1" &PortalFeature=3 AND VALIDATE_OK = "1" &SchedulerServiceFeature=3 AND VALIDATE_OK = "1" @@ -389,7 +395,11 @@ ""]]> "" AND DSOP_UPN = ""]]> - 1 + + + 1 + + VALIDATE_OK="0" 1 @@ -437,16 +447,22 @@ ""]]> "" AND DSOP_UPN = ""]]> - 1 + + + + 1 1 1 - - - - 3]]> - 3 AND &PortalFeature<>3]]> + + + + + + + 3 AND COMPFOUND_ESERVER=0]]> + 3 AND &PortalFeature<>3 AND COMPFOUND_SERVER=0]]> 1 1 @@ -540,9 +556,15 @@ - + + + + + + + @@ -589,6 +611,13 @@ + + + + + + + WSP_BASE @@ -611,7 +640,15 @@ - + + + + + + + + + 1 @@ -634,7 +671,7 @@ - (NOT Installed OR NOT WIX_UPGRADE_DETECTED) AND NOT(DB_AUTH = "Windows Authentication") + (NOT Installed AND NOT WIX_UPGRADE_DETECTED) AND NOT(DB_AUTH = "Windows Authentication") - (NOT Installed OR NOT WIX_UPGRADE_DETECTED) AND (DB_AUTH = "Windows Authentication") + (NOT Installed AND NOT WIX_UPGRADE_DETECTED) AND (DB_AUTH = "Windows Authentication") /// LoadSetupVariablesFromParameters. @@ -393,6 +397,9 @@ namespace WebsitePanel.Setup.Internal case ActionTypes.ConfigureSecureSessionModuleInWebConfig: ConfigureSecureSessionModuleInWebConfig(); break; + case ActionTypes.RestoreConfig: + RestoreXmlConfigs(Execute.SetupVariables); + break; } } catch (Exception ex) @@ -402,7 +409,6 @@ namespace WebsitePanel.Setup.Internal } } } - protected virtual List GetActions(string ComponentID) { return new List(); @@ -843,7 +849,7 @@ namespace WebsitePanel.Setup.Internal return; } // Load web.config - XmlDocument doc = new XmlDocument(); + var doc = new XmlDocument(); doc.Load(webConfigPath); // add node: @@ -993,7 +999,7 @@ namespace WebsitePanel.Setup.Internal return; } // Load web.config - XmlDocument doc = new XmlDocument(); + var doc = new XmlDocument(); doc.Load(webConfigPath); // do Windows 2008 platform-specific changes bool iis7 = (Context.IISVersion.Major >= 7); @@ -1229,7 +1235,7 @@ namespace WebsitePanel.Setup.Internal private string GetConnectionString(string webConfigPath) { string ret = null; - XmlDocument doc = new XmlDocument(); + var doc = new XmlDocument(); doc.Load(webConfigPath); //connection string string xPath = "configuration/connectionStrings/add[@name=\"EnterpriseServer\"]"; @@ -1244,7 +1250,7 @@ namespace WebsitePanel.Setup.Internal private string GetCryptoKey(string webConfigPath) { string ret = null; - XmlDocument doc = new XmlDocument(); + var doc = new XmlDocument(); doc.Load(webConfigPath); //crypto key string xPath = "configuration/appSettings/add[@key=\"WebsitePanel.CryptoKey\"]"; @@ -1258,7 +1264,7 @@ namespace WebsitePanel.Setup.Internal private bool IsEncryptionEnabled(string webConfigPath) { - XmlDocument doc = new XmlDocument(); + var doc = new XmlDocument(); doc.Load(webConfigPath); //encryption enabled string xPath = "configuration/appSettings/add[@key=\"WebsitePanel.EncryptionEnabled\"]"; @@ -2316,7 +2322,7 @@ namespace WebsitePanel.Setup.Internal } Log.WriteStart("Updating config.xml file"); - XmlDocument doc = new XmlDocument(); + var doc = new XmlDocument(); doc.Load(path); XmlNode serversNode = doc.SelectSingleNode("//myLittleAdmin/sqlservers"); @@ -2429,7 +2435,7 @@ namespace WebsitePanel.Setup.Internal return; } // Load web.config - XmlDocument doc = new XmlDocument(); + var doc = new XmlDocument(); doc.Load(webConfigPath); // Tighten WSE security on local machine @@ -2513,7 +2519,7 @@ namespace WebsitePanel.Setup.Internal } Log.WriteStart("Loading portal settings"); - XmlDocument doc = new XmlDocument(); + var doc = new XmlDocument(); doc.Load(path); string xPath = "configuration/connectionStrings/add[@name=\"SiteSqlServer\"]"; @@ -2605,7 +2611,7 @@ namespace WebsitePanel.Setup.Internal } Log.WriteStart("Updating site settings"); - XmlDocument doc = new XmlDocument(); + var doc = new XmlDocument(); doc.Load(path); XmlElement urlNode = doc.SelectSingleNode("SiteSettings/EnterpriseServer") as XmlElement; @@ -3178,7 +3184,7 @@ namespace WebsitePanel.Setup.Internal } Log.WriteStart("Updating configuration file (server password)"); - XmlDocument doc = new XmlDocument(); + var doc = new XmlDocument(); doc.Load(path); XmlElement passwordNode = doc.SelectSingleNode("//websitepanel.server/security/password") as XmlElement; @@ -3221,7 +3227,7 @@ namespace WebsitePanel.Setup.Internal } Log.WriteStart("Updating configuration file (service settings)"); - XmlDocument doc = new XmlDocument(); + var doc = new XmlDocument(); doc.Load(path); XmlElement ipNode = doc.SelectSingleNode("//configuration/appSettings/add[@key='WebsitePanel.HostIP']") as XmlElement; @@ -3881,7 +3887,7 @@ namespace WebsitePanel.Setup.Internal return; } // Load web.config - XmlDocument doc = new XmlDocument(); + var doc = new XmlDocument(); doc.Load(webConfigPath); // replace existing node: @@ -3915,8 +3921,63 @@ namespace WebsitePanel.Setup.Internal } #endregion #endregion + private void RestoreXmlConfigs(SetupVariables Ctx) + { + try + { + Log.WriteStart("RestoreXmlConfigs"); + var Backup = BackupRestore.Find(Ctx.InstallerFolder, "WebsitePanel", Ctx.ComponentName); + switch(Ctx.ComponentCode) + { + case "server": + { + Backup.XmlFiles.Add("Web.config"); + } + break; + case "enterpriseserver": + { + Backup.XmlFiles.Add("Web.config"); + } + break; + case "portal": + { + Backup.XmlFiles.Add("Web.config"); + Backup.XmlFiles.Add(@"App_Data\Countries.config"); + Backup.XmlFiles.Add(@"App_Data\CountryStates.config"); + Backup.XmlFiles.Add(@"App_Data\Ecommerce_Modules.config"); + Backup.XmlFiles.Add(@"App_Data\Ecommerce_Pages.config"); + Backup.XmlFiles.Add(@"App_Data\ESModule_ControlsHierarchy.config"); + Backup.XmlFiles.Add(@"App_Data\ModulesData.config"); + Backup.XmlFiles.Add(@"App_Data\SiteSettings.config"); + Backup.XmlFiles.Add(@"App_Data\SupportedLocales.config"); + Backup.XmlFiles.Add(@"App_Data\SupportedThemes.config"); + Backup.XmlFiles.Add(@"App_Data\WebsitePanel_Modules.config"); + Backup.XmlFiles.Add(@"App_Data\WebsitePanel_Pages.config"); + } + break; + } + var MainCfg = Path.Combine(Ctx.InstallerFolder, BackupRestore.MainConfig); + var XCfg = new XmlDocument(); + XCfg.Load(MainCfg); + if (XCfg.SelectSingleNode("//components").ChildNodes.Count == 0) + { + Log.WriteInfo("Restoring main config..."); + XmlDocumentMerge.Process(Backup.BackupMainConfigFile, MainCfg); + Context.ComponentId = WiXSetup.GetComponentID(Ctx); + AppConfig.LoadConfiguration(new ExeConfigurationFileMap { ExeConfigFilename = MainCfg }); + AppConfig.LoadComponentSettings(Ctx); + } + Log.WriteInfo(string.Format("Restoring xml config for component - {0}.", Ctx.ComponentFullName)); + Backup.Restore(); + Log.WriteEnd("RestoreXmlConfigs"); + } + catch (Exception ex) + { + Log.WriteError("RestoreXmlConfigs", ex); + throw; + } + } } - public class UninstallScript : SetupScript // UninstallPage { public UninstallScript(SetupVariables SessionVariables):base(SessionVariables) @@ -4117,12 +4178,22 @@ namespace WebsitePanel.Setup.Internal protected override List GetActions(string ComponentID) { var Scenario = base.GetActions(ComponentID); - var Act = new InstallAction(ActionTypes.UpdateConfig); - Act.Description = "Updating system configuration..."; - Scenario.Add(Act); - Act = new InstallAction(ActionTypes.StartApplicationPool); - Act.Description = "Starting IIS Application Pool..."; - Scenario.Add(Act); + Scenario.Add(new InstallAction(ActionTypes.RestoreConfig) { SetupVariables = Context, Description = "Restoring xml configuration files..." }); + Scenario.Add(new InstallAction(ActionTypes.UpdateConfig) { Description = "Updating system configuration..." }); + Scenario.Add(new InstallAction(ActionTypes.StartApplicationPool) { Description = "Starting IIS Application Pool..." }); + return Scenario; + } + } + public class MaintenanceScript: ExpressScript + { + public MaintenanceScript(SetupVariables SessionVariables):base(SessionVariables) + { + Context.SetupAction = SetupActions.Setup; + } + protected override List GetActions(string ComponentID) + { + var Scenario = base.GetActions(ComponentID); + Scenario.Add(new InstallAction(ActionTypes.UpdateConfig) { Description = "Updating system configuration..." }); return Scenario; } } @@ -4170,6 +4241,7 @@ namespace WebsitePanel.Setup.Internal else if (ModeExtension == ModeExtension.Restore) { Context.ComponentId = GetComponentID(Context); + Context.UpdateVersion = Context.Release; AppConfig.LoadComponentSettings(Context); new RestoreScript(Context).Run(); } @@ -4194,12 +4266,19 @@ namespace WebsitePanel.Setup.Internal } Script.Run(); } + protected override void Maintenance() + { + Context.ComponentId = GetComponentID(Context); + AppConfig.LoadComponentSettings(Context); + SetupScript Script = new MaintenanceScript(Context); + Script.Actions.Add(new InstallAction(ActionTypes.UpdateServerPassword) { Description = "Updating server password..." }); + Script.Run(); + } } - public class EServerSetup : WiXSetup { - public EServerSetup(SetupVariables Ctx) - : base(Ctx) + public EServerSetup(SetupVariables Ctx, ModeExtension Ext) + : base(Ctx, Ext) { } @@ -4210,7 +4289,7 @@ namespace WebsitePanel.Setup.Internal SetupVars.SetupAction = Action; SetupVars.IISVersion = Global.IISVersion; AppConfig.LoadConfiguration(new ExeConfigurationFileMap { ExeConfigFilename = GetFullConfigPath(SetupVars) }); - return new EServerSetup(SetupVars); + return new EServerSetup(SetupVars, GetModeExtension(Ctx)); } protected override void Install() { @@ -4240,6 +4319,7 @@ namespace WebsitePanel.Setup.Internal else if (ModeExtension == ModeExtension.Restore) { Context.ComponentId = GetComponentID(Context); + Context.UpdateVersion = Context.Release; AppConfig.LoadComponentSettings(Context); new RestoreScript(Context).Run(); } @@ -4264,12 +4344,19 @@ namespace WebsitePanel.Setup.Internal } Script.Run(); } + protected override void Maintenance() + { + Context.ComponentId = GetComponentID(Context); + AppConfig.LoadComponentSettings(Context); + SetupScript Script = new MaintenanceScript(Context); + Script.Actions.Add(new InstallAction(ActionTypes.UpdateServerAdminPassword) { Description = "Updating serveradmin password..." }); + Script.Run(); + } } - public class PortalSetup : WiXSetup { - public PortalSetup(SetupVariables Ctx) - : base(Ctx) + public PortalSetup(SetupVariables Ctx, ModeExtension Ext) + : base(Ctx, Ext) { } @@ -4280,7 +4367,7 @@ namespace WebsitePanel.Setup.Internal SetupVars.SetupAction = Action; SetupVars.IISVersion = Global.IISVersion; AppConfig.LoadConfiguration(new ExeConfigurationFileMap { ExeConfigFilename = GetFullConfigPath(SetupVars) }); - return new PortalSetup(SetupVars); + return new PortalSetup(SetupVars, GetModeExtension(Ctx)); } protected override void Install() { @@ -4306,17 +4393,11 @@ namespace WebsitePanel.Setup.Internal } if (WiXThrow) InstallFailed(); - - else if (ModeExtension == ModeExtension.Restore) - { - Context.ComponentId = GetComponentID(Context); - AppConfig.LoadComponentSettings(Context); - new RestoreScript(Context).Run(); - } } else if (ModeExtension == ModeExtension.Restore) { Context.ComponentId = GetComponentID(Context); + Context.UpdateVersion = Context.Release; AppConfig.LoadComponentSettings(Context); new RestoreScript(Context).Run(); } @@ -4348,8 +4429,15 @@ namespace WebsitePanel.Setup.Internal } Script.Run(); } + protected override void Maintenance() + { + Context.ComponentId = GetComponentID(Context); + AppConfig.LoadComponentSettings(Context); + SetupScript Script = new MaintenanceScript(Context); + Script.Actions.Add(new InstallAction(ActionTypes.UpdateEnterpriseServerUrl) { Description = "Updating site settings..." }); + Script.Run(); + } } - #region WiXActionManagers public class WiXServerActionManager : BaseActionManager { diff --git a/WebsitePanel.Installer/Sources/WebsitePanel.Setup/Internal/BackupRestore.cs b/WebsitePanel.Installer/Sources/WebsitePanel.Setup/Internal/BackupRestore.cs new file mode 100644 index 00000000..5778175f --- /dev/null +++ b/WebsitePanel.Installer/Sources/WebsitePanel.Setup/Internal/BackupRestore.cs @@ -0,0 +1,122 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Xml; +using Ionic.Zip; + +namespace WebsitePanel.Setup.Internal +{ + class BackupRestore + { + struct DirectoryTag + { + public string Name; + public DateTime Date; + public Version Version; + } + public const string MainConfig = "WebsitePanel.config"; + const string BackupDirectory = "Backup"; + const string ConfigDirectory = "Config"; + const string AppZip = @"App\app.zip"; + const string DateFormat = "yyyy-MM-dd"; + public BackupRestore() + { + XmlFiles = new List(); + } + public static BackupRestore Find(string Root, string Product, string Id) + { + var Result = default(BackupRestore); + var Dir = Path.Combine(Root, BackupDirectory); + var FullId = GetFullId(Product, Id); + if (Directory.Exists(Dir)) + { + var DirList = new List(); + foreach (var DateItem in Directory.GetDirectories(Dir)) + { + DateTime date; + var DateName = new DirectoryInfo(DateItem).Name; + if (DateTime.TryParseExact(DateName, DateFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out date)) + { + foreach (var VersionItem in Directory.GetDirectories(DateItem)) + { + var VersionName = new DirectoryInfo(VersionItem).Name; + if (VersionName.StartsWith(FullId, StringComparison.InvariantCultureIgnoreCase)) + { + Version BckpVersion; + var StrVersion = VersionName.Substring(FullId.Length); + if (Version.TryParse(StrVersion, out BckpVersion)) + { + DirList.Add(new DirectoryTag { Name = VersionItem, Date = date, Version = BckpVersion }); + } + } + } + } + } + var ByVersion = from i in DirList where i.Version == (from v in DirList select v.Version).Max() select i; + var ByDate = from i in ByVersion where i.Date == (from v in ByVersion select v.Date).Max() select i; + var SrcTag = ByDate.First(); + Result = new BackupRestore { Id = Id, Root = GetComponentRoot(SrcTag, Id), BackupFile = Path.Combine(SrcTag.Name, AppZip), BackupMainConfigFile = GetMainConfig(SrcTag) }; + } + return Result; + } + private static string GetComponentRoot(DirectoryTag DirTag, string Id) + { + var Cfg = GetMainConfig(DirTag); + if (string.IsNullOrWhiteSpace(Cfg)) + throw new Exception("Broken backup. Main config file not found."); + var XCfg = new XmlDocument(); + XCfg.Load(Cfg); + var Component = XCfg.SelectSingleNode(string.Format("//component[.//add/@key='ComponentName' and .//add/@value='{0}']", Id)); + var InstallFolder = Component.SelectSingleNode(".//add[@key='InstallFolder']"); + return InstallFolder.Attributes["value"].Value; + } + private static string GetMainConfig(DirectoryTag DirTag) + { + return Path.Combine(DirTag.Name, ConfigDirectory, MainConfig); + } + private static string GetFullId(string Product, string Id) + { + return string.Format("{0} {1}", Product, Id); + } + public virtual void Restore() + { + using (var Bckp = new ZipFile(BackupFile)) + { + foreach (var Xml in XmlFiles) + { + var SrcEntry = from Entry in Bckp.Entries where NormalizePath(Entry.FileName.ToLowerInvariant(), "/") == Xml.ToLowerInvariant() select Entry; + if (SrcEntry != null) + { + if (SrcEntry.LongCount() > 1) + throw new Exception(string.Format("Too many backup entries - {0}.", Xml)); + var FileEntry = SrcEntry.FirstOrDefault(); + if (FileEntry != null) + { + using (var InMem = new MemoryStream()) + { + FileEntry.Extract(InMem); + InMem.Seek(0, SeekOrigin.Begin); + using (var OutFile = new FileStream(Path.Combine(Root, Xml), FileMode.Open, FileAccess.ReadWrite)) + { + XmlDocumentMerge.Process(InMem, OutFile); + } + } + } + } + } + } + } + private string NormalizePath(string FilePath, string In) + { + return Path.Combine(FilePath.Split(new string[] { In }, StringSplitOptions.RemoveEmptyEntries)); + } + public string Id { get; set; } // Component full name. + public string Comment { get; set; } + public string BackupFile { get; set; } // Should be zip archive. + public string BackupMainConfigFile { get; set; } + public IList XmlFiles { get; set; } // Xml files (configs) to merge and update. + public string Root { get; set; } + } +} diff --git a/WebsitePanel.Installer/Sources/WebsitePanel.Setup/Internal/XmlDocumentMerge.cs b/WebsitePanel.Installer/Sources/WebsitePanel.Setup/Internal/XmlDocumentMerge.cs new file mode 100644 index 00000000..4c4511c4 --- /dev/null +++ b/WebsitePanel.Installer/Sources/WebsitePanel.Setup/Internal/XmlDocumentMerge.cs @@ -0,0 +1,139 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Xml; +using System.Xml.XPath; + +namespace WebsitePanel.Setup.Internal +{ + public static class XmlDocumentMerge + { + const string SuccessFormat = "Success: {0}."; + const string ErrorFormat = "Error: {0}."; + const string MergeCompleted = "XmlDocumentMerge completed"; + static XmlDocumentMerge() + { + KeyAttributes = new List { "name", "id", "key" }; + } + public static List KeyAttributes { get; set; } + public static string Process(string Src, string Dst, string SaveTo = "") + { + var Result = string.Empty; + if (!File.Exists(Src)) + Result = string.Format(ErrorFormat, string.Format("source document [{0}] does not exists", Src)); + else if (!File.Exists(Dst)) + Result = string.Format(ErrorFormat, string.Format("destination document [{0}] does not exists", Dst)); + else + { + try + { + var InStream = new FileStream(Src, FileMode.Open, FileAccess.Read); + var OutStream = new FileStream(Dst, FileMode.Open, FileAccess.ReadWrite); + Result = Process(InStream, + OutStream, + SaveTo); + InStream.Close(); + OutStream.Flush(); + OutStream.Close(); + } + catch (Exception ex) + { + Result = string.Format(ErrorFormat, ex.ToString()); + } + } + return Result; + } + public static string Process(Stream InSrc, Stream OutDst, string SaveTo = "") + { + var Result = string.Format(SuccessFormat, MergeCompleted); + try + { + var SrcDoc = new XmlDocument(); + SrcDoc.Load(InSrc); + var DstDoc = new XmlDocument(); + DstDoc.Load(OutDst); + var DstNavi = DstDoc.CreateNavigator(); + var DstIterator = DstNavi.SelectChildren(XPathNodeType.All); + while (DstIterator.MoveNext()) + Merge(DstIterator.Current.Clone(), SrcDoc, string.Empty); + if (string.IsNullOrWhiteSpace(SaveTo)) + { + OutDst.SetLength(0); + DstDoc.Save(OutDst); + } + else + DstDoc.Save(SaveTo); + } + catch (Exception ex) + { + Result = string.Format(ErrorFormat, ex.ToString()); + } + return Result; + } + private static string NodePath(string Parent, string Current) + { + var Result = string.Empty; + if (!string.IsNullOrWhiteSpace(Parent) && !string.IsNullOrWhiteSpace(Current)) + Result = string.Format("{0}/{1}", Parent, Current); + else if (!string.IsNullOrWhiteSpace(Parent)) + Result = Parent; + else if (!string.IsNullOrWhiteSpace(Current)) + Result = Current; + return Result; + } + private static string NodeView(XPathNavigator Navi) + { + foreach (var Attr in KeyAttributes) + { + var Value = Navi.GetAttribute(Attr, string.Empty); + if (!string.IsNullOrWhiteSpace(Value)) + return string.Format("{0}[@{1}='{2}']", Navi.Name, Attr, Value); + } + return Navi.Name; + } + private static void Merge(XPathNavigator DstNavi, XmlDocument SrcDoc, string Parent) + { + if (DstNavi.NodeType == XPathNodeType.Element) + { + var SrcElem = SrcDoc.SelectSingleNode(NodePath(Parent, NodeView(DstNavi))); + if (SrcElem != null) + { + if (DstNavi.MoveToFirstAttribute()) + { + do + { + var SrcElemAttr = SrcElem.Attributes[DstNavi.LocalName]; + if (SrcElemAttr != null) + DstNavi.SetValue(SrcElemAttr.Value); + } + while (DstNavi.MoveToNextAttribute()); + DstNavi.MoveToParent(); + } + } + } + else if (DstNavi.NodeType == XPathNodeType.Text) + { + var SrcElem = SrcDoc.SelectSingleNode(NodePath(Parent, NodeView(DstNavi))); + if (SrcElem != null) + DstNavi.SetValue(SrcElem.InnerText); + } + var Here = NodeView(DstNavi); + if (DstNavi.MoveToFirstChild()) + { + do + { + Merge(DstNavi, SrcDoc, NodePath(Parent, Here)); + } + while (DstNavi.MoveToNext()); + DstNavi.MoveToParent(); + } + else if (DstNavi.NodeType == XPathNodeType.Element) + { + var SrcElem = SrcDoc.SelectSingleNode(NodePath(Parent, Here)); + if (SrcElem != null && !string.IsNullOrWhiteSpace(SrcElem.InnerXml)) + foreach (XmlNode Child in SrcElem.ChildNodes) + DstNavi.AppendChild(Child.CloneNode(true).CreateNavigator()); + } + } + } +} diff --git a/WebsitePanel.Installer/Sources/WebsitePanel.Setup/WebsitePanel.Setup.csproj b/WebsitePanel.Installer/Sources/WebsitePanel.Setup/WebsitePanel.Setup.csproj index 246d4850..864c3e5d 100644 --- a/WebsitePanel.Installer/Sources/WebsitePanel.Setup/WebsitePanel.Setup.csproj +++ b/WebsitePanel.Installer/Sources/WebsitePanel.Setup/WebsitePanel.Setup.csproj @@ -144,6 +144,8 @@ + + diff --git a/WebsitePanel.Installer/Sources/WebsitePanel.WIXInstaller/CustomAction.cs b/WebsitePanel.Installer/Sources/WebsitePanel.WIXInstaller/CustomAction.cs index e14b3ce4..3bc32d46 100644 --- a/WebsitePanel.Installer/Sources/WebsitePanel.WIXInstaller/CustomAction.cs +++ b/WebsitePanel.Installer/Sources/WebsitePanel.WIXInstaller/CustomAction.cs @@ -54,6 +54,33 @@ namespace WebsitePanel.WIXInstaller #region CustomActions [CustomAction] + public static ActionResult MaintenanceServer(Session session) + { + var Result = ActionResult.Success; + Log.WriteStart("MaintenanceServer"); + Result = ProcessInstall(session, WiXInstallType.MaintenanceServer); + Log.WriteEnd("MaintenanceServer"); + return Result; + } + [CustomAction] + public static ActionResult MaintenanceEServer(Session session) + { + var Result = ActionResult.Success; + Log.WriteStart("MaintenanceEServer"); + Result = ProcessInstall(session, WiXInstallType.MaintenanceEnterpriseServer); + Log.WriteEnd("MaintenanceEServer"); + return Result; + } + [CustomAction] + public static ActionResult MaintenancePortal(Session session) + { + var Result = ActionResult.Success; + Log.WriteStart("MaintenancePortal"); + Result = ProcessInstall(session, WiXInstallType.MaintenancePortal); + Log.WriteEnd("MaintenancePortal"); + return Result; + } + [CustomAction] public static ActionResult PreFillSettings(Session session) { PopUpDebugger(); @@ -733,18 +760,27 @@ namespace WebsitePanel.WIXInstaller case WiXInstallType.RemoveServer: Install = ServerSetup.Create(Ctx.CustomActionData, SetupActions.Uninstall); break; + case WiXInstallType.MaintenanceServer: + Install = ServerSetup.Create(Ctx.CustomActionData, SetupActions.Setup); + break; case WiXInstallType.InstallEnterpriseServer: Install = EServerSetup.Create(Ctx.CustomActionData, SetupActions.Install); break; case WiXInstallType.RemoveEnterpriseServer: Install = EServerSetup.Create(Ctx.CustomActionData, SetupActions.Uninstall); break; + case WiXInstallType.MaintenanceEnterpriseServer: + Install = EServerSetup.Create(Ctx.CustomActionData, SetupActions.Setup); + break; case WiXInstallType.InstallPortal: Install = PortalSetup.Create(Ctx.CustomActionData, SetupActions.Install); break; case WiXInstallType.RemovePortal: Install = PortalSetup.Create(Ctx.CustomActionData, SetupActions.Uninstall); break; + case WiXInstallType.MaintenancePortal: + Install = PortalSetup.Create(Ctx.CustomActionData, SetupActions.Setup); + break; default: throw new NotImplementedException(); } @@ -796,7 +832,8 @@ namespace WebsitePanel.WIXInstaller RemoveServer, RemoveEnterpriseServer, RemovePortal, - RemoveUpdate, - RestoreUpdate + MaintenanceServer, + MaintenanceEnterpriseServer, + MaintenancePortal } } From ce508b178c1a26d28811ca5bace20801ed3992eb Mon Sep 17 00:00:00 2001 From: McMak Date: Wed, 13 May 2015 06:27:24 +0300 Subject: [PATCH 21/22] Improvements WiX UI, installed component detection, update via UI. --- .../Sources/Setup.WIXInstaller/Product.wxs | 12 +-- .../WebsitePanel.Setup/Common/Global.cs | 1 + .../WebsitePanel.Setup/Internal/Adapter.cs | 20 ++-- .../Internal/BackupRestore.cs | 14 ++- .../WebsitePanel.WIXInstaller/CustomAction.cs | 97 +++++++++++++++++++ .../WebsitePanel.WIXInstaller.csproj | 1 + 6 files changed, 127 insertions(+), 18 deletions(-) diff --git a/WebsitePanel.Installer/Sources/Setup.WIXInstaller/Product.wxs b/WebsitePanel.Installer/Sources/Setup.WIXInstaller/Product.wxs index 273fbfaf..6d4f921b 100644 --- a/WebsitePanel.Installer/Sources/Setup.WIXInstaller/Product.wxs +++ b/WebsitePanel.Installer/Sources/Setup.WIXInstaller/Product.wxs @@ -563,8 +563,8 @@ - - + + @@ -599,7 +599,7 @@ - + @@ -607,14 +607,14 @@ - + - + @@ -649,7 +649,7 @@ - 1 + diff --git a/WebsitePanel.Installer/Sources/WebsitePanel.Setup/Common/Global.cs b/WebsitePanel.Installer/Sources/WebsitePanel.Setup/Common/Global.cs index 6bf1759f..e0215046 100644 --- a/WebsitePanel.Installer/Sources/WebsitePanel.Setup/Common/Global.cs +++ b/WebsitePanel.Installer/Sources/WebsitePanel.Setup/Common/Global.cs @@ -39,6 +39,7 @@ namespace WebsitePanel.Setup public const string DefaultInstallPathRoot = @"C:\WebsitePanel"; public const string LoopbackIPv4 = "127.0.0.1"; public const string InstallerProductCode = "cfg core"; + public const string DefaultProductName = "WebsitePanel"; public abstract class Parameters { diff --git a/WebsitePanel.Installer/Sources/WebsitePanel.Setup/Internal/Adapter.cs b/WebsitePanel.Installer/Sources/WebsitePanel.Setup/Internal/Adapter.cs index f0f28301..5eeb3a0c 100644 --- a/WebsitePanel.Installer/Sources/WebsitePanel.Setup/Internal/Adapter.cs +++ b/WebsitePanel.Installer/Sources/WebsitePanel.Setup/Internal/Adapter.cs @@ -170,9 +170,13 @@ namespace WebsitePanel.Setup.Internal } public static string GetComponentID(SetupVariables Ctx) { - var XmlPath = string.Format("//component[.//add/@key='ComponentCode' and .//add/@value='{0}']", Ctx.ComponentCode); + return GetComponentID(GetFullConfigPath(Ctx), Ctx.ComponentCode); + } + public static string GetComponentID(string Cfg, string ComponentCode) + { + var XmlPath = string.Format("//component[.//add/@key='ComponentCode' and .//add/@value='{0}']", ComponentCode); var Xml = new XmlDocument(); - Xml.Load(GetFullConfigPath(Ctx)); + Xml.Load(Cfg); var Node = Xml.SelectSingleNode(XmlPath) as XmlElement; return Node == null ? null : Node.GetAttribute("id"); } @@ -3926,20 +3930,20 @@ namespace WebsitePanel.Setup.Internal try { Log.WriteStart("RestoreXmlConfigs"); - var Backup = BackupRestore.Find(Ctx.InstallerFolder, "WebsitePanel", Ctx.ComponentName); + var Backup = BackupRestore.Find(Ctx.InstallerFolder, Global.DefaultProductName, Ctx.ComponentName); switch(Ctx.ComponentCode) { - case "server": + case Global.Server.ComponentCode: { Backup.XmlFiles.Add("Web.config"); } break; - case "enterpriseserver": + case Global.EntServer.ComponentCode: { Backup.XmlFiles.Add("Web.config"); } break; - case "portal": + case Global.WebPortal.ComponentCode: { Backup.XmlFiles.Add("Web.config"); Backup.XmlFiles.Add(@"App_Data\Countries.config"); @@ -3957,9 +3961,7 @@ namespace WebsitePanel.Setup.Internal break; } var MainCfg = Path.Combine(Ctx.InstallerFolder, BackupRestore.MainConfig); - var XCfg = new XmlDocument(); - XCfg.Load(MainCfg); - if (XCfg.SelectSingleNode("//components").ChildNodes.Count == 0) + if (!BackupRestore.HaveChild(MainCfg, "//components")) { Log.WriteInfo("Restoring main config..."); XmlDocumentMerge.Process(Backup.BackupMainConfigFile, MainCfg); diff --git a/WebsitePanel.Installer/Sources/WebsitePanel.Setup/Internal/BackupRestore.cs b/WebsitePanel.Installer/Sources/WebsitePanel.Setup/Internal/BackupRestore.cs index 5778175f..91890d6e 100644 --- a/WebsitePanel.Installer/Sources/WebsitePanel.Setup/Internal/BackupRestore.cs +++ b/WebsitePanel.Installer/Sources/WebsitePanel.Setup/Internal/BackupRestore.cs @@ -8,7 +8,7 @@ using Ionic.Zip; namespace WebsitePanel.Setup.Internal { - class BackupRestore + public class BackupRestore { struct DirectoryTag { @@ -47,9 +47,7 @@ namespace WebsitePanel.Setup.Internal Version BckpVersion; var StrVersion = VersionName.Substring(FullId.Length); if (Version.TryParse(StrVersion, out BckpVersion)) - { DirList.Add(new DirectoryTag { Name = VersionItem, Date = date, Version = BckpVersion }); - } } } } @@ -61,6 +59,16 @@ namespace WebsitePanel.Setup.Internal } return Result; } + public static bool HaveChild(string XmlDocPath, string XmlPath) + { + var Result = false; + var XCfg = new XmlDocument(); + XCfg.Load(XmlDocPath); + var Node = XCfg.SelectSingleNode(XmlPath); + if (Node != null) + Result = Node.ChildNodes.Count > 0; + return Result; + } private static string GetComponentRoot(DirectoryTag DirTag, string Id) { var Cfg = GetMainConfig(DirTag); diff --git a/WebsitePanel.Installer/Sources/WebsitePanel.WIXInstaller/CustomAction.cs b/WebsitePanel.Installer/Sources/WebsitePanel.WIXInstaller/CustomAction.cs index 3bc32d46..0ff7782e 100644 --- a/WebsitePanel.Installer/Sources/WebsitePanel.WIXInstaller/CustomAction.cs +++ b/WebsitePanel.Installer/Sources/WebsitePanel.WIXInstaller/CustomAction.cs @@ -27,6 +27,7 @@ // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. using System; using System.Collections.Generic; +using System.Configuration; using System.Configuration.Install; using System.Data; using System.Data.Sql; @@ -87,6 +88,102 @@ namespace WebsitePanel.WIXInstaller var Ctx = session; Ctx.AttachToSetupLog(); Log.WriteStart("PreFillSettings"); + var WSP = Ctx["WEBSITEPANELDIR"]; + var CfgStr = string.Empty; + Func GetCfg = (string CfgDir) => + { + if (Directory.Exists(CfgDir)) + { + var CfgFile = Path.Combine(CfgDir, BackupRestore.MainConfig); + if (File.Exists(CfgFile) && BackupRestore.HaveChild(CfgFile, "//components")) + return CfgFile; + else + { + var Names = new string[] { Global.Server.ComponentName, Global.EntServer.ComponentName, Global.WebPortal.ComponentName }; + foreach (var Name in Names) + { + var Backup = BackupRestore.Find(CfgDir, Global.DefaultProductName, Name); + if (Backup != null && BackupRestore.HaveChild(Backup.BackupMainConfigFile, "//components")) + return CfgStr = Backup.BackupMainConfigFile; + } + } + } + return string.Empty; + }; + Func SetProperty = (Session CtxSession, string Prop, string Value) => + { + if(!string.IsNullOrWhiteSpace(Value)) + { + CtxSession[Prop] = Value; + return true; + } + return false; + }; + CfgStr = GetCfg(WSP); + if(string.IsNullOrWhiteSpace(CfgStr)) + { + var Drives = from Drive in DriveInfo.GetDrives() where Drive.DriveType == DriveType.Fixed select Drive; + foreach(var Drive in Drives) + { + var Dir = Path.Combine(Drive.RootDirectory.FullName, Global.DefaultProductName); + CfgStr = GetCfg(Dir); + if (!string.IsNullOrWhiteSpace(CfgStr)) + break; + } + } + if (!string.IsNullOrWhiteSpace(CfgStr)) + { + var EServerUrl = string.Empty; + AppConfig.LoadConfiguration(new ExeConfigurationFileMap { ExeConfigFilename = CfgStr }); + var CtxVars = new SetupVariables(); + CtxVars.ComponentId = WiXSetup.GetComponentID(CfgStr, Global.Server.ComponentCode); + if (!string.IsNullOrWhiteSpace(CtxVars.ComponentId)) + { + AppConfig.LoadComponentSettings(CtxVars); + Ctx["COMPFOUND_SERVER"] = "1"; + SetProperty(Ctx, "PI_SERVER_IP", CtxVars.WebSiteIP); + SetProperty(Ctx, "PI_SERVER_PORT", CtxVars.WebSitePort); + SetProperty(Ctx, "PI_SERVER_HOST", CtxVars.WebSiteDomain); + SetProperty(Ctx, "PI_SERVER_LOGIN", CtxVars.UserAccount); + SetProperty(Ctx, "PI_SERVER_PASSWORD", CtxVars.UserPassword); + SetProperty(Ctx, "PI_SERVER_PASSWORD_CONFIRM",CtxVars.UserPassword); + SetProperty(Ctx, "PI_SERVER_DOMAIN", CtxVars.UserDomain); + SetProperty(Ctx, "SERVER_ACCESS_PASSWORD", CtxVars.ServerPassword); + SetProperty(Ctx, "SERVER_ACCESS_PASSWORD_CONFIRM", CtxVars.ServerPassword); + } + CtxVars.ComponentId = WiXSetup.GetComponentID(CfgStr, Global.EntServer.ComponentCode); + if (!string.IsNullOrWhiteSpace(CtxVars.ComponentId)) + { + AppConfig.LoadComponentSettings(CtxVars); + Ctx["COMPFOUND_ESERVER"] = "1"; + SetProperty(Ctx, "PI_ESERVER_IP", CtxVars.WebSiteIP); + SetProperty(Ctx, "PI_ESERVER_PORT", CtxVars.WebSitePort); + SetProperty(Ctx, "PI_ESERVER_HOST", CtxVars.WebSiteDomain); + SetProperty(Ctx, "PI_ESERVER_LOGIN", CtxVars.UserAccount); + SetProperty(Ctx, "PI_ESERVER_PASSWORD", CtxVars.UserPassword); + SetProperty(Ctx, "PI_ESERVER_PASSWORD_CONFIRM", CtxVars.UserPassword); + SetProperty(Ctx, "PI_ESERVER_DOMAIN", CtxVars.UserDomain); + SetProperty(Ctx, "SERVERADMIN_PASSWORD", CtxVars.ServerAdminPassword); + SetProperty(Ctx, "SERVERADMIN_PASSWORD_CONFIRM", CtxVars.ServerAdminPassword); + EServerUrl = string.Format("http://{0}:{1}", CtxVars.WebSiteIP, CtxVars.WebSitePort); + } + CtxVars.ComponentId = WiXSetup.GetComponentID(CfgStr, Global.WebPortal.ComponentCode); + if (!string.IsNullOrWhiteSpace(CtxVars.ComponentId)) + { + AppConfig.LoadComponentSettings(CtxVars); + Ctx["COMPFOUND_PORTAL"] = "1"; + SetProperty(Ctx, "PI_PORTAL_IP", CtxVars.WebSiteIP); + SetProperty(Ctx, "PI_PORTAL_PORT", CtxVars.WebSitePort); + SetProperty(Ctx, "PI_PORTAL_HOST", CtxVars.WebSiteDomain); + SetProperty(Ctx, "PI_PORTAL_LOGIN", CtxVars.UserAccount); + SetProperty(Ctx, "PI_PORTAL_PASSWORD", CtxVars.UserPassword); + SetProperty(Ctx, "PI_PORTAL_PASSWORD_CONFIRM", CtxVars.UserPassword); + SetProperty(Ctx, "PI_PORTAL_DOMAIN", CtxVars.UserDomain); + if (!SetProperty(Ctx, "PI_ESERVER_URL", CtxVars.EnterpriseServerURL)) + if (!SetProperty(Ctx, "PI_ESERVER_URL", EServerUrl)) + SetProperty(Ctx, "PI_ESERVER_URL", Global.WebPortal.DefaultEntServURL); + } + } TryApllyNewPassword(Ctx, "PI_SERVER_PASSWORD"); TryApllyNewPassword(Ctx, "PI_ESERVER_PASSWORD"); TryApllyNewPassword(Ctx, "PI_PORTAL_PASSWORD"); diff --git a/WebsitePanel.Installer/Sources/WebsitePanel.WIXInstaller/WebsitePanel.WIXInstaller.csproj b/WebsitePanel.Installer/Sources/WebsitePanel.WIXInstaller/WebsitePanel.WIXInstaller.csproj index 1a4b44b7..0aee4f2c 100644 --- a/WebsitePanel.Installer/Sources/WebsitePanel.WIXInstaller/WebsitePanel.WIXInstaller.csproj +++ b/WebsitePanel.Installer/Sources/WebsitePanel.WIXInstaller/WebsitePanel.WIXInstaller.csproj @@ -47,6 +47,7 @@ ..\..\Lib\Microsoft.Web.Administration.dll + From ee19096e2da1680db023daeec1ed29c795641f2f Mon Sep 17 00:00:00 2001 From: dev_amdtel Date: Wed, 13 May 2015 17:10:29 +0300 Subject: [PATCH 22/22] Exchange2013 fixes --- .../Exchange2013.cs | 36 ++++++++++++------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/WebsitePanel/Sources/WebsitePanel.Providers.HostedSolution.Exchange2013/Exchange2013.cs b/WebsitePanel/Sources/WebsitePanel.Providers.HostedSolution.Exchange2013/Exchange2013.cs index 02dead74..28e536b7 100644 --- a/WebsitePanel/Sources/WebsitePanel.Providers.HostedSolution.Exchange2013/Exchange2013.cs +++ b/WebsitePanel/Sources/WebsitePanel.Providers.HostedSolution.Exchange2013/Exchange2013.cs @@ -4479,7 +4479,7 @@ namespace WebsitePanel.Providers.HostedSolution { ExchangeLog.LogStart("CheckOrganizationPublicFolderMailbox"); - Collection result = GetPublicFolderMailbox(runSpace, orgCanonicalName, GetPublicFolderMailboxName(organizationId)); + Collection result = GetPublicFolderMailbox(runSpace, orgCanonicalName, GetPublicFolderMailboxName(organizationId), true); if (result == null || result.Count == 0) { ExchangeTransaction transaction = StartTransaction(); @@ -4501,7 +4501,7 @@ namespace WebsitePanel.Providers.HostedSolution { ExchangeLog.LogStart("CheckOrganizationRootFolder"); - Collection result = GetPublicFolderObject(runSpace, orgCanonicalName+"/"+GetPublicFolderMailboxName(organizationId), "\\" + folder); + Collection result = GetPublicFolderObject(runSpace, orgCanonicalName+"/"+GetPublicFolderMailboxName(organizationId), "\\" + folder, true); if (result == null || result.Count == 0) { ExchangeTransaction transaction = StartTransaction(); @@ -4617,22 +4617,22 @@ namespace WebsitePanel.Providers.HostedSolution ExchangeLog.LogEnd("DeletePublicFolderInternal"); } - private Collection GetPublicFolderObject(Runspace runSpace, string mailbox, string id) + private Collection GetPublicFolderObject(Runspace runSpace, string mailbox, string id, bool checkExist = false) { Command cmd = new Command("Get-PublicFolder"); cmd.Parameters.Add("Identity", id); //cmd.Parameters.Add("Mailbox", mailbox); - Collection result = ExecuteShellCommand(runSpace, cmd); + Collection result = ExecuteShellCommand(runSpace, cmd, true, !checkExist); return result; } - private Collection GetPublicFolderMailbox(Runspace runSpace, string organizationDistinguishedName, string name) + private Collection GetPublicFolderMailbox(Runspace runSpace, string organizationDistinguishedName, string name, bool checkExist) { Command cmd = new Command("Get-Mailbox"); cmd.Parameters.Add("Identity", name); cmd.Parameters.Add("PublicFolder"); cmd.Parameters.Add("OrganizationalUnit", organizationDistinguishedName); - Collection result = ExecuteShellCommand(runSpace, cmd); + Collection result = ExecuteShellCommand(runSpace, cmd, true, !checkExist); return result; } @@ -5369,7 +5369,7 @@ namespace WebsitePanel.Providers.HostedSolution string resultObjectDN = null; Command cmd = new Command("Get-AddressList"); cmd.Parameters.Add("Identity", id); - Collection result = this.ExecuteShellCommand(runSpace, cmd); + Collection result = this.ExecuteShellCommand(runSpace, cmd, true, false); if ((result != null) && (result.Count > 0)) { resultObjectDN = this.GetResultObjectDN(result); @@ -6242,13 +6242,19 @@ namespace WebsitePanel.Providers.HostedSolution internal Collection ExecuteShellCommand(Runspace runSpace, Command cmd) { - return ExecuteShellCommand(runSpace, cmd, true); + return ExecuteShellCommand(runSpace, cmd, true, true); } internal Collection ExecuteShellCommand(Runspace runSpace, Command cmd, bool useDomainController) { object[] errors; - return ExecuteShellCommand(runSpace, cmd, useDomainController, out errors); + return ExecuteShellCommand(runSpace, cmd, useDomainController, out errors, true); + } + + internal Collection ExecuteShellCommand(Runspace runSpace, Command cmd, bool useDomainController, bool writeErrorExchangeLog) + { + object[] errors; + return ExecuteShellCommand(runSpace, cmd, useDomainController, out errors, writeErrorExchangeLog); } internal Collection ExecuteShellCommand(Runspace runSpace, Command cmd, ResultObject res) @@ -6272,10 +6278,10 @@ namespace WebsitePanel.Providers.HostedSolution internal Collection ExecuteShellCommand(Runspace runSpace, Command cmd, out object[] errors) { - return ExecuteShellCommand(runSpace, cmd, true, out errors); + return ExecuteShellCommand(runSpace, cmd, true, out errors, true); } - internal Collection ExecuteShellCommand(Runspace runSpace, Command cmd, bool useDomainController, out object[] errors) + internal Collection ExecuteShellCommand(Runspace runSpace, Command cmd, bool useDomainController, out object[] errors, bool writeErrorExchangeLog) { ExchangeLog.LogStart("ExecuteShellCommand"); List errorList = new List(); @@ -6309,8 +6315,12 @@ namespace WebsitePanel.Providers.HostedSolution foreach (object item in pipeLine.Error.ReadToEnd()) { errorList.Add(item); - string errorMessage = string.Format("Invoke error: {0}", item); - ExchangeLog.LogWarning(errorMessage); + + if (writeErrorExchangeLog) + { + string errorMessage = string.Format("Invoke error: {0}", item); + ExchangeLog.LogWarning(errorMessage); + } } } }