// ========================================================================================= // Constructors // ========================================================================================= /// <summary> /// Initializes a new instance of the <see cref="WixBuildMacroCollection"/> class. /// </summary> /// <param name="project">The project from which to read the properties.</param> public WixBuildMacroCollection(WixProjectNode project) { WixHelperMethods.VerifyNonNullArgument(project, "project"); // get the global SolutionX properties WixBuildMacroCollection.DefineSolutionProperties(project); foreach (string globalMacroName in globalMacroNames) { BuildProperty property = project.BuildEngine.GlobalProperties[globalMacroName]; if (property == null) { this.list.Add(globalMacroName, "*Undefined*"); } else { string value = property.FinalValue; this.list.Add(globalMacroName, value); } } // we need to call GetTargetPath first so that TargetDir and TargetPath are resolved correctly EnvDTE.Project automationObject = project.GetAutomationObject() as EnvDTE.Project; string configName = Microsoft.VisualStudio.Package.Utilities.GetActiveConfigurationName(automationObject); string platformName = Microsoft.VisualStudio.Package.Utilities.GetActivePlatformName(automationObject); project.Build(configName, platformName, WixProjectFileConstants.MsBuildTarget.GetTargetPath); // get the ProjectX and TargetX variables foreach (string macroName in macroNames) { string value = project.GetProjectProperty(macroName); this.list.Add(macroName, value); } }
// ========================================================================================= // Constructors // ========================================================================================= /// <summary> /// Initializes a new instance of the <see cref="WixPackageSettings"/> class. /// </summary> /// <param name="serviceProvider">The <see cref="IServiceProvider"/> to use.</param> public WixPackageSettings(IServiceProvider serviceProvider) { WixHelperMethods.VerifyNonNullArgument(serviceProvider, "serviceProvider"); if (serviceProvider != null) { // get the Visual Studio registry root ILocalRegistry3 localRegistry = WixHelperMethods.GetService <ILocalRegistry3, SLocalRegistry>(serviceProvider); ErrorHandler.ThrowOnFailure(localRegistry.GetLocalRegistryRoot(out this.visualStudioRegistryRoot)); } }
// ========================================================================================= // Constructors // ========================================================================================= /// <summary> /// Initializes a new instance of the <see cref="WixProjectNode"/> class. /// </summary> /// <param name="package">The <see cref="WixPackage"/> to which this project belongs.</param> public WixProjectNode(WixPackage package) { WixHelperMethods.VerifyNonNullArgument(package, "package"); this.package = package; // We allow destructive deletes on the project this.CanProjectDeleteItems = true; this.CanFileNodesHaveChilds = true; this.InitializeCATIDs(); }
// ========================================================================================= // Constructors // ========================================================================================= /// <summary> /// Creates a new project property object. /// </summary> /// <param name="project">Project that owns the property.</param> /// <param name="propertyName">Name of the property.</param> public ProjectProperty(WixProjectNode project, string propertyName) { WixHelperMethods.VerifyNonNullArgument(project, "project"); WixHelperMethods.VerifyNonNullArgument(propertyName, "propertyName"); this.project = project; this.propertyName = propertyName; this.perUser = ProjectProperty.PerUserProperties.Contains(propertyName); this.perConfig = !ProjectProperty.NonPerConfigProperties.Contains(propertyName); this.allowVariables = ProjectProperty.AllowVariablesProperties.Contains(propertyName); this.list = ProjectProperty.ListProperties.Contains(propertyName); this.endOfProjectFile = ProjectProperty.EndOfProjectFileProperties.Contains(propertyName); }
// ========================================================================================= // Constructors // ========================================================================================= /// <summary> /// Initializes a new instance of the <see cref="WixBuildMacroCollection"/> class. /// </summary> /// <param name="project">The project from which to read the properties.</param> public WixBuildMacroCollection(WixProjectNode project) { WixHelperMethods.VerifyNonNullArgument(project, "project"); // get the global SolutionX properties WixBuildMacroCollection.DefineSolutionProperties(project); foreach (string globalMacroName in globalMacroNames) { string property = null; project.BuildProject.GlobalProperties.TryGetValue(globalMacroName, out property); if (null == property) { this.list.Add(globalMacroName, "*Undefined*"); } else { this.list.Add(globalMacroName, property); } } // we need to call GetTargetPath first so that TargetDir and TargetPath are resolved correctly ConfigCanonicalName configCanonicalName; if (!Utilities.TryGetActiveConfigurationAndPlatform(project.Site, project, out configCanonicalName)) { throw new InvalidOperationException(); } Microsoft.VisualStudio.Package.BuildResult res = project.Build(configCanonicalName, WixProjectFileConstants.MsBuildTarget.GetTargetPath); // get the ProjectX and TargetX variables foreach (string macroName in macroNames) { string value; if (res.ProjectInstance != null) { value = res.ProjectInstance.GetPropertyValue(macroName); } else { value = project.GetProjectProperty(macroName); } this.list.Add(macroName, value); } }
/// <summary> /// Sets the value of the property. /// </summary> /// <param name="value">Property value to set.</param> /// <param name="configs">Optional list of configurations to set the property in; /// defaults to the project current configuration</param> /// <remarks> /// Before calling this method, the caller must ensure that the value is valid according to /// the <see cref="PropertyValidator"/> class, and that the project file is writable. /// In most cases the caller should also ensure that the new value is different from the /// existing value, to avoid dirtying the project file unnecessarily. /// </remarks> public void SetValue(string value, IList <ProjectConfig> configs) { WixHelperMethods.VerifyNonNullArgument(value, "value"); value = value.Trim(); PropertyPosition position = this.EndOfProjectFile ? PropertyPosition.UseExistingOrCreateAfterLastImport : PropertyPosition.UseExistingOrCreateAfterLastPropertyGroup; Project buildProject = this.project.BuildProject; if (this.PerUser) { if (this.project.UserBuildProject == null) { this.project.CreateUserBuildProject(); } buildProject = this.project.UserBuildProject; } value = this.Escape(value); if (this.PerConfig) { if (configs == null || configs.Count == 0) { configs = new ProjectConfig[] { this.project.CurrentConfig }; } foreach (ProjectConfig config in configs) { buildProject.SetProperty(this.propertyName, value, config.Condition, position); } } else { buildProject.SetProperty(this.propertyName, value, null, position); } this.project.InvalidatePropertyCache(); this.project.SetProjectFileDirty(true); }
// ========================================================================================= // Methods // ========================================================================================= /// <summary> /// Entry point for all property validation in WiX projects. /// </summary> /// <param name="propertyName">Name of the property being validated. (The name in the project file, not the localized name.)</param> /// <param name="value">Property value to be validated.</param> public static void ValidateProperty(string propertyName, string value) { WixHelperMethods.VerifyNonNullArgument(propertyName, "propertyName"); WixHelperMethods.VerifyNonNullArgument(value, "value"); switch (propertyName) { case WixProjectFileConstants.Cultures: ValidateCultures(WixStrings.Cultures, value); break; case WixProjectFileConstants.OutputName: ValidateFilename(WixStrings.OutputName, value); break; case WixProjectFileConstants.IntermediateOutputPath: case WixProjectFileConstants.OutputPath: ValidatePath(WixStrings.OutputPath, value); break; case WixProjectFileConstants.SuppressIces: ValidateWithRegex(WixStrings.Ices, value, icesValidationRegex, true, WixStrings.InvalidIce); break; case WixProjectFileConstants.SuppressSpecificWarnings: ValidateWithRegex(WixStrings.Warnings, value, warningsValidationRegex, true, WixStrings.InvalidWarnings); break; case WixProjectFileConstants.IncludeSearchPaths: ValidatePath(WixStrings.IncludePath, value); break; case WixProjectFileConstants.ReferencePaths: ValidatePath(WixStrings.ReferencePath, value); break; } }
/// <summary> /// Sets the value of the property. /// </summary> /// <param name="value">Property value to set.</param> /// <param name="configs">Optional list of configurations to set the property in; /// defaults to the project current configuration</param> /// <remarks> /// Before calling this method, the caller must ensure that the value is valid according to /// the <see cref="PropertyValidator"/> class, and that the project file is writable. /// In most cases the caller should also ensure that the new value is different from the /// existing value, to avoid dirtying the project file unnecessarily. /// </remarks> public void SetValue(string value, IList <ProjectConfig> configs) { WixHelperMethods.VerifyNonNullArgument(value, "value"); value = value.Trim(); MSBuild.Project buildProject = this.project.BuildProject; if (this.PerUser) { if (this.project.UserBuildProject == null) { this.project.CreateUserBuildProject(); } buildProject = this.project.UserBuildProject; } value = this.Escape(value); if (this.PerConfig) { if (configs == null || configs.Count == 0) { configs = new ProjectConfig[] { this.project.CurrentConfig }; } foreach (ProjectConfig config in configs) { bool set = false; // First see if there's an existing property group that matches our condition foreach (ProjectPropertyGroupElement propGroup in buildProject.Xml.PropertyGroups) { // if there is, set it within that group if (String.Equals(propGroup.Condition, config.Condition, StringComparison.Ordinal)) { propGroup.SetProperty(this.propertyName, value); set = true; break; } } // If not, add a new property group for the condition and set the property within it if (!set) { ProjectPropertyGroupElement newPropGroup = buildProject.Xml.AddPropertyGroup(); newPropGroup.Condition = config.Condition; newPropGroup.SetProperty(this.propertyName, value); set = true; } buildProject.ReevaluateIfNecessary(); } } else { if (this.EndOfProjectFile) { List <ProjectPropertyGroupElement> propertyGroupsToDelete = new List <ProjectPropertyGroupElement>(); // First see if there's an existing property group with our property foreach (ProjectPropertyGroupElement propGroup in buildProject.Xml.PropertyGroups) { List <ProjectPropertyElement> propertiesToDelete = new List <ProjectPropertyElement>(); if (!String.IsNullOrEmpty(propGroup.Condition)) { continue; } foreach (ProjectPropertyElement property in propGroup.Properties) { // if there is, remove it so the new value is at the end of the file if (String.IsNullOrEmpty(property.Condition) && String.Equals(property.Name, this.propertyName, StringComparison.OrdinalIgnoreCase)) { propertiesToDelete.Add(property); } } foreach (ProjectPropertyElement property in propertiesToDelete) { propGroup.RemoveChild(property); } if (propGroup.Count == 0) { propertyGroupsToDelete.Add(propGroup); } } foreach (ProjectPropertyGroupElement propGroup in propertyGroupsToDelete) { buildProject.Xml.RemoveChild(propGroup); } ProjectPropertyGroupElement newPropGroup = buildProject.Xml.CreatePropertyGroupElement(); buildProject.Xml.AppendChild(newPropGroup); newPropGroup.SetProperty(this.propertyName, value); } else { buildProject.SetProperty(this.propertyName, value); } } this.project.InvalidatePropertyCache(); this.project.SetProjectFileDirty(true); }