private void CreateDesignerClass() { //(re-)create the designer class VSLangProj.VSProjectItem vsPrjItem = ResourcesFile.Object as VSLangProj.VSProjectItem; if (vsPrjItem != null) { vsPrjItem.RunCustomTool(); } }
/// <summary> /// Runs the custom tool of a project item. /// </summary> /// <param name="project">IVsProject</param> /// <param name="itemId">item id</param> public static void RunCustomToolOfItem(this IVsProject project, uint itemId) { Microsoft.VisualStudio.OLE.Interop.IServiceProvider ppSP; project.GetItemContext(itemId, out ppSP); Microsoft.VisualStudio.Shell.ServiceProvider itemContextService = new Microsoft.VisualStudio.Shell.ServiceProvider(ppSP); EnvDTE.ProjectItem templateItem = (EnvDTE.ProjectItem)itemContextService.GetService(typeof(EnvDTE.ProjectItem)); VSLangProj.VSProjectItem vsProjectItem = templateItem.Object as VSLangProj.VSProjectItem; vsProjectItem.RunCustomTool(); }
public void how_to_convert_MSBuild_ProjectItem_to_VSProjectItem() { // Say you got an MSBuild ProjectItem somehow. Microsoft.Build.Evaluation.ProjectItem item = this.MsBuildLibrary.Items.First(pi => pi.UnevaluatedInclude == "Class1.cs"); VSLangProj.VSProjectItem vsItem = item.Adapt().AsVsLangItem(); Assert.IsNotNull(vsItem); // Now use item to force its custom tool to run. vsItem.RunCustomTool(); }
private void RunCustomTool(ProjectItem projectItem) { IVsSolution solution = (IVsSolution)GetGlobalService(typeof(SVsSolution)); IVsHierarchy project; solution.GetProjectOfUniqueName(projectItem.ContainingProject.UniqueName, out project); try { string docFullPath = projectItem.GetPath(); if (docFullPath == null) { docFullPath = projectItem.Name; } LogActivity("{0}", docFullPath); VSLangProj.VSProjectItem vsProjectItem = projectItem.Object as VSLangProj.VSProjectItem; vsProjectItem.RunCustomTool(); } catch { LogError(project, projectItem.Document.Name, $"Failed to Run Custom Tool on {projectItem.Name}"); } }
} // GetDataAdapterClone private void buttonOK_Click(object sender, System.EventArgs e) { string tableName = "Table"; if (this.checkedListBoxTables.CheckedItems.Count == 0) { MessageBox.Show("No tables were selected to be added to the dataset.", "Generate " + DATASETNAME_PREFIX); return; } string entry = this.checkedListBoxTables.CheckedItems[0].ToString(); int i = entry.LastIndexOf(" ("); if (i == -1) // should never happen { return; } tableName = entry.Substring(0, i); DbDataAdapter adapter = GetDataAdapterClone(this.dbDataAdapter); if (adapter == null) // return if badly configured adapter { return; } string dsName = "Table"; if (this.radioButtonNew.Checked) { dsName = this.textBoxNew.Text.Trim(); } else { string s = this.comboBoxExisting.Text; i = s.LastIndexOf('.'); if (i == -1) { dsName = s.Trim(); } else if (i < (s.Length - 1)) { dsName = s.Substring(i + 1).Trim(); } else { dsName = String.Empty; } } if (dsName.Length == 0) { MessageBox.Show("Dataset name is invalid.", "Generate " + DATASETNAME_PREFIX); return; } // make a DataSet that the DbAdapter can fill in DataSet ds = new DataSet(dsName); Cursor cursor = Cursor.Current; // save cursor, probably Arrow Cursor.Current = Cursors.WaitCursor; // hourglass cursor adapter.MissingSchemaAction = MissingSchemaAction.Add; adapter.MissingMappingAction = (this.dbDataAdapter.MissingMappingAction == MissingMappingAction.Error)? MissingMappingAction.Ignore : this.dbDataAdapter.MissingMappingAction; try { adapter.FillSchema(ds, SchemaType.Mapped); } catch (Exception ex) { Cursor.Current = cursor; MessageBox.Show(ex.Message, "Unable to generate " + DATASETNAME_PREFIX); return; } finally { Cursor.Current = cursor; } // restored Arrow cursor ds.Namespace = "http://www.tempuri.org/" + dsName + ".xsd"; // strip the useless MaxLength info that adds clutter to the XML foreach (DataTable dataTable in ds.Tables) { for (int j = 0; j < dataTable.Columns.Count; j++) { DataColumn dataColumn = dataTable.Columns[j]; dataColumn.MaxLength = -1; } } string fileName = System.IO.Path.Combine(currentProjectFullPath, dsName + ".xsd"); ds.WriteXmlSchema(fileName); // write the ingresDataSetn.xsd file EnvDTE.ProjectItem projItem = null; if (this.radioButtonExisting.Checked) // if existing project item { i = this.comboBoxExisting.SelectedIndex; projItem = (EnvDTE.ProjectItem)(this.existingDataSetProjectItems[i]); } else // else new project item { projItem = currentProject.ProjectItems.AddFromFile(fileName); EnvDTE.Property pp; pp = projItem.Properties.Item("CustomTool"); pp.Value = "MSDataSetGenerator"; } VSLangProj.VSProjectItem vsprojItem = projItem.Object as VSLangProj.VSProjectItem; if (vsprojItem != null) { vsprojItem.RunCustomTool(); // update the .cs or .vb file } if (!this.checkBoxAddToDesigner.Checked) // return if all done { this.DialogResult = DialogResult.OK; return; } // add the new dataset to the component tray string componentBaseName; if (currentProjectNamespace.Length == 0) { componentBaseName = dsName; } else { componentBaseName = currentProjectNamespace + "." + dsName; } System.ComponentModel.Design.IDesignerHost host = serviceProvider.GetService( typeof(System.ComponentModel.Design.IDesignerHost)) as System.ComponentModel.Design.IDesignerHost; if (host == null) { MessageBox.Show( "The IDesignerHost service interface " + "could not be obtained to process the request.", "Generate " + DATASETNAME_PREFIX); return; } Type componentType; try { componentType = host.GetType(componentBaseName); } catch (Exception ex) { MessageBox.Show(ex.Message, "Unable to get Type of " + componentBaseName); return; } IComponent newComponent; try { newComponent = host.CreateComponent(componentType); host.Container.Add(newComponent); } catch (Exception ex) { MessageBox.Show(ex.Message, "Unable to create component for " + componentBaseName); return; } // move the select pointer to the new component in the tray ISelectionService selService = newComponent.Site.GetService( typeof(ISelectionService)) as ISelectionService; if (selService != null) { ArrayList selList = new ArrayList(1); selList.Add(newComponent); selService.SetSelectedComponents( // move the selection to new selList, SelectionTypes.Replace); } this.DialogResult = DialogResult.OK; }
private void BuildAndUseResource(ProjectItem resourceFilePrjItem) { try { string resxFile = resourceFilePrjItem.Document.FullName; string nameSpace = m_Window.Project.Properties.Item("RootNamespace").Value.ToString(); #region get namespace from ResX designer file foreach (ProjectItem item in resourceFilePrjItem.ProjectItems) { if (item.Name.EndsWith(".resx", StringComparison.InvariantCultureIgnoreCase)) { continue; } foreach (CodeElement element in item.FileCodeModel.CodeElements) { if (element.Kind == vsCMElement.vsCMElementNamespace) { nameSpace = element.FullName; break; } //if } //foreach } //foreach #endregion //close the ResX file to modify it (force a checkout) resourceFilePrjItem.Document.Save(); //[13-07-10 DR]: MS has changed behavior of Close(vsSaveChanges.vsSaveChangesYes) in VS2012 resourceFilePrjItem.Document.Close(vsSaveChanges.vsSaveChangesYes); string name, value, comment = string.Empty; StringResource stringResource = m_SelectedStringResource;// this.dataGrid1.CurrentItem as StringResource; name = stringResource.Name; value = stringResource.Text; if (!m_IsCSharp || (m_TextDocument.Selection.Text.Length > 0) && (m_TextDocument.Selection.Text[0] == '@')) { value = value.Replace("\"\"", "\\\""); // [""] -> [\"] (change VB writing to CSharp) } //add to the resource file (checking for duplicate) if (!AppendStringResource(resxFile, name, value, comment)) { return; } //(re-)create the designer class VSLangProj.VSProjectItem vsPrjItem = resourceFilePrjItem.Object as VSLangProj.VSProjectItem; if (vsPrjItem != null) { vsPrjItem.RunCustomTool(); } //get the length of the selected string literal and replace by resource call int replaceLength = m_TextDocument.Selection.Text.Length; if (replaceLength > 0) { string className = System.IO.Path.GetFileNameWithoutExtension(resxFile).Replace('.', '_'), aliasName = className.Substring(0, className.Length - 6), //..._Resources -> ..._Res resourceCall = string.Concat(aliasName, ".", name); bool isGlobalResourceFile = m_Settings.IsUseGlobalResourceFile && string.IsNullOrEmpty(m_Settings.GlobalResourceFileName), isDontUseResourceUsingAlias = m_Settings.IsUseGlobalResourceFile && m_Settings.IsDontUseResourceAlias; if (isGlobalResourceFile) { //standard global resource file aliasName = string.Concat("Glbl", aliasName); resourceCall = string.Concat("Glbl", resourceCall); } //if int oldRow = m_TextDocument.Selection.ActivePoint.Line; if (!isDontUseResourceUsingAlias) { //insert the resource using alias (if not yet) CheckAndAddAlias(nameSpace, className, aliasName); } else { //create a resource call like "Properties.SRB_Strings_Resources.myResText", "Properties.Resources.myResText", "Resources.myResText" int lastDotPos = nameSpace.LastIndexOf('.'); string resxNameSpace = (lastDotPos >= 0) ? string.Concat(nameSpace.Substring(lastDotPos + 1), ".") : string.Empty; resourceCall = string.Concat(resxNameSpace, className, ".", name); } //else //insert the resource call, replacing the selected string literal m_TextDocument.Selection.Insert(resourceCall, (int)vsInsertFlags.vsInsertFlagsContainNewText); UpdateTableAndSelectNext(resourceCall.Length - replaceLength, m_TextDocument.Selection.ActivePoint.Line - oldRow); } //if } catch (Exception ex) { Trace.WriteLine($"### BuildAndUseResource() - {ex.ToString()}"); } }
protected override void OnClosed(EventArgs e) { if (_savedChanges) { // Make sure the current document has the necessary // extensions loaded. // UNDONE: We should be able to do this with the document // closed or open as text as well via a registered service // on the ORMDesignerPackage, but this is sufficient for now. Dictionary <string, string> requiredExtensions = null; string[] loadedExtensions = null; foreach (IORMGenerator selectedGenerator in _mainBranch.SelectedGenerators) { foreach (string requiredExtension in selectedGenerator.GetRequiredExtensionsForInputFormat("ORM")) { if (loadedExtensions == null) { loadedExtensions = (new ORMExtensionManager(_projectItem)).GetLoadedExtensions(_serviceProvider); } if (Array.BinarySearch <string>(loadedExtensions, requiredExtension) < 0) { if (requiredExtensions == null) { requiredExtensions = new Dictionary <string, string>(); } else if (requiredExtensions.ContainsKey(requiredExtension)) { continue; } requiredExtensions.Add(requiredExtension, requiredExtension); } } } if (requiredExtensions != null) { _savedChanges = ORMExtensionManager.EnsureExtensions(_projectItem, _serviceProvider, requiredExtensions.Values); } } if (_savedChanges) { // Delete the removed items from the project if (_removedItems != null) { EnvDTE.ProjectItems subItems = _projectItem.ProjectItems; foreach (string itemName in _removedItems.Keys) { try { EnvDTE.ProjectItem subItem = subItems.Item(itemName); if (subItem != null) { subItem.Delete(); } } catch (ArgumentException) { // Swallow } } } // throw away the original build item group if (_originalItemGroup != null) { try { #if VISUALSTUDIO_10_0 _project.RemoveChild(_originalItemGroup); #else _project.RemoveItemGroup(_originalItemGroup); #endif } catch (InvalidOperationException) { // Swallow } } #if VISUALSTUDIO_10_0 Dictionary <string, ProjectItemElement> removeItems = new Dictionary <string, ProjectItemElement>(); #else Dictionary <string, BuildItem> removeItems = new Dictionary <string, BuildItem>(); #endif string tmpFile = null; try { EnvDTE.ProjectItems projectItems = _projectItem.ProjectItems; #if VISUALSTUDIO_10_0 string itemDirectory = (new FileInfo((string)_project.FullPath)).DirectoryName; foreach (ProjectItemElement item in _itemGroup.Items) #else string itemDirectory = (new FileInfo((string)_project.FullFileName)).DirectoryName; foreach (BuildItem item in this._itemGroup) #endif { string filePath = string.Concat(itemDirectory, Path.DirectorySeparatorChar, item.Include); string fileName = (new FileInfo(item.Include)).Name; if (File.Exists(filePath)) { try { projectItems.AddFromFile(filePath); } catch (ArgumentException) { // Swallow } } else { if (tmpFile == null) { tmpFile = Path.GetTempFileName(); } EnvDTE.ProjectItem projectItem = projectItems.AddFromTemplate(tmpFile, fileName); string customTool = item.GetMetadata(ITEMMETADATA_GENERATOR); if (!string.IsNullOrEmpty(customTool)) { projectItem.Properties.Item("CustomTool").Value = customTool; } } removeItems[item.Include] = null; } } finally { if (tmpFile != null) { File.Delete(tmpFile); } } #if VISUALSTUDIO_10_0 foreach (ProjectItemGroupElement group in this._project.ItemGroups) #else foreach (BuildItemGroup group in this._project.ItemGroups) #endif { if (group.Condition.Trim() == this._itemGroup.Condition.Trim()) { continue; } #if VISUALSTUDIO_10_0 foreach (ProjectItemElement item in group.Items) #else foreach (BuildItem item in group) #endif { if (removeItems.ContainsKey(item.Include)) { removeItems[item.Include] = item; } } } foreach (string key in removeItems.Keys) { #if VISUALSTUDIO_10_0 ProjectItemElement removeItem; ProjectElementContainer removeFrom; if (null != (removeItem = removeItems[key]) && null != (removeFrom = removeItem.Parent)) { removeFrom.RemoveChild(removeItem); } #else BuildItem removeItem = removeItems[key]; if (removeItem != null) { _project.RemoveItem(removeItem); } #endif } VSLangProj.VSProjectItem vsProjectItem = _projectItem.Object as VSLangProj.VSProjectItem; if (vsProjectItem != null) { vsProjectItem.RunCustomTool(); } } else { #if VISUALSTUDIO_10_0 _project.RemoveChild(_itemGroup); #else _project.RemoveItemGroup(_itemGroup); #endif } base.OnClosed(e); }
protected override void OnClosed(EventArgs e) { if (_savedChanges) { // Make sure the current document has the necessary // extensions loaded. // UNDONE: We should be able to do this with the document // closed or open as text as well via a registered service // on the ORMDesignerPackage, but this is sufficient for now. Dictionary <string, string> requiredExtensions = null; string[] loadedExtensions = null; foreach (IORMGenerator selectedGenerator in _mainBranch.SelectedGenerators) { foreach (string requiredExtension in selectedGenerator.GetRequiredExtensionsForInputFormat("ORM")) { if (loadedExtensions == null) { loadedExtensions = (new ORMExtensionManager(_projectItem)).GetLoadedExtensions(_serviceProvider); } if (Array.BinarySearch <string>(loadedExtensions, requiredExtension) < 0) { if (requiredExtensions == null) { requiredExtensions = new Dictionary <string, string>(); } else if (requiredExtensions.ContainsKey(requiredExtension)) { continue; } requiredExtensions.Add(requiredExtension, requiredExtension); } } } if (requiredExtensions != null) { _savedChanges = ORMExtensionManager.EnsureExtensions(_projectItem, _serviceProvider, requiredExtensions.Values); } } if (_savedChanges) { #if VISUALSTUDIO_10_0 ProjectItemGroupElement itemGroup = _originalItemGroup; ProjectRootElement project = _project; #else // VISUALSTUDIO_10_0 BuildItemGroup itemGroup = _originalItemGroup; Microsoft.Build.BuildEngine.Project project = _project; #endif // VISUALSTUDIO_10_0 EnvDTE.ProjectItem projectItem = _projectItem; string sourceFileName = _sourceFileName; Dictionary <string, PseudoBuildItem> pseudoItems = _pseudoItemsByOutputFormat; IDictionary <string, IORMGenerator> generators = #if VISUALSTUDIO_15_0 ORMCustomTool.GetORMGenerators(_serviceProvider); #else ORMCustomTool.ORMGenerators; #endif PseudoBuildItem pseudoItem; string generatorNameData; // The first string is the primary generator, others are the format modifiers, space delimited IVsShell shell; Dictionary <string, IORMGenerator> generatorsWithTargetsByOutputFormat = null; IDictionary <string, ORMCustomToolUtility.GeneratorTargetSet> targetSetsByFormatName = null; foreach (PseudoBuildItem testPseudoItem in pseudoItems.Values) { string primaryGeneratorName; IList <string> generatorTargets; IORMGenerator generator; if (!string.IsNullOrEmpty(generatorNameData = testPseudoItem.CurrentGeneratorNames) && null != (primaryGeneratorName = ORMCustomToolUtility.GetPrimaryGeneratorName(generatorNameData)) && generators.TryGetValue(primaryGeneratorName, out generator) && null != (generatorTargets = generator.GeneratorTargetTypes) && 0 != generatorTargets.Count) { (generatorsWithTargetsByOutputFormat ?? (generatorsWithTargetsByOutputFormat = new Dictionary <string, IORMGenerator>(StringComparer.OrdinalIgnoreCase)))[generator.ProvidesOutputFormat] = generator; } } if (generatorsWithTargetsByOutputFormat != null) { IDictionary <string, GeneratorTarget[]> docTargets = null; EnvDTE.Document projectItemDocument = projectItem.Document; string itemPath; if (projectItemDocument != null) { using (Stream targetsStream = ORMCustomToolUtility.GetDocumentExtension <Stream>(projectItemDocument, "ORMGeneratorTargets", itemPath = projectItem.get_FileNames(0), _serviceProvider)) { if (targetsStream != null) { targetsStream.Seek(0, SeekOrigin.Begin); docTargets = new BinaryFormatter().Deserialize(targetsStream) as IDictionary <string, GeneratorTarget[]>; } } } else if (null != (shell = _serviceProvider.GetService(typeof(SVsShell)) as IVsShell)) { Guid pkgId = typeof(ORMDesignerPackage).GUID; IVsPackage package; if (0 != shell.IsPackageLoaded(ref pkgId, out package) || package == null) { shell.LoadPackage(ref pkgId, out package); } // Temporarily load the document so that the generator targets can be resolved. using (Store store = new ModelLoader(ORMDesignerPackage.ExtensionLoader, true).Load(projectItem.get_FileNames(0))) { docTargets = GeneratorTarget.ConsolidateGeneratorTargets(store as IFrameworkServices); } } // We have generators that care about targets, which means that ExpandGeneratorTargets will // product placeholder targets for these generators even if docTargets is currently null. // This allows the dialog to turn on a generator before the data (or even extension) to feed // it is available in the model and provides a smooth transition in and out of this placeholder // state. It is up to the individual generators to proceed without explicit target data or // to produce a message for the user with instructions on how to add the data to the model. Dictionary <string, string> generatorNamesByOutputFormat = new Dictionary <string, string>(); foreach (KeyValuePair <string, PseudoBuildItem> pair in pseudoItems) { generatorNameData = pair.Value.CurrentGeneratorNames; if (!string.IsNullOrEmpty(generatorNameData)) { generatorNamesByOutputFormat[pair.Key] = ORMCustomToolUtility.GetPrimaryGeneratorName(generatorNameData); } } targetSetsByFormatName = ORMCustomToolUtility.ExpandGeneratorTargets(generatorNamesByOutputFormat, docTargets #if VISUALSTUDIO_15_0 , _serviceProvider #endif // VISUALSTUDIO_15_0 ); } Dictionary <string, BitTracker> processedGeneratorTargets = null; if (targetSetsByFormatName != null) { processedGeneratorTargets = new Dictionary <string, BitTracker>(); foreach (KeyValuePair <string, ORMCustomToolUtility.GeneratorTargetSet> kvp in targetSetsByFormatName) { processedGeneratorTargets[kvp.Key] = new BitTracker(kvp.Value.Instances.Length); } } if (null != itemGroup) { #if VISUALSTUDIO_10_0 Dictionary <string, ProjectItemElement> removedItems = null; foreach (ProjectItemElement item in itemGroup.Items) #else // VISUALSTUDIO_10_0 Dictionary <string, BuildItem> removedItems = null; foreach (BuildItem item in itemGroup) #endif // VISUALSTUDIO_10_0 { string primaryGeneratorName; string outputFormat; IORMGenerator generator; if (null != (primaryGeneratorName = ORMCustomToolUtility.GetPrimaryGeneratorName(item.GetEvaluatedMetadata(ITEMMETADATA_ORMGENERATOR))) && string.Equals(item.GetEvaluatedMetadata(ITEMMETADATA_DEPENDENTUPON), sourceFileName, StringComparison.OrdinalIgnoreCase) && generators.TryGetValue(primaryGeneratorName, out generator) && pseudoItems.TryGetValue(outputFormat = generator.ProvidesOutputFormat, out pseudoItem)) { generatorNameData = pseudoItem.CurrentGeneratorNames; ORMCustomToolUtility.GeneratorTargetSet targetSet = null; BitTracker processedForFormat = default(BitTracker); if (targetSetsByFormatName != null) { if (targetSetsByFormatName.TryGetValue(outputFormat, out targetSet)) { processedForFormat = processedGeneratorTargets[outputFormat]; } } List <PseudoBuildInstance> originalInstances; bool removeInstance = false; if (string.IsNullOrEmpty(generatorNameData)) { // The item is deleted, mark for removal removeInstance = true; } else if (null != (originalInstances = pseudoItem.OriginalInstances)) { for (int i = 0, count = originalInstances.Count; i < count && !removeInstance; ++i) { PseudoBuildInstance instance = originalInstances[i]; if (instance.IsRemoved) { continue; } GeneratorTarget[] targets = instance.OriginalGeneratorTargets; if (targetSet != null) { if (targets == null) { // Remove, if a target set is available then it must be used removeInstance = true; } else { int instanceIndex = targetSet.IndexOfInstance(targets, delegate(int ignoreInstance) { return(processedForFormat[ignoreInstance]); }); if (instanceIndex == -1) { removeInstance = true; } else if (!processedForFormat[instanceIndex]) { if (instance.OriginalGeneratorNames != generatorNameData) { // This is a preexisting item, update its meta information ORMCustomToolUtility.SetItemMetaData(item, ITEMMETADATA_ORMGENERATOR, generatorNameData); } processedForFormat[instanceIndex] = true; processedGeneratorTargets[outputFormat] = processedForFormat; break; } } } else if (targets != null) { // Remove, formatter changed to one that does not use a generator target removeInstance = true; } else if (instance.OriginalGeneratorNames != generatorNameData) { // This is a preexisting item, update its meta information ORMCustomToolUtility.SetItemMetaData(item, ITEMMETADATA_ORMGENERATOR, generatorNameData); } if (removeInstance) { instance.IsRemoved = true; } } } if (removeInstance) { if (removedItems == null) { #if VISUALSTUDIO_10_0 removedItems = new Dictionary <string, ProjectItemElement>(); #else // VISUALSTUDIO_10_0 removedItems = new Dictionary <string, BuildItem>(); #endif // VISUALSTUDIO_10_0 } removedItems[ORMCustomToolUtility.GetItemInclude(item)] = item; } } } if (removedItems != null) { EnvDTE.ProjectItems subItems = projectItem.ProjectItems; #if VISUALSTUDIO_10_0 foreach (KeyValuePair <string, ProjectItemElement> removePair in removedItems) { ProjectItemElement removeItem = removePair.Value; ProjectElementContainer removeFrom; if (null != (removeFrom = removeItem.Parent)) { removeFrom.RemoveChild(removeItem); } #else // VISUALSTUDIO_10_0 foreach (KeyValuePair <string, BuildItem> removePair in removedItems) { project.RemoveItem(removePair.Value); #endif // VISUALSTUDIO_10_0 try { EnvDTE.ProjectItem subItem = subItems.Item(removePair.Key); if (subItem != null) { subItem.Delete(); } } catch (ArgumentException) { // Swallow } } } #if !VISUALSTUDIO_10_0 // Empty item groups remove themselves from the project, we'll need // to recreate below if the group is empty after the remove phase. if (itemGroup.Count == 0) { itemGroup = null; } #endif } // Removes and changes are complete, proceed with adds for any new items string newItemDirectory = null; string projectPath = null; EnvDTE.ProjectItems projectItems = null; string tmpFile = null; // Adding a file to our special item group adds it to the build system. However, // it does not add it to the parallel project system, which is what displays in // the solution explorer. Therefore, we also explicitly add the item to the // project system as well. Unfortunately, this extra add automatically creates // a redundant item (usually in a new item group) for our adding item. Track anything // we add through the project system so that we can remove these redundant items from the // build system when we're done. Dictionary <string, string> sideEffectItemNames = null; try { Action <IORMGenerator, string, ORMCustomToolUtility.GeneratorTargetSet, GeneratorTarget[]> addProjectItem = delegate(IORMGenerator generator, string allGenerators, ORMCustomToolUtility.GeneratorTargetSet targetSet, GeneratorTarget[] targetInstance) { if (itemGroup == null) { #if VISUALSTUDIO_10_0 itemGroup = project.AddItemGroup(); #else itemGroup = project.AddNewItemGroup(); #endif itemGroup.Condition = string.Concat(ITEMGROUP_CONDITIONSTART, _projectItemRelativePath, ITEMGROUP_CONDITIONEND); } if (newItemDirectory == null) { // Initialize general information #if VISUALSTUDIO_10_0 projectPath = project.FullPath; #else projectPath = project.FullFileName; #endif newItemDirectory = Path.GetDirectoryName(new Uri(projectPath).MakeRelativeUri(new Uri((string)projectItem.Properties.Item("LocalPath").Value)).ToString()); projectItems = projectItem.ProjectItems; } string defaultFileName = generator.GetOutputFileDefaultName(sourceFileName); string fileName = targetInstance == null ? defaultFileName : ORMCustomToolUtility.GeneratorTargetSet.DecorateFileName(defaultFileName, targetInstance); string fileRelativePath = Path.Combine(newItemDirectory, fileName); string fileAbsolutePath = string.Concat(new FileInfo(projectPath).DirectoryName, Path.DirectorySeparatorChar, fileRelativePath); #if VISUALSTUDIO_10_0 ProjectItemElement newBuildItem; #else BuildItem newBuildItem; #endif newBuildItem = generator.AddGeneratedFileItem(itemGroup, sourceFileName, fileRelativePath); if (allGenerators != null) { ORMCustomToolUtility.SetItemMetaData(newBuildItem, ITEMMETADATA_ORMGENERATOR, allGenerators); } if (targetInstance != null) { ORMCustomToolUtility.SetGeneratorTargetMetadata(newBuildItem, targetInstance); } (sideEffectItemNames ?? (sideEffectItemNames = new Dictionary <string, string>()))[fileRelativePath] = null; if (File.Exists(fileAbsolutePath)) { try { projectItems.AddFromFile(fileAbsolutePath); } catch (ArgumentException) { // Swallow } } else { if (tmpFile == null) { tmpFile = Path.GetTempFileName(); } EnvDTE.ProjectItem newProjectItem = projectItems.AddFromTemplate(tmpFile, fileName); string customTool; if (!string.IsNullOrEmpty(customTool = newBuildItem.GetMetadata(ITEMMETADATA_GENERATOR))) { newProjectItem.Properties.Item("CustomTool").Value = customTool; } } }; foreach (KeyValuePair <string, PseudoBuildItem> keyedPseudoItem in pseudoItems) { pseudoItem = keyedPseudoItem.Value; string allGenerators = pseudoItem.CurrentGeneratorNames; string primaryGenerator = ORMCustomToolUtility.GetPrimaryGeneratorName(allGenerators); if (allGenerators == primaryGenerator) { allGenerators = null; } IORMGenerator generator = generators[primaryGenerator]; string outputFormat = generator.ProvidesOutputFormat; ORMCustomToolUtility.GeneratorTargetSet targetSet = null; if (targetSetsByFormatName != null) { targetSetsByFormatName.TryGetValue(outputFormat, out targetSet); } if (targetSet != null) { // OriginalInstances were already updated in the remove loop and processed // instances were flagged. Find additional instances from the target set (created // just now from the current model), not from the pseudoItem (created from the project // files that possibly reflect a previous version of the model). GeneratorTarget[][] instances = targetSet.Instances; BitTracker processed = processedGeneratorTargets[outputFormat]; for (int i = 0, count = instances.Length; i < count; ++i) { if (!processed[i]) { addProjectItem(generator, allGenerators, targetSet, instances[i]); } } } else if (pseudoItem.OriginalInstances == null) { addProjectItem(generator, allGenerators, null, null); } else { // Make sure there was an original instance that did not have a target set. List <PseudoBuildInstance> originals = pseudoItem.OriginalInstances; int i = 0, count = originals.Count; for (; i < count; ++i) { if (originals[i].OriginalGeneratorTargets == null) { break; } } if (i == count) { addProjectItem(generator, allGenerators, null, null); } } } } finally { if (tmpFile != null) { File.Delete(tmpFile); } } if (sideEffectItemNames != null) { ORMCustomToolUtility.RemoveSideEffectItems(sideEffectItemNames, project, itemGroup); } #if VISUALSTUDIO_10_0 // Old group remove themselves when empty, but this is // not true in the new build system. Clean up as needed. if (itemGroup != null && itemGroup.Items.Count == 0) { project.RemoveChild(itemGroup); } #endif VSLangProj.VSProjectItem vsProjectItem = projectItem.Object as VSLangProj.VSProjectItem; if (vsProjectItem != null) { vsProjectItem.RunCustomTool(); } } base.OnClosed(e); }