using System; using System.Collections.Generic; using System.IO; using Microsoft.Win32; using WebsitePanel.Providers.SharePoint; using WebsitePanel.Providers.Utils; using WebsitePanel.Server.Utils; namespace WebsitePanel.Providers.HostedSolution { /// /// Provides hosted SharePoint server functionality implementation. /// public class HostedSharePointServer2013 : HostingServiceProviderBase, IHostedSharePointServer { #region Delegate private delegate TReturn SharePointAction(HostedSharePointServer2013Impl impl); #endregion #region Fields protected string LanguagePacksPath; protected string Wss3Registry32Key; protected string Wss3RegistryKey; #endregion #region Properties public string BackupTemporaryFolder { get { return ProviderSettings["BackupTemporaryFolder"]; } } public Uri RootWebApplicationUri { get { return new Uri(ProviderSettings["RootWebApplicationUri"]); } } #endregion #region Constructor public HostedSharePointServer2013() { Wss3RegistryKey = @"SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\15.0"; Wss3Registry32Key = @"SOFTWARE\Wow6432Node\Microsoft\Shared Tools\Web Server Extensions\15.0"; LanguagePacksPath = @"%commonprogramfiles%\microsoft shared\Web Server Extensions\15\HCCab\"; } #endregion #region Methods /// Gets list of supported languages by this installation of SharePoint. /// List of supported languages public int[] GetSupportedLanguages() { var impl = new HostedSharePointServer2013Impl(); return impl.GetSupportedLanguages(RootWebApplicationUri); } /// Gets list of SharePoint collections within root web application. /// List of SharePoint collections within root web application. public SharePointSiteCollection[] GetSiteCollections() { return ExecuteSharePointAction(impl => impl.GetSiteCollections(RootWebApplicationUri)); } /// Gets SharePoint collection within root web application with given name. /// Url that uniquely identifies site collection to be loaded. /// SharePoint collection within root web application with given name. public SharePointSiteCollection GetSiteCollection(string url) { return ExecuteSharePointAction(impl => impl.GetSiteCollection(RootWebApplicationUri, url)); } /// Creates site collection within predefined root web application. /// Information about site coolection to be created. public void CreateSiteCollection(SharePointSiteCollection siteCollection) { ExecuteSharePointAction(delegate(HostedSharePointServer2013Impl impl) { impl.CreateSiteCollection(RootWebApplicationUri, siteCollection); return null; }); } /// Deletes site collection under given url. /// The site collection to be deleted. public void DeleteSiteCollection(SharePointSiteCollection siteCollection) { ExecuteSharePointAction(delegate(HostedSharePointServer2013Impl impl) { impl.DeleteSiteCollection(RootWebApplicationUri, siteCollection); return null; }); } /// Backups site collection under give url. /// Url that uniquely identifies site collection to be deleted. /// Resulting backup file name. /// A value which shows whether created backup must be archived. /// Created backup full path. public string BackupSiteCollection(string url, string filename, bool zip) { return ExecuteSharePointAction(impl => impl.BackupSiteCollection(RootWebApplicationUri, url, filename, zip, BackupTemporaryFolder)); } /// Restores site collection under given url from backup. /// Site collection to be restored. /// Backup file name to restore from. public void RestoreSiteCollection(SharePointSiteCollection siteCollection, string filename) { ExecuteSharePointAction(delegate(HostedSharePointServer2013Impl impl) { impl.RestoreSiteCollection(RootWebApplicationUri, siteCollection, filename); return null; }); } /// Gets binary data chunk of specified size from specified offset. /// Path to file to get bunary data chunk from. /// Offset from which to start data reading. /// Binary data chunk length. /// Binary data chunk read from file. public virtual byte[] GetTempFileBinaryChunk(string path, int offset, int length) { byte[] buffer = FileUtils.GetFileBinaryChunk(path, offset, length); if (buffer.Length < length) { FileUtils.DeleteFile(path); } return buffer; } /// Appends supplied binary data chunk to file. /// Non existent file name to append to. /// Full path to existent file to append to. /// Binary data chunk to append to. /// Path to file that was appended with chunk. public virtual string AppendTempFileBinaryChunk(string fileName, string path, byte[] chunk) { if (path == null) { path = Path.Combine(Path.GetTempPath(), fileName); if (FileUtils.FileExists(path)) { FileUtils.DeleteFile(path); } } FileUtils.AppendFileBinaryContent(path, chunk); return path; } public void UpdateQuotas(string url, long maxStorage, long warningStorage) { ExecuteSharePointAction(delegate(HostedSharePointServer2013Impl impl) { impl.UpdateQuotas(RootWebApplicationUri, url, maxStorage, warningStorage); return null; }); } public SharePointSiteDiskSpace[] CalculateSiteCollectionsDiskSpace(string[] urls) { return ExecuteSharePointAction(impl => impl.CalculateSiteCollectionDiskSpace(RootWebApplicationUri, urls)); } public long GetSiteCollectionSize(string url) { return ExecuteSharePointAction(impl => impl.GetSiteCollectionSize(RootWebApplicationUri, url)); } public void SetPeoplePickerOu(string site, string ou) { ExecuteSharePointAction(delegate(HostedSharePointServer2013Impl impl) { impl.SetPeoplePickerOu(site, ou); return null; }); } public override bool IsInstalled() { return IsSharePointInstalled(); } /// Deletes service items that represent SharePoint site collection. /// Items to be deleted. public override void DeleteServiceItems(ServiceProviderItem[] items) { foreach (ServiceProviderItem item in items) { var sharePointSiteCollection = item as SharePointSiteCollection; if (sharePointSiteCollection != null) { try { DeleteSiteCollection(sharePointSiteCollection); } catch (Exception ex) { Log.WriteError(String.Format("Error deleting '{0}' {1}", item.Name, item.GetType().Name), ex); } } } } /// Calculates diskspace used by supplied service items. /// Service items to get diskspace usage for. /// Calculated disk space usage statistics. public override ServiceProviderItemDiskSpace[] GetServiceItemsDiskSpace(ServiceProviderItem[] items) { var itemsDiskspace = new List(); foreach (ServiceProviderItem item in items) { if (item is SharePointSiteCollection) { try { Log.WriteStart(String.Format("Calculating '{0}' site logs size", item.Name)); SharePointSiteCollection site = GetSiteCollection(item.Name); var diskspace = new ServiceProviderItemDiskSpace {ItemId = item.Id, DiskSpace = site.Diskspace}; itemsDiskspace.Add(diskspace); Log.WriteEnd(String.Format("Calculating '{0}' site logs size", item.Name)); } catch (Exception ex) { Log.WriteError(ex); } } } return itemsDiskspace.ToArray(); } /// Checks whether SharePoint 2013 is installed. /// true - if it is installed; false - otherwise. private bool IsSharePointInstalled() { RegistryKey spKey = Registry.LocalMachine.OpenSubKey(Wss3RegistryKey); RegistryKey spKey32 = Registry.LocalMachine.OpenSubKey(Wss3Registry32Key); if (spKey == null && spKey32 == null) { return false; } var spVal = (string) spKey.GetValue("SharePoint"); return (String.Compare(spVal, "installed", true) == 0); } /// Executes supplied action within separate application domain. /// Action to be executed. /// Any object that results from action execution or null if nothing is supposed to be returned. /// Is thrown in case supplied action is null. private static TReturn ExecuteSharePointAction(SharePointAction action) { if (action == null) { throw new ArgumentNullException("action"); } AppDomain domain = null; try { Type type = typeof (HostedSharePointServer2013Impl); var info = new AppDomainSetup {ApplicationBase = Path.GetDirectoryName(AppDomain.CurrentDomain.BaseDirectory), PrivateBinPath = "bin; bin/debug"}; domain = AppDomain.CreateDomain("WSS30", null, info); var impl = (HostedSharePointServer2013Impl) domain.CreateInstanceAndUnwrap(type.Assembly.FullName, type.FullName); return action(impl); } finally { if (domain != null) { AppDomain.Unload(domain); } } } #endregion } }