/// <summary> /// Casts the value read from the registry to the appropriate type and caches it. /// </summary> /// <param name="value">The value read from the registry.</param> protected override void CastAndStoreValue(object value) { try { this.Value = (int)value; } catch (InvalidCastException) { this.Value = this.DefaultValue; WixHelperMethods.TraceFail("Cannot convert '{0}' to an Int32.", value); } }
internal static void RemoveNonMemberItems(WixProjectNode project) { IList <HierarchyNode> nodeList = new List <HierarchyNode>(); WixHelperMethods.FindNodes(nodeList, project, WixProjectMembers.IsNodeNonMemberItem, null); for (int index = nodeList.Count - 1; index >= 0; index--) { HierarchyNode parent = nodeList[index].Parent; nodeList[index].OnItemDeleted(); parent.RemoveChild(nodeList[index]); } }
// ========================================================================================= // 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(); }
/// <summary> /// Initializes a new instance of the <see cref="WixExtensionReferenceNode"/> class. /// </summary> /// <param name="root">The root <see cref="WixProjectNode"/> that contains this node.</param> /// <param name="referencePath">The path to the wixlib reference file.</param> public WixExtensionReferenceNode(WixProjectNode root, string referencePath) : base(root, referencePath, WixProjectFileConstants.WixExtension) { referencePath = WixHelperMethods.ReplacePathWithBuildProperty(referencePath, ExtensionDirectoryToken, this.ExtensionDirectory); if (!referencePath.StartsWith(ExtensionDirectoryToken, StringComparison.Ordinal) && null != root) { referencePath = root.GetRelativePath(referencePath); } this.ItemNode.SetMetadata(ProjectFileConstants.HintPath, referencePath); this.InitializeFileChangeEvents(); }
/// <summary> /// When building a wixproj in VS, the configuration of referenced projects cannot be determined /// by MSBuild or from within an MSBuild task. So we'll get them from the VS project system here. /// </summary> /// <param name="project">The project where the properties are being defined; also the project /// whose references are being examined.</param> internal static void DefineProjectReferenceConfigurations(WixProjectNode project) { StringBuilder configList = new StringBuilder(); IVsSolutionBuildManager solutionBuildManager = WixHelperMethods.GetService <IVsSolutionBuildManager, SVsSolutionBuildManager>(project.Site); List <WixProjectReferenceNode> referenceNodes = new List <WixProjectReferenceNode>(); project.FindNodesOfType(referenceNodes); foreach (WixProjectReferenceNode referenceNode in referenceNodes) { IVsHierarchy hierarchy = VsShellUtilities.GetHierarchy(referenceNode.ProjectMgr.Site, referenceNode.ReferencedProjectGuid); string configuration = null; IVsProjectCfg2 projectCfg2 = null; IVsProjectCfg[] projectCfgArray = new IVsProjectCfg[1]; int hr = solutionBuildManager.FindActiveProjectCfg(IntPtr.Zero, IntPtr.Zero, hierarchy, projectCfgArray); ErrorHandler.ThrowOnFailure(hr); projectCfg2 = projectCfgArray[0] as IVsProjectCfg2; if (projectCfg2 != null) { hr = projectCfg2.get_DisplayName(out configuration); if (hr != 0) { Marshal.ThrowExceptionForHR(hr); } } if (configuration != null) { if (configList.Length > 0) { configList.Append(';'); } configList.Append(referenceNode.ReferencedProjectName); configList.Append('='); configList.Append(configuration); } } if (configList.Length > 0) { project.BuildProject.SetGlobalProperty("VSProjectConfigurations", configList.ToString()); } }
/// <summary> /// Gets the file system entries of a folder and its all sub-folders with relative path. /// </summary> /// <param name="baseFolder">Base folder.</param> /// <param name="filter">Filter to be used. default is "*"</param> /// <param name="fileList">Files list containing the relative file paths.</param> /// <param name="folderList">Folders list containing the relative folder paths.</param> private static void GetRelativeFileSystemEntries(string baseFolder, string filter, IList <string> fileList, IList <string> folderList) { if (baseFolder == null) { throw new ArgumentNullException("baseFolder"); } if (String.IsNullOrEmpty(filter)) { filter = "*"; // include all files and folders } if (fileList != null) { string[] fileEntries = Directory.GetFiles(baseFolder, filter, SearchOption.AllDirectories); foreach (string file in fileEntries) { FileInfo fileInfo = new FileInfo(file); if ((fileInfo.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden) { continue; } string fileRelativePath = WixHelperMethods.GetRelativePath(baseFolder, file); if (!String.IsNullOrEmpty(fileRelativePath)) { fileList.Add(fileRelativePath); } } } if (folderList != null) { string[] folderEntries = Directory.GetDirectories(baseFolder, filter, SearchOption.AllDirectories); foreach (string folder in folderEntries) { DirectoryInfo folderInfo = new DirectoryInfo(folder); if ((folderInfo.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden) { continue; } string folderRelativePath = WixHelperMethods.GetRelativePath(baseFolder, folder); if (!String.IsNullOrEmpty(folderRelativePath)) { folderList.Add(folderRelativePath); } } } }
// ========================================================================================= // 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="WixPackageSettings"/> class. /// </summary> /// <param name="serviceProvider">The <see cref="IServiceProvider"/> to use.</param> public WixPackageSettings(IServiceProvider serviceProvider) { WixHelperMethods.VerifyNonNullArgument(serviceProvider, "serviceProvider"); // get the Visual Studio registry root ILocalRegistry3 localRegistry = WixHelperMethods.GetService <ILocalRegistry3, SLocalRegistry>(serviceProvider); ErrorHandler.ThrowOnFailure(localRegistry.GetLocalRegistryRoot(out this.visualStudioRegistryRoot)); this.machineRootPath = WixHelperMethods.RegistryPathCombine(this.visualStudioRegistryRoot, @"InstalledProducts\WiX"); // initialize all of the machine settings this.toolsDirectory = new MachineSettingString(this.machineRootPath, KeyNames.ToolsDirectory, String.Empty); }
// ========================================================================================= // 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; // use the VS 2005 style property pages (project designer) instead of the old VS 2003 dialog this.SupportsProjectDesigner = true; this.InitializeCATIDs(); }
/// <summary> /// Gets the font provided by the VS environment for dialog UI. /// </summary> /// <returns>Dialog font, or null if it is not available.</returns> public static Font GetDialogFont() { IUIHostLocale uiHostLocale = WixHelperMethods.GetServiceNoThrow <IUIHostLocale, IUIHostLocale>(WixPackage.Instance); if (uiHostLocale != null) { UIDLGLOGFONT[] pLOGFONT = new UIDLGLOGFONT[1]; if (uiHostLocale.GetDialogFont(pLOGFONT) == 0) { return(Font.FromLogFont(pLOGFONT[0])); } } return(null); }
// ========================================================================================= // 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> /// Refreshes the data in the property browser /// </summary> internal static void RefreshPropertyBrowser() { IVsUIShell vsuiShell = WixPackage.GetGlobalService(typeof(SVsUIShell)) as IVsUIShell; if (vsuiShell == null) { string message = WixHelperMethods.SafeStringFormat(CultureInfo.CurrentUICulture, WixStrings.CannotGetService, typeof(IVsUIShell).Name); throw new InvalidOperationException(message); } else { int hr = vsuiShell.RefreshPropertyBrowser(0); if (hr != 0) { Marshal.ThrowExceptionForHR(hr); } } }
/// <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); }
/// <summary> /// Casts the value read from the registry to the appropriate type and caches it. /// </summary> /// <param name="value">The value read from the registry.</param> protected override void CastAndStoreValue(object value) { try { this.Value = (T)Enum.Parse(typeof(T), value.ToString(), true); } catch (Exception e) { if (e is FormatException || e is InvalidCastException) { this.Value = this.DefaultValue; WixHelperMethods.TraceFail("Cannot convert '{0}' to an enum of type '{1}'.", value, typeof(T).Name); } else { throw; } } }
int IProjectSourceNode.IncludeInProject() { WixProjectNode projectNode = this.ProjectMgr as WixProjectNode; if (projectNode == null || projectNode.IsClosed) { return((int)OleConstants.OLECMDERR_E_NOTSUPPORTED); } else if (!this.IsNonMemberItem) { return(VSConstants.S_OK); // do nothing, just ignore it. } using (WixHelperMethods.NewWaitCursor()) { // Check out the project file. if (!projectNode.QueryEditProjectFile(false)) { throw Marshal.GetExceptionForHR(VSConstants.OLE_E_PROMPTSAVECANCELLED); } // make sure that all parent folders are included in the project WixHelperMethods.EnsureParentFolderIncluded(this); // now add this node to the project. this.SetProperty((int)__VSHPROPID.VSHPROPID_IsNonMemberItem, false); this.ItemNode = projectNode.CreateMsBuildFileProjectElement(this.Url); this.ProjectMgr.Tracker.OnItemAdded(this.Url, VSADDFILEFLAGS.VSADDFILEFLAGS_NoFlags); // notify others ////projectNode.OnItemAdded(this.Parent, this); this.ReDraw(UIHierarchyElement.Icon); // We have to redraw the icon of the node as it is now a member of the project and should be drawn using a different icon. this.ReDraw(UIHierarchyElement.SccState); // update the SCC state icon. this.ResetProperties(); // refresh property browser... WixHelperMethods.RefreshPropertyBrowser(); } return(VSConstants.S_OK); }
/// <summary> /// Initialize common project properties with default value if they are empty. /// </summary> /// <remarks> /// The following common project properties are defaulted to projectName (if empty): ToolPath. /// If the project filename is not set then no properties are set. /// </remarks> protected override void InitializeProjectProperties() { // make sure the project file name has been set if (String.IsNullOrEmpty(this.FileName) || String.IsNullOrEmpty(Path.GetFileNameWithoutExtension(this.FileName))) { return; } // initialize the WixToolPath property from the value in the registry string toolsDirectory = this.package.Settings.ToolsDirectory; string programFilesDirectory = WixHelperMethods.EnsureTrailingDirectoryChar(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles)); // if the path in the registry starts with the same path as program files, then just put in $(ProgramFiles) to make it more portable if (toolsDirectory.StartsWith(programFilesDirectory, StringComparison.OrdinalIgnoreCase)) { toolsDirectory = "$(ProgramFiles)\\" + toolsDirectory.Substring(programFilesDirectory.Length); } this.SetProjectProperty(WixProjectFileConstants.WixToolPath, toolsDirectory); }
protected override int QueryStatusOnNode(Guid guidCmdGroup, uint cmd, IntPtr pCmdText, ref QueryStatusResult result) { if (VsPkgMenus.guidStandardCommandSet97 == guidCmdGroup && this.IsNonMemberItem) { switch ((VsCommands)cmd) { case VsCommands.ViewCode: result = QueryStatusResult.NOTSUPPORTED; return((int)OleConstants.MSOCMDERR_E_NOTSUPPORTED); } } int returnCode; if (WixHelperMethods.QueryStatusOnProjectSourceNode(this, guidCmdGroup, cmd, ref result, out returnCode)) { return(returnCode); } return(base.QueryStatusOnNode(guidCmdGroup, cmd, pCmdText, ref result)); }
/// <summary> /// Sets the expanded state of the folder. /// </summary> /// <param name="expanded">Flag that indicates the expanded state of the folder. /// This should be 'true' for expanded and 'false' for collapsed state.</param> protected void SetExpanded(bool expanded) { this.IsExpanded = expanded; this.SetProperty((int)__VSHPROPID.VSHPROPID_Expanded, expanded); // If we are in automation mode then skip the ui part if (!Utilities.IsInAutomationFunction(this.ProjectMgr.Site)) { IVsUIHierarchyWindow uiWindow = UIHierarchyUtilities.GetUIHierarchyWindow(this.ProjectMgr.Site, SolutionExplorer); if (null != uiWindow) { ErrorHandler.ThrowOnFailure(uiWindow.ExpandItem(this.ProjectMgr, this.ID, expanded ? EXPANDFLAGS.EXPF_ExpandFolder : EXPANDFLAGS.EXPF_CollapseFolder)); } // then post the expand command to the shell. Folder verification and creation will // happen in the setlabel code... IVsUIShell shell = WixHelperMethods.GetService <IVsUIShell, SVsUIShell>(this.ProjectMgr.Site); object dummy = null; Guid cmdGroup = VsMenus.guidStandardCommandSet97; ErrorHandler.ThrowOnFailure(shell.PostExecCommand(ref cmdGroup, (uint)(expanded ? VsCommands.Expand : VsCommands.Collapse), 0, ref dummy)); } }
/// <summary> /// Toggles the state of Show all files /// </summary> /// <returns>S_OK if it's possible to toggle the state, OLECMDERR_E_NOTSUPPORTED if not</returns> protected internal int ToggleShowAllFiles() { if (this.ProjectMgr == null || this.ProjectMgr.IsClosed) { return((int)OleConstants.OLECMDERR_E_NOTSUPPORTED); } using (WixHelperMethods.NewWaitCursor()) { this.showAllFilesEnabled = !this.showAllFilesEnabled; // toggle the flag if (this.showAllFilesEnabled) { WixProjectMembers.AddNonMemberItems(this); } else { WixProjectMembers.RemoveNonMemberItems(this); } } return(NativeMethods.S_OK); }
// ========================================================================================= // Methods // ========================================================================================= /// <summary> /// Sets the node property. /// </summary> /// <param name="propid">Property id.</param> /// <param name="value">Property value.</param> /// <returns>Returns success or failure code.</returns> public override int SetProperty(int propid, object value) { int result; __VSHPROPID id = (__VSHPROPID)propid; switch (id) { case __VSHPROPID.VSHPROPID_IsNonMemberItem: if (value == null) { throw new ArgumentNullException("value"); } bool boolValue; CCITracing.TraceCall(this.ID + "," + id.ToString()); if (Boolean.TryParse(value.ToString(), out boolValue)) { this.isNonMemberItem = boolValue; // Reset exclude from scc this.ExcludeNodeFromScc = this.IsNonMemberItem; } else { WixHelperMethods.TraceFail("Could not parse the IsNonMemberItem property value."); } result = VSConstants.S_OK; break; default: result = base.SetProperty(propid, value); break; } return(result); }
// ========================================================================================= // 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; } }
protected override int ExecCommandOnNode(Guid cmdGroup, uint cmd, uint cmdexecopt, IntPtr pvaIn, IntPtr pvaOut) { if (cmdGroup == VsMenus.guidStandardCommandSet97) { switch ((VsCommands)cmd) { case VsCommands.Refresh: WixHelperMethods.RefreshProject(this); return(VSConstants.S_OK); } } if (cmdGroup == VsMenus.guidStandardCommandSet2K) { switch ((VsCommands2K)cmd) { case VsCommands2K.SLNREFRESH: WixHelperMethods.RefreshProject(this); return(VSConstants.S_OK); } } return(base.ExecCommandOnNode(cmdGroup, cmd, cmdexecopt, pvaIn, pvaOut)); }
/// <summary> /// Shows invalid Wix reference message. /// </summary> protected void ShowInvalidWixReferenceMessage() { string errorMessage = String.Format(CultureInfo.CurrentUICulture, WixStrings.WixReferenceInvalid, this.Url); WixHelperMethods.ShowErrorMessageBox(this.ProjectMgr.Site, errorMessage); }
/// <summary> /// Replaces build properties in the path. /// </summary> /// <param name="path">Input path with build propeties.</param> /// <returns>Path with build properties evaluated and substituted.</returns> protected override string ReplacePropertiesInPath(string path) { path = WixHelperMethods.ReplaceBuildPropertyWithPath(path, ExtensionDirectoryToken, this.ExtensionDirectory); return(base.ReplacePropertiesInPath(path)); }
int IProjectSourceNode.ExcludeFromProject() { if (this.ProjectMgr == null || this.ProjectMgr.IsClosed) { return((int)OleConstants.OLECMDERR_E_NOTSUPPORTED); } else if (this.IsNonMemberItem) { return(VSConstants.S_OK); // do nothing, just ignore it. } using (WixHelperMethods.NewWaitCursor()) { // Ask Document tracker listeners if we can remove the item. { // just to limit the scope. string documentToRemove = this.GetMkDocument(); string[] filesToBeDeleted = new string[1] { documentToRemove }; VSQUERYREMOVEFILEFLAGS[] queryRemoveFlags = this.GetQueryRemoveFileFlags(filesToBeDeleted); if (!this.ProjectMgr.Tracker.CanRemoveItems(filesToBeDeleted, queryRemoveFlags)) { return((int)OleConstants.OLECMDERR_E_CANCELED); } // Close the document if it has a manager. DocumentManager manager = this.GetDocumentManager(); if (manager != null) { if (manager.Close(__FRAMECLOSE.FRAMECLOSE_PromptSave) == VSConstants.E_ABORT) { // User cancelled operation in message box. return(VSConstants.OLE_E_PROMPTSAVECANCELLED); } } // Check out the project file. if (!this.ProjectMgr.QueryEditProjectFile(false)) { throw Marshal.GetExceptionForHR(VSConstants.OLE_E_PROMPTSAVECANCELLED); } } // close the document window if open. this.CloseDocumentWindow(this); WixProjectNode projectNode = this.ProjectMgr as WixProjectNode; if (projectNode != null && projectNode.ShowAllFilesEnabled && File.Exists(this.Url)) { // need to store before removing the node. string url = this.Url; string include = this.ItemNode.GetMetadata(ProjectFileConstants.Include); this.ItemNode.RemoveFromProjectFile(); this.ProjectMgr.Tracker.OnItemRemoved(url, VSREMOVEFILEFLAGS.VSREMOVEFILEFLAGS_NoFlags); this.SetProperty((int)__VSHPROPID.VSHPROPID_IsNonMemberItem, true); // Set it as non member item this.ItemNode = new ProjectElement(this.ProjectMgr, null, true); // now we have to set a new ItemNode to indicate that this is virtual node. this.ItemNode.Rename(include); this.ItemNode.SetMetadata(ProjectFileConstants.Name, url); ////this.ProjectMgr.OnItemAdded(this.Parent, this); this.ReDraw(UIHierarchyElement.Icon); // We have to redraw the icon of the node as it is now not a member of the project and should be drawn using a different icon. this.ReDraw(UIHierarchyElement.SccState); // update the SCC state icon. } else if (this.Parent != null) // the project node has no parentNode { // Remove from the Hierarchy this.OnItemDeleted(); this.Parent.RemoveChild(this); this.ItemNode.RemoveFromProjectFile(); } this.ResetProperties(); // refresh property browser... WixHelperMethods.RefreshPropertyBrowser(); } return(VSConstants.S_OK); }
public override int UpgradeProject(string fileName, uint upgradeFlag, string copyLocation, out string upgradedFullyQualifiedFileName, IVsUpgradeLogger logger, out int upgradeRequired, out Guid newProjectFactory) { uint ignore; string projectName = Path.GetFileNameWithoutExtension(fileName); upgradedFullyQualifiedFileName = fileName; this.UpgradeProject_CheckOnly(fileName, logger, out upgradeRequired, out newProjectFactory, out ignore); if (upgradeRequired == 0) { upgradedFullyQualifiedFileName = fileName; return(VSConstants.S_OK); } IVsQueryEditQuerySave2 queryEditQuerySave = WixHelperMethods.GetService <IVsQueryEditQuerySave2, SVsQueryEditQuerySave>(this.Site); int qef = (int)tagVSQueryEditFlags.QEF_ReportOnly | (int)__VSQueryEditFlags2.QEF_AllowUnopenedProjects; uint verdict; uint moreInfo; string[] files = new string[1]; files[0] = fileName; bool continueUpgrade = false; ErrorHandler.ThrowOnFailure(queryEditQuerySave.QueryEditFiles((uint)qef, 1, files, null, null, out verdict, out moreInfo)); if (verdict == (uint)tagVSQueryEditResult.QER_EditOK) { continueUpgrade = true; } if (verdict == (uint)tagVSQueryEditResult.QER_EditNotOK) { logger.LogMessage((uint)__VSUL_ERRORLEVEL.VSUL_INFORMATIONAL, projectName, fileName, WixStrings.ReadOnlyFile); if ((moreInfo & (uint)tagVSQueryEditResultFlags.QER_ReadOnlyUnderScc) != 0) { qef = (int)tagVSQueryEditFlags.QEF_DisallowInMemoryEdits | (int)__VSQueryEditFlags2.QEF_AllowUnopenedProjects | (int)tagVSQueryEditFlags.QEF_ForceEdit_NoPrompting; ErrorHandler.ThrowOnFailure(queryEditQuerySave.QueryEditFiles((uint)qef, 1, files, null, null, out verdict, out moreInfo)); if (verdict == (uint)tagVSQueryEditResult.QER_EditOK) { continueUpgrade = true; } } if (continueUpgrade) { logger.LogMessage((uint)__VSUL_ERRORLEVEL.VSUL_INFORMATIONAL, projectName, fileName, WixStrings.CheckoutSuccess); } else { logger.LogMessage((uint)__VSUL_ERRORLEVEL.VSUL_ERROR, projectName, fileName, WixStrings.FailedToCheckoutProject); throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, WixStrings.FailedToCheckoutFile, fileName)); } } // If file was modified during the checkout, maybe upgrade is not needed if ((moreInfo & (uint)tagVSQueryEditResultFlags.QER_MaybeChanged) != 0) { this.UpgradeProject_CheckOnly(fileName, logger, out upgradeRequired, out newProjectFactory, out ignore); if (upgradeRequired == 0) { if (logger != null) { logger.LogMessage((uint)__VSUL_ERRORLEVEL.VSUL_INFORMATIONAL, projectName, fileName, WixStrings.UpgradeNoNeedToUpgradeAfterCheckout); } return(VSConstants.S_OK); } } if (continueUpgrade) { XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(fileName); xmlDoc.DocumentElement.SetAttribute(WixProjectFileConstants.ToolsVersion, "4.0"); bool targetsPathUpdated = false; foreach (XmlNode node in xmlDoc.DocumentElement.ChildNodes) { if (WixProjectFileConstants.PropertyGroup == node.Name) { foreach (XmlNode propertyNode in node.ChildNodes) { if (WixProjectFileConstants.WixTargetsPath == propertyNode.Name) { if (propertyNode.InnerText.Contains("\\Microsoft\\WiX\\v3.0\\")) { targetsPathUpdated = true; propertyNode.InnerText = propertyNode.InnerText.Replace("\\Microsoft\\WiX\\v3.0\\", "\\Microsoft\\WiX\\v3.x\\"); } else if (propertyNode.InnerText.Contains("\\Microsoft\\WiX\\v3.5\\")) { targetsPathUpdated = true; propertyNode.InnerText = propertyNode.InnerText.Replace("\\Microsoft\\WiX\\v3.5\\", "\\Microsoft\\WiX\\v3.x\\"); } if (propertyNode.InnerText.Contains("\\Wix2010.targets")) { targetsPathUpdated = true; propertyNode.InnerText = propertyNode.InnerText.Replace("\\Wix2010.targets", "\\Wix.targets"); } } } } } if (targetsPathUpdated) { logger.LogMessage((uint)__VSUL_ERRORLEVEL.VSUL_INFORMATIONAL, projectName, fileName, WixStrings.WixTargetsPathUpdated); } xmlDoc.Save(fileName); upgradedFullyQualifiedFileName = fileName; } return(VSConstants.S_OK); }
/// <summary> /// Excludes the file and folder items from their corresponding maps if they are part of the build. /// </summary> /// <param name="project">The project to modify.</param> /// <param name="fileList">List containing relative files paths.</param> /// <param name="folderList">List containing relative folder paths.</param> private static void ExcludeProjectBuildItems(WixProjectNode project, IList <string> fileList, IList <string> folderList) { BuildItemGroup projectItems = project.BuildProject.EvaluatedItems; if (projectItems == null) { return; // do nothig, just ignore it. } else if (fileList == null && folderList == null) { throw new ArgumentNullException("folderList"); } // we need these maps becuase we need to have both lowercase and actual case path information. // we use lower case paths for case-insesitive search of file entries and actual paths for // creating hierarchy node. if we don't do that, we will end up with duplicate nodes when the // case of path in .wixproj file doesn't match with the actual file path on the disk. IDictionary <string, string> folderMap = null; IDictionary <string, string> fileMap = null; if (folderList != null) { folderMap = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase); foreach (string folder in folderList) { folderMap.Add(folder, folder); } } if (fileList != null) { fileMap = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase); foreach (string file in fileList) { fileMap.Add(file, file); } } foreach (BuildItem buildItem in projectItems) { if (folderMap != null && folderMap.Count > 0 && String.Equals(buildItem.Name, ProjectFileConstants.Folder, StringComparison.OrdinalIgnoreCase)) { string relativePath = buildItem.FinalItemSpec; if (Path.IsPathRooted(relativePath)) // if not the relative path, make it relative { relativePath = WixHelperMethods.GetRelativePath(project.ProjectFolder, relativePath); } if (folderMap.ContainsKey(relativePath)) { folderList.Remove(folderMap[relativePath]); // remove it from the actual list. folderMap.Remove(relativePath); } } else if (fileMap != null && fileMap.Count > 0 && WixProjectMembers.IsWixFileItem(buildItem)) { string relativePath = buildItem.FinalItemSpec; if (Path.IsPathRooted(relativePath)) // if not the relative path, make it relative { relativePath = WixHelperMethods.GetRelativePath(project.ProjectFolder, relativePath); } if (fileMap.ContainsKey(relativePath)) { fileList.Remove(fileMap[relativePath]); // remove it from the actual list. fileMap.Remove(relativePath); } } } }
int IProjectSourceNode.ExcludeFromProject() { WixProjectNode projectNode = this.ProjectMgr as WixProjectNode; if (projectNode == null || projectNode.IsClosed) { return((int)OleConstants.OLECMDERR_E_NOTSUPPORTED); } else if (this.IsNonMemberItem) { return(VSConstants.S_OK); // do nothing, just ignore it. } using (WixHelperMethods.NewWaitCursor()) { // Check out the project file. if (!projectNode.QueryEditProjectFile(false)) { throw Marshal.GetExceptionForHR(VSConstants.OLE_E_PROMPTSAVECANCELLED); } // remove children, if any, before removing from the hierarchy for (HierarchyNode child = this.FirstChild; child != null; child = child.NextSibling) { IProjectSourceNode node = child as IProjectSourceNode; if (node != null) { int result = node.ExcludeFromProject(); if (result != VSConstants.S_OK) { return(result); } } } if (projectNode != null && projectNode.ShowAllFilesEnabled && Directory.Exists(this.Url)) { string url = this.Url; this.SetProperty((int)__VSHPROPID.VSHPROPID_IsNonMemberItem, true); this.ItemNode.RemoveFromProjectFile(); this.ItemNode = new ProjectElement(this.ProjectMgr, null, true); // now we have to create a new ItemNode to indicate that this is virtual node. this.ItemNode.Rename(url); this.ItemNode.SetMetadata(ProjectFileConstants.Name, this.Url); this.ReDraw(UIHierarchyElement.Icon); // we have to redraw the icon of the node as it is now not a member of the project and shoul be drawn using a different icon. } else if (this.Parent != null) // the project node has no parentNode { // this is important to make it non member item. otherwise, the multi-selection scenario would // not work if it has any parent child relation. this.SetProperty((int)__VSHPROPID.VSHPROPID_IsNonMemberItem, true); // remove from the hierarchy this.OnItemDeleted(); this.Parent.RemoveChild(this); this.ItemNode.RemoveFromProjectFile(); } // refresh property browser... WixHelperMethods.RefreshPropertyBrowser(); } return(VSConstants.S_OK); }
/// <summary> /// Converts the path to relative (if it is absolute) to the project folder. /// </summary> /// <param name="path">Path to be made relative.</param> /// <returns>Path relative to the project folder.</returns> public virtual string GetRelativePath(string path) { return(WixHelperMethods.GetRelativePath(this.ProjectFolder, path)); }
/// <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); }