diff --git a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/Common/WebPlatformInstaller.cs b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/Common/WebPlatformInstaller.cs
new file mode 100644
index 00000000..d7e28612
--- /dev/null
+++ b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/Common/WebPlatformInstaller.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace WebsitePanel.EnterpriseServer.Base.Common
+{
+ public class WebPlatformInstaller
+ {
+ public const string MAIN_FEED_URL = "https://www.microsoft.com/web/webpi/4.2/webproductlist.xml";
+ public const string ZOO_FEED = "http://www.helicontech.com/zoo/feed/wsp4";
+ }
+}
diff --git a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/System/SystemSettings.cs b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/System/SystemSettings.cs
index 904dec23..76778a16 100644
--- a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/System/SystemSettings.cs
+++ b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/System/SystemSettings.cs
@@ -42,6 +42,10 @@ namespace WebsitePanel.EnterpriseServer
public const string BACKUP_SETTINGS = "BackupSettings";
public const string SETUP_SETTINGS = "SetupSettings";
public const string WPI_SETTINGS = "WpiSettings";
+
+ // key to access to wpi main & custom feed in wpi settings
+ public const string WPI_MAIN_FEED_KEY = "WpiMainFeedUrl";
+ public const string FEED_ULS_KEY = "FeedUrls";
public static readonly SystemSettings Empty = new SystemSettings { SettingsArray = new string[][] {} };
diff --git a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/WebsitePanel.EnterpriseServer.Base.csproj b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/WebsitePanel.EnterpriseServer.Base.csproj
index 9350215a..2168e6e3 100644
--- a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/WebsitePanel.EnterpriseServer.Base.csproj
+++ b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/WebsitePanel.EnterpriseServer.Base.csproj
@@ -74,6 +74,7 @@
Code
+
diff --git a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer/Code/WebAppGallery/WebAppGalleryController.cs b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer/Code/WebAppGallery/WebAppGalleryController.cs
index ff0f06d2..e4fb539b 100644
--- a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer/Code/WebAppGallery/WebAppGalleryController.cs
+++ b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer/Code/WebAppGallery/WebAppGalleryController.cs
@@ -29,15 +29,14 @@
using System;
using System.Collections.Generic;
using System.Threading;
-using WebsitePanel.Providers.Web;
+using WebsitePanel.EnterpriseServer.Base.Common;
+using WebsitePanel.Providers.Web;
using WebsitePanel.Providers.ResultObjects;
using WebsitePanel.Providers.Database;
using WebsitePanel.Providers.WebAppGallery;
using System.Collections.Specialized;
-using System.Reflection;
using WebsitePanel.Providers.Common;
using System.Diagnostics;
-using System.IO;
namespace WebsitePanel.EnterpriseServer
{
@@ -72,28 +71,33 @@ namespace WebsitePanel.EnterpriseServer
private static string[] getFeedsFromSettingsByServiceId(int serviceId)
{
- StringDictionary serviceSettings = ServerController.GetServiceSettings(serviceId);
+ var wpiSettings = SystemController.GetSystemSettings(SystemSettings.WPI_SETTINGS);
- List arFeeds = new List();
+ List feeds = new List();
- if (Utils.ParseBool(serviceSettings["FeedEnableMicrosoft"], true))
+ // Microsoft feed
+ string mainFeedUrl = wpiSettings[SystemSettings.WPI_MAIN_FEED_KEY];
+ if (string.IsNullOrEmpty(mainFeedUrl))
{
- arFeeds.Add(esServers.MAIN_WPI_FEED);
+ mainFeedUrl = WebPlatformInstaller.MAIN_FEED_URL;
}
+ feeds.Add(mainFeedUrl);
- if (Utils.ParseBool(serviceSettings["FeedEnableHelicon"], true))
- {
- arFeeds.Add(esServers.HELICON_WPI_FEED);
- }
+ // Zoo Feed
+ feeds.Add(WebPlatformInstaller.ZOO_FEED);
- string additionalFeeds = serviceSettings["FeedUrls"];
+
+ // additional feeds
+ string additionalFeeds = wpiSettings[SystemSettings.FEED_ULS_KEY];
if (!string.IsNullOrEmpty(additionalFeeds))
{
- arFeeds.AddRange(additionalFeeds.Split(';'));
+ feeds.AddRange(additionalFeeds.Split(';'));
}
- return arFeeds.ToArray();
+ return feeds.ToArray();
}
+
+
public static void InitFeedsByServiceId(int UserId, int serviceId)
{
string[] feeds = getFeedsFromSettingsByServiceId(serviceId);
diff --git a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer/esServers.asmx.cs b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer/esServers.asmx.cs
index c9f4a3b2..982c6f11 100644
--- a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer/esServers.asmx.cs
+++ b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer/esServers.asmx.cs
@@ -35,6 +35,7 @@ using System.Collections.Generic;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.ComponentModel;
+using WebsitePanel.EnterpriseServer.Base.Common;
using WebsitePanel.Providers.Common;
using Microsoft.Web.Services3;
@@ -54,8 +55,10 @@ namespace WebsitePanel.EnterpriseServer
[ToolboxItem(false)]
public class esServers : System.Web.Services.WebService
{
- public const string MAIN_WPI_FEED = "https://www.microsoft.com/web/webpi/4.0/WebProductList.xml";
+ /*
+ public const string MAIN_WPI_FEED = "https://www.microsoft.com/web/webpi/4.2/WebProductList.xml";
public const string HELICON_WPI_FEED = "http://www.helicontech.com/zoo/feed/wsp4";
+ */
#region Servers
[WebMethod]
@@ -696,25 +699,28 @@ namespace WebsitePanel.EnterpriseServer
var wpiSettings = SystemController.GetSystemSettings(SystemSettings.WPI_SETTINGS);
- List arFeeds = new List();
+ List feeds = new List();
- if (Utils.ParseBool(wpiSettings["FeedEnableMicrosoft"] ,true))
+ // Microsoft feed
+ string mainFeedUrl = wpiSettings[SystemSettings.WPI_MAIN_FEED_KEY];
+ if (string.IsNullOrEmpty(mainFeedUrl))
{
- arFeeds.Add( MAIN_WPI_FEED );
+ mainFeedUrl = WebPlatformInstaller.MAIN_FEED_URL;
}
+ feeds.Add(mainFeedUrl);
- if (Utils.ParseBool(wpiSettings["FeedEnableHelicon"] ,true))
- {
- arFeeds.Add( HELICON_WPI_FEED );
- }
-
- string additionalFeeds = wpiSettings["FeedUrls"];
+ // Zoo Feed
+ feeds.Add(WebPlatformInstaller.ZOO_FEED);
+
+
+ // additional feeds
+ string additionalFeeds = wpiSettings[SystemSettings.FEED_ULS_KEY];
if (!string.IsNullOrEmpty(additionalFeeds))
{
- arFeeds.AddRange(additionalFeeds.Split(';'));
+ feeds.AddRange(additionalFeeds.Split(';'));
}
- OperatingSystemController.InitWPIFeeds(serverId, string.Join(";", arFeeds));
+ OperatingSystemController.InitWPIFeeds(serverId, string.Join(";", feeds));
}
diff --git a/WebsitePanel/Sources/WebsitePanel.Providers.Web.IIs60/IIs60.cs b/WebsitePanel/Sources/WebsitePanel.Providers.Web.IIs60/IIs60.cs
index 4aa4e55b..5319504f 100644
--- a/WebsitePanel/Sources/WebsitePanel.Providers.Web.IIs60/IIs60.cs
+++ b/WebsitePanel/Sources/WebsitePanel.Providers.Web.IIs60/IIs60.cs
@@ -279,7 +279,8 @@ namespace WebsitePanel.Providers.Web
get { return FileUtils.EvaluateSystemVariables(ProviderSettings["ProtectedFoldersFile"]); }
}
- protected string GalleryXmlFeedUrl
+ /*
+ protected string GalleryXmlFeedUrl
{
get
{
@@ -289,6 +290,7 @@ namespace WebsitePanel.Providers.Web
return ret;
}
}
+ */
#endregion
private WmiHelper wmi = null;
diff --git a/WebsitePanel/Sources/WebsitePanel.Providers.Web.IIs60/WebApplicationGallery.cs b/WebsitePanel/Sources/WebsitePanel.Providers.Web.IIs60/WebApplicationGallery.cs
deleted file mode 100644
index 913e9a2a..00000000
--- a/WebsitePanel/Sources/WebsitePanel.Providers.Web.IIs60/WebApplicationGallery.cs
+++ /dev/null
@@ -1,943 +0,0 @@
-// Copyright (c) 2012, Outercurve Foundation.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without modification,
-// are permitted provided that the following conditions are met:
-//
-// - Redistributions of source code must retain the above copyright notice, this
-// list of conditions and the following disclaimer.
-//
-// - Redistributions in binary form must reproduce the above copyright notice,
-// this list of conditions and the following disclaimer in the documentation
-// and/or other materials provided with the distribution.
-//
-// - Neither the name of the Outercurve Foundation nor the names of its
-// contributors may be used to endorse or promote products derived from this
-// software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
-// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-using System.Xml;
-using System.Xml.Serialization;
-
-using Microsoft.Practices.EnterpriseLibrary.Caching;
-using System.Net;
-using System.IO;
-using WebsitePanel.Server.Utils;
-using WebsitePanel.Providers.WebAppGallery;
-using System.Text.RegularExpressions;
-using System.Web;
-using System.Reflection;
-using Microsoft.Web.Deployment;
-using System.Diagnostics;
-using System.Threading;
-using System.Security.Cryptography;
-using System.Collections;
-using Microsoft.Win32;
-using System.Linq;
-
-namespace WebsitePanel.Providers.Web
-{
- [Obsolete]
- public sealed class WebApplicationGallery
- {
- // MS Deploy library
- private const string MS_DEPLOY_ASSEMBLY_NAME = "Microsoft.Web.Deployment";
-
- private CacheManager cache;
- private static DeploymentSkipDirective SkipMsSQL = new DeploymentSkipDirective("skipSqlDirective", "objectName=dbFullSql");
- private static DeploymentSkipDirective SkipMySQL = new DeploymentSkipDirective("skipSqlDirective", "objectName=dbMySql");
-
- public const string AtomFeedNamespace = "http://www.w3.org/2005/Atom";
-
- public static string WEB_PI_USER_AGENT_HEADER = "Platform-Installer/{0}({1})";
- public const string WEB_PI_APP_PACK_ROOT_INSTALLER_ITEM_MISSING = "Root installer item for the {0} application could not be found. Please contact your Web Application Gallery feed provider to resolve the error.";
- public const string WEB_PI_APP_PACK_DISPLAY_URL_MISSING = "Web application '{0}' could not be downloaded as installer displayURL is empty or missing.";
-
- // web application gallery
- public const string WAG_XML_FEED_CACHE_KEY = "WAG_XML_FEED_CACHE_KEY";
- public const int WEB_APPLICATIONS_CACHE_STORE_MINUTES = 60;
- public const int XML_FEED_RECOVERY_ATTEMPTS = 10;
- // public const string WAG_DEFAULT_FEED_URL = "https://www.microsoft.com/web/webpi/3.0/WebApplicationList.xml";
- public const string WAG_DEFAULT_FEED_URL = "https://www.microsoft.com/web/webpi/4.0/webapplicationlist.xml";
-
- // well-known parameters matching
- public readonly Dictionary wellKnownParameters
- = new Dictionary(StringComparer.InvariantCultureIgnoreCase)
- {
- {"Database Server", DeploymentParameterWellKnownTag.DBServer},
- {"Database Administrator", DeploymentParameterWellKnownTag.DBAdminUserName},
- {"Database Administrator Password", DeploymentParameterWellKnownTag.DBAdminPassword},
- {"Database Name", DeploymentParameterWellKnownTag.DBName},
- {"Database User Name", DeploymentParameterWellKnownTag.DBUserName},
- {"Database Password", DeploymentParameterWellKnownTag.DBUserPassword}
- };
-
- // well-known dependencies matching
- public readonly Dictionary wellKnownDependencies
- = new Dictionary(StringComparer.InvariantCultureIgnoreCase)
- {
- {"ASPNETApp", GalleryApplicationWellKnownDependency.AspNet20},
- {"ASPNET35App", GalleryApplicationWellKnownDependency.AspNet20},
- {"MVCApp", GalleryApplicationWellKnownDependency.AspNet20},
- {"ASPNET4App", GalleryApplicationWellKnownDependency.AspNet40},
- {"PHPApp", GalleryApplicationWellKnownDependency.PHP},
- {"SQLApp", GalleryApplicationWellKnownDependency.SQL},
- {"SQLDriverPHPApp", GalleryApplicationWellKnownDependency.SQL},
- {"MySQLApp", GalleryApplicationWellKnownDependency.MySQL}
- };
-
- private string feedXmlURI;
-
- static WebApplicationGallery()
- {
- AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_MSDeploy_AssemblyResolve);
- }
-
- static Assembly CurrentDomain_MSDeploy_AssemblyResolve(object sender, ResolveEventArgs args)
- {
- // Ensure we resolve MSDeploy assembly
- if (args.Name.StartsWith(MS_DEPLOY_ASSEMBLY_NAME) == false)
- return null;
- //
- var regkey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\IIS Extensions\MSDeploy");
- //
- if (regkey == null)
- return null;
- // Always start with the most recent version of MSDeploy
- var versionKeys = regkey.GetSubKeyNames().OrderByDescending(x => x).ToArray();
- // Log all version keys found
- Array.ForEach(versionKeys, (x) => { Log.WriteInfo("MSDeploy version key found: {0}", x); });
- // Determine appropriate key name to query for
- var installPathKey = (IntPtr.Size == 8) ? "InstallPath" : "InstallPath_x86";
-
- // Check if running in 32bit mode under 64bit Windows (WOW64) - works with .NET 2.0+
- if (Environment.GetEnvironmentVariable("PROCESSOR_ARCHITEW6432") == "AMD64")
- {
- installPathKey = "InstallPath_x64";
- }
-
- var fileVersion = String.Empty;
- //
- var libPath = String.Empty;
- //
- for (int i = 0; i < versionKeys.Length; i++)
- {
- var versionKey = regkey.OpenSubKey(versionKeys[i]);
- //
- libPath = Path.Combine(versionKey.GetValue(installPathKey).ToString(), String.Concat(MS_DEPLOY_ASSEMBLY_NAME, ".dll"));
- //
- Log.WriteInfo("MSDeploy v{0}; Lib Path: {1}", versionKeys[i], libPath);
- //
- if (File.Exists(libPath) == true)
- {
- Log.WriteInfo("MSDeploy Lib Path: {0};", libPath);
- var fileVerInfo = FileVersionInfo.GetVersionInfo(libPath);
- //
- WEB_PI_USER_AGENT_HEADER = String.Format(WEB_PI_USER_AGENT_HEADER, fileVerInfo.FileVersion, Environment.OSVersion.VersionString);
- //
- break;
- }
- }
- //
- if (String.IsNullOrEmpty(libPath) == false)
- return Assembly.LoadFrom(libPath);
- //
- return null;
- }
-
- public WebApplicationGallery()
- : this(WAG_DEFAULT_FEED_URL)
- {
- }
-
- public WebApplicationGallery(string feedXmlURI)
- {
- cache = CacheFactory.GetCacheManager();
- //
- this.feedXmlURI = feedXmlURI;
- }
-
- public XmlDocument GetServiceXmlFeed()
- {
- XmlDocument xmldoc = (XmlDocument)cache[WAG_XML_FEED_CACHE_KEY];
- //
- if (xmldoc == null)
- {
- // First trying to load as usual...
- try
- {
- //
- xmldoc = new XmlDocument();
- xmldoc.Load(feedXmlURI);
-
- // Add XML to the cache
- cache.Add(WAG_XML_FEED_CACHE_KEY, xmldoc);
- }
- catch (Exception ex)
- {
- Log.WriteError(
- String.Format(@"Could not load xml feed in a usual way from '{0}',
-thus proceed to XML-FEED-RECOVERY section to try download it again in an advanced way.
-No action is required the message for information purposes only.", feedXmlURI), ex);
- }
- // Unable to load feed in the usual way, so lets try to "fix" content-encoding issue
- if (!xmldoc.HasChildNodes)
- {
- //
- int numOfRetries = 0;
- //
- try
- {
- WebClient wc = new WebClient();
- wc.Headers.Add(HttpRequestHeader.UserAgent, WEB_PI_USER_AGENT_HEADER);
- // Setting response encoding explicitly
- wc.Encoding = Encoding.UTF8;
- //
- string feedXmlString = wc.DownloadString(feedXmlURI);
- // Loading XML for several times with shift the from the beginning may helps
- // to eliminate encoding issue (somtimes several starting bytes are not recognized
- // by the parser and thus feed load is failed)
- do
- {
- try
- {
- xmldoc.LoadXml(feedXmlString.Substring(numOfRetries));
-
- // Add XML to the cache
- cache.Add(WAG_XML_FEED_CACHE_KEY, xmldoc);
- //
- Log.WriteInfo("XML feed has been successfully added into the cache. See its content below.");
- Log.WriteInfo(xmldoc.OuterXml);
- // Exit from the loop if XML is loaded successfully
- break;
- }
- catch(Exception ex)
- {
- // Log an exception
- Log.WriteError(
- String.Format("XML-FEED-RECOVERY is failed at {0} attempt. {1} attempts left.", numOfRetries, XML_FEED_RECOVERY_ATTEMPTS-numOfRetries), ex);
- //
- numOfRetries++;
- }
- }
- while (numOfRetries <= XML_FEED_RECOVERY_ATTEMPTS);
- }
- catch (Exception ex)
- {
- // Log an exception
- Log.WriteError(@"XML-FEED-RECOVERY is failed to recover the feed automatically.
-Please ensure that the feed is a correct XML file if you use a custom one,
-otherwise contact WebsitePanel Software for further assistance.", ex);
- }
- }
- ////
- //XmlNamespaceManager nsmgr = GetXmlNsManager(xmldoc.NameTable);
- ////
- //XmlNode rootNode = xmldoc.DocumentElement.SelectSingleNode("atom:dependencies", nsmgr);
- ////
- //XmlNodeList idRefNodes = rootNode.SelectNodes(".//atom:dependency[@idref]", nsmgr);
- ////
- //foreach (XmlNode idRefNode in idRefNodes)
- //{
- // //
- // XmlNode idRefRepo = xmldoc.DocumentElement.SelectSingleNode(
- // String.Format("//atom:dependency[@id='{0}']", idRefNode.Attributes["idref"].Value), nsmgr);
- // //
- // if (idRefRepo != null)
- // {
- // idRefNode.ParentNode.ReplaceChild(idRefRepo.Clone(), idRefNode);
- // }
- //}
-
- ////
- //idRefNodes = xmldoc.DocumentElement.SelectNodes("//atom:dependency[@idref]", nsmgr);
- ////
- //foreach (XmlNode idRefNode in idRefNodes)
- //{
- // //
- // XmlNode idRefRepo = xmldoc.DocumentElement.SelectSingleNode(
- // String.Format("//atom:dependency[@id='{0}']", idRefNode.Attributes["idref"].Value), nsmgr);
- // //
- // if (idRefRepo != null)
- // {
- // idRefNode.ParentNode.ReplaceChild(idRefRepo.Clone(), idRefNode);
- // }
- //}
- }
- //
- return xmldoc;
- }
-
- public bool IsMsDeployInstalled()
- {
- //
- try
- {
- Assembly.Load(MS_DEPLOY_ASSEMBLY_NAME);
- return true;
- }
- catch
- {
- // type could not be instantiated
- return false;
- }
- }
-
- public List GetCategories()
- {
- XmlDocument xmldoc = GetServiceXmlFeed();
- //
- if (xmldoc == null)
- return null;
-
- // get namespace manager
- XmlNamespaceManager nsmgr = GetXmlNsManager(xmldoc.NameTable);
-
- // get the list of all categories that are used by applications
- List appCategories = new List();
- foreach (XmlNode node in xmldoc.SelectNodes("//atom:entry[@type='application']/atom:keywords/atom:keywordId", nsmgr))
- appCategories.Add(node.InnerText);
-
- // get the list of all categories defined in the feed
- // and filter them
- List categories = new List();
- foreach (XmlNode node in xmldoc.SelectNodes("/atom:feed/atom:keywords/atom:keyword", nsmgr))
- {
- string id = node.Attributes["id"].Value;
- string name = node.InnerText;
- if(appCategories.Contains(id))
- categories.Add(new GalleryCategory { Id = id, Name = name });
- }
-
- return categories;
- }
-
- public List GetApplications(string categoryName)
- {
- XmlDocument xmldoc = GetServiceXmlFeed();
- //
- if (xmldoc == null)
- return null;
- //
- XmlNamespaceManager nsmgr = GetXmlNsManager(xmldoc.NameTable);
- //
- string xQuery = String.IsNullOrEmpty(categoryName) ? "//atom:entry[@type='application']"
- : String.Format("//atom:entry[@type='application' and atom:keywords[atom:keywordId='{0}']]", categoryName);
- //
- List appList = new List();
- //
- foreach (XmlNode node in xmldoc.SelectNodes(xQuery, nsmgr))
- {
- appList.Add(DeserializeGalleryApplication(node, nsmgr));
- }
-
- // sort apps alphabetically
- appList.Sort( (a,b) => { return String.Compare(a.Title, b.Title, true); });
-
- //
- return appList;
- }
-
- public GalleryApplication GetApplicationByProductId(string productId)
- {
- XmlDocument xmldoc = GetServiceXmlFeed();
- //
- if (xmldoc == null)
- return null;
- //
- XmlNamespaceManager nsmgr = GetXmlNsManager(xmldoc.NameTable);
- //
- string xQuery = String.Format("//atom:entry[@type='application' and atom:productId='{0}']", productId);
- //
- XmlNode node = xmldoc.SelectSingleNode(xQuery, nsmgr);
- //
- GalleryApplication app = DeserializeGalleryApplication(node, nsmgr);
- //
- return app;
- }
-
- public string GetApplicationPackagePath(string productId)
- {
- return GetApplicationPackagePath(GetApplicationByProductId(productId));
- }
-
- public string GetApplicationPackagePath(GalleryApplication app)
- {
- //
- string appPackagePath = null;
- //
- if (app != null)
- {
- InstallerFile installerFile = null;
- // Acquire root installer item
- #region Atom Feed Version 0.2
- if (app.InstallerItems.Count > 0)
- {
- InstallerItem installerItem_0 = app.InstallerItems[0];
- if (installerItem_0 == null)
- {
- Log.WriteWarning(WEB_PI_APP_PACK_ROOT_INSTALLER_ITEM_MISSING, app.Title);
- return appPackagePath;
- }
- // Ensure web app package can be reached
- installerFile = installerItem_0.InstallerFile;
- }
- #endregion
-
- #region Atom Feed Version 2.0.1.0
- else if (app.Installers.Count > 0)
- {
- Installer installerItem_0 = app.Installers[0];
- if (installerItem_0 == null)
- {
- Log.WriteWarning(WEB_PI_APP_PACK_ROOT_INSTALLER_ITEM_MISSING, app.Title);
- return appPackagePath;
- }
- // Ensure web app package can be reached
- installerFile = installerItem_0.InstallerFile;
- }
- #endregion
-
- if (installerFile == null || String.IsNullOrEmpty(installerFile.InstallerUrl))
- {
- Log.WriteWarning(WEB_PI_APP_PACK_DISPLAY_URL_MISSING, app.Title);
- return appPackagePath;
- }
- //
- Log.WriteInfo("Web App Download URL: {0}", installerFile.InstallerUrl);
- // Trying to match the original file name
- HttpWebRequest webReq = (HttpWebRequest)HttpWebRequest.Create(installerFile.InstallerUrl);
- {
- //
- Regex regex = new Regex("filename=\"(?.{0,})\"");
- string packageName = null;
- //
- webReq.UserAgent = WEB_PI_USER_AGENT_HEADER;
- //
- using (HttpWebResponse webResp = (HttpWebResponse)webReq.GetResponse())
- {
- string httpHeader = webResp.Headers["Content-Disposition"];
- //
- if (!String.IsNullOrEmpty(httpHeader))
- {
- string fileName = Array.Find(httpHeader.Split(';'),
- x => x.Trim().StartsWith("filename="));
- //
- Match match = regex.Match(fileName);
- // Match has been acquired
- if (match != null && match.Success)
- {
- packageName = match.Groups["packageName"].Value;
- }
- }
- }
- // Download URL points to the download package directly
- if (String.IsNullOrEmpty(packageName))
- {
- packageName = Path.GetFileName(installerFile.InstallerUrl);
- }
- //
- if (HttpContext.Current != null)
- {
- appPackagePath = HttpContext.Current.Server.MapPath(String.Format("~/App_Cache/{0}", packageName));
- }
- else
- {
- string assemblyPath = Path.GetDirectoryName(this.GetType().Assembly.Location);
- appPackagePath = Path.Combine(assemblyPath, String.Format(@"App_Cache\{0}", packageName));
- }
- }
- }
- //
- return appPackagePath;
- }
-
- public List GetApplicationParameters(string productId)
- {
- string packageFile = GetApplicationPackagePath(productId);
- //
- if (String.IsNullOrEmpty(packageFile))
- return null;
- //
- List appParams = new List();
- //
- DeploymentObject iisApplication = null;
- //
- try
- {
- iisApplication = DeploymentManager.CreateObject(DeploymentWellKnownProvider.Package, packageFile);
- //
- foreach (DeploymentSyncParameter parameter in iisApplication.SyncParameters)
- {
- DeploymentParameter p = new DeploymentParameter
- {
- Name = parameter.Name,
- FriendlyName = !String.IsNullOrEmpty(parameter.FriendlyName) ? parameter.FriendlyName : parameter.Name,
- Value = parameter.Value,
- DefaultValue = parameter.DefaultValue,
- Description = parameter.Description,
- ValidationKind = (DeploymentParameterValidationKind)parameter.Validation.Kind,
- ValidationString = parameter.Validation.ValidationString,
- WellKnownTags = (DeploymentParameterWellKnownTag)parameter.WellKnownTags
- };
-
- // add to the list
- appParams.Add(p);
-
- // fix tags for parameters with hard-coded names
- if(wellKnownParameters.ContainsKey(p.Name))
- p.WellKnownTags |= wellKnownParameters[p.Name];
- }
- }
- catch (Exception ex)
- {
- // Log an error
- Log.WriteError(
- String.Format("Could not read deployment parameters from '{0}' package.", packageFile), ex);
- //
- throw;
- }
- finally
- {
- if (iisApplication != null)
- iisApplication.Dispose();
- }
- //
- return appParams;
- }
-
- public string InstallApplication(string productId, List updatedParameters)
- {
- string packageFile = GetApplicationPackagePath(productId);
- string applicationPath = null;
-
- if (String.IsNullOrEmpty(packageFile))
- return null;
-
- Log.WriteInfo("WebApp Package Path: {0}", packageFile);
-
- if (!File.Exists(packageFile))
- throw new Exception(GalleryErrors.PackageFileNotFound);
-
- // Setup source deployment options
- DeploymentBaseOptions sourceOptions = new DeploymentBaseOptions();
-
- // Add tracing capabilities
- sourceOptions.Trace += new EventHandler(sourceOptions_Trace);
- sourceOptions.TraceLevel = TraceLevel.Verbose;
-
- // Setup deployment provider
- DeploymentProviderOptions providerOptions = new DeploymentProviderOptions(DeploymentWellKnownProvider.Package);
-
- // Set the package path location
- providerOptions.Path = packageFile;
-
- // Prepare the package deployment procedure
- using (DeploymentObject iisApplication = DeploymentManager.CreateObject(providerOptions, sourceOptions))
- {
- // Setup destination deployment options
- DeploymentBaseOptions destinationOptions = new DeploymentBaseOptions();
- // Add tracing capabilities
- destinationOptions.Trace += new EventHandler(sourceOptions_Trace);
- destinationOptions.TraceLevel = TraceLevel.Verbose;
-
- // MSDEPLOY TEAM COMMENTS: For each parameter that was specified in the UI, set its value
- DeploymentParameterWellKnownTag databaseEngine = DeploymentParameterWellKnownTag.None;
-
- int i = 0;
- while(i < iisApplication.SyncParameters.Count)
- {
- // try to find parameter in updated parameters
- string name = iisApplication.SyncParameters[i].Name;
- DeploymentParameter updatedParameter = updatedParameters.Find( p => { return String.Compare(p.Name, name) == 0; });
-
- if(updatedParameter != null)
- {
- // parameter found
- // update its value
- iisApplication.SyncParameters[i].Value = updatedParameter.Value;
- i++; // advance to the next parameter
-
- // check for selected database engine
- if ((updatedParameter.WellKnownTags & DeploymentParameterWellKnownTag.MySql) == DeploymentParameterWellKnownTag.MySql)
- databaseEngine = DeploymentParameterWellKnownTag.MySql;
- else if ((updatedParameter.WellKnownTags & DeploymentParameterWellKnownTag.Sql) == DeploymentParameterWellKnownTag.Sql)
- databaseEngine = DeploymentParameterWellKnownTag.Sql;
-
- // get application path
- if ((updatedParameter.WellKnownTags & DeploymentParameterWellKnownTag.IisApp) == DeploymentParameterWellKnownTag.IisApp)
- applicationPath = updatedParameter.Value;
- }
- else
- {
- // parameter not found
- // delete it
- iisApplication.SyncParameters.Remove(name);
- }
- }
-
-
- // Skip SQL Server database scripts if not SQL Server was selected
- if (databaseEngine != DeploymentParameterWellKnownTag.Sql)
- sourceOptions.SkipDirectives.Add(SkipMsSQL);
-
- // Skip MySQL database scripts if not MySQL was selected
- if (databaseEngine != DeploymentParameterWellKnownTag.MySql)
- sourceOptions.SkipDirectives.Add(SkipMySQL);
-
- // Setup deployment options
- DeploymentSyncOptions syncOptions = new DeploymentSyncOptions();
- // Add tracing capabilities
- //syncOptions..Action += new EventHandler(syncOptions_Action);
- // Issue a syncronization signal between the parties
- iisApplication.SyncTo(DeploymentWellKnownProvider.Auto, applicationPath, destinationOptions, syncOptions);
- //
- Log.WriteInfo("{0}: {1}", "Application path", applicationPath);
- //
- }
- //
- return applicationPath;
- }
-
- #region Helper methods
-
- private XmlNamespaceManager GetXmlNsManager(XmlNameTable nt)
- {
- XmlNamespaceManager nsmgr = new XmlNamespaceManager(nt);
- nsmgr.AddNamespace("atom", "http://www.w3.org/2005/Atom");
- //
- return nsmgr;
- }
-
- private GalleryApplication DeserializeGalleryApplication(XmlNode node, XmlNamespaceManager nsmgr)
- {
- XmlSerializer xs = new XmlSerializer(typeof(GalleryApplication), AtomFeedNamespace);
- GalleryApplication app = (GalleryApplication)xs.Deserialize(new XmlNodeReader(node));
- //
- app.LastUpdated = XmlToDateTime(GetAtomNodeText(node, nsmgr, "updated"), "yyyy-M-dTHH:mm:ssZ");
- app.Published = XmlToDateTime(GetAtomNodeText(node, nsmgr, "published"), "yyyy-M-dTHH:mm:ssZ");
- app.Link = GetAtomNodeAttribute(node, nsmgr, "link", "href");
- //
- app.IconUrl = GetAtomNodeText(node, nsmgr, "images/atom:icon");
-
- // parse well-known dependencies
- UpdateApplicationWellKnownDependencies(app, app.Dependency);
-
- //
- return app;
- }
-
- private void UpdateApplicationWellKnownDependencies(GalleryApplication app, Dependency dependency)
- {
- if (dependency == null)
- return;
-
- if (dependency.IdRef != null && wellKnownDependencies.ContainsKey(dependency.IdRef))
- app.WellKnownDependencies |= wellKnownDependencies[dependency.IdRef];
-
- // process "And"
- foreach (Dependency d in dependency.And)
- UpdateApplicationWellKnownDependencies(app, d);
-
- // process "Or"
- foreach (Dependency d in dependency.Or)
- UpdateApplicationWellKnownDependencies(app, d);
-
- // process "LogicalAnd"
- foreach (Dependency d in dependency.LogicalAnd)
- UpdateApplicationWellKnownDependencies(app, d);
-
- // process "LogicalOr"
- foreach (Dependency d in dependency.LogicalOr)
- UpdateApplicationWellKnownDependencies(app, d);
- }
-
- private string GetAtomNodeText(XmlNode app, XmlNamespaceManager nsmgr, string nodeName)
- {
- XmlNode node = app.SelectSingleNode("atom:" + nodeName, nsmgr);
- if (node == null)
- return null;
- return node.InnerText;
- }
-
- private string GetAtomNodeAttribute(XmlNode app, XmlNamespaceManager nsmgr, string nodeName, string attributeName)
- {
- XmlNode node = app.SelectSingleNode("atom:" + nodeName, nsmgr);
- if (node == null)
- return null;
- string ret = null;
- XmlAttribute attribute = node.Attributes[attributeName];
- if (attribute != null)
- ret = attribute.Value;
- return ret;
- }
-
- private DateTime XmlToDateTime(string val, string format)
- {
- DateTime ret = DateTime.MinValue;
-
- try
- {
- if (!string.IsNullOrEmpty(val))
- ret = XmlConvert.ToDateTime(val, format);
- }
- catch (Exception) { }
- return ret;
- }
-
- private static string GetAtomNodeText(XmlNode node)
- {
- if (node == null)
- return null;
- return node.InnerText;
- }
-
- private void sourceOptions_Trace(object sender, DeploymentTraceEventArgs e)
- {
- Log.WriteInfo(e.Message);
- Log.WriteInfo("Event Level: " + e.EventLevel);
- Log.WriteInfo("Event Data: ");
- //
- foreach (string keyName in e.EventData.Keys)
- {
- Log.WriteInfo(keyName + " => " + e.EventData[keyName]);
- }
- }
-
- /*private void syncOptions_Action(object sender, DeploymentActionEventArgs e)
- {
- Log.WriteInfo(e.Message);
- Log.WriteInfo("Operation Type: " + e.OperationType);
- Log.WriteInfo("Event Data: ");
- //
- foreach (string keyName in e.EventData.Keys)
- {
- Log.WriteInfo(keyName + " => " + e.EventData[keyName]);
- }
- }*/
-
- #endregion
- }
-
- public class DownloadQueueItem
- {
- public String ItemKey;
- public WebClient ConnectionPoint;
- public DownloadProgressChangedEventArgs Progress;
- public string DownloadItemURI;
- public string LocalFilePathToStore;
-
- public void StartItemDownloadAsync(Object state)
- {
- ConnectionPoint.DownloadFileAsync(new Uri(DownloadItemURI), LocalFilePathToStore);
- }
- }
-
- public sealed class AppPackagesDownloader
- {
- private static List downloadQueue;
-
- static AppPackagesDownloader()
- {
- downloadQueue = new List();
- }
-
- //
- public static bool CheckApplicationPackageHashSum_MD5(string localFilePath, string md5)
- {
- if (!File.Exists(localFilePath))
- return false;
- //
- bool md5OK = false;
- //
- try
- {
- //
- MD5 md5File = new MD5CryptoServiceProvider();
- //
- string fileMd5Sum = BitConverter.ToString(
- md5File.ComputeHash(File.ReadAllBytes(localFilePath))).Replace("-", String.Empty);
- //
- md5OK = String.Equals(md5, fileMd5Sum, StringComparison.InvariantCultureIgnoreCase);
- }
- catch (Exception ex)
- {
- Log.WriteError(String.Format("Failed to compute MD5 sum for {0} package.", localFilePath), ex);
- }
- //
- return md5OK;
- }
-
- //
- public static bool CheckApplicationPackageHashSum_SHA1(string localFilePath, string sha1)
- {
- if (!File.Exists(localFilePath))
- return false;
- //
- bool sha1OK = false;
- //
- try
- {
- //
- SHA1 sha1File = new SHA1CryptoServiceProvider();
- //
- string fileSha1Sum = BitConverter.ToString(
- sha1File.ComputeHash(File.ReadAllBytes(localFilePath))).Replace("-", String.Empty);
- //
- sha1OK = String.Equals(sha1, fileSha1Sum, StringComparison.InvariantCultureIgnoreCase);
- //
- if (!sha1OK)
- Log.WriteWarning("SHA1-XML FEED: {0}; SHA1-FILE ON DISK: {1};", sha1, fileSha1Sum);
- }
- catch (Exception ex)
- {
- Log.WriteError(String.Format("Failed to compute SHA1 sum for {0} package.", localFilePath), ex);
- }
- //
- return sha1OK;
- }
-
- //
- public static bool IsApplicationInDownloadQueue(string appName)
- {
- bool exists = false;
- //
- if (!String.IsNullOrEmpty(appName))
- {
- ICollection ic = downloadQueue as ICollection;
- //
- lock (ic.SyncRoot)
- {
- exists = Array.Exists(downloadQueue.ToArray(),
- x => x.ItemKey == appName.ToLower());
- }
- }
- //
- return exists;
- }
-
- //
- public static void StartApplicationDownload(string appName, string packageUrl, string localPathToStore)
- {
- //
- bool appInQueue = IsApplicationInDownloadQueue(appName);
- //
- if (!appInQueue)
- {
- ICollection ic = downloadQueue as ICollection;
- //
- lock (ic.SyncRoot)
- {
- //
- DownloadQueueItem qi = new DownloadQueueItem
- {
- ItemKey = appName.ToLower(),
- ConnectionPoint = new WebClient(),
- Progress = null
- };
- //
- qi.DownloadItemURI = packageUrl;
- qi.LocalFilePathToStore = localPathToStore;
- qi.ConnectionPoint.Headers.Add(HttpRequestHeader.UserAgent, WebApplicationGallery.WEB_PI_USER_AGENT_HEADER);
- qi.ConnectionPoint.DownloadFileCompleted += new System.ComponentModel.AsyncCompletedEventHandler(wc_DownloadFileCompleted);
- qi.ConnectionPoint.DownloadProgressChanged += new DownloadProgressChangedEventHandler(wc_DownloadProgressChanged);
- //
- downloadQueue.Add(qi);
- // Start async download (10 attempts)
- int numOfAttempt = 0;
- do
- {
- try
- {
- bool success = ThreadPool.QueueUserWorkItem(
- new WaitCallback(qi.StartItemDownloadAsync));
- // Exit the loop if the item successfuly queued
- if (success)
- break;
- }
- catch (Exception ex)
- {
- numOfAttempt++;
- // Log an exception
- Log.WriteError(String.Format("Could not start distibutive download from the following URI: {0}", qi.DownloadItemURI), ex);
- }
- }
- while (numOfAttempt <= 10);
- }
- }
- }
-
- public static int GetApplicationDownloadProgress(string appName)
- {
- int appProgress = 0;
- //
- bool appInQueue = IsApplicationInDownloadQueue(appName);
- //
- if (appInQueue)
- {
- ICollection ic = downloadQueue as ICollection;
- //
- lock (ic.SyncRoot)
- {
- DownloadQueueItem qi = Array.Find(downloadQueue.ToArray(),
- x => x.ItemKey == appName.ToLower());
- //
- if (qi.Progress != null)
- appProgress = qi.Progress.ProgressPercentage;
- }
- }
- //
- return appProgress;
- }
-
- static void wc_DownloadFileCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
- {
- ICollection ic = downloadQueue as ICollection;
- //
- lock (ic.SyncRoot)
- {
- DownloadQueueItem qi = Array.Find(downloadQueue.ToArray(),
- x => x.ConnectionPoint == sender);
- //
- if (e.Error != null)
- {
- //
- if (qi != null)
- Log.WriteError(String.Format("Could not download app {0}", qi.ItemKey), e.Error);
- else
- Log.WriteError(e.Error);
- }
- //
- downloadQueue.Remove(qi);
- }
- }
-
- static void wc_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
- {
- ICollection ic = downloadQueue as ICollection;
- //
- lock (ic.SyncRoot)
- {
- DownloadQueueItem qi = Array.Find(downloadQueue.ToArray(),
- x => x.ConnectionPoint == sender);
-
- if (qi != null)
- qi.Progress = e;
- }
- }
- }
-}
\ No newline at end of file
diff --git a/WebsitePanel/Sources/WebsitePanel.Providers.Web.IIs60/WebsitePanel.Providers.Web.IIs60.csproj b/WebsitePanel/Sources/WebsitePanel.Providers.Web.IIs60/WebsitePanel.Providers.Web.IIs60.csproj
index 3e06a8b4..d14ee66c 100644
--- a/WebsitePanel/Sources/WebsitePanel.Providers.Web.IIs60/WebsitePanel.Providers.Web.IIs60.csproj
+++ b/WebsitePanel/Sources/WebsitePanel.Providers.Web.IIs60/WebsitePanel.Providers.Web.IIs60.csproj
@@ -93,7 +93,6 @@
-
diff --git a/WebsitePanel/Sources/WebsitePanel.Server/Code/WPIHelper.cs b/WebsitePanel/Sources/WebsitePanel.Server/Code/WPIHelper.cs
index 09ec94c2..1976ea33 100644
--- a/WebsitePanel/Sources/WebsitePanel.Server/Code/WPIHelper.cs
+++ b/WebsitePanel/Sources/WebsitePanel.Server/Code/WPIHelper.cs
@@ -57,8 +57,6 @@ namespace WebsitePanel.Server.Code
private readonly List _feeds;
private string _webPIinstallersFolder;
- //private const string MainWpiFeed = "https://www.microsoft.com/web/webpi/3.0/webproductlist.xml";
- private const string MainWpiFeed = "https://www.microsoft.com/web/webpi/4.0/WebProductList.xml";
private const string IisChoiceProduct = "StaticContent";
private const string WebMatrixChoiceProduct = "WebMatrix";
private ProductManager _productManager;
@@ -79,6 +77,14 @@ namespace WebsitePanel.Server.Code
public WpiHelper(IEnumerable feeds)
{
+ // check feeds is not empty
+ if (null == feeds || !feeds.Any())
+ {
+ throw new Exception("WpiHelper error: empty feed list in constructor");
+ }
+
+
+ // by default feeds must contains main MS WPI feed url and Zoo feed url
_feeds = new List();
_feeds.AddRange(feeds);
@@ -135,7 +141,6 @@ namespace WebsitePanel.Server.Code
}
#endregion
-
#region Keywords
public ReadOnlyCollection GetKeywords()
{
@@ -158,8 +163,6 @@ namespace WebsitePanel.Server.Code
}
#endregion
-
-
#region Products
public List GetProductsToInstall(string FeedLocation, string keywordId)
{
@@ -546,6 +549,7 @@ namespace WebsitePanel.Server.Code
}
#endregion
+
#endregion Public interface
@@ -553,12 +557,6 @@ namespace WebsitePanel.Server.Code
private void Initialize()
{
- // insert Main WebPI xml file
- if (!_feeds.Contains(MainWpiFeed, StringComparer.OrdinalIgnoreCase))
- {
- _feeds.Insert(0, MainWpiFeed);
- }
-
// create cache folder if not exists
//_webPIinstallersFolder = Environment.ExpandEnvironmentVariables(@"%LocalAppData%\Microsoft\Web Platform Installer\installers");
_webPIinstallersFolder = Path.Combine(
diff --git a/WebsitePanel/Sources/WebsitePanel.Server/WindowsServer.asmx.cs b/WebsitePanel/Sources/WebsitePanel.Server/WindowsServer.asmx.cs
index 8940e917..c6398bf5 100644
--- a/WebsitePanel/Sources/WebsitePanel.Server/WindowsServer.asmx.cs
+++ b/WebsitePanel/Sources/WebsitePanel.Server/WindowsServer.asmx.cs
@@ -477,11 +477,7 @@ namespace WebsitePanel.Server
}
- static string[] FEEDS = new string[]
- {
- // "https://www.microsoft.com/web/webpi/3.0/WebProductList.xml",
- // "http://www.helicontech.com/zoo/feed/"
- };
+ static private string[] _feeds = new string[]{};
[WebMethod]
public void InitWPIFeeds(string feedUrls)
@@ -491,18 +487,18 @@ namespace WebsitePanel.Server
throw new Exception("Empty feed list");
}
- string[] newFEEDS = feedUrls.Split(';');
+ string[] newFeeds = feedUrls.Split(';');
- if (newFEEDS.Length == 0)
+ if (newFeeds.Length == 0)
{
throw new Exception("Empty feed list");
}
- if (!ArraysEqual(newFEEDS, FEEDS))
+ if (!ArraysEqual(newFeeds, _feeds))
{
Log.WriteInfo("InitWPIFeeds - new value: " + feedUrls);
//Feeds settings have been channged
- FEEDS = newFEEDS;
+ _feeds = newFeeds;
wpi = null;
}
@@ -604,7 +600,7 @@ namespace WebsitePanel.Server
WPIServiceContract client = new WPIServiceContract();
- client.Initialize(FEEDS);
+ client.Initialize(_feeds);
client.BeginInstallation(products);
@@ -795,14 +791,14 @@ namespace WebsitePanel.Server
static WpiHelper wpi = null;
WpiHelper GetWpiFeed()
{
- if (FEEDS.Length == 0)
+ if (_feeds.Length == 0)
{
throw new Exception("Empty feed list");
}
if (null == wpi)
{
- wpi = new WpiHelper(FEEDS);
+ wpi = new WpiHelper(_feeds);
}
return wpi;
}
diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/App_LocalResources/SystemSettings.ascx.resx b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/App_LocalResources/SystemSettings.ascx.resx
index 1b0c52e9..feb70193 100644
--- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/App_LocalResources/SystemSettings.ascx.resx
+++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/App_LocalResources/SystemSettings.ascx.resx
@@ -147,4 +147,10 @@
Enable SSL:
+
+ Main feed URL:
+
+
+ Custom feeds:
+
\ No newline at end of file
diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/SystemSettings.ascx b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/SystemSettings.ascx
index f8d61d60..55b85a1a 100644
--- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/SystemSettings.ascx
+++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/SystemSettings.ascx
@@ -35,34 +35,28 @@
-
-
-
-<%--
+ TargetControlID="WpiPanel" meta:resourcekey="lclWpiSettings" Text="Web Platform Installer Settings"/>
+
+
+
- Enable Microsoft feed |
-
-
- |
+ |
+ |
-
- Enable HeliconTech feed |
-
-
+ | |
+
+
|
-
---%>
-
+