/CKS Developer Edition/CKS.Dev/Deployment/QuickDeployment/SharePointProjectFeatureArtefact.cs

# · C# · 204 lines · 126 code · 20 blank · 58 comment · 10 complexity · 4e11689e1da7d40c3a5c3be32d82bfd8 MD5 · raw file

  1. using System.IO;
  2. using System;
  3. using Microsoft.VisualStudio.SharePoint;
  4. using Microsoft.VisualStudio.SharePoint.Deployment;
  5. using Microsoft.VisualStudio.SharePoint.Packages;
  6. using System.ComponentModel.Composition;
  7. using System.Linq;
  8. using System.DirectoryServices;
  9. using System.Diagnostics;
  10. using System.Globalization;
  11. using System.Runtime.InteropServices;
  12. using System.Collections.Generic;
  13. using System.ComponentModel.Design;
  14. using System.Xml;
  15. using EnvDTE;
  16. using EnvDTE80;
  17. using Microsoft.Win32;
  18. using Microsoft.VisualStudio;
  19. using Microsoft.VisualStudio.Shell.Interop;
  20. using Microsoft.VisualStudio.OLE.Interop;
  21. using Microsoft.VisualStudio.Shell;
  22. using System.Reflection;
  23. namespace CKS.Dev.VisualStudio.SharePoint.Deployment.QuickDeployment
  24. {
  25. /// <summary>
  26. /// SharePoint project feature artefact.
  27. /// </summary>
  28. public class SharePointProjectFeatureArtefact : QuickCopyableSharePointArtefact
  29. {
  30. private ISharePointProjectFeature feature = null;
  31. private IEnumerable<QuickCopyableSharePointArtefact> kids = null;
  32. private Dictionary<string, string> tokens = null;
  33. /// <summary>
  34. /// Initializes a new instance of the <see cref="SharePointProjectFeatureArtefact"/> class.
  35. /// </summary>
  36. /// <param name="feature">The feature.</param>
  37. public SharePointProjectFeatureArtefact(ISharePointProjectFeature feature)
  38. {
  39. this.feature = feature;
  40. }
  41. /// <summary>
  42. /// Gets the name of the feature folder.
  43. /// </summary>
  44. /// <value>The name of the feature folder.</value>
  45. public string FeatureFolderName
  46. {
  47. get
  48. {
  49. // Even though a feature can be included in multiple projects/packages, the tokenized feature name is
  50. // always replaced with the VS project the feature is actually contained in.
  51. string featureFolderName = feature.Model.DeploymentPath;
  52. featureFolderName = featureFolderName.Replace("$SharePoint.Project.FileNameWithoutExtension$", feature.Project.Name);
  53. featureFolderName = featureFolderName.Replace("$SharePoint.Feature.FileNameWithoutExtension$", PathUtility.GetLastFolderName(feature.FullPath));
  54. return featureFolderName;
  55. }
  56. }
  57. /// <summary>
  58. /// Gets all the child artefacts of this artefact.
  59. /// </summary>
  60. /// <value></value>
  61. public override IEnumerable<QuickCopyableSharePointArtefact> ChildArtefacts
  62. {
  63. get
  64. {
  65. if (kids == null)
  66. {
  67. List<QuickCopyableSharePointArtefact> children = new List<QuickCopyableSharePointArtefact>();
  68. // Get SPIs in this feature - will only include those that are set to be packaged.
  69. foreach (ISharePointProjectItem spi in feature.ProjectItems)
  70. {
  71. children.Add(new SharePointProjectItemArtefact(spi));
  72. }
  73. kids = children;
  74. }
  75. return kids;
  76. }
  77. }
  78. /// <summary>
  79. /// Determines if this artefact is packaged anywhere in the solution.
  80. /// </summary>
  81. /// <param name="service">The SharePoint service.</param>
  82. /// <returns>True if the artefact is packaged.</returns>
  83. public override bool IsPackaged(ISharePointProjectService service)
  84. {
  85. return feature.IsPartOfAnyProjectPackage(service);
  86. }
  87. /// <summary>
  88. /// Determines if this artefact is packaged as part of a specific project.
  89. /// </summary>
  90. /// <param name="project">The SharePoint project.</param>
  91. /// <returns>True if the artefact is packaged.</returns>
  92. public override bool IsPackaged(ISharePointProject project)
  93. {
  94. return feature.IsPartOfProjectPackage(project);
  95. }
  96. /// <summary>
  97. /// Gets all projects in the solution where this artefact is packaged.
  98. /// </summary>
  99. /// <param name="service">The SharePoint service.</param>
  100. /// <returns>
  101. /// An enumerable of the SharePoint projects.
  102. /// </returns>
  103. public override IEnumerable<ISharePointProject> GetPackagedProjects(ISharePointProjectService service)
  104. {
  105. return feature.GetProjectsWhereInPackage(service);
  106. }
  107. /// <summary>
  108. /// Gets the substitution tokens for this artefact.
  109. /// </summary>
  110. /// <value></value>
  111. /// <returns>The tokens dictionary.</returns>
  112. public override Dictionary<string, string> Tokens
  113. {
  114. get
  115. {
  116. if (tokens == null)
  117. {
  118. tokens = new Dictionary<string, string>();
  119. tokens.Add("SharePoint.Feature.FileName", Path.GetFileName(feature.FeatureFile.Name));
  120. tokens.Add("SharePoint.Feature.FileNameWithoutExtension", Path.GetFileNameWithoutExtension(feature.FeatureFile.Name));
  121. tokens.Add("SharePoint.Feature.DeploymentPath", this.FeatureFolderName);
  122. tokens.Add("SharePoint.Feature.Id", feature.Id.ToString());
  123. }
  124. return tokens;
  125. }
  126. }
  127. /// <summary>
  128. /// Quick copy this artefact in the context of the specific package, but wherever this artefact is contained in that package.
  129. /// </summary>
  130. /// <param name="packageProject"></param>
  131. /// <param name="requiresQuickPackage"></param>
  132. public override void QuickCopy(SharePointPackageArtefact packageProject, bool requiresQuickPackage)
  133. {
  134. // We are directly deploying just this feature and have not been called by our parent.
  135. if (feature.IsPartOfProjectPackage(packageProject.Project))
  136. {
  137. // Pass in the package itself as the parent.
  138. this.QuickCopy(packageProject, packageProject, requiresQuickPackage);
  139. }
  140. }
  141. /// <summary>
  142. /// Quick copy this artefact in the context of the specific package, and the specific containing artefact only.
  143. /// </summary>
  144. /// <param name="packageProject">The project.</param>
  145. /// <param name="parentArtefact">The deployable SharePoint artefact.</param>
  146. /// <param name="requiresQuickPackage">Flag to indicate it requires a quick package.</param>
  147. public override void QuickCopy(SharePointPackageArtefact packageProject, QuickCopyableSharePointArtefact parentArtefact, bool requiresQuickPackage)
  148. {
  149. if (parentArtefact == null)
  150. {
  151. throw new NotSupportedException();
  152. }
  153. else if (parentArtefact is SharePointPackageArtefact)
  154. {
  155. string sourcePathBase = packageProject.BasePackagePath;
  156. string featureFolderName = this.FeatureFolderName;
  157. feature.Project.ProjectService.Logger.ActivateOutputWindow();
  158. feature.Project.ProjectService.Logger.WriteLine("------ Quick Copying Feature: " + this.FeatureFolderName + " ------", LogCategory.Status);
  159. // Feature.xml must first be Quick Copied.
  160. if (requiresQuickPackage)
  161. {
  162. // Tokens consist of those from this package, and feature.
  163. Dictionary<string, string> allTokens = new Dictionary<string, string>();
  164. allTokens.AddRange(packageProject.Tokens);
  165. allTokens.AddRange(this.Tokens);
  166. // TODO: Merge feature.feature.
  167. feature.Project.ProjectService.Logger.ActivateOutputWindow();
  168. feature.Project.ProjectService.Logger.WriteLine("WARNING: Quick packaging of changes to Feature.feature is not yet supported. The last packaged version of the file will be copied.", LogCategory.Warning);
  169. //QuickDeploymentUtilities.CopyFileWithTokenReplacement(packageProject.Project, file.Name, originalFileProjectRelative, sourcePackagePathProjectRelative, allTokens);
  170. }
  171. QuickDeploymentUtilities.CopyFile(packageProject.Project, "Feature.xml", Path.Combine(sourcePathBase, featureFolderName), "{SharePointRoot}\\Template\\Features\\" + featureFolderName);
  172. // Process items in features. Note that we are only processing items that have been set to be packaged.
  173. foreach (SharePointProjectItemArtefact spi in this.ChildArtefacts.Select(ca => ca as SharePointProjectItemArtefact))
  174. {
  175. spi.QuickCopy(packageProject, this, requiresQuickPackage);
  176. }
  177. }
  178. else
  179. {
  180. throw new NotSupportedException();
  181. }
  182. }
  183. }
  184. }