aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Prebuild/src/Core/Targets/VSGenericTarget.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Prebuild/src/Core/Targets/VSGenericTarget.cs')
-rw-r--r--Prebuild/src/Core/Targets/VSGenericTarget.cs619
1 files changed, 327 insertions, 292 deletions
diff --git a/Prebuild/src/Core/Targets/VSGenericTarget.cs b/Prebuild/src/Core/Targets/VSGenericTarget.cs
index fdcc2b9..cd3f5bb 100644
--- a/Prebuild/src/Core/Targets/VSGenericTarget.cs
+++ b/Prebuild/src/Core/Targets/VSGenericTarget.cs
@@ -5,32 +5,27 @@ Copyright (c) 2008 Matthew Holmes (matthew@wildfiregames.com), John Anderson (so
5Redistribution and use in source and binary forms, with or without modification, are permitted 5Redistribution and use in source and binary forms, with or without modification, are permitted
6provided that the following conditions are met: 6provided that the following conditions are met:
7 7
8* Redistributions of source code must retain the above copyright notice, this list of conditions 8 * Redistributions of source code must retain the above copyright notice, this list of conditions
9 and the following disclaimer. 9 and the following disclaimer.
10* Redistributions in binary form must reproduce the above copyright notice, this list of conditions 10 * Redistributions in binary form must reproduce the above copyright notice, this list of conditions
11 and the following disclaimer in the documentation and/or other materials provided with the 11 and the following disclaimer in the documentation and/or other materials provided with the
12 distribution. 12 distribution.
13* The name of the author may not be used to endorse or promote products derived from this software 13 * The name of the author may not be used to endorse or promote products derived from this software
14 without specific prior written permission. 14 without specific prior written permission.
15 15
16THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 16THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
17BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 20OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 21OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
22IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 22IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23*/ 23 */
24#endregion 24#endregion
25 25
26using System; 26using System;
27using System.Collections;
28using System.Collections.Generic; 27using System.Collections.Generic;
29using System.Collections.Specialized;
30using System.IO; 28using System.IO;
31using System.Text;
32
33using Prebuild.Core.Attributes;
34using Prebuild.Core.Interfaces; 29using Prebuild.Core.Interfaces;
35using Prebuild.Core.Nodes; 30using Prebuild.Core.Nodes;
36using Prebuild.Core.Utilities; 31using Prebuild.Core.Utilities;
@@ -46,59 +41,59 @@ namespace Prebuild.Core.Targets
46 { 41 {
47 #region Fields 42 #region Fields
48 43
49 readonly Hashtable tools = new Hashtable(); 44 readonly Dictionary<string, ToolInfo> tools = new Dictionary<string, ToolInfo>();
50 Kernel kernel; 45 Kernel kernel;
51 #endregion 46 #endregion
52 47
53 #region Properties 48 #region Properties
54 /// <summary> 49 /// <summary>
55 /// Gets or sets the solution version. 50 /// Gets or sets the solution version.
56 /// </summary> 51 /// </summary>
57 /// <value>The solution version.</value> 52 /// <value>The solution version.</value>
58 public abstract string SolutionVersion { get; } 53 public abstract string SolutionVersion { get; }
59 /// <summary> 54 /// <summary>
60 /// Gets or sets the product version. 55 /// Gets or sets the product version.
61 /// </summary> 56 /// </summary>
62 /// <value>The product version.</value> 57 /// <value>The product version.</value>
63 public abstract string ProductVersion { get; } 58 public abstract string ProductVersion { get; }
64 /// <summary> 59 /// <summary>
65 /// Gets or sets the schema version. 60 /// Gets or sets the schema version.
66 /// </summary> 61 /// </summary>
67 /// <value>The schema version.</value> 62 /// <value>The schema version.</value>
68 public abstract string SchemaVersion { get; } 63 public abstract string SchemaVersion { get; }
69 /// <summary> 64 /// <summary>
70 /// Gets or sets the name of the version. 65 /// Gets or sets the name of the version.
71 /// </summary> 66 /// </summary>
72 /// <value>The name of the version.</value> 67 /// <value>The name of the version.</value>
73 public abstract string VersionName { get; } 68 public abstract string VersionName { get; }
74 /// <summary> 69 /// <summary>
75 /// Gets or sets the version. 70 /// Gets or sets the version.
76 /// </summary> 71 /// </summary>
77 /// <value>The version.</value> 72 /// <value>The version.</value>
78 public abstract VSVersion Version { get; } 73 public abstract VSVersion Version { get; }
79 /// <summary> 74 /// <summary>
80 /// Gets the name. 75 /// Gets the name.
81 /// </summary> 76 /// </summary>
82 /// <value>The name.</value> 77 /// <value>The name.</value>
83 public abstract string Name { get; } 78 public abstract string Name { get; }
84 79
85 protected abstract string GetToolsVersionXml(FrameworkVersion version); 80 protected abstract string GetToolsVersionXml(FrameworkVersion version);
86 public abstract string SolutionTag { get; } 81 public abstract string SolutionTag { get; }
87 82
88 #endregion 83 #endregion
89 84
90 #region Constructors 85 #region Constructors
91 86
92 /// <summary> 87 /// <summary>
93 /// Initializes a new instance of the <see cref="VSGenericTarget"/> class. 88 /// Initializes a new instance of the <see cref="VSGenericTarget"/> class.
94 /// </summary> 89 /// </summary>
95 protected VSGenericTarget() 90 protected VSGenericTarget()
96 { 91 {
97 this.tools["C#"] = new ToolInfo("C#", "{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}", "csproj", "CSHARP", "$(MSBuildBinPath)\\Microsoft.CSHARP.Targets"); 92 tools["C#"] = new ToolInfo("C#", "{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}", "csproj", "CSHARP", "$(MSBuildBinPath)\\Microsoft.CSHARP.Targets");
98 this.tools["Database"] = new ToolInfo("Database", "{4F174C21-8C12-11D0-8340-0000F80270F8}", "dbp", "UNKNOWN"); 93 tools["Database"] = new ToolInfo("Database", "{4F174C21-8C12-11D0-8340-0000F80270F8}", "dbp", "UNKNOWN");
99 this.tools["Boo"] = new ToolInfo("Boo", "{45CEA7DC-C2ED-48A6-ACE0-E16144C02365}", "booproj", "Boo", "$(BooBinPath)\\Boo.Microsoft.Build.targets"); 94 tools["Boo"] = new ToolInfo("Boo", "{45CEA7DC-C2ED-48A6-ACE0-E16144C02365}", "booproj", "Boo", "$(BooBinPath)\\Boo.Microsoft.Build.targets");
100 this.tools["VisualBasic"] = new ToolInfo("VisualBasic", "{F184B08F-C81C-45F6-A57F-5ABD9991F28F}", "vbproj", "VisualBasic", "$(MSBuildBinPath)\\Microsoft.VisualBasic.Targets"); 95 tools["VisualBasic"] = new ToolInfo("VisualBasic", "{F184B08F-C81C-45F6-A57F-5ABD9991F28F}", "vbproj", "VisualBasic", "$(MSBuildBinPath)\\Microsoft.VisualBasic.Targets");
101 this.tools["Folder"] = new ToolInfo("Folder", "{2150E333-8FDC-42A3-9474-1A3956D46DE8}", null, null); 96 tools["Folder"] = new ToolInfo("Folder", "{2150E333-8FDC-42A3-9474-1A3956D46DE8}", null, null);
102 } 97 }
103 98
104 #endregion 99 #endregion
@@ -124,7 +119,7 @@ namespace Prebuild.Core.Targets
124 } 119 }
125 catch (ArgumentException) 120 catch (ArgumentException)
126 { 121 {
127 this.kernel.Log.Write(LogType.Warning, "Could not resolve reference path: {0}", node.Path); 122 kernel.Log.Write(LogType.Warning, "Could not resolve reference path: {0}", node.Path);
128 } 123 }
129 } 124 }
130 125
@@ -144,7 +139,7 @@ namespace Prebuild.Core.Targets
144 private static ProjectNode FindProjectInSolutionRecursively(string name, SolutionNode solution) 139 private static ProjectNode FindProjectInSolutionRecursively(string name, SolutionNode solution)
145 { 140 {
146 if (solution.ProjectsTable.ContainsKey(name)) 141 if (solution.ProjectsTable.ContainsKey(name))
147 return (ProjectNode)solution.ProjectsTable[name]; 142 return solution.ProjectsTable[name];
148 143
149 foreach (SolutionNode child in solution.Solutions) 144 foreach (SolutionNode child in solution.Solutions)
150 { 145 {
@@ -163,7 +158,7 @@ namespace Prebuild.Core.Targets
163 throw new UnknownLanguageException("Unknown .NET language: " + project.Language); 158 throw new UnknownLanguageException("Unknown .NET language: " + project.Language);
164 } 159 }
165 160
166 ToolInfo toolInfo = (ToolInfo)tools[project.Language]; 161 ToolInfo toolInfo = tools[project.Language];
167 string projectFile = Helper.MakeFilePath(project.FullPath, project.Name, toolInfo.FileExtension); 162 string projectFile = Helper.MakeFilePath(project.FullPath, project.Name, toolInfo.FileExtension);
168 StreamWriter ps = new StreamWriter(projectFile); 163 StreamWriter ps = new StreamWriter(projectFile);
169 164
@@ -173,83 +168,83 @@ namespace Prebuild.Core.Targets
173 #region Project File 168 #region Project File
174 using (ps) 169 using (ps)
175 { 170 {
176 ps.WriteLine("<Project DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\" ToolsVersion=\"{0}\">", this.Version == VSVersion.VS10 ? "4.0" : "3.5"); 171 ps.WriteLine("<Project DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\" {0}>", GetToolsVersionXml(project.FrameworkVersion));
177 ps.WriteLine(" <PropertyGroup>"); 172 ps.WriteLine(" <PropertyGroup>");
178 ps.WriteLine(" <ProjectType>Local</ProjectType>"); 173 ps.WriteLine(" <ProjectType>Local</ProjectType>");
179 ps.WriteLine(" <ProductVersion>{0}</ProductVersion>", this.ProductVersion); 174 ps.WriteLine(" <ProductVersion>{0}</ProductVersion>", ProductVersion);
180 ps.WriteLine(" <SchemaVersion>{0}</SchemaVersion>", this.SchemaVersion); 175 ps.WriteLine(" <SchemaVersion>{0}</SchemaVersion>", SchemaVersion);
181 ps.WriteLine(" <ProjectGuid>{{{0}}}</ProjectGuid>", project.Guid.ToString().ToUpper()); 176 ps.WriteLine(" <ProjectGuid>{{{0}}}</ProjectGuid>", project.Guid.ToString().ToUpper());
182 177
183 // Visual Studio has a hard coded guid for the project type 178 // Visual Studio has a hard coded guid for the project type
184 if (project.Type == ProjectType.Web) 179 if (project.Type == ProjectType.Web)
185 ps.WriteLine(" <ProjectTypeGuids>{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>"); 180 ps.WriteLine(" <ProjectTypeGuids>{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>");
186 ps.WriteLine(" <Configuration Condition=\" '$(Configuration)' == '' \">Debug</Configuration>"); 181 ps.WriteLine(" <Configuration Condition=\" '$(Configuration)' == '' \">Debug</Configuration>");
187 ps.WriteLine(" <Platform Condition=\" '$(Platform)' == '' \">AnyCPU</Platform>"); 182 ps.WriteLine(" <ApplicationIcon>{0}</ApplicationIcon>", project.AppIcon);
188 ps.WriteLine(" <ApplicationIcon>{0}</ApplicationIcon>", project.AppIcon); 183 ps.WriteLine(" <AssemblyKeyContainerName>");
189 ps.WriteLine(" <AssemblyKeyContainerName>"); 184 ps.WriteLine(" </AssemblyKeyContainerName>");
190 ps.WriteLine(" </AssemblyKeyContainerName>"); 185 ps.WriteLine(" <AssemblyName>{0}</AssemblyName>", project.AssemblyName);
191 ps.WriteLine(" <AssemblyName>{0}</AssemblyName>", project.AssemblyName);
192 foreach (ConfigurationNode conf in project.Configurations) 186 foreach (ConfigurationNode conf in project.Configurations)
193 { 187 {
194 if (conf.Options.KeyFile != "") 188 if (conf.Options.KeyFile != "")
195 { 189 {
196 ps.WriteLine(" <AssemblyOriginatorKeyFile>{0}</AssemblyOriginatorKeyFile>", conf.Options.KeyFile); 190 ps.WriteLine(" <AssemblyOriginatorKeyFile>{0}</AssemblyOriginatorKeyFile>", conf.Options.KeyFile);
197 ps.WriteLine(" <SignAssembly>true</SignAssembly>"); 191 ps.WriteLine(" <SignAssembly>true</SignAssembly>");
198 break; 192 break;
199 } 193 }
200 } 194 }
201 ps.WriteLine(" <DefaultClientScript>JScript</DefaultClientScript>"); 195 ps.WriteLine(" <DefaultClientScript>JScript</DefaultClientScript>");
202 ps.WriteLine(" <DefaultHTMLPageLayout>Grid</DefaultHTMLPageLayout>"); 196 ps.WriteLine(" <DefaultHTMLPageLayout>Grid</DefaultHTMLPageLayout>");
203 ps.WriteLine(" <DefaultTargetSchema>IE50</DefaultTargetSchema>"); 197 ps.WriteLine(" <DefaultTargetSchema>IE50</DefaultTargetSchema>");
204 ps.WriteLine(" <DelaySign>false</DelaySign>"); 198 ps.WriteLine(" <DelaySign>false</DelaySign>");
205 ps.WriteLine(" <TargetFrameworkVersion>{0}</TargetFrameworkVersion>", project.FrameworkVersion.ToString().Replace("_", ".")); 199 ps.WriteLine(" <TargetFrameworkVersion>{0}</TargetFrameworkVersion>", project.FrameworkVersion.ToString().Replace("_", "."));
206 200
207 ps.WriteLine(" <OutputType>{0}</OutputType>", project.Type == ProjectType.Web ? ProjectType.Library.ToString() : project.Type.ToString()); 201 ps.WriteLine(" <OutputType>{0}</OutputType>", project.Type == ProjectType.Web ? ProjectType.Library.ToString() : project.Type.ToString());
208 ps.WriteLine(" <AppDesignerFolder>{0}</AppDesignerFolder>", project.DesignerFolder); 202 ps.WriteLine(" <AppDesignerFolder>{0}</AppDesignerFolder>", project.DesignerFolder);
209 ps.WriteLine(" <RootNamespace>{0}</RootNamespace>", project.RootNamespace); 203 ps.WriteLine(" <RootNamespace>{0}</RootNamespace>", project.RootNamespace);
210 ps.WriteLine(" <StartupObject>{0}</StartupObject>", project.StartupObject); 204 ps.WriteLine(" <StartupObject>{0}</StartupObject>", project.StartupObject);
211 if (string.IsNullOrEmpty(project.DebugStartParameters)) 205 if (string.IsNullOrEmpty(project.DebugStartParameters))
212 { 206 {
213 ps.WriteLine(" <StartArguments>{0}</StartArguments>", project.DebugStartParameters); 207 ps.WriteLine(" <StartArguments>{0}</StartArguments>", project.DebugStartParameters);
214 } 208 }
215 ps.WriteLine(" <FileUpgradeFlags>"); 209 ps.WriteLine(" <FileUpgradeFlags>");
216 ps.WriteLine(" </FileUpgradeFlags>"); 210 ps.WriteLine(" </FileUpgradeFlags>");
217 211
218 ps.WriteLine(" </PropertyGroup>"); 212 ps.WriteLine(" </PropertyGroup>");
219 213
220 foreach (ConfigurationNode conf in project.Configurations) 214 foreach (ConfigurationNode conf in project.Configurations)
221 { 215 {
222 ps.Write(" <PropertyGroup "); 216 ps.Write(" <PropertyGroup ");
223 ps.WriteLine("Condition=\" '$(Configuration)|$(Platform)' == '{0}|AnyCPU' \">", conf.Name); 217 ps.WriteLine("Condition=\" '$(Configuration)|$(Platform)' == '{0}|{1}' \">", conf.Name, conf.Platform);
224 ps.WriteLine(" <AllowUnsafeBlocks>{0}</AllowUnsafeBlocks>", conf.Options["AllowUnsafe"]); 218 ps.WriteLine(" <AllowUnsafeBlocks>{0}</AllowUnsafeBlocks>", conf.Options["AllowUnsafe"]);
225 ps.WriteLine(" <BaseAddress>{0}</BaseAddress>", conf.Options["BaseAddress"]); 219 ps.WriteLine(" <BaseAddress>{0}</BaseAddress>", conf.Options["BaseAddress"]);
226 ps.WriteLine(" <CheckForOverflowUnderflow>{0}</CheckForOverflowUnderflow>", conf.Options["CheckUnderflowOverflow"]); 220 ps.WriteLine(" <CheckForOverflowUnderflow>{0}</CheckForOverflowUnderflow>", conf.Options["CheckUnderflowOverflow"]);
227 ps.WriteLine(" <ConfigurationOverrideFile>"); 221 ps.WriteLine(" <ConfigurationOverrideFile>");
228 ps.WriteLine(" </ConfigurationOverrideFile>"); 222 ps.WriteLine(" </ConfigurationOverrideFile>");
229 ps.WriteLine(" <DefineConstants>{0}</DefineConstants>", conf.Options["CompilerDefines"]); 223 ps.WriteLine(" <DefineConstants>{0}</DefineConstants>", conf.Options["CompilerDefines"]);
230 ps.WriteLine(" <DocumentationFile>{0}</DocumentationFile>", Helper.NormalizePath(conf.Options["XmlDocFile"].ToString())); 224 ps.WriteLine(" <DocumentationFile>{0}</DocumentationFile>", Helper.NormalizePath(conf.Options["XmlDocFile"].ToString()));
231 ps.WriteLine(" <DebugSymbols>{0}</DebugSymbols>", conf.Options["DebugInformation"]); 225 ps.WriteLine(" <DebugSymbols>{0}</DebugSymbols>", conf.Options["DebugInformation"]);
232 ps.WriteLine(" <FileAlignment>{0}</FileAlignment>", conf.Options["FileAlignment"]); 226 ps.WriteLine(" <FileAlignment>{0}</FileAlignment>", conf.Options["FileAlignment"]);
233 ps.WriteLine(" <Optimize>{0}</Optimize>", conf.Options["OptimizeCode"]); 227 ps.WriteLine(" <Optimize>{0}</Optimize>", conf.Options["OptimizeCode"]);
234 if (project.Type != ProjectType.Web) 228 if (project.Type != ProjectType.Web)
235 ps.WriteLine(" <OutputPath>{0}</OutputPath>", 229 ps.WriteLine(" <OutputPath>{0}</OutputPath>",
236 Helper.EndPath(Helper.NormalizePath(conf.Options["OutputPath"].ToString()))); 230 Helper.EndPath(Helper.NormalizePath(conf.Options["OutputPath"].ToString())));
237 else 231 else
238 ps.WriteLine(" <OutputPath>{0}</OutputPath>", 232 ps.WriteLine(" <OutputPath>{0}</OutputPath>",
239 Helper.EndPath(Helper.NormalizePath("bin\\"))); 233 Helper.EndPath(Helper.NormalizePath("bin\\")));
240 234
241 ps.WriteLine(" <RegisterForComInterop>{0}</RegisterForComInterop>", conf.Options["RegisterComInterop"]); 235 ps.WriteLine(" <RegisterForComInterop>{0}</RegisterForComInterop>", conf.Options["RegisterComInterop"]);
242 ps.WriteLine(" <RemoveIntegerChecks>{0}</RemoveIntegerChecks>", conf.Options["RemoveIntegerChecks"]); 236 ps.WriteLine(" <RemoveIntegerChecks>{0}</RemoveIntegerChecks>", conf.Options["RemoveIntegerChecks"]);
243 ps.WriteLine(" <TreatWarningsAsErrors>{0}</TreatWarningsAsErrors>", conf.Options["WarningsAsErrors"]); 237 ps.WriteLine(" <TreatWarningsAsErrors>{0}</TreatWarningsAsErrors>", conf.Options["WarningsAsErrors"]);
244 ps.WriteLine(" <WarningLevel>{0}</WarningLevel>", conf.Options["WarningLevel"]); 238 ps.WriteLine(" <WarningLevel>{0}</WarningLevel>", conf.Options["WarningLevel"]);
245 ps.WriteLine(" <NoStdLib>{0}</NoStdLib>", conf.Options["NoStdLib"]); 239 ps.WriteLine(" <NoStdLib>{0}</NoStdLib>", conf.Options["NoStdLib"]);
246 ps.WriteLine(" <NoWarn>{0}</NoWarn>", conf.Options["SuppressWarnings"]); 240 ps.WriteLine(" <NoWarn>{0}</NoWarn>", conf.Options["SuppressWarnings"]);
247 ps.WriteLine(" </PropertyGroup>"); 241 ps.WriteLine(" <PlatformTarget>{0}</PlatformTarget>", conf.Platform);
242 ps.WriteLine(" </PropertyGroup>");
248 } 243 }
249 244
250 //ps.WriteLine(" </Settings>"); 245 //ps.WriteLine(" </Settings>");
251 246
252 List<ProjectNode> projectReferences = new List<ProjectNode>(); 247 Dictionary<ReferenceNode, ProjectNode> projectReferences = new Dictionary<ReferenceNode, ProjectNode>();
253 List<ReferenceNode> otherReferences = new List<ReferenceNode>(); 248 List<ReferenceNode> otherReferences = new List<ReferenceNode>();
254 249
255 foreach (ReferenceNode refr in project.References) 250 foreach (ReferenceNode refr in project.References)
@@ -259,57 +254,75 @@ namespace Prebuild.Core.Targets
259 if (projectNode == null) 254 if (projectNode == null)
260 otherReferences.Add(refr); 255 otherReferences.Add(refr);
261 else 256 else
262 projectReferences.Add(projectNode); 257 projectReferences.Add(refr, projectNode);
263 } 258 }
264 // Assembly References 259 // Assembly References
265 ps.WriteLine(" <ItemGroup>"); 260 ps.WriteLine(" <ItemGroup>");
266 261
267 foreach (ReferenceNode refr in otherReferences) 262 foreach (ReferenceNode refr in otherReferences)
268 { 263 {
269 ps.Write(" <Reference"); 264 ps.Write(" <Reference");
270 ps.Write(" Include=\""); 265 ps.Write(" Include=\"");
271 ps.Write(refr.Name); 266 ps.Write(refr.Name);
272 ps.WriteLine("\" >"); 267 ps.WriteLine("\" >");
273 ps.Write(" <Name>"); 268 ps.Write(" <Name>");
274 ps.Write(refr.Name); 269 ps.Write(refr.Name);
275 ps.WriteLine("</Name>"); 270 ps.WriteLine("</Name>");
276 // TODO: Allow reference to *.exe files 271
277 ps.WriteLine(" <Private>{0}</Private>", refr.LocalCopy); 272 if(!String.IsNullOrEmpty(refr.Path))
278 ps.WriteLine(" </Reference>"); 273 {
274 // Use absolute path to assembly (for determining assembly type)
275 string absolutePath = Path.Combine(project.FullPath, refr.Path);
276 if(File.Exists(Helper.MakeFilePath(absolutePath, refr.Name, "exe"))) {
277 // Assembly is an executable (exe)
278 ps.WriteLine(" <HintPath>{0}</HintPath>", Helper.MakeFilePath(refr.Path, refr.Name, "exe"));
279 } else if(File.Exists(Helper.MakeFilePath(absolutePath, refr.Name, "dll"))) {
280 // Assembly is an library (dll)
281 ps.WriteLine(" <HintPath>{0}</HintPath>", Helper.MakeFilePath(refr.Path, refr.Name, "dll"));
282 } else {
283 string referencePath = Helper.MakeFilePath(refr.Path, refr.Name, "dll");
284 kernel.Log.Write(LogType.Warning, "Reference \"{0}\": The specified file doesn't exist.", referencePath);
285 ps.WriteLine(" <HintPath>{0}</HintPath>", Helper.MakeFilePath(refr.Path, refr.Name, "dll"));
286 }
287 }
288
289 ps.WriteLine(" <Private>{0}</Private>", refr.LocalCopy);
290 ps.WriteLine(" </Reference>");
279 } 291 }
280 ps.WriteLine(" </ItemGroup>"); 292 ps.WriteLine(" </ItemGroup>");
281 293
282 //Project References 294 //Project References
283 ps.WriteLine(" <ItemGroup>"); 295 ps.WriteLine(" <ItemGroup>");
284 foreach (ProjectNode projectReference in projectReferences) 296 foreach (KeyValuePair<ReferenceNode, ProjectNode> pair in projectReferences)
285 { 297 {
286 ToolInfo tool = (ToolInfo)tools[projectReference.Language]; 298 ToolInfo tool = tools[pair.Value.Language];
287 if (tools == null) 299 if (tools == null)
288 throw new UnknownLanguageException(); 300 throw new UnknownLanguageException();
289 301
290 string path = 302 string path =
291 Helper.MakePathRelativeTo(project.FullPath, 303 Helper.MakePathRelativeTo(project.FullPath,
292 Helper.MakeFilePath(projectReference.FullPath, projectReference.Name, tool.FileExtension)); 304 Helper.MakeFilePath(pair.Value.FullPath, pair.Value.Name, tool.FileExtension));
293 ps.WriteLine(" <ProjectReference Include=\"{0}\">", path); 305 ps.WriteLine(" <ProjectReference Include=\"{0}\">", path);
294 306
295 // TODO: Allow reference to visual basic projects 307 // TODO: Allow reference to visual basic projects
296 ps.WriteLine(" <Name>{0}</Name>", projectReference.Name); 308 ps.WriteLine(" <Name>{0}</Name>", pair.Value.Name);
297 ps.WriteLine(" <Project>{0}</Project>", projectReference.Guid.ToString("B").ToUpper()); 309 ps.WriteLine(" <Project>{0}</Project>", pair.Value.Guid.ToString("B").ToUpper());
298 ps.WriteLine(" <Package>{0}</Package>", tool.Guid.ToUpper()); 310 ps.WriteLine(" <Package>{0}</Package>", tool.Guid.ToUpper());
299 311
300 ps.WriteLine(" <Private>False</Private>" ); 312 //This is the Copy Local flag in VS
313 ps.WriteLine(" <Private>{0}</Private>", pair.Key.LocalCopy);
301 314
302 ps.WriteLine(" </ProjectReference>"); 315 ps.WriteLine(" </ProjectReference>");
303 } 316 }
304 ps.WriteLine(" </ItemGroup>"); 317 ps.WriteLine(" </ItemGroup>");
305 318
306 // ps.WriteLine(" </Build>"); 319 // ps.WriteLine(" </Build>");
307 ps.WriteLine(" <ItemGroup>"); 320 ps.WriteLine(" <ItemGroup>");
308 321
309 // ps.WriteLine(" <Include>"); 322 // ps.WriteLine(" <Include>");
310 List<string> list = new List<string>(); 323 List<string> list = new List<string>();
311 324
312 foreach (string path in project.Files) 325 foreach (string path in project.Files)
313 { 326 {
314 string lower = path.ToLower(); 327 string lower = path.ToLower();
315 if (lower.EndsWith(".resx")) 328 if (lower.EndsWith(".resx"))
@@ -318,93 +331,106 @@ namespace Prebuild.Core.Targets
318 if (!list.Contains(codebehind)) 331 if (!list.Contains(codebehind))
319 list.Add(codebehind); 332 list.Add(codebehind);
320 } 333 }
334
321 } 335 }
322 336
323 foreach (string file in project.Files) 337 foreach (string filePath in project.Files)
324 { 338 {
325 // if (file == "Properties\\Bind.Designer.cs") 339 // if (file == "Properties\\Bind.Designer.cs")
326 // { 340 // {
327 // Console.WriteLine("Wait a minute!"); 341 // Console.WriteLine("Wait a minute!");
328 // Console.WriteLine(project.Files.GetSubType(file).ToString()); 342 // Console.WriteLine(project.Files.GetSubType(file).ToString());
329 // } 343 // }
330 344 SubType subType = project.Files.GetSubType(filePath);
331 SubType subType = project.Files.GetSubType(file); 345
346 // Visual Studio chokes on file names if forward slash is used as a path separator
347 // instead of backslash. So we must make sure that all file paths written to the
348 // project file use \ as a path separator.
349 string file = filePath.Replace(@"/", @"\");
332 350
333 if (subType != SubType.Code && subType != SubType.Settings && subType != SubType.Designer 351 if (subType != SubType.Code && subType != SubType.Settings && subType != SubType.Designer
334 && subType != SubType.CodeBehind) 352 && subType != SubType.CodeBehind)
335 { 353 {
336 ps.WriteLine(" <EmbeddedResource Include=\"{0}\">", file.Substring(0, file.LastIndexOf('.')) + ".resx"); 354 ps.WriteLine(" <EmbeddedResource Include=\"{0}\">", file.Substring(0, file.LastIndexOf('.')) + ".resx");
337 ps.WriteLine(" <DependentUpon>{0}</DependentUpon>", Path.GetFileName(file)); 355 ps.WriteLine(" <DependentUpon>{0}</DependentUpon>", Path.GetFileName(file));
338 ps.WriteLine(" <SubType>Designer</SubType>"); 356 ps.WriteLine(" <SubType>Designer</SubType>");
339 ps.WriteLine(" </EmbeddedResource>"); 357 ps.WriteLine(" </EmbeddedResource>");
340 // 358 //
341 } 359 }
342 360
343 if (subType == SubType.Designer) 361 if (subType == SubType.Designer)
344 { 362 {
345 ps.WriteLine(" <EmbeddedResource Include=\"{0}\">", file); 363 ps.WriteLine(" <EmbeddedResource Include=\"{0}\">", file);
346 ps.WriteLine(" <SubType>" + subType + "</SubType>");
347 ps.WriteLine(" <Generator>ResXFileCodeGenerator</Generator>");
348 364
349 string autogen_name = file.Substring(0, file.LastIndexOf('.')) + ".Designer.cs"; 365 string autogen_name = file.Substring(0, file.LastIndexOf('.')) + ".Designer.cs";
350 string dependent_name = file.Substring(0, file.LastIndexOf('.')) + ".cs"; 366 string dependent_name = filePath.Substring(0, file.LastIndexOf('.')) + ".cs";
351
352 ps.WriteLine(" <LastGenOutput>{0}</LastGenOutput>", autogen_name);
353 367
354 // Check for a parent .cs file with the same name as this designer file 368 // Check for a parent .cs file with the same name as this designer file
355 if (File.Exists(dependent_name)) 369 if (File.Exists(Helper.NormalizePath(dependent_name)))
356 ps.WriteLine(" <DependentUpon>{0}</DependentUpon>", Path.GetFileName(dependent_name)); 370 {
371 ps.WriteLine(" <DependentUpon>{0}</DependentUpon>", Path.GetFileName(dependent_name));
372 }
373 else
374 {
375 ps.WriteLine(" <Generator>ResXFileCodeGenerator</Generator>");
376 ps.WriteLine(" <LastGenOutput>{0}</LastGenOutput>", Path.GetFileName(autogen_name));
377 ps.WriteLine(" <SubType>" + subType + "</SubType>");
378 }
357 379
358 ps.WriteLine(" </EmbeddedResource>"); 380 ps.WriteLine(" </EmbeddedResource>");
359 if (File.Exists(autogen_name)) 381 if (File.Exists(Helper.NormalizePath(autogen_name)))
360 { 382 {
361 ps.WriteLine(" <Compile Include=\"{0}\">", autogen_name); 383 ps.WriteLine(" <Compile Include=\"{0}\">", autogen_name);
362 ps.WriteLine(" <AutoGen>True</AutoGen>"); 384 //ps.WriteLine(" <DesignTime>True</DesignTime>");
363 ps.WriteLine(" <DesignTime>True</DesignTime>"); 385
364 386 // If a parent .cs file exists, link this autogen file to it. Otherwise link
365 // If a parent .cs file exists, link this autogen file to it. Otherwise link 387 // to the designer file
366 // to the designer file 388 if (File.Exists(dependent_name))
367 if (File.Exists(dependent_name)) 389 {
368 ps.WriteLine(" <DependentUpon>{0}</DependentUpon>", Path.GetFileName(dependent_name)); 390 ps.WriteLine(" <DependentUpon>{0}</DependentUpon>", Path.GetFileName(dependent_name));
369 else 391 }
370 ps.WriteLine(" <DependentUpon>{0}</DependentUpon>", Path.GetFileName(file)); 392 else
371 393 {
372 ps.WriteLine(" </Compile>"); 394 ps.WriteLine(" <AutoGen>True</AutoGen>");
395 ps.WriteLine(" <DependentUpon>{0}</DependentUpon>", Path.GetFileName(filePath));
396 }
397
398 ps.WriteLine(" </Compile>");
373 } 399 }
374 list.Add(autogen_name); 400 list.Add(autogen_name);
375 } 401 }
376 if (subType == SubType.Settings) 402 if (subType == SubType.Settings)
377 { 403 {
378 ps.Write(" <{0} ", project.Files.GetBuildAction(file)); 404 ps.Write(" <{0} ", project.Files.GetBuildAction(filePath));
379 ps.WriteLine("Include=\"{0}\">", file); 405 ps.WriteLine("Include=\"{0}\">", file);
380 string fileName = Path.GetFileName(file); 406 string fileName = Path.GetFileName(filePath);
381 if (project.Files.GetBuildAction(file) == BuildAction.None) 407 if (project.Files.GetBuildAction(filePath) == BuildAction.None)
382 { 408 {
383 ps.WriteLine(" <Generator>SettingsSingleFileGenerator</Generator>"); 409 ps.WriteLine(" <Generator>SettingsSingleFileGenerator</Generator>");
384 ps.WriteLine(" <LastGenOutput>{0}</LastGenOutput>", fileName.Substring(0, fileName.LastIndexOf('.')) + ".Designer.cs"); 410 ps.WriteLine(" <LastGenOutput>{0}</LastGenOutput>", fileName.Substring(0, fileName.LastIndexOf('.')) + ".Designer.cs");
385 } 411 }
386 else 412 else
387 { 413 {
388 ps.WriteLine(" <SubType>Code</SubType>"); 414 ps.WriteLine(" <SubType>Code</SubType>");
389 ps.WriteLine(" <AutoGen>True</AutoGen>"); 415 ps.WriteLine(" <AutoGen>True</AutoGen>");
390 ps.WriteLine(" <DesignTimeSharedInput>True</DesignTimeSharedInput>"); 416 ps.WriteLine(" <DesignTimeSharedInput>True</DesignTimeSharedInput>");
391 string fileNameShort = fileName.Substring(0, fileName.LastIndexOf('.')); 417 string fileNameShort = fileName.Substring(0, fileName.LastIndexOf('.'));
392 string fileNameShorter = fileNameShort.Substring(0, fileNameShort.LastIndexOf('.')); 418 string fileNameShorter = fileNameShort.Substring(0, fileNameShort.LastIndexOf('.'));
393 ps.WriteLine(" <DependentUpon>{0}</DependentUpon>", Path.GetFileName(fileNameShorter + ".settings")); 419 ps.WriteLine(" <DependentUpon>{0}</DependentUpon>", Path.GetFileName(fileNameShorter + ".settings"));
394 } 420 }
395 ps.WriteLine(" </{0}>", project.Files.GetBuildAction(file)); 421 ps.WriteLine(" </{0}>", project.Files.GetBuildAction(filePath));
396 } 422 }
397 else if (subType != SubType.Designer) 423 else if (subType != SubType.Designer)
398 { 424 {
399 string path = Helper.NormalizePath(file); 425 string path = Helper.NormalizePath(file);
400 string path_lower = path.ToLower(); 426 string path_lower = path.ToLower();
401 427
402 if (!list.Contains(file)) 428 if (!list.Contains(filePath))
403 { 429 {
404 ps.Write(" <{0} ", project.Files.GetBuildAction(path)); 430 ps.Write(" <{0} ", project.Files.GetBuildAction(filePath));
405 431
406 int startPos = 0; 432 int startPos = 0;
407 if (project.Files.GetPreservePath(file)) 433 if (project.Files.GetPreservePath(filePath))
408 { 434 {
409 while ((@"./\").IndexOf(file.Substring(startPos, 1)) != -1) 435 while ((@"./\").IndexOf(file.Substring(startPos, 1)) != -1)
410 startPos++; 436 startPos++;
@@ -415,60 +441,75 @@ namespace Prebuild.Core.Targets
415 startPos = file.LastIndexOf(Path.GetFileName(path)); 441 startPos = file.LastIndexOf(Path.GetFileName(path));
416 } 442 }
417 443
418 ps.WriteLine("Include=\"{0}\">", path); 444 // be sure to write out the path with backslashes so VS recognizes
445 // the file properly.
446 ps.WriteLine("Include=\"{0}\">", file);
419 447
420 int last_period_index = file.LastIndexOf('.'); 448 int last_period_index = file.LastIndexOf('.');
421 string short_file_name = file.Substring(0, last_period_index); 449 string short_file_name = file.Substring(0, last_period_index);
422 string extension = Path.GetExtension(path); 450 string extension = Path.GetExtension(path);
423 string designer_format = string.Format(".designer{0}", extension); 451 // make this upper case, so that when File.Exists tests for the
452 // existence of a designer file on a case-sensitive platform,
453 // it is correctly identified.
454 string designer_format = string.Format(".Designer{0}", extension);
424 455
425 if (path_lower.EndsWith(designer_format)) 456 if (path_lower.EndsWith(designer_format.ToLowerInvariant()))
426 { 457 {
427 int designer_index = path_lower.IndexOf(designer_format); 458 int designer_index = path.IndexOf(designer_format);
428 string file_name = path.Substring(0, designer_index); 459 string file_name = path.Substring(0, designer_index);
429 460
430 if (File.Exists(file_name)) 461 // There are two corrections to the next lines:
431 ps.WriteLine(" <DependentUpon>{0}</DependentUpon>", Path.GetFileName(file_name)); 462 // 1. Fix the connection between a designer file and a form
463 // or usercontrol that don't have an associated resx file.
464 // 2. Connect settings files to associated designer files.
465 if (File.Exists(file_name + extension))
466 ps.WriteLine(" <DependentUpon>{0}</DependentUpon>", Path.GetFileName(file_name + extension));
432 else if (File.Exists(file_name + ".resx")) 467 else if (File.Exists(file_name + ".resx"))
433 ps.WriteLine(" <DependentUpon>{0}</DependentUpon>", Path.GetFileName(file_name + ".resx")); 468 ps.WriteLine(" <DependentUpon>{0}</DependentUpon>", Path.GetFileName(file_name + ".resx"));
469 else if (File.Exists(file_name + ".settings"))
470 {
471 ps.WriteLine(" <DependentUpon>{0}</DependentUpon>", Path.GetFileName(file_name + ".settings"));
472 ps.WriteLine(" <AutoGen>True</AutoGen>");
473 ps.WriteLine(" <DesignTimeSharedInput>True</DesignTimeSharedInput>");
474 }
434 } 475 }
435 else if (subType == SubType.CodeBehind) 476 else if (subType == SubType.CodeBehind)
436 { 477 {
437 ps.WriteLine(" <DependentUpon>{0}</DependentUpon>", Path.GetFileName(short_file_name)); 478 ps.WriteLine(" <DependentUpon>{0}</DependentUpon>", Path.GetFileName(short_file_name));
438 } 479 }
439 if (project.Files.GetIsLink(file)) 480 if (project.Files.GetIsLink(filePath))
440 { 481 {
441 string alias = project.Files.GetLinkPath(file); 482 string alias = project.Files.GetLinkPath(filePath);
442 alias += file.Substring(startPos); 483 alias += file.Substring(startPos);
443 alias = Helper.NormalizePath(alias); 484 alias = Helper.NormalizePath(alias);
444 ps.WriteLine(" <Link>{0}</Link>", alias); 485 ps.WriteLine(" <Link>{0}</Link>", alias);
445 } 486 }
446 else if (project.Files.GetBuildAction(file) != BuildAction.None) 487 else if (project.Files.GetBuildAction(filePath) != BuildAction.None)
447 { 488 {
448 if (project.Files.GetBuildAction(file) != BuildAction.EmbeddedResource) 489 if (project.Files.GetBuildAction(filePath) != BuildAction.EmbeddedResource)
449 { 490 {
450 ps.WriteLine(" <SubType>{0}</SubType>", subType); 491 ps.WriteLine(" <SubType>{0}</SubType>", subType);
451 } 492 }
452 } 493 }
453 494
454 if (project.Files.GetCopyToOutput(file) != CopyToOutput.Never) 495 if (project.Files.GetCopyToOutput(filePath) != CopyToOutput.Never)
455 { 496 {
456 ps.WriteLine(" <CopyToOutputDirectory>{0}</CopyToOutputDirectory>", project.Files.GetCopyToOutput(file)); 497 ps.WriteLine(" <CopyToOutputDirectory>{0}</CopyToOutputDirectory>", project.Files.GetCopyToOutput(filePath));
457 } 498 }
458 499
459 ps.WriteLine(" </{0}>", project.Files.GetBuildAction(file)); 500 ps.WriteLine(" </{0}>", project.Files.GetBuildAction(filePath));
460 } 501 }
461 } 502 }
462 } 503 }
463 504
464 ps.WriteLine(" </ItemGroup>"); 505 ps.WriteLine(" </ItemGroup>");
465 ps.WriteLine(" <Import Project=\"" + toolInfo.ImportProject + "\" />"); 506 ps.WriteLine(" <Import Project=\"" + toolInfo.ImportProject + "\" />");
466 ps.WriteLine(" <PropertyGroup>"); 507 ps.WriteLine(" <PropertyGroup>");
467 ps.WriteLine(" <PreBuildEvent>"); 508 ps.WriteLine(" <PreBuildEvent>");
468 ps.WriteLine(" </PreBuildEvent>"); 509 ps.WriteLine(" </PreBuildEvent>");
469 ps.WriteLine(" <PostBuildEvent>"); 510 ps.WriteLine(" <PostBuildEvent>");
470 ps.WriteLine(" </PostBuildEvent>"); 511 ps.WriteLine(" </PostBuildEvent>");
471 ps.WriteLine(" </PropertyGroup>"); 512 ps.WriteLine(" </PropertyGroup>");
472 ps.WriteLine("</Project>"); 513 ps.WriteLine("</Project>");
473 } 514 }
474 #endregion 515 #endregion
@@ -478,23 +519,36 @@ namespace Prebuild.Core.Targets
478 ps = new StreamWriter(projectFile + ".user"); 519 ps = new StreamWriter(projectFile + ".user");
479 using (ps) 520 using (ps)
480 { 521 {
522 // Get the first configuration from the project.
523 ConfigurationNode firstConfiguration = null;
524
525 if (project.Configurations.Count > 0)
526 {
527 firstConfiguration = project.Configurations[0];
528 }
529
481 ps.WriteLine("<Project xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">"); 530 ps.WriteLine("<Project xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">");
482 //ps.WriteLine( "<VisualStudioProject>" ); 531 //ps.WriteLine( "<VisualStudioProject>" );
483 //ps.WriteLine(" <{0}>", toolInfo.XMLTag); 532 //ps.WriteLine(" <{0}>", toolInfo.XMLTag);
484 //ps.WriteLine(" <Build>"); 533 //ps.WriteLine(" <Build>");
485 ps.WriteLine(" <PropertyGroup>"); 534 ps.WriteLine(" <PropertyGroup>");
486 //ps.WriteLine(" <Settings ReferencePath=\"{0}\">", MakeRefPath(project)); 535 //ps.WriteLine(" <Settings ReferencePath=\"{0}\">", MakeRefPath(project));
487 ps.WriteLine(" <Configuration Condition=\" '$(Configuration)' == '' \">Debug</Configuration>"); 536
488 ps.WriteLine(" <Platform Condition=\" '$(Platform)' == '' \">AnyCPU</Platform>"); 537 if (firstConfiguration != null)
489 ps.WriteLine(" <ReferencePath>{0}</ReferencePath>", MakeRefPath(project)); 538 {
490 ps.WriteLine(" <LastOpenVersion>{0}</LastOpenVersion>", this.ProductVersion); 539 ps.WriteLine(" <Configuration Condition=\" '$(Configuration)' == '' \">{0}</Configuration>", firstConfiguration.Name);
491 ps.WriteLine(" <ProjectView>ProjectFiles</ProjectView>"); 540 ps.WriteLine(" <Platform Condition=\" '$(Platform)' == '' \">{0}</Platform>", firstConfiguration.Platform);
492 ps.WriteLine(" <ProjectTrust>0</ProjectTrust>"); 541 }
493 ps.WriteLine(" </PropertyGroup>"); 542
543 ps.WriteLine(" <ReferencePath>{0}</ReferencePath>", MakeRefPath(project));
544 ps.WriteLine(" <LastOpenVersion>{0}</LastOpenVersion>", ProductVersion);
545 ps.WriteLine(" <ProjectView>ProjectFiles</ProjectView>");
546 ps.WriteLine(" <ProjectTrust>0</ProjectTrust>");
547 ps.WriteLine(" </PropertyGroup>");
494 foreach (ConfigurationNode conf in project.Configurations) 548 foreach (ConfigurationNode conf in project.Configurations)
495 { 549 {
496 ps.Write(" <PropertyGroup"); 550 ps.Write(" <PropertyGroup");
497 ps.Write(" Condition = \" '$(Configuration)|$(Platform)' == '{0}|AnyCPU' \"", conf.Name); 551 ps.Write(" Condition = \" '$(Configuration)|$(Platform)' == '{0}|{1}' \"", conf.Name, conf.Platform);
498 ps.WriteLine(" />"); 552 ps.WriteLine(" />");
499 } 553 }
500 ps.WriteLine("</Project>"); 554 ps.WriteLine("</Project>");
@@ -504,9 +558,9 @@ namespace Prebuild.Core.Targets
504 kernel.CurrentWorkingDirectory.Pop(); 558 kernel.CurrentWorkingDirectory.Pop();
505 } 559 }
506 560
507 private void WriteSolution(SolutionNode solution, bool writeSolutionToDisk) 561 private void WriteSolution(SolutionNode solution, bool writeSolutionToDisk)
508 { 562 {
509 kernel.Log.Write("Creating {0} solution and project files", this.VersionName); 563 kernel.Log.Write("Creating {0} solution and project files", VersionName);
510 564
511 foreach (SolutionNode child in solution.Solutions) 565 foreach (SolutionNode child in solution.Solutions)
512 { 566 {
@@ -531,13 +585,13 @@ namespace Prebuild.Core.Targets
531 kernel.Log.Write(""); 585 kernel.Log.Write("");
532 string solutionFile = Helper.MakeFilePath(solution.FullPath, solution.Name, "sln"); 586 string solutionFile = Helper.MakeFilePath(solution.FullPath, solution.Name, "sln");
533 587
534 using (StreamWriter ss = new StreamWriter(solutionFile)) 588 using (StreamWriter ss = new StreamWriter(solutionFile))
535 { 589 {
536 kernel.CurrentWorkingDirectory.Push(); 590 kernel.CurrentWorkingDirectory.Push();
537 Helper.SetCurrentDir(Path.GetDirectoryName(solutionFile)); 591 Helper.SetCurrentDir(Path.GetDirectoryName(solutionFile));
538 592
539 ss.WriteLine("Microsoft Visual Studio Solution File, Format Version {0}", this.SolutionVersion); 593 ss.WriteLine("Microsoft Visual Studio Solution File, Format Version {0}", SolutionVersion);
540 ss.WriteLine(SolutionTag); 594 ss.WriteLine(SolutionTag);
541 595
542 WriteProjectDeclarations(ss, solution, solution); 596 WriteProjectDeclarations(ss, solution, solution);
543 597
@@ -546,7 +600,7 @@ namespace Prebuild.Core.Targets
546 ss.WriteLine("\tGlobalSection(SolutionConfigurationPlatforms) = preSolution"); 600 ss.WriteLine("\tGlobalSection(SolutionConfigurationPlatforms) = preSolution");
547 foreach (ConfigurationNode conf in solution.Configurations) 601 foreach (ConfigurationNode conf in solution.Configurations)
548 { 602 {
549 ss.WriteLine("\t\t{0}|Any CPU = {0}|Any CPU", conf.Name); 603 ss.WriteLine("\t\t{0} = {0}", conf.NameAndPlatform);
550 } 604 }
551 ss.WriteLine("\tEndGlobalSection"); 605 ss.WriteLine("\tEndGlobalSection");
552 606
@@ -571,7 +625,7 @@ namespace Prebuild.Core.Targets
571 } 625 }
572 } 626 }
573 627
574 private void WriteProjectDeclarations(StreamWriter writer, SolutionNode actualSolution, SolutionNode embeddedSolution) 628 private void WriteProjectDeclarations(TextWriter writer, SolutionNode actualSolution, SolutionNode embeddedSolution)
575 { 629 {
576 foreach (SolutionNode childSolution in embeddedSolution.Solutions) 630 foreach (SolutionNode childSolution in embeddedSolution.Solutions)
577 { 631 {
@@ -595,7 +649,7 @@ namespace Prebuild.Core.Targets
595 } 649 }
596 } 650 }
597 651
598 private static void WriteNestedProjectMap(StreamWriter writer, SolutionNode embeddedSolution) 652 private static void WriteNestedProjectMap(TextWriter writer, SolutionNode embeddedSolution)
599 { 653 {
600 foreach (ProjectNode project in embeddedSolution.Projects) 654 foreach (ProjectNode project in embeddedSolution.Projects)
601 { 655 {
@@ -614,31 +668,31 @@ namespace Prebuild.Core.Targets
614 } 668 }
615 } 669 }
616 670
617 private static void WriteNestedProject(StreamWriter writer, SolutionNode solution, Guid projectGuid) 671 private static void WriteNestedProject(TextWriter writer, SolutionNode solution, Guid projectGuid)
618 { 672 {
619 WriteNestedFolder(writer, solution.Guid, projectGuid); 673 WriteNestedFolder(writer, solution.Guid, projectGuid);
620 } 674 }
621 675
622 private static void WriteNestedFolder(StreamWriter writer, Guid parentGuid, Guid childGuid) 676 private static void WriteNestedFolder(TextWriter writer, Guid parentGuid, Guid childGuid)
623 { 677 {
624 writer.WriteLine("\t\t{0} = {1}", 678 writer.WriteLine("\t\t{0} = {1}",
625 childGuid.ToString("B").ToUpper(), 679 childGuid.ToString("B").ToUpper(),
626 parentGuid.ToString("B").ToUpper()); 680 parentGuid.ToString("B").ToUpper());
627 } 681 }
628 682
629 private static void WriteConfigurationLines(ICollection configurations, SolutionNode solution, StreamWriter ss) 683 private static void WriteConfigurationLines(IEnumerable<ConfigurationNode> configurations, SolutionNode solution, TextWriter ss)
630 { 684 {
631 foreach (ProjectNode project in solution.Projects) 685 foreach (ProjectNode project in solution.Projects)
632 { 686 {
633 foreach (ConfigurationNode conf in configurations) 687 foreach (ConfigurationNode conf in configurations)
634 { 688 {
635 ss.WriteLine("\t\t{0}.{1}|Any CPU.ActiveCfg = {1}|Any CPU", 689 ss.WriteLine("\t\t{0}.{1}.ActiveCfg = {1}",
636 project.Guid.ToString("B").ToUpper(), 690 project.Guid.ToString("B").ToUpper(),
637 conf.Name); 691 conf.NameAndPlatform);
638 692
639 ss.WriteLine("\t\t{0}.{1}|Any CPU.Build.0 = {1}|Any CPU", 693 ss.WriteLine("\t\t{0}.{1}.Build.0 = {1}",
640 project.Guid.ToString("B").ToUpper(), 694 project.Guid.ToString("B").ToUpper(),
641 conf.Name); 695 conf.NameAndPlatform);
642 } 696 }
643 } 697 }
644 698
@@ -648,54 +702,37 @@ namespace Prebuild.Core.Targets
648 } 702 }
649 } 703 }
650 704
651 private void WriteSolutionFiles(SolutionNode solution, StreamWriter ss) 705 private void WriteSolutionFiles(SolutionNode solution, TextWriter ss)
652 { 706 {
653 if (solution.Files != null && solution.Files.Count > 0) 707 if(solution.Files != null && solution.Files.Count > 0)
654 { 708 WriteProject(ss, "Folder", solution.Guid, "Solution Files", "Solution Files", solution.Files);
655 WriteProject(ss, "Folder", solution.Guid, "Solution Files", "Solution Files", solution.Files);
656 }
657 } 709 }
658 710
659 private void WriteEmbeddedSolution(StreamWriter writer, SolutionNode embeddedSolution) 711 private void WriteEmbeddedSolution(TextWriter writer, SolutionNode embeddedSolution)
660 { 712 {
661 WriteProject(writer, "Folder", embeddedSolution.Guid, embeddedSolution.Name, embeddedSolution.Name, embeddedSolution.Files); 713 WriteProject(writer, "Folder", embeddedSolution.Guid, embeddedSolution.Name, embeddedSolution.Name, embeddedSolution.Files);
662 } 714 }
663 715
664 private void WriteProject(SolutionNode solution, StreamWriter ss, ProjectNode project) 716 private void WriteProject(SolutionNode solution, TextWriter ss, ProjectNode project)
665 { 717 {
666 WriteProject(ss, solution, project.Language, project.Guid, project.Name, project.FullPath); 718 WriteProject(ss, solution, project.Language, project.Guid, project.Name, project.FullPath);
667 } 719 }
668 720
669 private void WriteProject(SolutionNode solution, StreamWriter ss, DatabaseProjectNode dbProject) 721 private void WriteProject(SolutionNode solution, TextWriter ss, DatabaseProjectNode dbProject)
670 { 722 {
671 if (solution.Files != null && solution.Files.Count > 0) 723 if (solution.Files != null && solution.Files.Count > 0)
672 WriteProject(ss, solution, "Database", dbProject.Guid, dbProject.Name, dbProject.FullPath); 724 WriteProject(ss, solution, "Database", dbProject.Guid, dbProject.Name, dbProject.FullPath);
673 } 725 }
674 726
675 private static bool ExtensionSpecified(string refName)
676 {
677 return refName.EndsWith(".dll") || refName.EndsWith(".exe");
678 }
679
680 private static string GetProjectExtension(ProjectNode project)
681 {
682 string extension = ".dll";
683 if (project.Type == ProjectType.Exe)
684 {
685 extension = ".exe";
686 }
687 return extension;
688 }
689
690 const string ProjectDeclarationBeginFormat = "Project(\"{0}\") = \"{1}\", \"{2}\", \"{3}\""; 727 const string ProjectDeclarationBeginFormat = "Project(\"{0}\") = \"{1}\", \"{2}\", \"{3}\"";
691 const string ProjectDeclarationEndFormat = "EndProject"; 728 const string ProjectDeclarationEndFormat = "EndProject";
692 729
693 private void WriteProject(StreamWriter ss, SolutionNode solution, string language, Guid guid, string name, string projectFullPath) 730 private void WriteProject(TextWriter ss, SolutionNode solution, string language, Guid guid, string name, string projectFullPath)
694 { 731 {
695 if (!tools.ContainsKey(language)) 732 if (!tools.ContainsKey(language))
696 throw new UnknownLanguageException("Unknown .NET language: " + language); 733 throw new UnknownLanguageException("Unknown .NET language: " + language);
697 734
698 ToolInfo toolInfo = (ToolInfo)tools[language]; 735 ToolInfo toolInfo = tools[language];
699 736
700 string path = Helper.MakePathRelativeTo(solution.FullPath, projectFullPath); 737 string path = Helper.MakePathRelativeTo(solution.FullPath, projectFullPath);
701 738
@@ -704,23 +741,23 @@ namespace Prebuild.Core.Targets
704 WriteProject(ss, language, guid, name, path); 741 WriteProject(ss, language, guid, name, path);
705 } 742 }
706 743
707 private void WriteProject(StreamWriter writer, string language, Guid projectGuid, string name, string location) 744 private void WriteProject(TextWriter writer, string language, Guid projectGuid, string name, string location)
708 { 745 {
709 WriteProject(writer, language, projectGuid, name, location, null); 746 WriteProject(writer, language, projectGuid, name, location, null);
710 } 747 }
711 748
712 private void WriteProject(StreamWriter writer, string language, Guid projectGuid, string name, string location, FilesNode files) 749 private void WriteProject(TextWriter writer, string language, Guid projectGuid, string name, string location, FilesNode files)
713 { 750 {
714 if (!tools.ContainsKey(language)) 751 if (!tools.ContainsKey(language))
715 throw new UnknownLanguageException("Unknown .NET language: " + language); 752 throw new UnknownLanguageException("Unknown .NET language: " + language);
716 753
717 ToolInfo toolInfo = (ToolInfo)tools[language]; 754 ToolInfo toolInfo = tools[language];
718 755
719 writer.WriteLine(ProjectDeclarationBeginFormat, 756 writer.WriteLine(ProjectDeclarationBeginFormat,
720 toolInfo.Guid, 757 toolInfo.Guid,
721 name, 758 name,
722 location, 759 location,
723 projectGuid.ToString("B").ToUpper()); 760 projectGuid.ToString("B").ToUpper());
724 761
725 if (files != null) 762 if (files != null)
726 { 763 {
@@ -738,7 +775,7 @@ namespace Prebuild.Core.Targets
738 private void WriteDatabaseProject(SolutionNode solution, DatabaseProjectNode project) 775 private void WriteDatabaseProject(SolutionNode solution, DatabaseProjectNode project)
739 { 776 {
740 string projectFile = Helper.MakeFilePath(project.FullPath, project.Name, "dbp"); 777 string projectFile = Helper.MakeFilePath(project.FullPath, project.Name, "dbp");
741 IndentedTextWriter ps = new IndentedTextWriter(new StreamWriter(projectFile), " "); 778 IndentedTextWriter ps = new IndentedTextWriter(new StreamWriter(projectFile), " ");
742 779
743 kernel.CurrentWorkingDirectory.Push(); 780 kernel.CurrentWorkingDirectory.Push();
744 781
@@ -777,12 +814,10 @@ namespace Prebuild.Core.Targets
777 kernel.CurrentWorkingDirectory.Pop(); 814 kernel.CurrentWorkingDirectory.Pop();
778 } 815 }
779 816
780 private bool ContainsSqlFiles(string folder) 817 private static bool ContainsSqlFiles(string folder)
781 { 818 {
782 foreach (string file in Directory.GetFiles(folder, "*.sql")) 819 if(Directory.GetFiles(folder, "*.sql").Length > 0)
783 {
784 return true; // if the folder contains 1 .sql file, that's good enough 820 return true; // if the folder contains 1 .sql file, that's good enough
785 }
786 821
787 foreach (string child in Directory.GetDirectories(folder)) 822 foreach (string child in Directory.GetDirectories(folder))
788 { 823 {
@@ -793,7 +828,7 @@ namespace Prebuild.Core.Targets
793 return false; 828 return false;
794 } 829 }
795 830
796 private void WriteDatabaseFoldersAndFiles(IndentedTextWriter writer, string folder) 831 private static void WriteDatabaseFoldersAndFiles(IndentedTextWriter writer, string folder)
797 { 832 {
798 foreach (string child in Directory.GetDirectories(folder)) 833 foreach (string child in Directory.GetDirectories(folder))
799 { 834 {
@@ -816,7 +851,7 @@ namespace Prebuild.Core.Targets
816 { 851 {
817 kernel.Log.Write("...Cleaning project: {0}", project.Name); 852 kernel.Log.Write("...Cleaning project: {0}", project.Name);
818 853
819 ToolInfo toolInfo = (ToolInfo)tools[project.Language]; 854 ToolInfo toolInfo = tools[project.Language];
820 string projectFile = Helper.MakeFilePath(project.FullPath, project.Name, toolInfo.FileExtension); 855 string projectFile = Helper.MakeFilePath(project.FullPath, project.Name, toolInfo.FileExtension);
821 string userFile = projectFile + ".user"; 856 string userFile = projectFile + ".user";
822 857
@@ -826,7 +861,7 @@ namespace Prebuild.Core.Targets
826 861
827 private void CleanSolution(SolutionNode solution) 862 private void CleanSolution(SolutionNode solution)
828 { 863 {
829 kernel.Log.Write("Cleaning {0} solution and project files", this.VersionName, solution.Name); 864 kernel.Log.Write("Cleaning {0} solution and project files", VersionName, solution.Name);
830 865
831 string slnFile = Helper.MakeFilePath(solution.FullPath, solution.Name, "sln"); 866 string slnFile = Helper.MakeFilePath(solution.FullPath, solution.Name, "sln");
832 string suoFile = Helper.MakeFilePath(solution.FullPath, solution.Name, "suo"); 867 string suoFile = Helper.MakeFilePath(solution.FullPath, solution.Name, "suo");