public static XmlDocument LoadProjectXml(string path) { if (!_cachedProjectXml.Contains(path)) { XmlDocument doc = new XmlDocument(); if (!ProjectFactory.IsUrl(path)) { using (StreamReader sr = new StreamReader(path, Encoding.Default, true)) { doc.Load(sr); } } else { Uri uri = new Uri(path); if (uri.Scheme == Uri.UriSchemeFile) { using (StreamReader sr = new StreamReader(uri.LocalPath, Encoding.Default, true)) { doc.Load(sr); } } else { doc.LoadXml(WebDavClient.GetFileContentsStatic(path)); } } _cachedProjectXml[path] = doc; } return((XmlDocument)_cachedProjectXml[path]); }
/// <summary> /// Builds the specified solution configuration. /// </summary> /// <param name="solutionConfiguration">The solution configuration.</param> /// <returns></returns> protected override BuildResult Build(Configuration solutionConfiguration) { bool bSuccess = true; bool outputUpdated; string tempFile = null; GacCache.RecreateDomain(); try { // obtain project configuration (corresponding with solution configuration) ConfigurationSettings cs = (ConfigurationSettings) BuildConfigurations[solutionConfiguration]; // perform prebuild actions (for VS.NET 2003 and higher) if (!PreBuild(cs)) { // no longer bother trying to build the project and do not // execute any post-build events return BuildResult.Failed; } // unregister types exposed to COM, and unregister type // library (if it exists) UnregisterForComInterop(cs, solutionConfiguration); // ensure temp directory exists if (!Directory.Exists(TemporaryFiles.BasePath)) { Directory.CreateDirectory(TemporaryFiles.BasePath); } // compile neutral and localized resx files CompileResXFiles(solutionConfiguration); // check if project output needs to be rebuilt if (CheckUpToDate(solutionConfiguration)) { Log(Level.Verbose, "Project is up-to-date."); // project output is up-to-date outputUpdated = false; } else { // prepare the project for build Prepare(solutionConfiguration); // check if project does not contain any sources if (_sourceFiles.Count == 0) { // create temp file tempFile = Path.GetTempFileName(); // add temp file to collection of sources to compile // as command line compilers require a least one source // file to be specified, but VS.NET supports empty // projects _sourceFiles[tempFile] = null; } string tempResponseFile = FileUtils.CombinePaths(TemporaryFiles.BasePath, CommandFile); using (StreamWriter sw = File.CreateText(tempResponseFile)) { // write compiler options WriteCompilerOptions(sw, solutionConfiguration); } Log(Level.Verbose, "Starting compiler..."); if (SolutionTask.Verbose) { using (StreamReader sr = new StreamReader(tempResponseFile)) { Log(Level.Verbose, "Commands:"); // increment indentation level SolutionTask.Project.Indent(); try { while (true) { // read line string line = sr.ReadLine(); if (line == null) { break; } // display line Log(Level.Verbose, " " + line); } } finally { // restore indentation level SolutionTask.Project.Unindent(); } } } ProcessStartInfo psi = GetProcessStartInfo(cs, tempResponseFile); psi.UseShellExecute = false; psi.RedirectStandardOutput = true; // start compiler Process p = Process.Start(psi); while (true) { // read line string line = p.StandardOutput.ReadLine(); if (line == null) { break; } // display line Log(Level.Info, line); } p.WaitForExit(); int exitCode = p.ExitCode; Log(Level.Verbose, "{0}! (exit code = {1})", (exitCode == 0) ? "Success" : "Failure", exitCode); if (exitCode > 0) { bSuccess = false; } // project output has been updated outputUpdated = true; } #region Process culture-specific resource files Log(Level.Verbose, "Building satellite assemblies..."); Hashtable resourceSets = GetLocalizedResources(); foreach (LocalizedResourceSet localizedResourceSet in resourceSets.Values) { AssemblyLinkerTask al = new AssemblyLinkerTask(); al.Project = SolutionTask.Project; al.NamespaceManager = SolutionTask.NamespaceManager; al.Parent = SolutionTask; al.BaseDirectory = cs.OutputDir; al.InitializeTaskConfiguration(); DirectoryInfo satelliteBuildDir = localizedResourceSet. GetBuildDirectory(cs); // ensure satellite build directory exists if (!satelliteBuildDir.Exists) { satelliteBuildDir.Create(); } al.OutputFile = localizedResourceSet.GetSatelliteAssemblyPath( cs, ProjectSettings); al.OutputTarget = "lib"; al.Culture = localizedResourceSet.Culture.Name; al.TemplateFile = new FileInfo(cs.BuildPath); foreach (Resource resource in localizedResourceSet.Resources) { FileInfo compiledResourceFile = null; if (resource.IsResX) { // localized resx files have already been compiled compiledResourceFile = resource.GetCompiledResourceFile( solutionConfiguration); } else { // compile resource compiledResourceFile = resource.Compile(solutionConfiguration); } // add resources to embed EmbeddedResource embeddedResource = new EmbeddedResource( compiledResourceFile.FullName, resource.GetManifestResourceName(solutionConfiguration)); al.EmbeddedResources.Add(embeddedResource); } // increment indentation level SolutionTask.Project.Indent(); try { Log(Level.Verbose, " - {0}", al.Culture); // run assembly linker al.Execute(); } finally { // restore indentation level SolutionTask.Project.Unindent(); } } #endregion Process culture-specific resource files #region Register project output for COM Interop // check if we need to build type library if (cs.RegisterForComInterop) { // create type library in output dir, and register it using // that path to match VS.NET string typeLibPath = GetTypeLibraryPath(cs); RegisterForComInterop(cs, solutionConfiguration, typeLibPath); // copy generated type library to object directory to match // VS.NET string objTypeLibPath = Path.ChangeExtension(cs.BuildPath, ".tlb"); CopyFile(new FileInfo(typeLibPath), new FileInfo (objTypeLibPath), SolutionTask); } #endregion Register project output for COM Interop #region Deploy project and configuration level output files // copy primary project output (and related files) Hashtable outputFiles = CollectionsUtil.CreateCaseInsensitiveHashtable(); GetOutputFiles(solutionConfiguration, outputFiles); foreach (DictionaryEntry de in outputFiles) { string srcPath = (string) de.Key; string relativePath = (string) de.Value; if (IsWebProject) { WebDavClient wdc = new WebDavClient(new Uri(_webProjectBaseUrl)); wdc.UploadFile(srcPath, FileUtils.CombinePaths(cs.RelativeOutputDir, relativePath).Replace(@"\", "/")); } else { // determine destination file FileInfo destFile = new FileInfo(FileUtils.CombinePaths(cs.OutputDir.FullName, relativePath)); // copy file using <copy> task CopyFile(new FileInfo(srcPath), destFile, SolutionTask); } } #endregion Deploy project and configuration level output files if (ProjectSettings.RunPostBuildEvent != null) { if (!PostBuild(cs, !outputUpdated || bSuccess, outputUpdated)) { bSuccess = false; } } if (!bSuccess) { Log(Level.Error, "Build failed."); return BuildResult.Failed; } return outputUpdated ? BuildResult.SuccessOutputUpdated : BuildResult.Success; } finally { // check if temporary file was created to support empty projects if (tempFile != null) { // ensure temp file is deleted File.Delete(tempFile); } } }
/// <summary> /// Initializes a new instance of the <see cref="ManagedProjectBase"/> class. /// </summary> /// <param name="solution">The solution.</param> /// <param name="projectPath">The project path.</param> /// <param name="xmlDefinition">The XML definition.</param> /// <param name="solutionTask">The solution task.</param> /// <param name="tfc">The TFC.</param> /// <param name="gacCache">The gac cache.</param> /// <param name="refResolver">The reference resolver.</param> /// <param name="outputDir">The output dir.</param> /// <exception cref="System.ArgumentNullException"> /// projectPath /// or /// xmlDefinition /// </exception> protected ManagedProjectBase(SolutionBase solution, string projectPath, XmlElement xmlDefinition, SolutionTask solutionTask, TempFileCollection tfc, GacCache gacCache, ReferencesResolver refResolver, DirectoryInfo outputDir) : base(xmlDefinition, solutionTask, tfc, gacCache, refResolver, outputDir) { if (projectPath == null) { throw new ArgumentNullException("projectPath"); } if (xmlDefinition == null) { throw new ArgumentNullException("xmlDefinition"); } _references = new ArrayList(); _neutralResources = new ArrayList(); _localizedResources = new ArrayList(); _sourceFiles = CollectionsUtil.CreateCaseInsensitiveHashtable(); _projectPath = projectPath; _projectLocation = DetermineProjectLocation(xmlDefinition); if (!IsWebProject) { _projectDirectory = new FileInfo(projectPath).Directory; } else { string projectDirectory = projectPath.Replace(":", "_"); projectDirectory = projectDirectory.Replace("/", "_"); projectDirectory = projectDirectory.Replace("\\", "_"); _projectDirectory = new DirectoryInfo(FileUtils.CombinePaths( TemporaryFiles.BasePath, projectDirectory)); // ensure project directory exists if (!_projectDirectory.Exists) { _projectDirectory.Create(); _projectDirectory.Refresh(); } _webProjectBaseUrl = projectPath.Substring(0, projectPath.LastIndexOf("/")); } _projectSettings = new ProjectSettings(xmlDefinition, (XmlElement) xmlDefinition.SelectSingleNode("//Build/Settings"), this); XmlNodeList nlConfigurations = xmlDefinition.SelectNodes("//Config"); foreach (XmlElement elemConfig in nlConfigurations) { ConfigurationSettings cs = new ConfigurationSettings(this, elemConfig, OutputDir); ProjectConfigurations[Configuration.Parse(cs.Name)] = cs; } XmlNodeList nlReferences = xmlDefinition.SelectNodes("//References/Reference"); foreach (XmlElement elemReference in nlReferences) { ReferenceBase reference = CreateReference(solution, elemReference); _references.Add(reference); } XmlNodeList nlFiles = xmlDefinition.SelectNodes("//Files/Include/File"); foreach (XmlElement elemFile in nlFiles) { string buildAction = StringUtils.ConvertEmptyToNull(elemFile.GetAttribute("BuildAction")); string sourceFile; if (!String.IsNullOrEmpty(elemFile.GetAttribute("Link"))) { sourceFile = FileUtils.GetFullPath(FileUtils.CombinePaths( ProjectDirectory.FullName, elemFile.GetAttribute("Link"))); } else { sourceFile = FileUtils.GetFullPath(FileUtils.CombinePaths( ProjectDirectory.FullName, elemFile.GetAttribute("RelPath"))); } if (IsWebProject) { WebDavClient wdc = new WebDavClient(new Uri(_webProjectBaseUrl)); wdc.DownloadFile(sourceFile, elemFile.Attributes["RelPath"].Value); switch (buildAction) { case "Compile": _sourceFiles[sourceFile] = null; break; case "EmbeddedResource": RegisterEmbeddedResource(sourceFile, elemFile); break; case null: if (string.Compare(Path.GetExtension(sourceFile), FileExtension, true, CultureInfo.InvariantCulture) == 0) { _sourceFiles[sourceFile] = null; } break; } } else { switch (buildAction) { case "Compile": _sourceFiles[sourceFile] = null; break; case "EmbeddedResource": RegisterEmbeddedResource(sourceFile, elemFile); break; case null: if (string.Compare(Path.GetExtension(sourceFile), FileExtension, true, CultureInfo.InvariantCulture) == 0) { _sourceFiles[sourceFile] = null; } break; } // check if file is "App.config" (using case-insensitive comparison) if (string.Compare("App.config", elemFile.GetAttribute("RelPath"), true, CultureInfo.InvariantCulture) == 0) { // App.config is only an output file for executable projects if (ProjectSettings.OutputType == ManagedOutputType.Executable || ProjectSettings.OutputType == ManagedOutputType.WindowsExecutable) { ExtraOutputFiles[sourceFile] = ProjectSettings.OutputFileName + ".config"; } } } } }