1+ <#@ template language="C#" hostspecific="True" #>
2+ <#@ assembly name="System.Xml" #>
3+ <#@ assembly name="EnvDTE" #>
4+ <#@ assembly name="Microsoft.VisualStudio.OLE.Interop" #>
5+ <#@ assembly name="Microsoft.VisualStudio.Shell" #>
6+ <#@ assembly name="Microsoft.VisualStudio.Shell.Interop" #>
7+ <#@ assembly name="Microsoft.VisualStudio.Shell.Interop.8.0" #>
8+ <#@ import namespace="System.Collections.Generic" #>
9+ <#@ import namespace="System.Diagnostics" #>
10+ <#@ import namespace="System.IO" #>
11+ <#@ import namespace="System.Text" #>
12+ <#@ import namespace="System.Xml" #>
13+ <#@ import namespace="Microsoft.VisualStudio.Shell" #>
14+ <#@ import namespace="Microsoft.VisualStudio.Shell.Interop" #>
15+ <#@ import namespace="Microsoft.VisualStudio.TextTemplating" #>
16+ <#+
17+ List<string> __savedOutputs = new List<string>();
18+ Engine __engine = new Engine();
19+
20+ void DeleteOldOutputs()
21+ {
22+ EnvDTE.ProjectItem templateProjectItem = __getTemplateProjectItem();
23+ foreach (EnvDTE.ProjectItem childProjectItem in templateProjectItem.ProjectItems)
24+ {
25+ if (!__savedOutputs.Contains(childProjectItem.Name))
26+ childProjectItem.Delete();
27+ }
28+ }
29+
30+
31+
32+
33+ void ProcessTemplate(string templateFileName, string outputFileName)
34+ {
35+ string templateDirectory = Path.GetDirectoryName(Host.TemplateFile);
36+
37+ string outputFilePath = Path.Combine(templateDirectory, outputFileName);
38+
39+
40+ string template = File.ReadAllText(Host.ResolvePath(templateFileName));
41+ string output = __engine.ProcessTemplate(template, Host);
42+ File.WriteAllText(outputFilePath, output);
43+
44+ EnvDTE.ProjectItem templateProjectItem = __getTemplateProjectItem();
45+ templateProjectItem.ProjectItems.AddFromFile(outputFilePath);
46+
47+ __savedOutputs.Add(outputFilePath);
48+ }
49+
50+ void SaveOutput(string outputFileName)
51+ {
52+ string templateDirectory = Path.GetDirectoryName(Host.TemplateFile);
53+
54+ string outputFilePath = Path.Combine(templateDirectory, outputFileName);
55+
56+
57+ File.WriteAllText(outputFilePath, this.GenerationEnvironment.ToString());
58+ this.GenerationEnvironment = new StringBuilder();
59+
60+ EnvDTE.ProjectItem templateProjectItem = __getTemplateProjectItem();
61+ templateProjectItem.ProjectItems.AddFromFile(outputFilePath);
62+
63+ __savedOutputs.Add(outputFilePath);
64+ }
65+
66+ EnvDTE.ProjectItem __getTemplateProjectItem()
67+ {
68+ EnvDTE.Project dteProject = __getTemplateProject();
69+
70+ IVsProject vsProject = __dteProjectToVsProject(dteProject);
71+
72+ int iFound = 0;
73+ uint itemId = 0;
74+ VSDOCUMENTPRIORITY[] pdwPriority = new VSDOCUMENTPRIORITY[1];
75+ int result = vsProject.IsDocumentInProject(Host.TemplateFile, out iFound, pdwPriority, out itemId);
76+ if (result != VSConstants.S_OK)
77+ throw new Exception("Unexpected error calling IVsProject.IsDocumentInProject");
78+ if (iFound == 0)
79+ throw new Exception("Cannot retrieve ProjectItem for template file");
80+ if (itemId == 0)
81+ throw new Exception("Cannot retrieve ProjectItem for template file");
82+
83+ Microsoft.VisualStudio.OLE.Interop.IServiceProvider itemContext = null;
84+ result = vsProject.GetItemContext(itemId, out itemContext);
85+ if (result != VSConstants.S_OK)
86+ throw new Exception("Unexpected error calling IVsProject.GetItemContext");
87+ if (itemContext == null)
88+ throw new Exception("IVsProject.GetItemContext returned null");
89+
90+ ServiceProvider itemContextService = new ServiceProvider(itemContext);
91+ EnvDTE.ProjectItem templateItem = (EnvDTE.ProjectItem)itemContextService.GetService(typeof(EnvDTE.ProjectItem));
92+ Debug.Assert(templateItem != null, "itemContextService.GetService returned null");
93+
94+ return templateItem;
95+ }
96+
97+ EnvDTE.Project __getTemplateProject()
98+ {
99+ IServiceProvider hostServiceProvider = (IServiceProvider)Host;
100+ if (hostServiceProvider == null)
101+ throw new Exception("Host property returned unexpected value (null)");
102+
103+ EnvDTE.DTE dte = (EnvDTE.DTE)hostServiceProvider.GetService(typeof(EnvDTE.DTE));
104+ if (dte == null)
105+ throw new Exception("Unable to retrieve EnvDTE.DTE");
106+
107+ Array activeSolutionProjects = (Array)dte.ActiveSolutionProjects;
108+ if (activeSolutionProjects == null)
109+ throw new Exception("DTE.ActiveSolutionProjects returned null");
110+
111+ EnvDTE.Project dteProject = (EnvDTE.Project)activeSolutionProjects.GetValue(0);
112+ if (dteProject == null)
113+ throw new Exception("DTE.ActiveSolutionProjects[0] returned null");
114+
115+ return dteProject;
116+ }
117+
118+ static IVsProject __dteProjectToVsProject(EnvDTE.Project project)
119+ {
120+ if (project == null)
121+ throw new ArgumentNullException("project");
122+
123+ string projectGuid = null;
124+
125+ // DTE does not expose the project GUId that exists at in the msbuild project file.
126+ // Cannot use MSBuild object model because it uses a static instance of the Engine,
127+ // and using the Project will cause it to be unloaded from the engine when the
128+ // GC collects the variable that we declare.
129+ using (XmlReader projectReader = XmlReader.Create(project.FileName))
130+ {
131+ projectReader.MoveToContent();
132+ object nodeName = projectReader.NameTable.Add("ProjectGuid");
133+ while (projectReader.Read())
134+ {
135+ if (Object.Equals(projectReader.LocalName, nodeName))
136+ {
137+ projectGuid = (string)projectReader.ReadElementContentAsString();
138+ break;
139+ }
140+ }
141+ }
142+ if (string.IsNullOrEmpty(projectGuid))
143+ throw new Exception("Unable to find ProjectGuid element in the project file");
144+
145+ Microsoft.VisualStudio.OLE.Interop.IServiceProvider dteServiceProvider =
146+ (Microsoft.VisualStudio.OLE.Interop.IServiceProvider)project.DTE;
147+ IServiceProvider serviceProvider = new ServiceProvider(dteServiceProvider);
148+ IVsHierarchy vsHierarchy = VsShellUtilities.GetHierarchy(serviceProvider, new Guid(projectGuid));
149+
150+ IVsProject vsProject = (IVsProject)vsHierarchy;
151+ if (vsProject == null)
152+ throw new ArgumentException("Project is not a VS project.");
153+ return vsProject;
154+ }
155+ #>
0 commit comments