private string GetValue(bool finalValue, IList <XProjectConfig> configs, bool booleanValue) { MSBuild.Project buildProject = this.PerUser ? this.project.UserBuildProject : this.project.BuildProject; if (buildProject == null) { return(null); } string value; if (this.PerConfig) { if (configs == null || configs.Count == 0) { configs = new XProjectConfig[] { this.project.CurrentConfig }; } value = this.GetPerConfigValue(buildProject, finalValue, configs, booleanValue); } else { MSBuild.ProjectProperty buildProperty = buildProject.GetProperty(this.propertyName); value = this.GetBuildPropertyValue(buildProperty, finalValue); if (booleanValue && String.IsNullOrEmpty(value)) { value = Boolean.FalseString; } } return(value); }
private string GetPerConfigValue(MSBuild.Project buildProject, bool finalValue, IList <XProjectConfig> configs, bool nullIsFalse) { string unifiedValue = null; for (int i = 0; i < configs.Count; i++) { XProjectConfig config = configs[i]; bool resetCache = (i == 0); // we should be using the buildProject parameter here, but this isn't implemented in MPF MSBuild.ProjectProperty buildProperty = config.GetMsBuildProperty(this.propertyName, resetCache); string value = this.GetBuildPropertyValue(buildProperty, finalValue); if (value != null) { value = value.Trim(); } if (nullIsFalse && String.IsNullOrEmpty(value)) { value = Boolean.FalseString; } if (i == 0) { unifiedValue = value; } else if (unifiedValue != value) { unifiedValue = null; // indicates indeterminate value break; } } return(unifiedValue); }
/// <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 <XProjectConfig> configs) { XHelperMethods.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 XProjectConfig[] { (XProjectConfig)this.project.CurrentConfig }; } foreach (XProjectConfig 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>(); var groups = 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; } groups.Add(propGroup); 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); groups.Remove(propGroup); } } foreach (ProjectPropertyGroupElement propGroup in propertyGroupsToDelete) { buildProject.Xml.RemoveChild(propGroup); } ProjectPropertyGroupElement newPropGroup; if (groups.Count > 1) { newPropGroup = groups[groups.Count - 1]; } else { 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); }
/// <summary> /// The environment calls this to set the currently selected objects that the property page should show. /// </summary> /// <param name="count">The count of elements in <paramref name="punk"/>.</param> /// <param name="punk">An array of <b>IUnknown</b> objects to show in the property page.</param> /// <remarks> /// We are supposed to cache these objects until we get another call with <paramref name="count"/> = 0. /// Also, the environment is supposed to call this before calling <see cref="IPropertyPage2.Activate"/>, /// but like all things when interacting with Visual Studio, don't trust that and code defensively. /// </remarks> void IPropertyPage.SetObjects(uint count, object[] punk) { if (count == 0) { if (this.project != null) { //this.project.OutputTypeChanged -= this.HandleOutputTypeChanged; this.project = null; } return; } if (punk[0] is ProjectConfig) { List <XProjectConfig> configs = new List <XProjectConfig>(); for (int i = 0; i < count; i++) { XProjectConfig config = (XProjectConfig)punk[i]; if (this.project == null) { this.project = config.ProjectMgr as XProjectNode; //this.project.OutputTypeChanged += this.HandleOutputTypeChanged; } configs.Add(config); } this.projectConfigs = configs.ToArray(); } else if (punk[0] is NodeProperties) { if (this.project == null) { this.project = (punk[0] as NodeProperties).Node.ProjectMgr as XProjectNode; //this.project.OutputTypeChanged += this.HandleOutputTypeChanged; } Dictionary <string, XProjectConfig> configsMap = new Dictionary <string, XProjectConfig>(); for (int i = 0; i < count; i++) { NodeProperties property = (NodeProperties)punk[i]; IVsCfgProvider provider; ErrorHandler.ThrowOnFailure(property.Node.ProjectMgr.GetCfgProvider(out provider)); uint[] expected = new uint[1]; ErrorHandler.ThrowOnFailure(provider.GetCfgs(0, null, expected, null)); if (expected[0] > 0) { XProjectConfig[] configs = new XProjectConfig[expected[0]]; uint[] actual = new uint[1]; int hr = provider.GetCfgs(expected[0], configs, actual, null); if (hr != 0) { Marshal.ThrowExceptionForHR(hr); } foreach (XProjectConfig config in configs) { if (!configsMap.ContainsKey(config.ConfigName)) { configsMap.Add(config.ConfigName, config); } } } } if (configsMap.Count > 0) { if (this.projectConfigs == null) { this.projectConfigs = new XProjectConfig[configsMap.Keys.Count]; } configsMap.Values.CopyTo(this.projectConfigs, 0); } } if (this.active && this.project != null) { this.PropertyPagePanel.BindProperties(); this.IsDirty = false; } }