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