diff --git a/data/templates/file/CSharp/CSharp.Interface.xft b/data/templates/file/CSharp/CSharp.Interface.xft index e97052fcdf..2bb847ec4d 100644 --- a/data/templates/file/CSharp/CSharp.Interface.xft +++ b/data/templates/file/CSharp/CSharp.Interface.xft @@ -30,7 +30,7 @@ namespace ${StandardNamespace} /// /// Description of ${ClassName}. /// - public interface I${ClassName} + public interface ${ClassName} { } diff --git a/src/AddIns/BackendBindings/VBNetBinding/Project/Src/VbcEncodingFixingLogger.cs b/src/AddIns/BackendBindings/VBNetBinding/Project/Src/VbcEncodingFixingLogger.cs index 9e8bee7c10..05bebbdfcb 100644 --- a/src/AddIns/BackendBindings/VBNetBinding/Project/Src/VbcEncodingFixingLogger.cs +++ b/src/AddIns/BackendBindings/VBNetBinding/Project/Src/VbcEncodingFixingLogger.cs @@ -18,16 +18,16 @@ namespace VBNetBinding /// public class VbcEncodingFixingLogger : IMSBuildAdditionalLogger { - public ILogger CreateLogger(MSBuildEngineWorker engineWorker) + public ILogger CreateLogger(MSBuildEngine engineWorker) { return new VbcLoggerImpl(engineWorker); } private class VbcLoggerImpl : ILogger { - MSBuildEngineWorker engineWorker; + MSBuildEngine engineWorker; - public VbcLoggerImpl(MSBuildEngineWorker engineWorker) + public VbcLoggerImpl(MSBuildEngine engineWorker) { this.engineWorker = engineWorker; } diff --git a/src/AddIns/Misc/CodeAnalysis/Src/FxCopLogger.cs b/src/AddIns/Misc/CodeAnalysis/Src/FxCopLogger.cs index 72231bfcf0..679006665d 100644 --- a/src/AddIns/Misc/CodeAnalysis/Src/FxCopLogger.cs +++ b/src/AddIns/Misc/CodeAnalysis/Src/FxCopLogger.cs @@ -17,16 +17,16 @@ namespace ICSharpCode.CodeAnalysis { public class FxCopLogger : IMSBuildAdditionalLogger { - public ILogger CreateLogger(MSBuildEngineWorker engineWorker) + public ILogger CreateLogger(MSBuildEngine engineWorker) { return new FxCopLoggerImpl(engineWorker); } private class FxCopLoggerImpl : ILogger { - MSBuildEngineWorker engineWorker; + MSBuildEngine engineWorker; - public FxCopLoggerImpl(MSBuildEngineWorker engineWorker) + public FxCopLoggerImpl(MSBuildEngine engineWorker) { this.engineWorker = engineWorker; } @@ -54,7 +54,7 @@ namespace ICSharpCode.CodeAnalysis public void Initialize(IEventSource eventSource) { this.eventSource = eventSource; - engineWorker.OutputText("${res:ICSharpCode.CodeAnalysis.RunningFxCopOn} " + Path.GetFileNameWithoutExtension(engineWorker.CurrentProjectFile) + "\r\n"); + engineWorker.OutputText("${res:ICSharpCode.CodeAnalysis.RunningFxCopOn} " + Path.GetFileNameWithoutExtension(engineWorker.CurrentProjectFile)); eventSource.ErrorRaised += OnError; eventSource.WarningRaised += OnWarning; } diff --git a/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj b/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj index 76522ccbc5..a693af6c4d 100644 --- a/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj +++ b/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj @@ -95,7 +95,9 @@ - + + + @@ -715,6 +717,10 @@ + + {C3CBC8E3-81D8-4C5B-9941-DCCD12D50B1F} + ICSharpCode.SharpDevelop.BuildWorker + {924EE450-603D-49C1-A8E5-4AFAA31CE6F3} ICSharpCode.SharpDevelop.Dom diff --git a/src/Main/Base/Project/Resources/ProjectAndSolutionOptionsPanel.xfrm b/src/Main/Base/Project/Resources/ProjectAndSolutionOptionsPanel.xfrm index 158d2977b8..3555df871e 100644 --- a/src/Main/Base/Project/Resources/ProjectAndSolutionOptionsPanel.xfrm +++ b/src/Main/Base/Project/Resources/ProjectAndSolutionOptionsPanel.xfrm @@ -5,64 +5,81 @@ - + + - - + + - - - + + - + - + - + - + - + - + + - + + + + + + + + + + + + + + + + + - + - + - + \ No newline at end of file diff --git a/src/Main/Base/Project/Src/Commands/BuildCommands.cs b/src/Main/Base/Project/Src/Commands/BuildCommands.cs index 16cce6854a..55e6c0e8cc 100644 --- a/src/Main/Base/Project/Src/Commands/BuildCommands.cs +++ b/src/Main/Base/Project/Src/Commands/BuildCommands.cs @@ -106,7 +106,7 @@ namespace ICSharpCode.SharpDevelop.Project.Commands public override void StartBuild() { ProjectService.RaiseEventStartBuild(); - ProjectService.OpenSolution.StartBuild(new BuildOptions(BuildTarget.Build, CallbackMethod)); + BuildEngine.BuildInGui(ProjectService.OpenSolution, new BuildOptions(BuildTarget.Build, CallbackMethod)); } public override void AfterBuild() @@ -120,7 +120,7 @@ namespace ICSharpCode.SharpDevelop.Project.Commands public override void StartBuild() { ProjectService.RaiseEventStartBuild(); - ProjectService.OpenSolution.StartBuild(new BuildOptions(BuildTarget.Rebuild, CallbackMethod)); + BuildEngine.BuildInGui(ProjectService.OpenSolution, new BuildOptions(BuildTarget.Rebuild, CallbackMethod)); } public override void AfterBuild() @@ -133,7 +133,7 @@ namespace ICSharpCode.SharpDevelop.Project.Commands { public override void StartBuild() { - ProjectService.OpenSolution.StartBuild(new BuildOptions(BuildTarget.Clean, CallbackMethod)); + BuildEngine.BuildInGui(ProjectService.OpenSolution, new BuildOptions(BuildTarget.Clean, CallbackMethod)); } } @@ -173,7 +173,7 @@ namespace ICSharpCode.SharpDevelop.Project.Commands public override void StartBuild() { ProjectService.RaiseEventStartBuild(); - this.ProjectToBuild.StartBuild(new BuildOptions(BuildTarget.Build, CallbackMethod, AdditionalProperties)); + BuildEngine.BuildInGui(this.ProjectToBuild, new BuildOptions(BuildTarget.Build, CallbackMethod, AdditionalProperties)); } public override void AfterBuild() @@ -190,7 +190,7 @@ namespace ICSharpCode.SharpDevelop.Project.Commands public override void StartBuild() { ProjectService.RaiseEventStartBuild(); - this.ProjectToBuild.StartBuild(new BuildOptions(BuildTarget.Rebuild, CallbackMethod, AdditionalProperties)); + BuildEngine.BuildInGui(this.ProjectToBuild, new BuildOptions(BuildTarget.Rebuild, CallbackMethod, AdditionalProperties)); } } @@ -198,7 +198,7 @@ namespace ICSharpCode.SharpDevelop.Project.Commands { public override void StartBuild() { - this.ProjectToBuild.StartBuild(new BuildOptions(BuildTarget.Clean, CallbackMethod, null)); + BuildEngine.BuildInGui(this.ProjectToBuild, new BuildOptions(BuildTarget.Clean, CallbackMethod)); } } diff --git a/src/Main/Base/Project/Src/Gui/Dialogs/OptionPanels/IDEOptions/ProjectAndSolutionOptionsPanel.cs b/src/Main/Base/Project/Src/Gui/Dialogs/OptionPanels/IDEOptions/ProjectAndSolutionOptionsPanel.cs index 52183b6e77..c1787d90cb 100644 --- a/src/Main/Base/Project/Src/Gui/Dialogs/OptionPanels/IDEOptions/ProjectAndSolutionOptionsPanel.cs +++ b/src/Main/Base/Project/Src/Gui/Dialogs/OptionPanels/IDEOptions/ProjectAndSolutionOptionsPanel.cs @@ -21,11 +21,12 @@ namespace ICSharpCode.SharpDevelop.Gui.OptionPanels // read properties ControlDictionary["projectLocationTextBox"].Text = PropertyService.Get("ICSharpCode.SharpDevelop.Gui.Dialogs.NewProjectDialog.DefaultPath", - Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal), - "SharpDevelop Projects")).ToString(); - + Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal), + "SharpDevelop Projects")).ToString(); + ((CheckBox)ControlDictionary["loadPrevProjectCheckBox"]).Checked = PropertyService.Get("SharpDevelop.LoadPrevProjectOnStartup", false); - ((CheckBox)ControlDictionary["showErrorListCheckBox"]).Checked = ErrorListPad.ShowAfterBuild; + ((CheckBox)ControlDictionary["showErrorListCheckBox"]).Checked = Project.BuildOptions.ShowErrorListAfterBuild; + ((NumericUpDown)ControlDictionary["parallelBuildNumericUpDown"]).Value = Project.BuildOptions.DefaultParallelProjectCount; ((Button)ControlDictionary["selectProjectLocationButton"]).Click += new EventHandler(SelectProjectLocationButtonClicked); } @@ -42,9 +43,10 @@ namespace ICSharpCode.SharpDevelop.Gui.OptionPanels } // set properties - PropertyService.Set("ICSharpCode.SharpDevelop.Gui.Dialogs.NewProjectDialog.DefaultPath", projectPath); + PropertyService.Set("ICSharpCode.SharpDevelop.Gui.Dialogs.NewProjectDialog.DefaultPath", projectPath); PropertyService.Set("SharpDevelop.LoadPrevProjectOnStartup", ((CheckBox)ControlDictionary["loadPrevProjectCheckBox"]).Checked); - ErrorListPad.ShowAfterBuild = ((CheckBox)ControlDictionary["showErrorListCheckBox"]).Checked; + Project.BuildOptions.ShowErrorListAfterBuild = ((CheckBox)ControlDictionary["showErrorListCheckBox"]).Checked; + Project.BuildOptions.DefaultParallelProjectCount = (int)((NumericUpDown)ControlDictionary["parallelBuildNumericUpDown"]).Value; return true; } diff --git a/src/Main/Base/Project/Src/Gui/Pads/ErrorList/ErrorListPad.cs b/src/Main/Base/Project/Src/Gui/Pads/ErrorList/ErrorListPad.cs index b11fb62f12..0b4e328586 100644 --- a/src/Main/Base/Project/Src/Gui/Pads/ErrorList/ErrorListPad.cs +++ b/src/Main/Base/Project/Src/Gui/Pads/ErrorList/ErrorListPad.cs @@ -63,10 +63,10 @@ namespace ICSharpCode.SharpDevelop.Gui public static bool ShowAfterBuild { get { - return PropertyService.Get("SharpDevelop.ShowErrorListAfterBuild", true); + return Project.BuildOptions.ShowErrorListAfterBuild; } set { - PropertyService.Set("SharpDevelop.ShowErrorListAfterBuild", value); + Project.BuildOptions.ShowErrorListAfterBuild = value; } } diff --git a/src/Main/Base/Project/Src/Gui/Pads/ProjectBrowser/NodeBuilder/DefaultDotNetNodeBuilder.cs b/src/Main/Base/Project/Src/Gui/Pads/ProjectBrowser/NodeBuilder/DefaultDotNetNodeBuilder.cs index 842d08511f..0a5ade7300 100644 --- a/src/Main/Base/Project/Src/Gui/Pads/ProjectBrowser/NodeBuilder/DefaultDotNetNodeBuilder.cs +++ b/src/Main/Base/Project/Src/Gui/Pads/ProjectBrowser/NodeBuilder/DefaultDotNetNodeBuilder.cs @@ -31,18 +31,13 @@ namespace ICSharpCode.SharpDevelop.Project missingNode.Text = ResourceService.GetString("ICSharpCode.SharpDevelop.Commands.ProjectBrowser.ProjectFileNotFound"); missingNode.AddTo(projectNode); } else if (project is UnknownProject) { - string ext = Path.GetExtension(project.FileName); - if (".proj".Equals(ext, StringComparison.OrdinalIgnoreCase) - || ".build".Equals(ext, StringComparison.OrdinalIgnoreCase)) - { - projectNode.OpenedImage = projectNode.ClosedImage = "Icons.16x16.XMLFileIcon"; - projectNode.Nodes.Clear(); - } else { - CustomNode unknownNode = new CustomNode(); - unknownNode.SetIcon("Icons.16x16.Warning"); - unknownNode.Text = StringParser.Parse(((UnknownProject)project).WarningText); - unknownNode.AddTo(projectNode); - } + CustomNode unknownNode = new CustomNode(); + unknownNode.SetIcon("Icons.16x16.Warning"); + unknownNode.Text = StringParser.Parse(((UnknownProject)project).WarningText); + unknownNode.AddTo(projectNode); + } else if (project is MSBuildFileProject) { + projectNode.OpenedImage = projectNode.ClosedImage = "Icons.16x16.XMLFileIcon"; + projectNode.Nodes.Clear(); } else { new ReferenceFolder(project).AddTo(projectNode); } diff --git a/src/Main/Base/Project/Src/Gui/Pads/ProjectBrowser/TreeNodes/ProjectNode.cs b/src/Main/Base/Project/Src/Gui/Pads/ProjectBrowser/TreeNodes/ProjectNode.cs index 17638c3012..f6b52ea654 100644 --- a/src/Main/Base/Project/Src/Gui/Pads/ProjectBrowser/TreeNodes/ProjectNode.cs +++ b/src/Main/Base/Project/Src/Gui/Pads/ProjectBrowser/TreeNodes/ProjectNode.cs @@ -112,7 +112,7 @@ namespace ICSharpCode.SharpDevelop.Project public override void ActivateItem() { - if (project is UnknownProject && Nodes.Count == 0) { + if (project is MSBuildFileProject) { FileService.OpenFile(project.FileName); } } diff --git a/src/Main/Base/Project/Src/Gui/Workbench/Layouts/SdiWorkspaceLayout.cs b/src/Main/Base/Project/Src/Gui/Workbench/Layouts/SdiWorkspaceLayout.cs index c0d10f6d07..535f63b9d1 100644 --- a/src/Main/Base/Project/Src/Gui/Workbench/Layouts/SdiWorkspaceLayout.cs +++ b/src/Main/Base/Project/Src/Gui/Workbench/Layouts/SdiWorkspaceLayout.cs @@ -579,7 +579,7 @@ namespace ICSharpCode.SharpDevelop.Gui content.Control.Dock = DockStyle.Fill; SdiWorkspaceWindow sdiWorkspaceWindow = new SdiWorkspaceWindow(); sdiWorkspaceWindow.ViewContents.Add(content); - content.SecondaryViewContents.Apply(sdiWorkspaceWindow.ViewContents.Add); + content.SecondaryViewContents.Foreach(sdiWorkspaceWindow.ViewContents.Add); sdiWorkspaceWindow.CloseEvent += new EventHandler(CloseWindowEvent); if (dockPanel != null) { sdiWorkspaceWindow.Show(dockPanel); diff --git a/src/Main/Base/Project/Src/Gui/Workbench/Layouts/SdiWorkspaceWindow.cs b/src/Main/Base/Project/Src/Gui/Workbench/Layouts/SdiWorkspaceWindow.cs index 94f3e389c8..f44b13a9a3 100644 --- a/src/Main/Base/Project/Src/Gui/Workbench/Layouts/SdiWorkspaceWindow.cs +++ b/src/Main/Base/Project/Src/Gui/Workbench/Layouts/SdiWorkspaceWindow.cs @@ -332,7 +332,7 @@ namespace ICSharpCode.SharpDevelop.Gui case DialogResult.Yes: if (ActiveViewContent.PrimaryFile != null) { while (true) { - ActiveViewContent.Files.Apply(ICSharpCode.SharpDevelop.Commands.SaveFile.Save); + ActiveViewContent.Files.Foreach(ICSharpCode.SharpDevelop.Commands.SaveFile.Save); if (ActiveViewContent.IsDirty) { if (MessageService.AskQuestion("${res:MainWindow.DiscardChangesMessage}")) { diff --git a/src/Main/Base/Project/Src/Project/AbstractProject.cs b/src/Main/Base/Project/Src/Project/AbstractProject.cs index 5ce923dd0f..cefb15243f 100644 --- a/src/Main/Base/Project/Src/Project/AbstractProject.cs +++ b/src/Main/Base/Project/Src/Project/AbstractProject.cs @@ -401,10 +401,6 @@ namespace ICSharpCode.SharpDevelop.Project return null; } - public virtual void StartBuild(BuildOptions options) - { - } - /// /// Creates a new projectItem for the passed itemType /// @@ -452,5 +448,29 @@ namespace ICSharpCode.SharpDevelop.Project public virtual void ResolveAssemblyReferences() { } + + public virtual void StartBuild(ProjectBuildOptions options, IBuildFeedbackSink feedbackSink) + { + feedbackSink.ReportError(new BuildError { ErrorText = "Building project " + Name + " is not supported.", IsWarning = true }); + // we don't know how to build anything, report that we're done. + feedbackSink.Done(true); + } + + public virtual ICollection GetBuildDependencies(ProjectBuildOptions buildOptions) + { + List result = new List(); + foreach (ProjectSection section in this.ProjectSections) { + if (section.Name == "ProjectDependencies") { + foreach (SolutionItem item in section.Items) { + foreach (IProject p in ParentSolution.Projects) { + if (p.IdGuid == item.Name) { + result.Add(p); + } + } + } + } + } + return result; + } } } diff --git a/src/Main/Base/Project/Src/Project/BuildEngine.cs b/src/Main/Base/Project/Src/Project/BuildEngine.cs new file mode 100644 index 0000000000..61e2e1a34d --- /dev/null +++ b/src/Main/Base/Project/Src/Project/BuildEngine.cs @@ -0,0 +1,492 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.Collections.Generic; +using System.Linq; + +namespace ICSharpCode.SharpDevelop.Project +{ + /// + /// Supports building a project with dependencies or the whole solution. + /// Creates a build graph and then builds it using topological sort. + /// + /// Supports building multiple projects in parallel. + /// + public sealed class BuildEngine + { + #region Building in the SharpDevelop GUI + static bool guiBuildRunning; + + public static void BuildInGui(IBuildable project, BuildOptions options) + { + if (guiBuildRunning) { + BuildResults results = new BuildResults(); + results.Add(new BuildError(null, Core.ResourceService.GetString("MainWindow.CompilerMessages.MSBuildAlreadyRunning"))); + results.Result = BuildResultCode.MSBuildAlreadyRunning; + options.Callback(results); + } else { + Gui.WorkbenchSingleton.Workbench.GetPad(typeof(Gui.CompilerMessageView)).BringPadToFront(); + StartBuild(project, options, new MessageViewSink(TaskService.BuildMessageViewCategory)); + } + } + + sealed class MessageViewSink : IBuildFeedbackSink + { + Gui.MessageViewCategory messageView; + + public MessageViewSink(ICSharpCode.SharpDevelop.Gui.MessageViewCategory messageView) + { + this.messageView = messageView; + } + + public void ReportError(BuildError error) + { + } + + public void ReportMessage(string message) + { + messageView.AppendLine(message); + } + + public void Done(bool success) + { + guiBuildRunning = false; + } + } + #endregion + + #region StartBuild + public static void StartBuild(IBuildable project, BuildOptions options, IBuildFeedbackSink realtimeBuildFeedbackSink) + { + if (project == null) + throw new ArgumentNullException("solution"); + if (options == null) + throw new ArgumentNullException("options"); + + Solution solution = project.ParentSolution; + if (solution == null) + throw new ArgumentException("project.ParentSolution must not be null", "project"); + + if (string.IsNullOrEmpty(options.SolutionConfiguration)) + options.SolutionConfiguration = solution.Preferences.ActiveConfiguration; + if (string.IsNullOrEmpty(options.SolutionPlatform)) + options.SolutionPlatform = solution.Preferences.ActivePlatform; + + BuildEngine engine = new BuildEngine(options, project); + engine.buildStart = DateTime.Now; + engine.combinedBuildFeedbackSink = realtimeBuildFeedbackSink; + engine.configMatchings = solution.GetActiveConfigurationsAndPlatformsForProjects(options.SolutionConfiguration, options.SolutionPlatform); + try { + engine.rootNode = engine.CreateBuildGraph(project); + } catch (CyclicDependencyException ex) { + if (ex.Project1 != null && ex.Project2 != null) + engine.results.Add(new BuildError(null, "Cyclic dependency between " + ex.Project1.Name + " and " + ex.Project2.Name)); + else + engine.results.Add(new BuildError(null, "Cyclic dependency")); + engine.results.Result = BuildResultCode.BuildFileError; + realtimeBuildFeedbackSink.Done(false); + options.Callback(engine.results); + return; + } + + engine.workersToStart = options.ParallelProjectCount; + if (engine.workersToStart < 1) + engine.workersToStart = 1; + + engine.ReportMessageInternal("${res:MainWindow.CompilerMessages.BuildStarted}"); + engine.StartBuildProjects(); + } + #endregion + + #region inner class BuildNode + sealed class BuildNode : IBuildFeedbackSink + { + readonly BuildEngine engine; + internal readonly IBuildable project; + internal ProjectBuildOptions options; + internal BuildNode[] dependencies; + /// specifies whether the node has been constructed completely (all dependencies initialized) + internal bool nodeComplete; + /// specifies whether this node has started building + internal bool buildStarted; + /// specifies whether this node has finished building + internal bool buildFinished; + + /// specifies whether the node produces build errors + internal bool hasErrors; + + /// The number of dependencies missing until this node can be built + internal int outstandingDependencies; + + /// The list of nodes that directly depend on this node + internal List dependentOnThis = new List(); + + int totalDependentOnThisCount = -1; + + /// Gets the number of nodes that depend on this node + /// directly or indirectly + internal int TotalDependentOnThisCount { + get { + if (totalDependentOnThisCount >= 0) + return totalDependentOnThisCount; + + // make a depth-first search to determine the size of the tree of + // projects that depends on this project: + HashSet visitedNodes = new HashSet(); + VisitDependentOnThis(visitedNodes, this); + totalDependentOnThisCount = visitedNodes.Count; + return totalDependentOnThisCount; + } + } + + static void VisitDependentOnThis(HashSet visitedNodes, BuildNode node) + { + if (visitedNodes.Add(node)) { + foreach (BuildNode n in node.dependentOnThis) { + VisitDependentOnThis(visitedNodes, n); + } + } + } + + /// The list of messages that were not reported because another node held the + /// output lock + internal List unreportedMessageList; + + public BuildNode(BuildEngine engine, IBuildable project) + { + this.engine = engine; + this.project = project; + } + + public void ReportError(BuildError error) + { + engine.ReportError(this, error); + } + + public void ReportMessage(string message) + { + engine.ReportMessage(this, message); + } + + public void Done(bool success) + { + engine.OnBuildFinished(this, success); + } + } + #endregion + + #region BuildEngine fields and constructor + readonly Dictionary nodeDict = new Dictionary(); + readonly BuildOptions options; + List configMatchings; + BuildNode rootNode; + IBuildable rootProject; + BuildResults results = new BuildResults(); + DateTime buildStart; + + List projectsReadyForBuildStart = new List(); + int workersToStart, runningWorkers; + + private BuildEngine(BuildOptions options, IBuildable rootProject) + { + this.options = options; + this.rootProject = rootProject; + } + #endregion + + #region CreateBuildGraph + BuildNode CreateBuildGraph(IBuildable project) + { + BuildNode node; + if (nodeDict.TryGetValue(project, out node)) { + return node; + } + node = new BuildNode(this, project); + nodeDict[project] = node; + InitializeProjectOptions(node); + InitializeDependencies(node); + + node.nodeComplete = true; + return node; + } + + void InitializeProjectOptions(BuildNode node) + { + IBuildable project = node.project; + // Create options for building the project + node.options = new ProjectBuildOptions(options.Target); + // find the project configuration + foreach (var matching in configMatchings) { + if (matching.Project == project) { + node.options.Configuration = matching.Configuration; + node.options.Platform = matching.Platform; + } + } + if (string.IsNullOrEmpty(node.options.Configuration)) + node.options.Configuration = options.SolutionConfiguration; + if (string.IsNullOrEmpty(node.options.Platform)) + node.options.Platform = options.SolutionPlatform; + + // copy properties to project options + options.GlobalAdditionalProperties.Foreach(node.options.Properties.Add); + if (project == rootProject) { + foreach (var pair in options.ProjectAdditionalProperties) { + node.options.Properties[pair.Key] = pair.Value; + } + } + } + + void InitializeDependencies(BuildNode node) + { + // Initialize dependencies + if (options.BuildDependentProjects) { + var dependencies = node.project.GetBuildDependencies(node.options); + if (dependencies != null) { + node.dependencies = dependencies + .Select(CreateBuildGraph) + .Distinct().ToArray(); + } + } + if (node.dependencies == null) { + node.dependencies = new BuildNode[0]; + } + node.outstandingDependencies = node.dependencies.Length; + foreach (BuildNode d in node.dependencies) { + if (!d.nodeComplete) + throw new CyclicDependencyException(node.project, d.project); + d.dependentOnThis.Add(node); + } + if (node.outstandingDependencies == 0) { + projectsReadyForBuildStart.Add(node); + } + } + + [Serializable] + sealed class CyclicDependencyException : Exception + { + public IBuildable Project1, Project2; + + public CyclicDependencyException() + { + } + + public CyclicDependencyException(IBuildable project1, IBuildable project2) + { + this.Project1 = project1; + this.Project2 = project2; + } + } + #endregion + + #region Building + void StartBuildProjects() + { + lock (this) { + while (workersToStart > 0) { + if (projectsReadyForBuildStart.Count == 0) { + if (runningWorkers == 0) { + BuildDone(); + } + return; + } + + workersToStart--; + + int projectToStartIndex = 0; + for (int i = 1; i < projectsReadyForBuildStart.Count; i++) { + if (CompareBuildOrder(projectsReadyForBuildStart[i], + projectsReadyForBuildStart[projectToStartIndex]) < 0) + { + projectToStartIndex = i; + } + } + BuildNode node = projectsReadyForBuildStart[projectToStartIndex]; + projectsReadyForBuildStart.RemoveAt(projectToStartIndex); + node.buildStarted = true; + + bool hasDependencyErrors = false; + foreach (BuildNode n in node.dependencies) { + if (!n.buildFinished) + throw new Exception("Trying to build project with unfinished dependencies"); + hasDependencyErrors |= n.hasErrors; + } + + ICSharpCode.Core.LoggingService.Debug("Start building " + node.project.Name); + runningWorkers++; + if (hasDependencyErrors) { + ICSharpCode.Core.LoggingService.Debug("Skipped building " + node.project.Name + " (errors in dependencies)"); + node.hasErrors = true; + node.Done(false); + } else { + node.project.StartBuild(node.options, node); + } + } + } + } + + static int CompareBuildOrder(BuildNode a, BuildNode b) + { + // When the build graph looks like this: + // 1 2 + // \ / \ + // 3 4 + // / \ + // 5 6 + // And we have 2 build workers, determining the build order alphabetically only would result + // in this order: + // 4, 5 + // 6 + // 3 + // 1, 2 + // However, we can build faster if we build 5+6 first: + // 5, 6 + // 3, 4 + // 1, 2 + // + // As heuristic, we first build the projects that have the most projects dependent on it. + int r = -(a.TotalDependentOnThisCount.CompareTo(b.TotalDependentOnThisCount)); + if (r == 0) + r = string.Compare(a.project.Name, b.project.Name, StringComparison.CurrentCultureIgnoreCase); + return r; + } + + void OnBuildFinished(BuildNode node, bool success) + { + ICSharpCode.Core.LoggingService.Debug("Finished building " + node.project.Name); + lock (this) { + if (node.buildFinished) { + throw new InvalidOperationException("This node already finished building, do not call IBuildFeedbackSink.Done() multiple times!"); + } + runningWorkers--; + node.buildFinished = true; + node.hasErrors = !success; + foreach (BuildNode n in node.dependentOnThis) { + n.outstandingDependencies--; + if (n.outstandingDependencies == 0) + projectsReadyForBuildStart.Add(n); + } + workersToStart++; + } + LogBuildFinished(node); + StartBuildProjects(); + } + + bool buildIsDone; + + void BuildDone() + { + lock (this) { + if (buildIsDone) + return; + buildIsDone = true; + } + foreach (BuildNode n in nodeDict.Values) { + if (!n.buildFinished) { + throw new Exception("All workers done, but a project did not finish building"); + } + } + string buildTime = " (" + (DateTime.Now - buildStart).ToString() + ")"; + + if (rootNode.hasErrors) { + results.Result = BuildResultCode.Error; + + ReportMessageInternal("${res:MainWindow.CompilerMessages.BuildFailed}" + buildTime); + //StatusBarService.SetMessage("${res:MainWindow.CompilerMessages.BuildFailed}"); + } else { + results.Result = BuildResultCode.Success; + + ReportMessageInternal("${res:MainWindow.CompilerMessages.BuildFinished}" + buildTime); + //StatusBarService.SetMessage("${res:MainWindow.CompilerMessages.BuildFinished}"); + } + if (combinedBuildFeedbackSink != null) { + combinedBuildFeedbackSink.Done(results.Result == BuildResultCode.Success); + } + if (options.Callback != null) { + Gui.WorkbenchSingleton.MainForm.BeginInvoke(options.Callback, results); + } + } + #endregion + + #region Logging + IBuildFeedbackSink combinedBuildFeedbackSink; + /// + /// The node that currently may output messages. + /// To avoid confusing the user in parallel builds, only one project may output messages; + /// the messages from other projects will be enqueued and written to the output as soon + /// as the project holding the lock finishes building. + /// + BuildNode nodeWithOutputLock; + Queue nodesWaitingForOutputLock = new Queue(); + + void ReportError(BuildNode source, BuildError error) + { + if (!error.IsWarning) + source.hasErrors = true; + results.Add(error); + ReportMessage(source, error.ToString()); + if (combinedBuildFeedbackSink != null) { + combinedBuildFeedbackSink.ReportError(error); + } + } + + void ReportMessage(BuildNode source, string message) + { + Console.WriteLine(source.project.Name + " reports " + message); + bool hasOutputLock; + lock (this) { + if (nodeWithOutputLock == null) { + nodeWithOutputLock = source; + } + hasOutputLock = nodeWithOutputLock == source; + if (!hasOutputLock) { + if (source.unreportedMessageList == null) { + nodesWaitingForOutputLock.Enqueue(source); + source.unreportedMessageList = new List(); + } + source.unreportedMessageList.Add(message); + } + } + if (hasOutputLock) { + ReportMessageInternal(message); + } + } + + void LogBuildFinished(BuildNode node) + { + List messagesToReport = null; + bool newNodeWithOutputLockAlreadyFinishedBuilding = false; + lock (this) { + if (node == nodeWithOutputLock) { + if (nodesWaitingForOutputLock.Count > 0) { + nodeWithOutputLock = nodesWaitingForOutputLock.Dequeue(); + messagesToReport = nodeWithOutputLock.unreportedMessageList; + nodeWithOutputLock.unreportedMessageList = null; + newNodeWithOutputLockAlreadyFinishedBuilding = nodeWithOutputLock.buildFinished; + } else { + nodeWithOutputLock = null; + } + } + } + if (messagesToReport != null) { + messagesToReport.Foreach(ReportMessageInternal); + } + if (newNodeWithOutputLockAlreadyFinishedBuilding) { + // if the node already finished building before it got the output lock, we need + // to release the output lock again here + LogBuildFinished(nodeWithOutputLock); + } + } + + void ReportMessageInternal(string message) + { + if (combinedBuildFeedbackSink != null) + combinedBuildFeedbackSink.ReportMessage(message); + } + #endregion + } +} diff --git a/src/Main/Base/Project/Src/Project/BuildOptions.cs b/src/Main/Base/Project/Src/Project/BuildOptions.cs index 780a89c5ec..abb845be6a 100644 --- a/src/Main/Base/Project/Src/Project/BuildOptions.cs +++ b/src/Main/Base/Project/Src/Project/BuildOptions.cs @@ -7,36 +7,106 @@ using System; using System.Collections.Generic; +using ICSharpCode.Core; namespace ICSharpCode.SharpDevelop.Project { public delegate void BuildCallback(BuildResults results); + /// + /// Specifies options for building a single project. + /// + public class ProjectBuildOptions + { + BuildTarget target; + IDictionary properties = new SortedList(); + + public BuildTarget Target { + get { return target; } + } + + public IDictionary Properties { + get { return properties; } + } + + public ProjectBuildOptions(BuildTarget target) + { + this.target = target; + } + + /// + /// Specifies the project configuration used for the build. + /// + public string Configuration { get; set; } + + /// + /// Specifies the project platform used for the build. + /// + public string Platform { get; set; } + } + /// /// Specifies options when starting a build. /// public class BuildOptions { + public static bool ShowErrorListAfterBuild { + get { + return PropertyService.Get("SharpDevelop.ShowErrorListAfterBuild", true); + } + set { + PropertyService.Set("SharpDevelop.ShowErrorListAfterBuild", value); + } + } + + public static int DefaultParallelProjectCount { + get { + return PropertyService.Get("SharpDevelop.BuildParallelProjectCount", Environment.ProcessorCount); + } + set { + PropertyService.Set("SharpDevelop.BuildParallelProjectCount", value); + } + } + BuildCallback callback; BuildTarget target; - IDictionary additionalProperties; + IDictionary globalAdditionalProperties = new SortedList(); + IDictionary projectAdditionalProperties = new SortedList(); - public BuildOptions() - { - this.target = BuildTarget.Build; - } + /// + /// Specifies whether dependencies should be built. + /// + public bool BuildDependentProjects { get; set; } + + /// + /// Specifies the solution configuration used for the build. + /// + public string SolutionConfiguration { get; set; } + + /// + /// Specifies the solution platform used for the build. + /// + public string SolutionPlatform { get; set; } + + /// + /// Specifies the number of projects that should be built in parallel. + /// + public int ParallelProjectCount { get; set; } public BuildOptions(BuildTarget target, BuildCallback callback) { this.callback = callback; this.target = target; + this.BuildDependentProjects = true; + this.ParallelProjectCount = DefaultParallelProjectCount; } - public BuildOptions(BuildTarget target, BuildCallback callback, IDictionary additionalProperties) + public BuildOptions(BuildTarget target, BuildCallback callback, IDictionary projectAdditionalProperties) + : this(target, callback) { - this.callback = callback; - this.target = target; - this.additionalProperties = additionalProperties; + if (projectAdditionalProperties == null) + throw new ArgumentNullException("projectAdditionalProperties"); + this.projectAdditionalProperties = projectAdditionalProperties; } public BuildCallback Callback { @@ -47,8 +117,12 @@ namespace ICSharpCode.SharpDevelop.Project get { return target; } } - public IDictionary AdditionalProperties { - get { return additionalProperties; } + public IDictionary GlobalAdditionalProperties { + get { return globalAdditionalProperties; } + } + + public IDictionary ProjectAdditionalProperties { + get { return projectAdditionalProperties; } } } } diff --git a/src/Main/Base/Project/Src/Project/IBuildFeedbackSink.cs b/src/Main/Base/Project/Src/Project/IBuildFeedbackSink.cs new file mode 100644 index 0000000000..647d412305 --- /dev/null +++ b/src/Main/Base/Project/Src/Project/IBuildFeedbackSink.cs @@ -0,0 +1,36 @@ +// +// +// +// +// $Revision$ +// + +using System; + +namespace ICSharpCode.SharpDevelop.Project +{ + /// + /// Interface for reporting build results in real-time. + /// + public interface IBuildFeedbackSink + { + /// + /// Reports an build error by adding it to the error list. + /// This member is thread-safe. + /// + void ReportError(BuildError error); + + /// + /// Reports a build message. + /// This member is thread-safe. + /// + void ReportMessage(string message); + + /// + /// Notifies the build engine that the build of a project has finished. + /// You sould not call any methods after the Done() call. + /// This member is thread-safe. + /// + void Done(bool success); + } +} diff --git a/src/Main/Base/Project/Src/Project/IProject.cs b/src/Main/Base/Project/Src/Project/IProject.cs index 1bb117b34d..0ec6e77c99 100644 --- a/src/Main/Base/Project/Src/Project/IProject.cs +++ b/src/Main/Base/Project/Src/Project/IProject.cs @@ -22,7 +22,7 @@ namespace ICSharpCode.SharpDevelop.Project /// When you implement IProject, you should also implement IProjectItemListProvider and IProjectAllowChangeConfigurations /// public interface IProject - : ISolutionFolder, IDisposable, IMementoCapable + : IBuildable, ISolutionFolder, IDisposable, IMementoCapable { /// /// Gets the list of items in the project. This member is thread-safe. @@ -202,11 +202,6 @@ namespace ICSharpCode.SharpDevelop.Project /// ParseProjectContent CreateProjectContent(); - /// - /// Starts building the project using the specified options. - /// - void StartBuild(BuildOptions options); - /// /// Creates a new ProjectItem for the passed MSBuild item. /// @@ -224,6 +219,23 @@ namespace ICSharpCode.SharpDevelop.Project void ResolveAssemblyReferences(); } + /// + /// A project or solution. + /// + public interface IBuildable : ISolutionFolder + { + /// + /// Gets the list of projects on which this project depends. + /// + ICollection GetBuildDependencies(ProjectBuildOptions buildOptions); + + /// + /// Starts building the project using the specified options. + /// This member must be implemented thread-safe. + /// + void StartBuild(ProjectBuildOptions buildOptions, IBuildFeedbackSink feedbackSink); + } + /// /// Interface for adding and removing items from a project. Not part of the IProject /// interface because in nearly all cases, ProjectService.Add/RemoveProjectItem should diff --git a/src/Main/Base/Project/Src/Project/MSBuildAdditionalLogger.cs b/src/Main/Base/Project/Src/Project/MSBuildAdditionalLogger.cs index 075bc934b0..78aae06fe1 100644 --- a/src/Main/Base/Project/Src/Project/MSBuildAdditionalLogger.cs +++ b/src/Main/Base/Project/Src/Project/MSBuildAdditionalLogger.cs @@ -16,7 +16,7 @@ namespace ICSharpCode.SharpDevelop.Project /// public interface IMSBuildAdditionalLogger { - ILogger CreateLogger(MSBuildEngineWorker engineWorker); + ILogger CreateLogger(MSBuildEngine engine); } /// @@ -67,23 +67,23 @@ namespace ICSharpCode.SharpDevelop.Project addIn = codon.AddIn; } - public ILogger CreateLogger(MSBuildEngineWorker engineWorker) + public ILogger CreateLogger(MSBuildEngine engine) { - return new TaskBoundAdditionalLogger(this, engineWorker); + return new TaskBoundAdditionalLogger(this, engine); } } private class TaskBoundAdditionalLogger : ILogger { TaskBoundAdditionalLoggerDescriptor desc; - MSBuildEngineWorker engineWorker; + MSBuildEngine engine; ILogger baseLogger; bool isActive; - public TaskBoundAdditionalLogger(TaskBoundAdditionalLoggerDescriptor desc, MSBuildEngineWorker engineWorker) + public TaskBoundAdditionalLogger(TaskBoundAdditionalLoggerDescriptor desc, MSBuildEngine engine) { this.desc = desc; - this.engineWorker = engineWorker; + this.engine = engine; } void CreateBaseLogger() @@ -93,7 +93,7 @@ namespace ICSharpCode.SharpDevelop.Project baseLogger = obj as ILogger; IMSBuildAdditionalLogger addLog = obj as IMSBuildAdditionalLogger; if (addLog != null) { - baseLogger = addLog.CreateLogger(engineWorker); + baseLogger = addLog.CreateLogger(engine); } } } diff --git a/src/Main/Base/Project/Src/Project/MSBuildBasedProject.cs b/src/Main/Base/Project/Src/Project/MSBuildBasedProject.cs index 04b3ad139d..6f58b60691 100644 --- a/src/Main/Base/Project/Src/Project/MSBuildBasedProject.cs +++ b/src/Main/Base/Project/Src/Project/MSBuildBasedProject.cs @@ -816,24 +816,34 @@ namespace ICSharpCode.SharpDevelop.Project #endregion #region Building - public override void StartBuild(BuildOptions options) + public override ICollection GetBuildDependencies(ProjectBuildOptions buildOptions) { - RunMSBuild(this.ParentSolution, this, - this.ParentSolution.Preferences.ActiveConfiguration, - this.ParentSolution.Preferences.ActivePlatform, - options); + ICollection result = base.GetBuildDependencies(buildOptions); + foreach (ProjectItem item in GetItemsOfType(ItemType.ProjectReference)) { + ProjectReferenceProjectItem prpi = item as ProjectReferenceProjectItem; + if (prpi != null && prpi.ReferencedProject != null) + result.Add(prpi.ReferencedProject); + } + return result; + } + + public override void StartBuild(ProjectBuildOptions options, IBuildFeedbackSink feedbackSink) + { + MSBuildEngine.Build(this, options, feedbackSink); } + /* internal static void RunMSBuild(Solution solution, IProject project, string configuration, string platform, BuildOptions options) { WorkbenchSingleton.Workbench.GetPad(typeof(CompilerMessageView)).BringPadToFront(); - MSBuildEngine engine = new MSBuildEngine(); + oldMSBuildEngine engine = new oldMSBuildEngine(); engine.Configuration = configuration; engine.Platform = platform; engine.MessageView = TaskService.BuildMessageViewCategory; engine.Run(solution, project, options); } + */ #endregion #region Loading diff --git a/src/Main/Base/Project/Src/Project/MSBuildEngine.cs b/src/Main/Base/Project/Src/Project/MSBuildEngine.cs index a499b098a9..bc6adb76c8 100644 --- a/src/Main/Base/Project/Src/Project/MSBuildEngine.cs +++ b/src/Main/Base/Project/Src/Project/MSBuildEngine.cs @@ -16,6 +16,7 @@ using ICSharpCode.Core; using ICSharpCode.SharpDevelop.Gui; using Microsoft.Build.BuildEngine; using Microsoft.Build.Framework; +using ICSharpCode.SharpDevelop.BuildWorker; namespace ICSharpCode.SharpDevelop.Project { @@ -73,479 +74,241 @@ namespace ICSharpCode.SharpDevelop.Project MSBuildProperties.Add("BuildingInsideVisualStudio", "true"); } - #region Properties - MessageViewCategory messageView; + public static void Build(IProject project, ProjectBuildOptions options, IBuildFeedbackSink feedbackSink) + { + if (project == null) + throw new ArgumentNullException("project"); + if (options == null) + throw new ArgumentNullException("options"); + if (feedbackSink == null) + throw new ArgumentNullException("feedbackSink"); + + MSBuildEngine engine = new MSBuildEngine(project, options, feedbackSink); + engine.StartBuild(); + } - /// - /// The the output is written to. - /// - public MessageViewCategory MessageView { - get { - return messageView; + IProject project; + ProjectBuildOptions options; + IBuildFeedbackSink feedbackSink; + + private MSBuildEngine(IProject project, ProjectBuildOptions options, IBuildFeedbackSink feedbackSink) + { + this.project = project; + this.options = options; + this.feedbackSink = feedbackSink; + } + + void StartBuild() + { + WorkerManager.ShowError = MessageService.ShowError; + BuildWorker.BuildSettings settings = new BuildWorker.BuildSettings(); + SharpDevelopLogger logger = new SharpDevelopLogger(this); + settings.Logger.Add(logger); + foreach (IMSBuildAdditionalLogger loggerProvider in MSBuildEngine.AdditionalMSBuildLoggers) { + settings.Logger.Add(loggerProvider.CreateLogger(this)); } - set { - messageView = value; + + BuildJob job = new BuildJob(); + job.ProjectFileName = project.FileName; + + BuildPropertyGroup pg = new BuildPropertyGroup(); + MSBuildBasedProject.InitializeMSBuildProjectProperties(pg); + foreach (BuildProperty p in pg) { + job.Properties[p.Name] = p.FinalValue; } + + Solution solution = project.ParentSolution; + job.Properties["SolutionDir"] = EnsureBackslash(solution.Directory); + job.Properties["SolutionExt"] = ".sln"; + job.Properties["SolutionFileName"] = Path.GetFileName(solution.FileName); + job.Properties["SolutionPath"] = solution.FileName; + + foreach (var pair in options.Properties) { + job.Properties[pair.Key] = pair.Value; + } + job.Properties["Configuration"] = options.Configuration; + if (options.Platform == "Any CPU") + job.Properties["Platform"] = "AnyCPU"; + else + job.Properties["Platform"] = options.Platform; + job.Target = options.Target.TargetName; + + bool buildInProcess = false; + if (Interlocked.CompareExchange(ref isBuildingInProcess, 1, 0) == 0) { + buildInProcess = true; + } + + if (buildInProcess) { + settings.BuildDoneCallback = delegate(bool success) { + if (Interlocked.Exchange(ref isBuildingInProcess, 0) != 1) { + MessageService.ShowError("isBuildingInProcess should have been 1!"); + } + logger.FlushCurrentError(); + feedbackSink.Done(success); + }; + + Thread thread = new Thread(new ThreadStart( + delegate { + lock (MSBuildInternals.InProcessMSBuildLock) { + WorkerManager.RunBuildInProcess(job, settings); + } + })); + thread.Name = "InProcess build thread"; + thread.SetApartmentState(ApartmentState.STA); + thread.Start(); + } else { + settings.BuildDoneCallback = delegate(bool success) { + logger.FlushCurrentError(); + feedbackSink.Done(success); + }; + + WorkerManager.StartBuild(job, settings); + } + } + + static int isBuildingInProcess; + + static string EnsureBackslash(string path) + { + if (path.EndsWith("\\")) + return path; + else + return path + "\\"; } - string configuration; + BuildError currentErrorOrWarning; /// - /// The configuration of the solution or project that should be builded. - /// Use null to build the default configuration. + /// Gets the last build error/warning created by the default + /// SharpDevelop logger. /// - public string Configuration { + public BuildError CurrentErrorOrWarning { get { - return configuration; - } - set { - configuration = value; + return currentErrorOrWarning; } } - string platform; + Stack projectFiles = new Stack(); /// - /// The platform of the solution or project that should be builded. - /// Use null to build the default platform. + /// Gets the name of the currently building project file. /// - public string Platform { + public string CurrentProjectFile { get { - return platform; - } - set { - platform = value; + if (projectFiles.Count == 0) + return null; + else + return projectFiles.Peek(); } } - #endregion - volatile static bool isRunning = false; + public void OutputText(string message) + { + feedbackSink.ReportMessage(message); + } - public void Run(Solution solution, IProject project, BuildOptions options) + public void ReportError(BuildError error) { - if (isRunning) { - BuildResults results = new BuildResults(); - results.Result = BuildResultCode.MSBuildAlreadyRunning; - results.Add(new BuildError(null, ResourceService.GetString("MainWindow.CompilerMessages.MSBuildAlreadyRunning"))); - if (options.Callback != null) { - options.Callback(results); - } - } else { - isRunning = true; - Thread thread = new Thread(new BuildRun(solution, project, options, this).RunMainBuild); - thread.Name = "MSBuildEngine main worker"; - thread.SetApartmentState(ApartmentState.STA); - thread.Start(); - } + feedbackSink.ReportError(error); } - internal sealed class BuildRun + class SharpDevelopLogger : ILogger { - Solution solution; - IProject project; - BuildOptions options; - MSBuildEngine parentEngine; - internal BuildResults currentResults = new BuildResults(); - List projectsToBuild = new List(); + MSBuildEngine worker; - public BuildRun(Solution solution, IProject project, BuildOptions options, MSBuildEngine parentEngine) + public SharpDevelopLogger(MSBuildEngine engine) { - this.solution = solution; - this.project = project; - this.options = options; - this.parentEngine = parentEngine; + this.worker = engine; } - #region Main Build - [STAThread] - internal void RunMainBuild() + void AppendText(string text) { - try { - PrepareBuild(); - - if (MSBuildEngine.isRunning) { - StartWorkerBuild(); - } - } catch (Exception ex) { - MessageService.ShowError(ex); - } + worker.OutputText(text); } - void Finish() + internal void FlushCurrentError() { - LoggingService.Debug("MSBuild finished"); - MSBuildEngine.isRunning = false; - if (currentResults.Result == BuildResultCode.None) { - currentResults.Result = BuildResultCode.Success; - } - if (currentResults.Result == BuildResultCode.Success) { - parentEngine.MessageView.AppendLine("${res:MainWindow.CompilerMessages.BuildFinished}"); - StatusBarService.SetMessage("${res:MainWindow.CompilerMessages.BuildFinished}"); - } else { - parentEngine.MessageView.AppendLine("${res:MainWindow.CompilerMessages.BuildFailed}"); - StatusBarService.SetMessage("${res:MainWindow.CompilerMessages.BuildFailed}"); - } - if (options.Callback != null) { - WorkbenchSingleton.MainForm.BeginInvoke(options.Callback, currentResults); + if (worker.currentErrorOrWarning != null) { + worker.ReportError(worker.currentErrorOrWarning); + worker.currentErrorOrWarning = null; } } - void PrepareBuild() + void OnProjectStarted(object sender, ProjectStartedEventArgs e) { - parentEngine.MessageView.AppendLine("${res:MainWindow.CompilerMessages.BuildStarted}"); - - // first parse the solution file into a MSBuild project - LoggingService.Debug("Parsing solution file " + solution.FileName); - - Engine engine = CreateEngine(); - if (parentEngine.Configuration != null) { - engine.GlobalProperties.SetProperty("Configuration", parentEngine.Configuration); - } - if (parentEngine.Platform != null) { - engine.GlobalProperties.SetProperty("Platform", parentEngine.Platform); - } - Project solutionProject = LoadProject(engine, solution.FileName); - if (solutionProject == null) { - Finish(); - return; - } - - // get the projects that should be built - IEnumerable projectsToBuildWithoutDependencies; - if (project == null) - projectsToBuildWithoutDependencies = solution.Projects; - else - projectsToBuildWithoutDependencies = GetAllReferencedProjects(project); - - projectsToBuild = (from p in projectsToBuildWithoutDependencies - select new ProjectToBuild(p.FileName, options.Target.TargetName)).ToList(); - - Dictionary projectDict = new Dictionary(StringComparer.InvariantCultureIgnoreCase); - foreach (ProjectToBuild ptb in projectsToBuild) { - projectDict[ptb.file] = ptb; - } - - // use the information from the parsed solution file to determine build level, configuration and - // platform of the projects to build - - for (int level = 0;; level++) { - BuildItemGroup group = solutionProject.GetEvaluatedItemsByName("BuildLevel" + level); - if (group.Count == 0) - break; - foreach (BuildItem item in group) { - string path = FileUtility.GetAbsolutePath(solution.Directory, item.Include); - ProjectToBuild ptb; - if (projectDict.TryGetValue(path, out ptb)) { - ptb.level = level; - ptb.configuration = item.GetEvaluatedMetadata("Configuration"); - ptb.platform = item.GetEvaluatedMetadata("Platform"); - } else { - // don't warn when compiling a specific project, but simply ignore projects - // that are not required - if (project == null) { - parentEngine.MessageView.AppendLine("Cannot build project file: " + path + " (project is not loaded by SharpDevelop)"); - } - } - } - } - - projectsToBuild.Sort( - delegate(ProjectToBuild ptb1, ProjectToBuild ptb2) { - if (ptb1.level == ptb2.level) { - return Path.GetFileName(ptb1.file).CompareTo(Path.GetFileName(ptb2.file)); - } else { - return ptb1.level.CompareTo(ptb2.level); - } - }); - - bool noProjectsToBuild = true; - for (int i = 0; i < projectsToBuild.Count; i++) { - if (projectsToBuild[i].level < 0) { - parentEngine.MessageView.AppendLine("Skipping " + Path.GetFileName(projectsToBuild[i].file)); - } else { - noProjectsToBuild = false; - break; - } - } - if (noProjectsToBuild) { - parentEngine.MessageView.AppendLine("There are no projects to build."); - Finish(); - } + worker.projectFiles.Push(e.ProjectFile); } - #endregion - - #region Worker build - int workerCount; - int maxWorkerCount; - /// - /// Runs the first worker on this thread and creates new threads if required - /// - void StartWorkerBuild() + void OnProjectFinished(object sender, ProjectFinishedEventArgs e) { - workerCount = 1; - // one build worker thread is maximum - MSBuild sets the working directory - // and thus cannot run multiple times in the same process - maxWorkerCount = 1; - RunWorkerBuild(); + FlushCurrentError(); + worker.projectFiles.Pop(); } - // Reuse worker objects: improves performance because MSBuild can cache Xml documents - Queue unusedWorkers = new Queue(); + string activeTaskName; - /// - /// Runs one worker thread - /// - [STAThread] - void RunWorkerBuild() + void OnTaskStarted(object sender, TaskStartedEventArgs e) { - LoggingService.Debug("Build Worker thread started"); - MSBuildEngineWorker worker = null; - try { - lock (projectsToBuild) { - if (unusedWorkers.Count > 0) - worker = unusedWorkers.Dequeue(); - } - if (worker == null) { - worker = new MSBuildEngineWorker(parentEngine, this); - } - while (RunWorkerInternal(worker)); - } catch (Exception ex) { - MessageService.ShowError(ex); - } finally { - bool wasLastWorker; - lock (projectsToBuild) { - workerCount--; - wasLastWorker = workerCount == 0; - if (worker != null) { - unusedWorkers.Enqueue(worker); - } - } - LoggingService.Debug("Build Worker thread finished"); - if (wasLastWorker) { - Finish(); - } + activeTaskName = e.TaskName; + if (MSBuildEngine.CompileTaskNames.Contains(e.TaskName.ToLowerInvariant())) { + AppendText("${res:MainWindow.CompilerMessages.CompileVerb} " + Path.GetFileNameWithoutExtension(e.ProjectFile)); } } - int lastUniqueWorkerID; - int currentBuildLevel; - - /// - /// Find available work and run it on the specified worker. - /// - bool RunWorkerInternal(MSBuildEngineWorker worker) + void OnTaskFinished(object sender, TaskFinishedEventArgs e) { - ProjectToBuild nextFreeProject = null; - lock (projectsToBuild) { - foreach (ProjectToBuild ptb in projectsToBuild) { - if (ptb.buildStarted == false && ptb.level == currentBuildLevel) { - if (nextFreeProject == null) { - nextFreeProject = ptb; - - // all workers busy, don't look if there is more work available - if (workerCount == maxWorkerCount) - break; - } else { - // free workers available + additional work available: - // start a new worker - LoggingService.Debug("Starting a new worker"); - workerCount++; - Thread thread = new Thread(RunWorkerBuild); - thread.Name = "MSBuildEngine worker " + (++lastUniqueWorkerID); - thread.SetApartmentState(ApartmentState.STA); - thread.Start(); - - // start at most one additional worker, the new worker can - // start more threads if desired - break; - } - } - } - if (nextFreeProject == null) { - // are all projects on the current level done? - bool allDone = true; - foreach (ProjectToBuild ptb in projectsToBuild) { - if (ptb.level == currentBuildLevel) { - if (!ptb.buildFinished) { - allDone = false; - break; - } - } - } - if (allDone) { - currentBuildLevel++; - if (currentBuildLevel > projectsToBuild[projectsToBuild.Count - 1].level) { - return false; - } - return true; - } else { - // nothing to do for this worker thread - return false; - } - } - // now build nextFreeProject - nextFreeProject.buildStarted = true; - } // end lock - - StatusBarService.SetMessage("${res:MainWindow.CompilerMessages.BuildVerb} " + Path.GetFileNameWithoutExtension(nextFreeProject.file) + "..."); - - // run the build: - if (worker.Build(nextFreeProject)) { - // build successful: mark it as finished - lock (projectsToBuild) { - nextFreeProject.buildFinished = true; - } - } - return true; + FlushCurrentError(); } - #endregion - #region Managing the output lock - /// - /// Queue of output text to write when lock is released. - /// - /// Also serves as object to ensure access to outputLockIsAquired is thread-safe. - /// - Queue queuedOutputText = new Queue(); - volatile bool outputLockIsAquired; - - internal bool TryAquireOutputLock() + void OnError(object sender, BuildErrorEventArgs e) { - lock (queuedOutputText) { - if (outputLockIsAquired) { - return false; - } else { - outputLockIsAquired = true; - return true; - } - } + AppendError(e.File, e.LineNumber, e.ColumnNumber, e.Code, e.Message, false); } - internal void ReleaseOutputLock() + void OnWarning(object sender, BuildWarningEventArgs e) { - lock (queuedOutputText) { - outputLockIsAquired = false; - while (queuedOutputText.Count > 0) { - parentEngine.MessageView.AppendText(queuedOutputText.Dequeue()); - } - } + AppendError(e.File, e.LineNumber, e.ColumnNumber, e.Code, e.Message, true); } - internal void EnqueueTextForAppendWhenOutputLockIsReleased(string text) + void AppendError(string file, int lineNumber, int columnNumber, string code, string message, bool isWarning) { - lock (queuedOutputText) { - if (outputLockIsAquired) { - queuedOutputText.Enqueue(text); - } else { - parentEngine.MessageView.AppendText(text); + if (string.Equals(file, activeTaskName, StringComparison.InvariantCultureIgnoreCase)) { + file = ""; + } else if (FileUtility.IsValidPath(file)) { + bool isShortFileName = file == Path.GetFileNameWithoutExtension(file); + if (worker.CurrentProjectFile != null) { + file = Path.Combine(Path.GetDirectoryName(worker.CurrentProjectFile), file); } - } - } - #endregion - - #region CreateEngine / LoadProject - internal Engine CreateEngine() - { - Engine engine = MSBuildInternals.CreateEngine(); - - MSBuildBasedProject.InitializeMSBuildProjectProperties(engine.GlobalProperties); - - if (options.AdditionalProperties != null) { - foreach (KeyValuePair entry in options.AdditionalProperties) { - engine.GlobalProperties.SetProperty(entry.Key, entry.Value); + if (isShortFileName && !File.Exists(file)) { + file = ""; } } - engine.GlobalProperties.SetProperty("SolutionDir", EnsureBackslash(solution.Directory)); - engine.GlobalProperties.SetProperty("SolutionExt", ".sln"); - engine.GlobalProperties.SetProperty("SolutionFileName", Path.GetFileName(solution.FileName)); - engine.GlobalProperties.SetProperty("SolutionPath", solution.FileName); - - return engine; + FlushCurrentError(); + BuildError error = new BuildError(file, lineNumber, columnNumber, code, message); + error.IsWarning = isWarning; + worker.currentErrorOrWarning = error; } - static string EnsureBackslash(string path) - { - if (path.EndsWith("\\")) - return path; - else - return path + "\\"; - } + #region ILogger interface implementation + public LoggerVerbosity Verbosity { get; set; } + public string Parameters { get; set; } - internal Project LoadProject(Engine engine, string fileName) + public void Initialize(IEventSource eventSource) { - Project project = engine.CreateNewProject(); - try { - project.Load(fileName); - - // When we set BuildingInsideVisualStudio, MSBuild tries to build all projects - // every time because in Visual Studio, the host compiler does the change detection - // We override the property '_ComputeNonExistentFileProperty' which is responsible - // for recompiling each time - our _ComputeNonExistentFileProperty does nothing, - // which re-enables the MSBuild's usual change detection - project.Targets.AddNewTarget("_ComputeNonExistentFileProperty"); - - return project; - } catch (ArgumentException ex) { - currentResults.Result = BuildResultCode.BuildFileError; - currentResults.Add(new BuildError("", ex.Message)); - } catch (InvalidProjectFileException ex) { - currentResults.Result = BuildResultCode.BuildFileError; - currentResults.Add(new BuildError(ex.ProjectFile, ex.LineNumber, ex.ColumnNumber, ex.ErrorCode, ex.Message)); - } - return null; + eventSource.ProjectStarted += new ProjectStartedEventHandler(OnProjectStarted); + eventSource.ProjectFinished += new ProjectFinishedEventHandler(OnProjectFinished); + eventSource.TaskStarted += new TaskStartedEventHandler(OnTaskStarted); + eventSource.TaskFinished += new TaskFinishedEventHandler(OnTaskFinished); + + eventSource.ErrorRaised += new BuildErrorEventHandler(OnError); + eventSource.WarningRaised += new BuildWarningEventHandler(OnWarning); } - #endregion - #region GetAllReferencedProjects - /// - /// Gets all projects referenced by the project. - /// - static ICollection GetAllReferencedProjects(IProject project) + public void Shutdown() { - HashSet referencedProjects = new HashSet(); - Stack stack = new Stack(); - referencedProjects.Add(project); - stack.Push(project); - while (stack.Count != 0) { - project = stack.Pop(); - foreach (ProjectItem item in project.GetItemsOfType(ItemType.ProjectReference)) { - ProjectReferenceProjectItem prpi = item as ProjectReferenceProjectItem; - if (prpi != null) { - if (referencedProjects.Add(prpi.ReferencedProject)) { - stack.Push(prpi.ReferencedProject); - } - } - } - } - - return referencedProjects; } #endregion - - } - - internal sealed class ProjectToBuild - { - internal string file; - internal int level = -1; - internal string configuration; - internal string platform; - internal string targets; - - // build status. Three possible values: - // buildStarted=buildFinished=false => build not yet started - // buildStarted=true, buildFinished=false => build running - // buildStarted=buildFinished=true => build finished - internal bool buildStarted; - internal bool buildFinished; - - internal ProjectToBuild(string file, string targets) - { - this.file = file; - this.targets = targets; - } } } } diff --git a/src/Main/Base/Project/Src/Project/MSBuildEngineWorker.cs b/src/Main/Base/Project/Src/Project/MSBuildEngineWorker.cs deleted file mode 100644 index 261c4d896b..0000000000 --- a/src/Main/Base/Project/Src/Project/MSBuildEngineWorker.cs +++ /dev/null @@ -1,253 +0,0 @@ -// -// -// -// -// $Revision$ -// - -using System; -using System.Text; -using System.Collections.Generic; -using Microsoft.Build.Framework; -using Microsoft.Build.BuildEngine; -using ICSharpCode.SharpDevelop.Gui; -using System.IO; -using ICSharpCode.Core; - -namespace ICSharpCode.SharpDevelop.Project -{ - public sealed class MSBuildEngineWorker - { - MSBuildEngine parentEngine; - MSBuildEngine.BuildRun buildRun; - Engine engine; - SharpDevelopLogger logger; - - internal MSBuildEngineWorker(MSBuildEngine parentEngine, MSBuildEngine.BuildRun buildRun) - { - this.parentEngine = parentEngine; - this.buildRun = buildRun; - engine = buildRun.CreateEngine(); - - logger = new SharpDevelopLogger(this); - engine.RegisterLogger(logger); - foreach (IMSBuildAdditionalLogger loggerProvider in MSBuildEngine.AdditionalMSBuildLoggers) { - engine.RegisterLogger(loggerProvider.CreateLogger(this)); - } - } - - internal bool Build(MSBuildEngine.ProjectToBuild ptb) - { - LoggingService.Debug("Run MSBuild on " + ptb.file); - - if (!string.IsNullOrEmpty(ptb.configuration)) { - engine.GlobalProperties.SetProperty("Configuration", ptb.configuration); - } - if (!string.IsNullOrEmpty(ptb.platform)) { - engine.GlobalProperties.SetProperty("Platform", ptb.platform); - } - - bool success; - lock (MSBuildInternals.InProcessMSBuildLock) { - Microsoft.Build.BuildEngine.Project project = buildRun.LoadProject(engine, ptb.file); - if (project == null) { - LoggingService.Debug("Error loading " + ptb.file); - return false; - } - foreach (string additionalTargetFile in MSBuildEngine.AdditionalTargetFiles) { - project.AddNewImport(additionalTargetFile, null); - } - - if (string.IsNullOrEmpty(ptb.targets)) { - success = engine.BuildProject(project); - } else { - success = engine.BuildProject(project, ptb.targets.Split(';')); - } - } - - logger.FlushCurrentError(); - ReleaseOutput(); - - LoggingService.Debug("MSBuild on " + ptb.file + " finished " + (success ? "successfully" : "with error")); - return success; - } - - bool outputAcquired; - StringBuilder cachedOutput; - - public void OutputText(string text) - { - if (outputAcquired == false && cachedOutput == null) { - outputAcquired = buildRun.TryAquireOutputLock(); - if (!outputAcquired) { - cachedOutput = new StringBuilder(); - } - } - if (outputAcquired) { - parentEngine.MessageView.AppendText(text); - } else { - cachedOutput.Append(text); - } - } - - void ReleaseOutput() - { - if (cachedOutput != null) { - buildRun.EnqueueTextForAppendWhenOutputLockIsReleased(cachedOutput.ToString()); - cachedOutput = null; - } - if (outputAcquired) { - buildRun.ReleaseOutputLock(); - } - } - - #region CurrentBuild properties - BuildError currentErrorOrWarning; - - /// - /// Gets the last build error/warning created by the default - /// SharpDevelop logger. - /// - public BuildError CurrentErrorOrWarning { - get { - return currentErrorOrWarning; - } - } - - Stack projectFiles = new Stack(); - - /// - /// Gets the name of the currently building project file. - /// - public string CurrentProjectFile { - get { - if (projectFiles.Count == 0) - return null; - else - return projectFiles.Peek(); - } - } - #endregion - - class SharpDevelopLogger : ILogger - { - MSBuildEngineWorker worker; - BuildResults results; - - public SharpDevelopLogger(MSBuildEngineWorker worker) - { - this.worker = worker; - this.results = worker.buildRun.currentResults; - } - - void AppendText(string text) - { - worker.OutputText(text + "\r\n"); - } - - internal void FlushCurrentError() - { - if (worker.currentErrorOrWarning != null) { - AppendText(worker.currentErrorOrWarning.ToString()); - worker.currentErrorOrWarning = null; - } - } - - void OnProjectStarted(object sender, ProjectStartedEventArgs e) - { - worker.projectFiles.Push(e.ProjectFile); - } - - void OnProjectFinished(object sender, ProjectFinishedEventArgs e) - { - FlushCurrentError(); - worker.projectFiles.Pop(); - } - - string activeTaskName; - - void OnTaskStarted(object sender, TaskStartedEventArgs e) - { - activeTaskName = e.TaskName; - if (MSBuildEngine.CompileTaskNames.Contains(e.TaskName.ToLowerInvariant())) { - AppendText("${res:MainWindow.CompilerMessages.CompileVerb} " + Path.GetFileNameWithoutExtension(e.ProjectFile)); - } - } - - void OnTaskFinished(object sender, TaskFinishedEventArgs e) - { - FlushCurrentError(); - } - - void OnError(object sender, BuildErrorEventArgs e) - { - AppendError(e.File, e.LineNumber, e.ColumnNumber, e.Code, e.Message, false); - } - - void OnWarning(object sender, BuildWarningEventArgs e) - { - AppendError(e.File, e.LineNumber, e.ColumnNumber, e.Code, e.Message, true); - } - - void AppendError(string file, int lineNumber, int columnNumber, string code, string message, bool isWarning) - { - if (string.Equals(file, activeTaskName, StringComparison.InvariantCultureIgnoreCase)) { - file = ""; - } else if (FileUtility.IsValidPath(file)) { - bool isShortFileName = file == Path.GetFileNameWithoutExtension(file); - if (worker.CurrentProjectFile != null) { - file = Path.Combine(Path.GetDirectoryName(worker.CurrentProjectFile), file); - } - if (isShortFileName && !File.Exists(file)) { - file = ""; - } - } - FlushCurrentError(); - BuildError error = new BuildError(file, lineNumber, columnNumber, code, message); - error.IsWarning = isWarning; - results.Add(error); - worker.currentErrorOrWarning = error; - } - - #region ILogger interface implementation - LoggerVerbosity verbosity = LoggerVerbosity.Minimal; - - public LoggerVerbosity Verbosity { - get { - return verbosity; - } - set { - verbosity = value; - } - } - - string parameters; - - public string Parameters { - get { - return parameters; - } - set { - parameters = value; - } - } - - public void Initialize(IEventSource eventSource) - { - eventSource.ProjectStarted += new ProjectStartedEventHandler(OnProjectStarted); - eventSource.ProjectFinished += new ProjectFinishedEventHandler(OnProjectFinished); - eventSource.TaskStarted += new TaskStartedEventHandler(OnTaskStarted); - eventSource.TaskFinished += new TaskFinishedEventHandler(OnTaskFinished); - - eventSource.ErrorRaised += new BuildErrorEventHandler(OnError); - eventSource.WarningRaised += new BuildWarningEventHandler(OnWarning); - } - - public void Shutdown() - { - - } - #endregion - } - } -} diff --git a/src/Main/Base/Project/Src/Project/MSBuildFileProject.cs b/src/Main/Base/Project/Src/Project/MSBuildFileProject.cs new file mode 100644 index 0000000000..b5412f6c03 --- /dev/null +++ b/src/Main/Base/Project/Src/Project/MSBuildFileProject.cs @@ -0,0 +1,30 @@ +// +// +// +// +// $Revision$ +// + +using System; +using ICSharpCode.Core; + +namespace ICSharpCode.SharpDevelop.Project +{ + /// + /// A project that is not a real project, but a MSBuild file included as project. + /// + public class MSBuildFileProject : AbstractProject + { + public MSBuildFileProject(string fileName, string title) + { + Name = title; + FileName = fileName; + TypeGuid = "{00000000-0000-0000-0000-000000000000}"; + } + + public override void StartBuild(ProjectBuildOptions options, IBuildFeedbackSink feedbackSink) + { + MSBuildEngine.Build(this, options, feedbackSink); + } + } +} diff --git a/src/Main/Base/Project/Src/Project/Solution/Solution.cs b/src/Main/Base/Project/Src/Project/Solution/Solution.cs index 07714f31ca..d626b85878 100644 --- a/src/Main/Base/Project/Src/Project/Solution/Solution.cs +++ b/src/Main/Base/Project/Src/Project/Solution/Solution.cs @@ -26,7 +26,7 @@ namespace ICSharpCode.SharpDevelop.Project } } - public class Solution : SolutionFolder, IDisposable, IMSBuildEngineProvider + public class Solution : SolutionFolder, IDisposable, IMSBuildEngineProvider, IBuildable { /// contains , (IProject/ISolutionFolder) pairs. Dictionary guidDictionary = new Dictionary(); @@ -1142,12 +1142,20 @@ namespace ICSharpCode.SharpDevelop.Project } #endregion - public void StartBuild(BuildOptions options) + #region Building + ICollection IBuildable.GetBuildDependencies(ProjectBuildOptions buildOptions) { - MSBuildBasedProject.RunMSBuild(this, null, - this.Preferences.ActiveConfiguration, - this.Preferences.ActivePlatform, - options); + List result = new List(); + foreach (IProject p in this.Projects) + result.Add(p); + return result; } + + void IBuildable.StartBuild(ProjectBuildOptions buildOptions, IBuildFeedbackSink feedbackSink) + { + // building a solution finishes immediately: we only care for the dependencies + feedbackSink.Done(true); + } + #endregion } } diff --git a/src/Main/Base/Project/Src/Services/LanguageBinding/LanguageBindingService.cs b/src/Main/Base/Project/Src/Services/LanguageBinding/LanguageBindingService.cs index 5e699bd079..d3347be8d6 100644 --- a/src/Main/Base/Project/Src/Services/LanguageBinding/LanguageBindingService.cs +++ b/src/Main/Base/Project/Src/Services/LanguageBinding/LanguageBindingService.cs @@ -129,8 +129,16 @@ namespace ICSharpCode.SharpDevelop newProject.TypeGuid = projectTypeGuid; } } else { - newProject = new UnknownProject(location, title); - newProject.TypeGuid = projectTypeGuid; + string ext = Path.GetExtension(location); + if (".proj".Equals(ext, StringComparison.OrdinalIgnoreCase) + || ".build".Equals(ext, StringComparison.OrdinalIgnoreCase)) + { + newProject = new MSBuildFileProject(location, title); + newProject.TypeGuid = projectTypeGuid; + } else { + newProject = new UnknownProject(location, title); + newProject.TypeGuid = projectTypeGuid; + } } } return newProject; diff --git a/src/Main/Base/Project/Src/Services/ParserService/ParseProjectContent.cs b/src/Main/Base/Project/Src/Services/ParserService/ParseProjectContent.cs index 8fc86328fd..7c797f6960 100644 --- a/src/Main/Base/Project/Src/Services/ParserService/ParseProjectContent.cs +++ b/src/Main/Base/Project/Src/Services/ParserService/ParseProjectContent.cs @@ -132,7 +132,7 @@ namespace ICSharpCode.SharpDevelop } } }; - project.StartBuild(new BuildOptions(BuildTarget.ResolveComReferences, afterBuildCallback)); + BuildEngine.BuildInGui(project, new BuildOptions(BuildTarget.ResolveComReferences, afterBuildCallback)); }; // enqueue actions when adding multiple COM references so that multiple builds of the same project diff --git a/src/Main/Base/Project/Src/Util/ExtensionMethods.cs b/src/Main/Base/Project/Src/Util/ExtensionMethods.cs index cebf78cfae..feb027462d 100644 --- a/src/Main/Base/Project/Src/Util/ExtensionMethods.cs +++ b/src/Main/Base/Project/Src/Util/ExtensionMethods.cs @@ -18,9 +18,9 @@ namespace ICSharpCode.SharpDevelop public static class ExtensionMethods { /// - /// Applies an action to all elements in the input. + /// Runs an action for all elements in the input. /// - public static void Apply(this IEnumerable input, Action action) + public static void Foreach(this IEnumerable input, Action action) { if (input == null) throw new ArgumentNullException("input"); diff --git a/src/Main/ICSharpCode.SharpDevelop.BuildWorker/BuildJob.cs b/src/Main/ICSharpCode.SharpDevelop.BuildWorker/BuildJob.cs new file mode 100644 index 0000000000..f0967b3bdd --- /dev/null +++ b/src/Main/ICSharpCode.SharpDevelop.BuildWorker/BuildJob.cs @@ -0,0 +1,52 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.Collections.Generic; +using System.Text; + +namespace ICSharpCode.SharpDevelop.BuildWorker +{ + /// + /// The settings used to start a build. + /// + [Serializable] + public class BuildJob + { + public string ProjectFileName { get; set; } + public string Target { get; set; } + + Dictionary properties = new Dictionary(); + + public Dictionary Properties { + get { return properties; } + } + + List additionalImports = new List(); + + public List AdditionalImports { + get { return additionalImports; } + } + + public override string ToString() + { + StringBuilder b = new StringBuilder(); + b.AppendLine("BuildJob:"); + b.AppendLine(" ProjectFileName = " + ProjectFileName); + b.AppendLine(" Target = " + Target); + b.AppendLine(" " + Properties.Count + " Properties:"); + foreach (KeyValuePair pair in Properties) { + b.AppendLine(" " + pair.Key + " = " + pair.Value); + } + b.AppendLine(" " + AdditionalImports.Count + " Additional Imports:"); + foreach (string import in AdditionalImports) { + b.AppendLine(" " + import); + } + return b.ToString(); + } + } +} diff --git a/src/Main/ICSharpCode.SharpDevelop.BuildWorker/Configuration/AssemblyInfo.cs b/src/Main/ICSharpCode.SharpDevelop.BuildWorker/Configuration/AssemblyInfo.cs new file mode 100644 index 0000000000..5d86f9d39a --- /dev/null +++ b/src/Main/ICSharpCode.SharpDevelop.BuildWorker/Configuration/AssemblyInfo.cs @@ -0,0 +1,16 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.Reflection; +using System.Runtime.CompilerServices; + +[assembly: AssemblyTitle("SharpDevelop Build Worker")] +[assembly: AssemblyDescription("Runs MSBuild")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] diff --git a/src/Main/ICSharpCode.SharpDevelop.BuildWorker/EventSource.cs b/src/Main/ICSharpCode.SharpDevelop.BuildWorker/EventSource.cs new file mode 100644 index 0000000000..d724f737a4 --- /dev/null +++ b/src/Main/ICSharpCode.SharpDevelop.BuildWorker/EventSource.cs @@ -0,0 +1,79 @@ +// +// +// +// +// $Revision$ +// + +using System; +using Microsoft.Build.Framework; + +namespace ICSharpCode.SharpDevelop.BuildWorker +{ + class EventSource : IEventSource + { + public event BuildMessageEventHandler MessageRaised; + public event BuildErrorEventHandler ErrorRaised; + public event BuildWarningEventHandler WarningRaised; + public event BuildStartedEventHandler BuildStarted; + public event BuildFinishedEventHandler BuildFinished; + public event ProjectStartedEventHandler ProjectStarted; + public event ProjectFinishedEventHandler ProjectFinished; + public event TargetStartedEventHandler TargetStarted; + public event TargetFinishedEventHandler TargetFinished; + public event TaskStartedEventHandler TaskStarted; + public event TaskFinishedEventHandler TaskFinished; + public event CustomBuildEventHandler CustomEventRaised; + public event BuildStatusEventHandler StatusEventRaised; + + public event AnyEventHandler AnyEventRaised; + + public void RaiseEvent(BuildEventArgs e) + { + if (e is BuildStatusEventArgs) { + if (e is TargetStartedEventArgs) { + if (TargetStarted != null) + TargetStarted(this, (TargetStartedEventArgs)e); + } else if (e is TargetFinishedEventArgs) { + if (TargetFinished != null) + TargetFinished(this, (TargetFinishedEventArgs)e); + } else if (e is TaskStartedEventArgs) { + if (TaskStarted != null) + TaskStarted(this, (TaskStartedEventArgs)e); + } else if (e is TaskFinishedEventArgs) { + if (TaskFinished != null) + TaskFinished(this, (TaskFinishedEventArgs)e); + } else if (e is ProjectStartedEventArgs) { + if (ProjectStarted != null) + ProjectStarted(this, (ProjectStartedEventArgs)e); + } else if (e is ProjectFinishedEventArgs) { + if (ProjectFinished != null) + ProjectFinished(this, (ProjectFinishedEventArgs)e); + } else if (e is BuildStartedEventArgs) { + if (BuildStarted != null) + BuildStarted(this, (BuildStartedEventArgs)e); + } else if (e is BuildFinishedEventArgs) { + if (BuildFinished != null) + BuildFinished(this, (BuildFinishedEventArgs)e); + } + if (StatusEventRaised != null) + StatusEventRaised(this, (BuildStatusEventArgs)e); + } else if (e is BuildMessageEventArgs) { + if (MessageRaised != null) + MessageRaised(this, (BuildMessageEventArgs)e); + } else if (e is BuildWarningEventArgs) { + if (WarningRaised != null) + WarningRaised(this, (BuildWarningEventArgs)e); + } else if (e is BuildErrorEventArgs) { + if (ErrorRaised != null) + ErrorRaised(this, (BuildErrorEventArgs)e); + } else if (e is CustomBuildEventArgs) { + if (CustomEventRaised != null) + CustomEventRaised(this, (CustomBuildEventArgs)e); + } + + if (AnyEventRaised != null) + AnyEventRaised(this, e); + } + } +} diff --git a/src/Main/ICSharpCode.SharpDevelop.BuildWorker/ICSharpCode.SharpDevelop.BuildWorker.csproj b/src/Main/ICSharpCode.SharpDevelop.BuildWorker/ICSharpCode.SharpDevelop.BuildWorker.csproj new file mode 100644 index 0000000000..4f06f73adc --- /dev/null +++ b/src/Main/ICSharpCode.SharpDevelop.BuildWorker/ICSharpCode.SharpDevelop.BuildWorker.csproj @@ -0,0 +1,70 @@ + + + {C3CBC8E3-81D8-4C5B-9941-DCCD12D50B1F} + Debug + AnyCPU + Exe + ICSharpCode.SharpDevelop.BuildWorker + ICSharpCode.SharpDevelop.BuildWorker + v3.5 + False + False + 4 + false + ..\..\..\bin\ + True + ..\ICSharpCode.SharpDevelop.snk + False + File + + + true + Full + False + True + DEBUG;TRACE + + + False + None + True + False + TRACE + + + False + Auto + 4194304 + AnyCPU + 4096 + + + + + + + + + + + + + Configuration\GlobalAssemblyInfo.cs + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Main/ICSharpCode.SharpDevelop.BuildWorker/Interprocess/HostProcess.cs b/src/Main/ICSharpCode.SharpDevelop.BuildWorker/Interprocess/HostProcess.cs new file mode 100644 index 0000000000..6b13b57881 --- /dev/null +++ b/src/Main/ICSharpCode.SharpDevelop.BuildWorker/Interprocess/HostProcess.cs @@ -0,0 +1,102 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.Diagnostics; +using System.Net; +using System.Net.Sockets; +using System.IO; +using System.Threading; +using System.Reflection; + +namespace ICSharpCode.SharpDevelop.BuildWorker.Interprocess +{ + /// + /// Used in the worker process to refer to the host. + /// + public class HostProcess + { + object workerObject; + + public HostProcess(object workerObject) + { + this.workerObject = workerObject; + } + + TcpClient client; + PacketReceiver receiver; + PacketSender sender; + + ManualResetEvent shutdownEvent; + bool connectionIsLost; + + internal const int SendKeepAliveInterval = 10000; + + public void WorkerProcessMain(string argument) + { + int port = int.Parse(argument); + + client = new TcpClient(); + client.Connect(new IPEndPoint(IPAddress.Loopback, port)); + Stream stream = client.GetStream(); + receiver = new PacketReceiver(); + sender = new PacketSender(stream); + shutdownEvent = new ManualResetEvent(false); + receiver.ConnectionLost += OnConnectionLost; + receiver.PacketReceived += OnPacketReceived; + sender.WriteFailed += OnConnectionLost; + + receiver.StartReceive(stream); + while (!shutdownEvent.WaitOne(SendKeepAliveInterval, false)) { + Program.Log("Sending keep-alive packet"); + sender.Send(new byte[0]); + } + + Program.Log("Closing client (end of WorkerProcessMain)"); + client.Close(); + shutdownEvent.Close(); + } + + public void Disconnect() + { + client.Close(); + } + + public void CallMethodOnHost(string methodName, params object[] args) + { + sender.Send(WorkerProcess.SerializeObject(new WorkerProcess.MethodCall(methodName, args))); + } + + void OnConnectionLost(object sender, EventArgs e) + { + lock (this) { + if (connectionIsLost) + return; + Program.Log("OnConnectionLost"); + connectionIsLost = true; + shutdownEvent.Set(); + } + } + + void OnPacketReceived(object sender, PacketReceivedEventArgs e) + { + Program.Log("OnPacketReceived"); + if (e.Packet.Length != 0) { + try { + WorkerProcess.MethodCall mc = (WorkerProcess.MethodCall)WorkerProcess.DeserializeObject(e.Packet); + mc.CallOn(workerObject); + } catch (TargetInvocationException ex) { + Program.Log(ex.ToString()); + CallMethodOnHost("ReportException", ex.InnerException); + } catch (Exception ex) { + Program.Log(ex.ToString()); + CallMethodOnHost("ReportException", ex); + } + } + } + } +} diff --git a/src/Main/ICSharpCode.SharpDevelop.BuildWorker/Interprocess/IHostObject.cs b/src/Main/ICSharpCode.SharpDevelop.BuildWorker/Interprocess/IHostObject.cs new file mode 100644 index 0000000000..74a82b13f5 --- /dev/null +++ b/src/Main/ICSharpCode.SharpDevelop.BuildWorker/Interprocess/IHostObject.cs @@ -0,0 +1,16 @@ +// +// +// +// +// $Revision$ +// + +using System; + +namespace ICSharpCode.SharpDevelop.BuildWorker.Interprocess +{ + public interface IHostObject + { + void ReportException(Exception ex); + } +} diff --git a/src/Main/ICSharpCode.SharpDevelop.BuildWorker/Interprocess/PacketReceiver.cs b/src/Main/ICSharpCode.SharpDevelop.BuildWorker/Interprocess/PacketReceiver.cs new file mode 100644 index 0000000000..750d45fe9a --- /dev/null +++ b/src/Main/ICSharpCode.SharpDevelop.BuildWorker/Interprocess/PacketReceiver.cs @@ -0,0 +1,138 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.Net; +using System.Net.Sockets; +using System.Diagnostics; +using System.IO; +using System.Runtime; +using System.Runtime.Serialization; +using System.Runtime.Serialization.Formatters; +using System.Runtime.Serialization.Formatters.Binary; + +namespace ICSharpCode.SharpDevelop.BuildWorker.Interprocess +{ + public sealed class PacketReceiver + { + Stream stream; + byte[] buffer = new byte[10000]; + int bufferReadOffset; + + public void StartReceive(Stream stream) + { + if (stream == null) + throw new ArgumentNullException("stream"); + if (this.stream != null) + throw new InvalidOperationException("StartReceive can be called only once."); + this.stream = stream; + try { + stream.BeginRead(buffer, 0, buffer.Length, OnReceive, null); + } catch (ObjectDisposedException) { + OnConnectionLost(); + } catch (IOException) { + OnConnectionLost(); + } + } + + int maxPacketSize = int.MaxValue - 20000; + + /// + /// Gets/Sets the maximum allowed packet size in bytes. + /// + public int MaxPacketSize { + get { return maxPacketSize; } + set { + if (value < 1) + throw new ArgumentOutOfRangeException("value", value, "MaxPacketSize must be >0"); + maxPacketSize = value; + } + } + + void OnReceive(IAsyncResult ar) + { + int bytes; + try { + bytes = stream.EndRead(ar); + } catch (ObjectDisposedException) { + OnConnectionLost(); + return; + } catch (IOException) { + OnConnectionLost(); + return; + } + bufferReadOffset += bytes; + int packetStart = 0; + int packetSize = -1; + while (bufferReadOffset >= packetStart + 4) { + packetSize = BitConverter.ToInt32(buffer, packetStart); + if (packetSize < 4) + throw new ProtocolViolationException("packetSize must be > 4"); + if (packetSize - 4 > MaxPacketSize) + throw new ProtocolViolationException("packetSize must be smaller than MaxPacketSize"); + if (bufferReadOffset >= packetStart + packetSize) { + //Debug.WriteLine("receiving packet of size " + packetSize); + byte[] packet = new byte[packetSize - 4]; + Array.Copy(buffer, packetStart + 4, packet, 0, packet.Length); + OnPacketReceived(packet); + packetStart += packetSize; + } else { + break; + } + } + if (packetStart != 0) { + // copy half-received packet to the beginning of the buffer + int copyAmount = bufferReadOffset - packetStart; + for (int i = 0; i < copyAmount; i++) { + buffer[i] = buffer[i + packetStart]; + } + bufferReadOffset = copyAmount; + } + if (packetSize > buffer.Length) { + Debug.WriteLine("resizing receive buffer for packet of size " + packetSize); + Array.Resize(ref buffer, Math.Max(packetSize, buffer.Length * 2)); + } + try { + stream.BeginRead(buffer, bufferReadOffset, buffer.Length - bufferReadOffset, OnReceive, null); + } catch (ObjectDisposedException) { + OnConnectionLost(); + } catch (IOException) { + OnConnectionLost(); + } + } + + void OnConnectionLost() + { + if (ConnectionLost != null) + ConnectionLost(this, EventArgs.Empty); + } + + void OnPacketReceived(byte[] packet) + { + if (PacketReceived != null) + PacketReceived(this, new PacketReceivedEventArgs(packet)); + } + + public event EventHandler ConnectionLost; + public event EventHandler PacketReceived; + } + + public class PacketReceivedEventArgs : EventArgs + { + byte[] packet; + + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] + public byte[] Packet { + get { return packet; } + } + + public PacketReceivedEventArgs(byte[] packet) + { + this.packet = packet; + } + } +} diff --git a/src/Main/ICSharpCode.SharpDevelop.BuildWorker/Interprocess/PacketSender.cs b/src/Main/ICSharpCode.SharpDevelop.BuildWorker/Interprocess/PacketSender.cs new file mode 100644 index 0000000000..d0afe95fcf --- /dev/null +++ b/src/Main/ICSharpCode.SharpDevelop.BuildWorker/Interprocess/PacketSender.cs @@ -0,0 +1,67 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.IO; +using System.Threading; + +namespace ICSharpCode.SharpDevelop.BuildWorker.Interprocess +{ + /// + /// Description of PacketSender. + /// + public sealed class PacketSender + { + Stream targetStream; + public PacketSender(Stream stream) + { + if (stream == null) + throw new ArgumentNullException("stream"); + targetStream = stream; + } + + public void Send(byte[] packet) + { + if (packet == null) + throw new ArgumentNullException("packet"); + Send(new MemoryStream(packet, false)); + } + + public void Send(Stream stream) + { + if (stream == null) + throw new ArgumentNullException("stream"); + byte[] buffer = new byte[4 + stream.Length]; + unchecked { + buffer[0] = (byte)buffer.Length; + buffer[1] = (byte)(buffer.Length >> 8); + buffer[2] = (byte)(buffer.Length >> 16); + buffer[3] = (byte)(buffer.Length >> 24); + } + int pos = 4; + int c; + do { + c = stream.Read(buffer, pos, buffer.Length - pos); + pos += c; + } while (c > 0); + try { + targetStream.Write(buffer, 0, buffer.Length); + } catch (Exception ex) { + ICSharpCode.SharpDevelop.BuildWorker.Program.Log(ex.ToString()); + OnWriteFailed(); + } + } + + void OnWriteFailed() + { + if (WriteFailed != null) + WriteFailed(this, EventArgs.Empty); + } + + public event EventHandler WriteFailed; + } +} diff --git a/src/Main/ICSharpCode.SharpDevelop.BuildWorker/Interprocess/WorkerProcess.cs b/src/Main/ICSharpCode.SharpDevelop.BuildWorker/Interprocess/WorkerProcess.cs new file mode 100644 index 0000000000..15fa970e8b --- /dev/null +++ b/src/Main/ICSharpCode.SharpDevelop.BuildWorker/Interprocess/WorkerProcess.cs @@ -0,0 +1,224 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.Diagnostics; +using System.Reflection; +using System.Net; +using System.Net.Sockets; +using System.IO; +using System.Runtime.Serialization.Formatters; +using System.Runtime.Serialization.Formatters.Binary; +using System.Runtime.Serialization; +using System.Threading; + +namespace ICSharpCode.SharpDevelop.BuildWorker.Interprocess +{ + /// + /// Manages a worker process that communicates with the host using a local TCP connection. + /// + public sealed class WorkerProcess + { + object hostObject; + + public WorkerProcess(IHostObject hostObject) + { + if (hostObject == null) + throw new ArgumentException("hostObject"); + this.hostObject = hostObject; + } + + TcpListener listener; + Process process; + + TcpClient client; + PacketSender sender; + PacketReceiver receiver; + + public void Start(ProcessStartInfo info) + { + listener = new TcpListener(IPAddress.Loopback, 0); + listener.Start(); + string argument = ((IPEndPoint)listener.LocalEndpoint).Port.ToString(); + + string oldArguments = info.Arguments; + info.Arguments += " " + argument; + process = Process.Start(info); + info.Arguments = oldArguments; + + SetTimeout(); + listener.BeginAcceptTcpClient(OnAcceptTcpClient, null); + } + + Timer currentTimer; + + void SetTimeout() + { + lock (this) { + ClearTimeout(); + currentTimer = new Timer(OnTimeout, null, HostProcess.SendKeepAliveInterval * 3 / 2, -1); + } + } + + void ClearTimeout() + { + lock (this) { + if (currentTimer != null) { + currentTimer.Dispose(); + currentTimer = null; + } + } + } + + void OnTimeout(object state) + { + Program.Log("OnTimeout"); + Kill(); + } + + void OnAcceptTcpClient(IAsyncResult ar) + { + SetTimeout(); + try { + client = listener.EndAcceptTcpClient(ar); + } catch (SocketException) { + // error connecting + } + listener.Stop(); + listener = null; + + if (client == null) { + OnConnectionLost(null, null); + } else { + Stream stream = client.GetStream(); + receiver = new PacketReceiver(); + sender = new PacketSender(stream); + receiver.ConnectionLost += OnConnectionLost; + receiver.PacketReceived += OnPacketReceived; + + receiver.StartReceive(stream); + OnReady(); + } + } + + public void Shutdown() + { + Program.Log("Shutdown"); + OnWorkerLost(); + if (client != null) { + client.Close(); + } + } + + void OnConnectionLost(object sender, EventArgs e) + { + Program.Log("OnConnectionLost"); + SetTimeout(); + OnWorkerLost(); + } + + void OnPacketReceived(object sender, PacketReceivedEventArgs e) + { + SetTimeout(); + if (e.Packet.Length != 0) { + MethodCall mc = (MethodCall)DeserializeObject(e.Packet); + mc.CallOn(hostObject); + } + } + + public void Kill() + { + Program.Log("Kill"); + ClearTimeout(); + OnWorkerLost(); + if (client != null) { + client.Close(); + client = null; + } + if (process != null) { + try { + if (!process.HasExited) { + process.Kill(); + } + } catch (InvalidOperationException) { + // may occur when the worker process crashes + } + process = null; + } + } + + int workerIsLost; + + void OnReady() + { + if (workerIsLost == 1) + return; + Program.Log("OnReady"); + if (Ready != null) + Ready(this, EventArgs.Empty); + } + + void OnWorkerLost() + { + if (Interlocked.Exchange(ref workerIsLost, 1) == 1) + return; + Program.Log("OnWorkerLost"); + if (WorkerLost != null) + WorkerLost(this, EventArgs.Empty); + } + + /// + /// Occurs when the worker process is ready to execute a job. + /// + public event EventHandler Ready; + + /// + /// Occurs when the connection to the worker process broke. + /// + public event EventHandler WorkerLost; + + public void CallMethodOnWorker(string methodName, params object[] args) + { + sender.Send(SerializeObject(new MethodCall(methodName, args))); + } + + internal static MemoryStream SerializeObject(object obj) + { + MemoryStream ms = new MemoryStream(); + BinaryFormatter bf = new BinaryFormatter(); + bf.Serialize(ms, obj); + ms.Position = 0; + return ms; + } + + internal static object DeserializeObject(byte[] packet) + { + BinaryFormatter bf = new BinaryFormatter(); + return bf.Deserialize(new MemoryStream(packet, false)); + } + + [Serializable] + internal class MethodCall + { + public readonly string MethodName; + public readonly object[] Arguments; + + public MethodCall(string methodName, object[] arguments) + { + this.MethodName = methodName; + this.Arguments = arguments; + } + + public void CallOn(object target) + { + target.GetType().InvokeMember(MethodName, + BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Instance, + null, target, Arguments); + } + } + } +} diff --git a/src/Main/ICSharpCode.SharpDevelop.BuildWorker/Program.cs b/src/Main/ICSharpCode.SharpDevelop.BuildWorker/Program.cs new file mode 100644 index 0000000000..c1260398af --- /dev/null +++ b/src/Main/ICSharpCode.SharpDevelop.BuildWorker/Program.cs @@ -0,0 +1,323 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.Collections.Generic; +using System.IO; +using System.Diagnostics; +using System.Threading; +using ICSharpCode.SharpDevelop.BuildWorker.Interprocess; +using Microsoft.Build.Framework; +using Microsoft.Build.BuildEngine; + +// activate this define to see the build worker window +//#define WORKERDEBUG + +namespace ICSharpCode.SharpDevelop.BuildWorker +{ + class Program + { + static HostProcess host; + BuildJob currentJob; + bool requestCancellation; + + internal static void Main(string[] args) + { + AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(AppDomain_CurrentDomain_UnhandledException); + + if (args.Length == 2 && args[0] == "worker") { + try { + host = new HostProcess(new Program()); + host.WorkerProcessMain(args[1]); + } catch (Exception ex) { + ShowMessageBox(ex.ToString()); + } + } else { + Program.Log("ICSharpCode.SharpDevelop.BuildWorker.exe is used to compile " + + "MSBuild projects inside SharpDevelop."); + Program.Log("If you want to compile projects on the command line, use " + + "MSBuild.exe (part of the .NET Framework)"); + } + } + + static void AppDomain_CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) + { + ShowMessageBox(e.ExceptionObject.ToString()); + } + + internal static ProcessStartInfo CreateStartInfo() + { + ProcessStartInfo info = new ProcessStartInfo(typeof(Program).Assembly.Location); + info.WorkingDirectory = Path.GetDirectoryName(info.FileName); + info.Arguments = "worker"; + #if RELEASE || !WORKERDEBUG + info.UseShellExecute = false; + info.CreateNoWindow = true; + #endif + return info; + } + + internal static void ShowMessageBox(string text) + { + System.Windows.Forms.MessageBox.Show(text, "SharpDevelop Build Worker Process"); + } + + [Conditional("DEBUG")] + internal static void Log(string text) + { + #if WORKERDEBUG + DateTime now = DateTime.Now; + Console.WriteLine(now.ToString() + "," + now.Millisecond.ToString("d3") + " " + text); + #endif + } + + // Called with CallMethodOnWorker + public void StartBuild(BuildJob job) + { + if (job == null) + throw new ArgumentNullException("job"); + lock (this) { + if (currentJob != null) + throw new InvalidOperationException("Already running a job"); + currentJob = job; + requestCancellation = false; + } + #if DEBUG && WORKERDEBUG + Console.Title = "BuildWorker - " + Path.GetFileName(job.ProjectFileName); + #endif + Program.Log("Got job:"); + Program.Log(job.ToString()); + Program.Log("Start build thread"); + Thread thread = new Thread(RunThread); + thread.Name = "Build thread"; + thread.SetApartmentState(ApartmentState.STA); + thread.Start(); + } + + // Called with CallMethodOnWorker + public void CancelBuild() + { + lock (this) { + requestCancellation = true; + } + } + + Engine engine; + + void RunThread() + { + Program.Log("In build thread"); + bool success = false; + try { + if (engine == null) { + engine = CreateEngine(); + } + success = DoBuild(); + } catch (Exception ex) { + host.CallMethodOnHost("ReportException", ex); + } finally { + Program.Log("BuildDone"); + + #if DEBUG && WORKERDEBUG + Console.Title = "BuildWorker - no job"; + #endif + + lock (this) { + currentJob = null; + } + // in the moment we call BuildDone, we can get the next job + host.CallMethodOnHost("BuildDone", success); + } + } + + Engine CreateEngine() + { + Engine engine = new Engine(ToolsetDefinitionLocations.Registry + | ToolsetDefinitionLocations.ConfigurationFile); + + engine.RegisterLogger(new ForwardingLogger(this)); + + return engine; + } + + InProcessLogger inProcessLogger; + + internal void BuildInProcess(BuildSettings settings, BuildJob job) + { + lock (this) { + if (currentJob != null) + throw new InvalidOperationException("Already running a job"); + currentJob = job; + requestCancellation = false; + inProcessLogger = new InProcessLogger(); + } + bool success = false; + try { + if (engine == null) { + engine = new Engine(ToolsetDefinitionLocations.Registry + | ToolsetDefinitionLocations.ConfigurationFile); + } + engine.UnregisterAllLoggers(); + engine.RegisterLogger(inProcessLogger); + foreach (ILogger logger in settings.Logger) { + logger.Initialize(inProcessLogger.EventSource); + } + success = DoBuild(); + foreach (ILogger logger in settings.Logger) { + logger.Shutdown(); + } + engine.UnregisterAllLoggers(); + } catch (Exception ex) { + if (WorkerManager.ShowError != null) + WorkerManager.ShowError(ex); + else + Program.ShowMessageBox(ex.ToString()); + } finally { + lock (this) { + currentJob = null; + } + if (settings.BuildDoneCallback != null) + settings.BuildDoneCallback(success); + } + } + + bool DoBuild() + { + engine.GlobalProperties.Clear(); + foreach (KeyValuePair pair in currentJob.Properties) { + engine.GlobalProperties.SetProperty(pair.Key, pair.Value); + } + + Project project = LoadProject(engine, currentJob.ProjectFileName); + if (project == null) + return false; + + if (string.IsNullOrEmpty(currentJob.Target)) { + return engine.BuildProject(project); + } else { + return engine.BuildProject(project, currentJob.Target.Split(';')); + } + } + + Project LoadProject(Engine engine, string fileName) + { + Project project = engine.CreateNewProject(); + try { + project.Load(fileName); + + // When we set BuildingInsideVisualStudio, MSBuild tries to build all projects + // every time because in Visual Studio, the host compiler does the change detection + // We override the property '_ComputeNonExistentFileProperty' which is responsible + // for recompiling each time - our _ComputeNonExistentFileProperty does nothing, + // which re-enables the MSBuild's usual change detection + project.Targets.AddNewTarget("_ComputeNonExistentFileProperty"); + + foreach (string additionalImport in currentJob.AdditionalImports) { + project.AddNewImport(additionalImport, null); + } + + return project; + } catch (ArgumentException ex) { + ReportError(ex.Message); + } catch (InvalidProjectFileException ex) { + ReportError(new BuildErrorEventArgs(ex.ErrorSubcategory, ex.ErrorCode, ex.ProjectFile, + ex.LineNumber, ex.ColumnNumber, ex.EndLineNumber, ex.EndColumnNumber, + ex.BaseMessage, ex.HelpKeyword, ex.Source)); + } + return null; + } + + void ReportError(string message) + { + ReportError(new BuildErrorEventArgs(null, null, null, -1, -1, -1, -1, + message, null, "SharpDevelopBuildWorker")); + } + + void ReportError(BuildErrorEventArgs e) + { + if (host != null) { + HostReportEvent(e); + } else { + // enable error reporting for in-process builds + InProcessLogger logger = inProcessLogger; + if (logger != null) { + logger.EventSource.RaiseEvent(e); + } + } + } + + void HostReportEvent(BuildEventArgs e) + { + host.CallMethodOnHost("ReportEvent", e); + } + + sealed class ForwardingLogger : ILogger + { + Program program; + + public ForwardingLogger(Program program) + { + this.program = program; + } + + IEventSource eventSource; + + public LoggerVerbosity Verbosity { get; set; } + public string Parameters { get; set; } + + public void Initialize(IEventSource eventSource) + { + this.eventSource = eventSource; + eventSource.AnyEventRaised += OnAnyEventRaised; + } + + public void Shutdown() + { + eventSource.AnyEventRaised -= OnAnyEventRaised; + } + + void OnAnyEventRaised(object sender, BuildEventArgs e) + { + if (program.requestCancellation) + throw new BuildCancelException(); + program.HostReportEvent(e); + } + } + + sealed class InProcessLogger : ILogger + { + public readonly EventSource EventSource = new EventSource(); + + public LoggerVerbosity Verbosity { get; set; } + + public string Parameters { get; set; } + + IEventSource realEventSource; + + public void Initialize(IEventSource eventSource) + { + this.realEventSource = eventSource; + this.realEventSource.AnyEventRaised += OnAnyEventRaised; + } + + public void Shutdown() + { + this.realEventSource.AnyEventRaised -= OnAnyEventRaised; + } + + void OnAnyEventRaised(object sender, BuildEventArgs e) + { + this.EventSource.RaiseEvent(e); + } + } + + [Serializable] + sealed class BuildCancelException : Exception + { + } + } +} \ No newline at end of file diff --git a/src/Main/ICSharpCode.SharpDevelop.BuildWorker/WorkerManager.cs b/src/Main/ICSharpCode.SharpDevelop.BuildWorker/WorkerManager.cs new file mode 100644 index 0000000000..c4c78ef848 --- /dev/null +++ b/src/Main/ICSharpCode.SharpDevelop.BuildWorker/WorkerManager.cs @@ -0,0 +1,265 @@ +// +// +// +// +// $Revision$ +// + +using Microsoft.Build.Framework; +using System; +using System.Collections.Generic; +using System.Threading; +using System.Diagnostics; +using ICSharpCode.SharpDevelop.BuildWorker.Interprocess; + +namespace ICSharpCode.SharpDevelop.BuildWorker +{ + /// + /// Manages the list of running child worker processes. + /// + public static class WorkerManager + { + /// + /// Delegate executed on the host when an exception occurs. + /// + public static Action ShowError { get; set; } + + const int MaxWorkerProcessCount = 16; + + static readonly object lockObject = new object(); + static Queue outstandingBuildRuns = new Queue(); + static int workerProcessCount; + static List freeWorkerProcesses = new List(); + + static WorkerProcessHost DequeueFreeWorkerProcess() + { + WorkerProcessHost h = freeWorkerProcesses[freeWorkerProcesses.Count - 1]; + freeWorkerProcesses.RemoveAt(freeWorkerProcesses.Count - 1); + return h; + } + + public static void StartBuild(BuildJob job, BuildSettings settings) + { + if (job == null) + throw new ArgumentNullException("job"); + if (settings == null) + throw new ArgumentNullException("settings"); + + BuildRun buildRun = new BuildRun(job, settings); + lock (lockObject) { + if (freeWorkerProcesses.Count > 0) { + DequeueFreeWorkerProcess().StartBuild(buildRun); + } else { + outstandingBuildRuns.Enqueue(buildRun); + if (workerProcessCount < MaxWorkerProcessCount) { + workerProcessCount++; + (new WorkerProcessHost()).Start(); + } + } + } + } + + static Program inProcessBuildWorker; + + public static void RunBuildInProcess(BuildJob job, BuildSettings settings) + { + if (job == null) + throw new ArgumentNullException("job"); + if (settings == null) + throw new ArgumentNullException("settings"); + lock (lockObject) { + if (inProcessBuildWorker == null) + inProcessBuildWorker = new Program(); + } + inProcessBuildWorker.BuildInProcess(settings, job); + } + + static readonly object timerLock = new object(); + static Timer lastBuildDoneTimer; + + static void SetLastBuildDoneTimer() + { + lock (timerLock) { + if (lastBuildDoneTimer != null) { + lastBuildDoneTimer.Dispose(); + lastBuildDoneTimer = null; + } + lastBuildDoneTimer = new Timer(LastBuildDoneTimerCallback, null, 60000, 20000); + } + } + + static void ClearLastBuildDoneTimer() + { + lock (timerLock) { + if (lastBuildDoneTimer != null) { + lastBuildDoneTimer.Dispose(); + lastBuildDoneTimer = null; + } + } + } + + static void LastBuildDoneTimerCallback(object state) + { + lock (lockObject) { + if (freeWorkerProcesses.Count > 0) { + DequeueFreeWorkerProcess().Shutdown(); + } else { + ClearLastBuildDoneTimer(); + } + } + } + + sealed class BuildRun + { + internal BuildJob job; + internal BuildSettings settings; + EventSource eventSource = new EventSource(); + + public BuildRun(BuildJob job, BuildSettings settings) + { + this.job = job; + this.settings = settings; + foreach (ILogger logger in settings.Logger) { + logger.Initialize(eventSource); + } + } + + public void RaiseError(string message) + { + RaiseEvent(new BuildErrorEventArgs(null, null, null, -1, -1, -1, -1, message, null, "SharpDevelopBuildWorkerManager")); + } + + public void RaiseEvent(BuildEventArgs e) + { + eventSource.RaiseEvent(e); + } + + public void Done(bool success) + { + SetLastBuildDoneTimer(); + try { + foreach (ILogger logger in settings.Logger) { + logger.Shutdown(); + } + } finally { + if (settings.BuildDoneCallback != null) + settings.BuildDoneCallback(success); + } + } + } + + sealed class WorkerProcessHost : IHostObject + { + WorkerProcess process; + + internal void Start() + { + process = new WorkerProcess(this); + process.Ready += OnReady; + process.WorkerLost += OnWorkerLost; + + process.Start(Program.CreateStartInfo()); + } + + BuildRun currentBuildRun; + + // runs in lock(lockObject) + internal void StartBuild(BuildRun nextBuildRun) + { + Debug.Assert(currentBuildRun == null); + currentBuildRun = nextBuildRun; + process.CallMethodOnWorker("StartBuild", currentBuildRun.job); + } + + void OnReady(object sender, EventArgs e) + { + BuildRun nextBuildRun = null; + lock (lockObject) { + if (outstandingBuildRuns.Count > 0) + nextBuildRun = outstandingBuildRuns.Dequeue(); + else + freeWorkerProcesses.Add(this); + } + if (nextBuildRun != null) { + StartBuild(nextBuildRun); + } + } + + void OnWorkerLost(object sender, EventArgs e) + { + lock (lockObject) { + workerProcessCount--; + freeWorkerProcesses.Remove(this); + if (workerProcessCount == 0 && currentBuildRun == null) { + // error starting worker => we must + // cancel all outstanding build runs to prevent them from waiting + // for a worker becoming ready when all workers are dead + while (workerProcessCount == 0 && outstandingBuildRuns.Count > 0) { + BuildRun r = outstandingBuildRuns.Dequeue(); + Monitor.Exit(lockObject); + r.RaiseError("Error starting worker process."); + r.Done(false); + Monitor.Enter(lockObject); + } + } + } + BuildRun buildRun = Interlocked.Exchange(ref currentBuildRun, null); + if (buildRun != null) { + buildRun.RaiseError("Worker process lost during build"); + buildRun.Done(false); + } + } + + internal void Shutdown() + { + process.Shutdown(); + } + + // Called with CallMethodOnHost + public void ReportEvent(BuildEventArgs e) + { + BuildRun buildRun = currentBuildRun; + if (buildRun != null) { + buildRun.RaiseEvent(e); + } + } + + // Called with CallMethodOnHost + public void BuildDone(bool success) + { + BuildRun buildRun = Interlocked.Exchange(ref currentBuildRun, null); + if (buildRun != null) { + // OnReady must be called before buildRun.Done - the callback + // might trigger another build, and if this worker process + // isn't marked as ready, a new process will be created even + // though this one could do the work. + OnReady(null, null); + buildRun.Done(success); + } + } + + public void ReportException(Exception ex) + { + // shutdown worker if it produced an exception + try { + process.Shutdown(); + } catch {} + + if (ShowError != null) + ShowError(ex); + else + Program.ShowMessageBox(ex.ToString()); + } + } + } + + public sealed class BuildSettings + { + List logger = new List(); + public Action BuildDoneCallback { get; set; } + + public ICollection Logger { + get { return logger; } + } + } +} diff --git a/src/Main/ICSharpCode.SharpDevelop.BuildWorker/app.config b/src/Main/ICSharpCode.SharpDevelop.BuildWorker/app.config new file mode 100644 index 0000000000..acbc7ec0cc --- /dev/null +++ b/src/Main/ICSharpCode.SharpDevelop.BuildWorker/app.config @@ -0,0 +1,15 @@ + + + + + + + + + + + + diff --git a/src/SharpDevelop.Tests.sln b/src/SharpDevelop.Tests.sln index 9f9a7bb816..e466590c03 100644 --- a/src/SharpDevelop.Tests.sln +++ b/src/SharpDevelop.Tests.sln @@ -1,110 +1,112 @@  Microsoft Visual Studio Solution File, Format Version 10.00 # Visual Studio 2008 -# SharpDevelop 3.0.0.2644 +# SharpDevelop 3.0.0.2693 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "AddIns", "AddIns", "{14A277EE-7DF1-4529-B639-7D1EF334C1C5}" ProjectSection(SolutionItems) = postProject EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SearchAndReplace.Tests", "AddIns\Misc\SearchAndReplace\Test\SearchAndReplace.Tests.csproj", "{A569DCC1-C608-45FD-B770-4F79335EF154}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CSharpBinding", "AddIns\BackendBindings\CSharpBinding\Project\CSharpBinding.csproj", "{1F1AC7CD-D154-45BB-8EAF-804CA8055F5A}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SearchAndReplace", "AddIns\Misc\SearchAndReplace\Project\SearchAndReplace.csproj", "{9196DD8A-B4D4-4780-8742-C5762E547FC2}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NRefactoryToBooConverter", "AddIns\BackendBindings\Boo\NRefactoryToBooConverter\Project\NRefactoryToBooConverter.csproj", "{DBCF20A1-BA13-4582-BFA9-74DE4D987B73}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "WpfDesign", "WpfDesign", "{C12B6EA7-2EFC-4368-B585-EC69EFCC3F97}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NRefactoryToBooConverter.Tests", "AddIns\BackendBindings\Boo\NRefactoryToBooConverter\Test\NRefactoryToBooConverter.Tests.csproj", "{C9DE556D-325C-4544-B29F-16A9EB7C9830}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Debugger", "Debugger", "{6604365C-C702-4C10-9BA8-637F1E3D4D0D}" ProjectSection(SolutionItems) = postProject EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WpfDesign", "AddIns\DisplayBindings\WpfDesign\WpfDesign\Project\WpfDesign.csproj", "{66A378A1-E9F4-4AD5-8946-D0EC06C2902F}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TreeListView", "AddIns\Misc\Debugger\TreeListView\Project\TreeListView.csproj", "{B08385CD-F0CC-488C-B4F4-EEB34B6D2688}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WpfDesign.Designer", "AddIns\DisplayBindings\WpfDesign\WpfDesign.Designer\Project\WpfDesign.Designer.csproj", "{78CC29AC-CC79-4355-B1F2-97936DF198AC}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Debugger.Core", "AddIns\Misc\Debugger\Debugger.Core\Project\Debugger.Core.csproj", "{1D18D788-F7EE-4585-A23B-34DC8EC63CB8}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WpfDesign.Tests", "AddIns\DisplayBindings\WpfDesign\WpfDesign.Designer\Tests\WpfDesign.Tests.csproj", "{943DBBB3-E84E-4CF4-917C-C05AFA8743C1}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Debugger.AddIn", "AddIns\Misc\Debugger\Debugger.AddIn\Project\Debugger.AddIn.csproj", "{EC06F96A-AEEC-49D6-B03D-AB87C6EB674C}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WpfDesign.XamlDom", "AddIns\DisplayBindings\WpfDesign\WpfDesign.XamlDom\Project\WpfDesign.XamlDom.csproj", "{88DA149F-21B2-48AB-82C4-28FB6BDFD783}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Debugger.Tests", "AddIns\Misc\Debugger\Debugger.Tests\Project\Debugger.Tests.csproj", "{A4C858C8-51B6-4265-A695-A20FCEBA1D19}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTesting.Tests", "AddIns\Misc\UnitTesting\Test\UnitTesting.Tests.csproj", "{44A8DE09-CAB9-49D8-9CFC-5EB0A552F181}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XmlEditor", "AddIns\DisplayBindings\XmlEditor\Project\XmlEditor.csproj", "{6B717BD1-CD5E-498C-A42E-9E6A4584DC48}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WixBinding.Tests", "AddIns\BackendBindings\WixBinding\Test\WixBinding.Tests.csproj", "{388E7B64-0393-4EB4-A3E3-5C474F141853}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XmlEditor.Tests", "AddIns\DisplayBindings\XmlEditor\Test\XmlEditor.Tests.csproj", "{FC0FE702-A87D-4D70-A9B6-1ECCD611125F}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WixBinding", "AddIns\BackendBindings\WixBinding\Project\WixBinding.csproj", "{e1b288a2-08ee-4318-8bbb-8ab72c69e33e}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VBNetBinding", "AddIns\BackendBindings\VBNetBinding\Project\VBNetBinding.csproj", "{BF38FB72-B380-4196-AF8C-95749D726C61}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeAnalysis", "AddIns\Misc\CodeAnalysis\CodeAnalysis.csproj", "{3EAA45A9-735C-4AC7-A799-947B93EA449D}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeCoverage.Tests", "AddIns\Misc\CodeCoverage\Test\CodeCoverage.Tests.csproj", "{A5C0E8F8-9D04-46ED-91D6-1DEF1575313B}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FormsDesigner", "AddIns\DisplayBindings\FormsDesigner\Project\FormsDesigner.csproj", "{7D7E92DF-ACEB-4B69-92C8-8AC7A703CD57}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeCoverage", "AddIns\Misc\CodeCoverage\Project\CodeCoverage.csproj", "{08ce9972-283b-44f4-82fa-966f7dfa6b7a}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BooBinding.Tests", "AddIns\BackendBindings\Boo\BooBinding\Test\BooBinding.Tests.csproj", "{6FA16499-896F-4C02-BB43-1AF5C6C7C713}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTesting", "AddIns\Misc\UnitTesting\UnitTesting.csproj", "{1F261725-6318-4434-A1B1-6C70CE4CD324}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BooBinding", "AddIns\BackendBindings\Boo\BooBinding\Project\BooBinding.csproj", "{4AC2D5F1-F671-480C-A075-6BF62B3721B2}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTesting", "AddIns\Misc\UnitTesting\UnitTesting.csproj", "{1F261725-6318-4434-A1B1-6C70CE4CD324}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BooBinding.Tests", "AddIns\BackendBindings\Boo\BooBinding\Test\BooBinding.Tests.csproj", "{6FA16499-896F-4C02-BB43-1AF5C6C7C713}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeCoverage", "AddIns\Misc\CodeCoverage\Project\CodeCoverage.csproj", "{08ce9972-283b-44f4-82fa-966f7dfa6b7a}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FormsDesigner", "AddIns\DisplayBindings\FormsDesigner\Project\FormsDesigner.csproj", "{7D7E92DF-ACEB-4B69-92C8-8AC7A703CD57}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeCoverage.Tests", "AddIns\Misc\CodeCoverage\Test\CodeCoverage.Tests.csproj", "{A5C0E8F8-9D04-46ED-91D6-1DEF1575313B}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeAnalysis", "AddIns\Misc\CodeAnalysis\CodeAnalysis.csproj", "{3EAA45A9-735C-4AC7-A799-947B93EA449D}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VBNetBinding", "AddIns\BackendBindings\VBNetBinding\Project\VBNetBinding.csproj", "{BF38FB72-B380-4196-AF8C-95749D726C61}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WixBinding", "AddIns\BackendBindings\WixBinding\Project\WixBinding.csproj", "{e1b288a2-08ee-4318-8bbb-8ab72c69e33e}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XmlEditor.Tests", "AddIns\DisplayBindings\XmlEditor\Test\XmlEditor.Tests.csproj", "{FC0FE702-A87D-4D70-A9B6-1ECCD611125F}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WixBinding.Tests", "AddIns\BackendBindings\WixBinding\Test\WixBinding.Tests.csproj", "{388E7B64-0393-4EB4-A3E3-5C474F141853}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XmlEditor", "AddIns\DisplayBindings\XmlEditor\Project\XmlEditor.csproj", "{6B717BD1-CD5E-498C-A42E-9E6A4584DC48}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTesting.Tests", "AddIns\Misc\UnitTesting\Test\UnitTesting.Tests.csproj", "{44A8DE09-CAB9-49D8-9CFC-5EB0A552F181}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Debugger", "Debugger", "{6604365C-C702-4C10-9BA8-637F1E3D4D0D}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "WpfDesign", "WpfDesign", "{C12B6EA7-2EFC-4368-B585-EC69EFCC3F97}" ProjectSection(SolutionItems) = postProject EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Debugger.Tests", "AddIns\Misc\Debugger\Debugger.Tests\Project\Debugger.Tests.csproj", "{A4C858C8-51B6-4265-A695-A20FCEBA1D19}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Debugger.AddIn", "AddIns\Misc\Debugger\Debugger.AddIn\Project\Debugger.AddIn.csproj", "{EC06F96A-AEEC-49D6-B03D-AB87C6EB674C}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WpfDesign.XamlDom", "AddIns\DisplayBindings\WpfDesign\WpfDesign.XamlDom\Project\WpfDesign.XamlDom.csproj", "{88DA149F-21B2-48AB-82C4-28FB6BDFD783}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Debugger.Core", "AddIns\Misc\Debugger\Debugger.Core\Project\Debugger.Core.csproj", "{1D18D788-F7EE-4585-A23B-34DC8EC63CB8}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WpfDesign.Tests", "AddIns\DisplayBindings\WpfDesign\WpfDesign.Designer\Tests\WpfDesign.Tests.csproj", "{943DBBB3-E84E-4CF4-917C-C05AFA8743C1}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TreeListView", "AddIns\Misc\Debugger\TreeListView\Project\TreeListView.csproj", "{B08385CD-F0CC-488C-B4F4-EEB34B6D2688}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WpfDesign.Designer", "AddIns\DisplayBindings\WpfDesign\WpfDesign.Designer\Project\WpfDesign.Designer.csproj", "{78CC29AC-CC79-4355-B1F2-97936DF198AC}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NRefactoryToBooConverter.Tests", "AddIns\BackendBindings\Boo\NRefactoryToBooConverter\Test\NRefactoryToBooConverter.Tests.csproj", "{C9DE556D-325C-4544-B29F-16A9EB7C9830}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WpfDesign", "AddIns\DisplayBindings\WpfDesign\WpfDesign\Project\WpfDesign.csproj", "{66A378A1-E9F4-4AD5-8946-D0EC06C2902F}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NRefactoryToBooConverter", "AddIns\BackendBindings\Boo\NRefactoryToBooConverter\Project\NRefactoryToBooConverter.csproj", "{DBCF20A1-BA13-4582-BFA9-74DE4D987B73}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SearchAndReplace", "AddIns\Misc\SearchAndReplace\Project\SearchAndReplace.csproj", "{9196DD8A-B4D4-4780-8742-C5762E547FC2}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CSharpBinding", "AddIns\BackendBindings\CSharpBinding\Project\CSharpBinding.csproj", "{1F1AC7CD-D154-45BB-8EAF-804CA8055F5A}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SearchAndReplace.Tests", "AddIns\Misc\SearchAndReplace\Test\SearchAndReplace.Tests.csproj", "{A569DCC1-C608-45FD-B770-4F79335EF154}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Libraries", "Libraries", "{9421EDF4-9769-4BE9-B5A6-C87DE221D73C}" ProjectSection(SolutionItems) = postProject EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Aga.Controls", "Libraries\TreeViewAdv\Aga.Controls\Aga.Controls.csproj", "{E73BB233-D88B-44A7-A98F-D71EE158381D}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.Build.Tasks.Tests", "Libraries\ICSharpCode.Build.Tasks\Test\ICSharpCode.Build.Tasks.Tests.csproj", "{B7C2A664-B454-4920-AC6E-318F5274B2EF}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NRefactory", "Libraries\NRefactory\Project\NRefactory.csproj", "{3A9AE6AA-BC07-4A2F-972C-581E3AE2F195}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.TextEditor.Tests", "Libraries\ICSharpCode.TextEditor\Test\ICSharpCode.TextEditor.Tests.csproj", "{6259D767-BA7C-484D-9472-68F350A20086}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WinFormsUI", "Libraries\DockPanel_Src\WinFormsUI\WinFormsUI.csproj", "{D3C782BA-178E-4235-A3BA-8C11DEBB6BEE}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.TextEditor", "Libraries\ICSharpCode.TextEditor\Project\ICSharpCode.TextEditor.csproj", "{2D18BE89-D210-49EB-A9DD-2246FBB3DF6D}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.Build.Tasks", "Libraries\ICSharpCode.Build.Tasks\Project\ICSharpCode.Build.Tasks.csproj", "{4139CCF6-FB49-4A9D-B2CF-331E9EA3198D}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NRefactoryTests", "Libraries\NRefactory\Test\NRefactoryTests.csproj", "{870115DD-960A-4406-A6B9-600BCDC36A03}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.Build.Tasks", "Libraries\ICSharpCode.Build.Tasks\Project\ICSharpCode.Build.Tasks.csproj", "{4139CCF6-FB49-4A9D-B2CF-331E9EA3198D}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.TextEditor", "Libraries\ICSharpCode.TextEditor\Project\ICSharpCode.TextEditor.csproj", "{2D18BE89-D210-49EB-A9DD-2246FBB3DF6D}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WinFormsUI", "Libraries\DockPanel_Src\WinFormsUI\WinFormsUI.csproj", "{D3C782BA-178E-4235-A3BA-8C11DEBB6BEE}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.TextEditor.Tests", "Libraries\ICSharpCode.TextEditor\Test\ICSharpCode.TextEditor.Tests.csproj", "{6259D767-BA7C-484D-9472-68F350A20086}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NRefactory", "Libraries\NRefactory\Project\NRefactory.csproj", "{3A9AE6AA-BC07-4A2F-972C-581E3AE2F195}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.Build.Tasks.Tests", "Libraries\ICSharpCode.Build.Tasks\Test\ICSharpCode.Build.Tasks.Tests.csproj", "{B7C2A664-B454-4920-AC6E-318F5274B2EF}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Aga.Controls", "Libraries\TreeViewAdv\Aga.Controls\Aga.Controls.csproj", "{E73BB233-D88B-44A7-A98F-D71EE158381D}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Main", "Main", "{5A3EBEBA-0560-41C1-966B-23F7D03A5486}" ProjectSection(SolutionItems) = postProject EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.SharpDevelop.Widgets", "Main\ICSharpCode.SharpDevelop.Widgets\Project\ICSharpCode.SharpDevelop.Widgets.csproj", "{8035765F-D51F-4A0C-A746-2FD100E19419}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StartUp", "Main\StartUp\Project\StartUp.csproj", "{1152B71B-3C05-4598-B20D-823B5D40559E}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.SharpDevelop.Dom", "Main\ICSharpCode.SharpDevelop.Dom\Project\ICSharpCode.SharpDevelop.Dom.csproj", "{924EE450-603D-49C1-A8E5-4AFAA31CE6F3}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.Core", "Main\Core\Project\ICSharpCode.Core.csproj", "{35CEF10F-2D4C-45F2-9DD1-161E0FEC583C}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.SharpDevelop.Sda", "Main\ICSharpCode.SharpDevelop.Sda\ICSharpCode.SharpDevelop.Sda.csproj", "{80318B5F-A25D-45AB-8A95-EF31D2370A4C}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.SharpDevelop", "Main\Base\Project\ICSharpCode.SharpDevelop.csproj", "{2748AD25-9C63-4E12-877B-4DCE96FBED54}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.SharpDevelop.Tests", "Main\Base\Test\ICSharpCode.SharpDevelop.Tests.csproj", "{4980B743-B32F-4aba-AABD-45E2CAD3568D}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.Core.Tests", "Main\Core\Test\ICSharpCode.Core.Tests.csproj", "{AD6FAA08-D6F5-4DBA-AF85-F4DA9F40C3B5}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.SharpDevelop.Tests", "Main\Base\Test\ICSharpCode.SharpDevelop.Tests.csproj", "{4980B743-B32F-4aba-AABD-45E2CAD3568D}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.SharpDevelop.Sda", "Main\ICSharpCode.SharpDevelop.Sda\ICSharpCode.SharpDevelop.Sda.csproj", "{80318B5F-A25D-45AB-8A95-EF31D2370A4C}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.SharpDevelop", "Main\Base\Project\ICSharpCode.SharpDevelop.csproj", "{2748AD25-9C63-4E12-877B-4DCE96FBED54}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.SharpDevelop.Dom", "Main\ICSharpCode.SharpDevelop.Dom\Project\ICSharpCode.SharpDevelop.Dom.csproj", "{924EE450-603D-49C1-A8E5-4AFAA31CE6F3}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.Core", "Main\Core\Project\ICSharpCode.Core.csproj", "{35CEF10F-2D4C-45F2-9DD1-161E0FEC583C}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.SharpDevelop.Widgets", "Main\ICSharpCode.SharpDevelop.Widgets\Project\ICSharpCode.SharpDevelop.Widgets.csproj", "{8035765F-D51F-4A0C-A746-2FD100E19419}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StartUp", "Main\StartUp\Project\StartUp.csproj", "{1152B71B-3C05-4598-B20D-823B5D40559E}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.SharpDevelop.BuildWorker", "Main\ICSharpCode.SharpDevelop.BuildWorker\ICSharpCode.SharpDevelop.BuildWorker.csproj", "{C3CBC8E3-81D8-4C5B-9941-DCCD12D50B1F}" EndProject Project("{00000000-0000-0000-0000-000000000000}") = "Tools", "Tools\Tools.build", "{970116b0-f96b-4257-8579-986b9cf086f5}" EndProject @@ -322,54 +324,59 @@ Global {A569DCC1-C608-45FD-B770-4F79335EF154}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {A569DCC1-C608-45FD-B770-4F79335EF154}.Release|Any CPU.Build.0 = Release|Any CPU {A569DCC1-C608-45FD-B770-4F79335EF154}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C3CBC8E3-81D8-4C5B-9941-DCCD12D50B1F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C3CBC8E3-81D8-4C5B-9941-DCCD12D50B1F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C3CBC8E3-81D8-4C5B-9941-DCCD12D50B1F}.Release|Any CPU.Build.0 = Release|Any CPU + {C3CBC8E3-81D8-4C5B-9941-DCCD12D50B1F}.Release|Any CPU.ActiveCfg = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution - {1F1AC7CD-D154-45BB-8EAF-804CA8055F5A} = {14A277EE-7DF1-4529-B639-7D1EF334C1C5} - {DBCF20A1-BA13-4582-BFA9-74DE4D987B73} = {14A277EE-7DF1-4529-B639-7D1EF334C1C5} - {C9DE556D-325C-4544-B29F-16A9EB7C9830} = {14A277EE-7DF1-4529-B639-7D1EF334C1C5} - {6604365C-C702-4C10-9BA8-637F1E3D4D0D} = {14A277EE-7DF1-4529-B639-7D1EF334C1C5} - {6B717BD1-CD5E-498C-A42E-9E6A4584DC48} = {14A277EE-7DF1-4529-B639-7D1EF334C1C5} - {FC0FE702-A87D-4D70-A9B6-1ECCD611125F} = {14A277EE-7DF1-4529-B639-7D1EF334C1C5} - {BF38FB72-B380-4196-AF8C-95749D726C61} = {14A277EE-7DF1-4529-B639-7D1EF334C1C5} - {A5C0E8F8-9D04-46ED-91D6-1DEF1575313B} = {14A277EE-7DF1-4529-B639-7D1EF334C1C5} - {08ce9972-283b-44f4-82fa-966f7dfa6b7a} = {14A277EE-7DF1-4529-B639-7D1EF334C1C5} - {1F261725-6318-4434-A1B1-6C70CE4CD324} = {14A277EE-7DF1-4529-B639-7D1EF334C1C5} - {4AC2D5F1-F671-480C-A075-6BF62B3721B2} = {14A277EE-7DF1-4529-B639-7D1EF334C1C5} - {6FA16499-896F-4C02-BB43-1AF5C6C7C713} = {14A277EE-7DF1-4529-B639-7D1EF334C1C5} - {7D7E92DF-ACEB-4B69-92C8-8AC7A703CD57} = {14A277EE-7DF1-4529-B639-7D1EF334C1C5} - {3EAA45A9-735C-4AC7-A799-947B93EA449D} = {14A277EE-7DF1-4529-B639-7D1EF334C1C5} - {e1b288a2-08ee-4318-8bbb-8ab72c69e33e} = {14A277EE-7DF1-4529-B639-7D1EF334C1C5} - {388E7B64-0393-4EB4-A3E3-5C474F141853} = {14A277EE-7DF1-4529-B639-7D1EF334C1C5} - {44A8DE09-CAB9-49D8-9CFC-5EB0A552F181} = {14A277EE-7DF1-4529-B639-7D1EF334C1C5} - {C12B6EA7-2EFC-4368-B585-EC69EFCC3F97} = {14A277EE-7DF1-4529-B639-7D1EF334C1C5} - {9196DD8A-B4D4-4780-8742-C5762E547FC2} = {14A277EE-7DF1-4529-B639-7D1EF334C1C5} {A569DCC1-C608-45FD-B770-4F79335EF154} = {14A277EE-7DF1-4529-B639-7D1EF334C1C5} - {88DA149F-21B2-48AB-82C4-28FB6BDFD783} = {C12B6EA7-2EFC-4368-B585-EC69EFCC3F97} - {943DBBB3-E84E-4CF4-917C-C05AFA8743C1} = {C12B6EA7-2EFC-4368-B585-EC69EFCC3F97} - {78CC29AC-CC79-4355-B1F2-97936DF198AC} = {C12B6EA7-2EFC-4368-B585-EC69EFCC3F97} - {66A378A1-E9F4-4AD5-8946-D0EC06C2902F} = {C12B6EA7-2EFC-4368-B585-EC69EFCC3F97} - {B08385CD-F0CC-488C-B4F4-EEB34B6D2688} = {6604365C-C702-4C10-9BA8-637F1E3D4D0D} - {1D18D788-F7EE-4585-A23B-34DC8EC63CB8} = {6604365C-C702-4C10-9BA8-637F1E3D4D0D} - {EC06F96A-AEEC-49D6-B03D-AB87C6EB674C} = {6604365C-C702-4C10-9BA8-637F1E3D4D0D} + {9196DD8A-B4D4-4780-8742-C5762E547FC2} = {14A277EE-7DF1-4529-B639-7D1EF334C1C5} + {C12B6EA7-2EFC-4368-B585-EC69EFCC3F97} = {14A277EE-7DF1-4529-B639-7D1EF334C1C5} + {44A8DE09-CAB9-49D8-9CFC-5EB0A552F181} = {14A277EE-7DF1-4529-B639-7D1EF334C1C5} + {388E7B64-0393-4EB4-A3E3-5C474F141853} = {14A277EE-7DF1-4529-B639-7D1EF334C1C5} + {e1b288a2-08ee-4318-8bbb-8ab72c69e33e} = {14A277EE-7DF1-4529-B639-7D1EF334C1C5} + {3EAA45A9-735C-4AC7-A799-947B93EA449D} = {14A277EE-7DF1-4529-B639-7D1EF334C1C5} + {7D7E92DF-ACEB-4B69-92C8-8AC7A703CD57} = {14A277EE-7DF1-4529-B639-7D1EF334C1C5} + {6FA16499-896F-4C02-BB43-1AF5C6C7C713} = {14A277EE-7DF1-4529-B639-7D1EF334C1C5} + {4AC2D5F1-F671-480C-A075-6BF62B3721B2} = {14A277EE-7DF1-4529-B639-7D1EF334C1C5} + {1F261725-6318-4434-A1B1-6C70CE4CD324} = {14A277EE-7DF1-4529-B639-7D1EF334C1C5} + {08ce9972-283b-44f4-82fa-966f7dfa6b7a} = {14A277EE-7DF1-4529-B639-7D1EF334C1C5} + {A5C0E8F8-9D04-46ED-91D6-1DEF1575313B} = {14A277EE-7DF1-4529-B639-7D1EF334C1C5} + {BF38FB72-B380-4196-AF8C-95749D726C61} = {14A277EE-7DF1-4529-B639-7D1EF334C1C5} + {FC0FE702-A87D-4D70-A9B6-1ECCD611125F} = {14A277EE-7DF1-4529-B639-7D1EF334C1C5} + {6B717BD1-CD5E-498C-A42E-9E6A4584DC48} = {14A277EE-7DF1-4529-B639-7D1EF334C1C5} + {6604365C-C702-4C10-9BA8-637F1E3D4D0D} = {14A277EE-7DF1-4529-B639-7D1EF334C1C5} + {C9DE556D-325C-4544-B29F-16A9EB7C9830} = {14A277EE-7DF1-4529-B639-7D1EF334C1C5} + {DBCF20A1-BA13-4582-BFA9-74DE4D987B73} = {14A277EE-7DF1-4529-B639-7D1EF334C1C5} + {1F1AC7CD-D154-45BB-8EAF-804CA8055F5A} = {14A277EE-7DF1-4529-B639-7D1EF334C1C5} {A4C858C8-51B6-4265-A695-A20FCEBA1D19} = {6604365C-C702-4C10-9BA8-637F1E3D4D0D} - {3A9AE6AA-BC07-4A2F-972C-581E3AE2F195} = {9421EDF4-9769-4BE9-B5A6-C87DE221D73C} - {D3C782BA-178E-4235-A3BA-8C11DEBB6BEE} = {9421EDF4-9769-4BE9-B5A6-C87DE221D73C} - {4139CCF6-FB49-4A9D-B2CF-331E9EA3198D} = {9421EDF4-9769-4BE9-B5A6-C87DE221D73C} - {870115DD-960A-4406-A6B9-600BCDC36A03} = {9421EDF4-9769-4BE9-B5A6-C87DE221D73C} - {2D18BE89-D210-49EB-A9DD-2246FBB3DF6D} = {9421EDF4-9769-4BE9-B5A6-C87DE221D73C} - {6259D767-BA7C-484D-9472-68F350A20086} = {9421EDF4-9769-4BE9-B5A6-C87DE221D73C} - {B7C2A664-B454-4920-AC6E-318F5274B2EF} = {9421EDF4-9769-4BE9-B5A6-C87DE221D73C} + {EC06F96A-AEEC-49D6-B03D-AB87C6EB674C} = {6604365C-C702-4C10-9BA8-637F1E3D4D0D} + {1D18D788-F7EE-4585-A23B-34DC8EC63CB8} = {6604365C-C702-4C10-9BA8-637F1E3D4D0D} + {B08385CD-F0CC-488C-B4F4-EEB34B6D2688} = {6604365C-C702-4C10-9BA8-637F1E3D4D0D} + {66A378A1-E9F4-4AD5-8946-D0EC06C2902F} = {C12B6EA7-2EFC-4368-B585-EC69EFCC3F97} + {78CC29AC-CC79-4355-B1F2-97936DF198AC} = {C12B6EA7-2EFC-4368-B585-EC69EFCC3F97} + {943DBBB3-E84E-4CF4-917C-C05AFA8743C1} = {C12B6EA7-2EFC-4368-B585-EC69EFCC3F97} + {88DA149F-21B2-48AB-82C4-28FB6BDFD783} = {C12B6EA7-2EFC-4368-B585-EC69EFCC3F97} {E73BB233-D88B-44A7-A98F-D71EE158381D} = {9421EDF4-9769-4BE9-B5A6-C87DE221D73C} - {1152B71B-3C05-4598-B20D-823B5D40559E} = {5A3EBEBA-0560-41C1-966B-23F7D03A5486} - {35CEF10F-2D4C-45F2-9DD1-161E0FEC583C} = {5A3EBEBA-0560-41C1-966B-23F7D03A5486} - {2748AD25-9C63-4E12-877B-4DCE96FBED54} = {5A3EBEBA-0560-41C1-966B-23F7D03A5486} - {4980B743-B32F-4aba-AABD-45E2CAD3568D} = {5A3EBEBA-0560-41C1-966B-23F7D03A5486} - {AD6FAA08-D6F5-4DBA-AF85-F4DA9F40C3B5} = {5A3EBEBA-0560-41C1-966B-23F7D03A5486} - {80318B5F-A25D-45AB-8A95-EF31D2370A4C} = {5A3EBEBA-0560-41C1-966B-23F7D03A5486} - {924EE450-603D-49C1-A8E5-4AFAA31CE6F3} = {5A3EBEBA-0560-41C1-966B-23F7D03A5486} + {B7C2A664-B454-4920-AC6E-318F5274B2EF} = {9421EDF4-9769-4BE9-B5A6-C87DE221D73C} + {6259D767-BA7C-484D-9472-68F350A20086} = {9421EDF4-9769-4BE9-B5A6-C87DE221D73C} + {2D18BE89-D210-49EB-A9DD-2246FBB3DF6D} = {9421EDF4-9769-4BE9-B5A6-C87DE221D73C} + {870115DD-960A-4406-A6B9-600BCDC36A03} = {9421EDF4-9769-4BE9-B5A6-C87DE221D73C} + {4139CCF6-FB49-4A9D-B2CF-331E9EA3198D} = {9421EDF4-9769-4BE9-B5A6-C87DE221D73C} + {D3C782BA-178E-4235-A3BA-8C11DEBB6BEE} = {9421EDF4-9769-4BE9-B5A6-C87DE221D73C} + {3A9AE6AA-BC07-4A2F-972C-581E3AE2F195} = {9421EDF4-9769-4BE9-B5A6-C87DE221D73C} + {C3CBC8E3-81D8-4C5B-9941-DCCD12D50B1F} = {5A3EBEBA-0560-41C1-966B-23F7D03A5486} {8035765F-D51F-4A0C-A746-2FD100E19419} = {5A3EBEBA-0560-41C1-966B-23F7D03A5486} + {924EE450-603D-49C1-A8E5-4AFAA31CE6F3} = {5A3EBEBA-0560-41C1-966B-23F7D03A5486} + {80318B5F-A25D-45AB-8A95-EF31D2370A4C} = {5A3EBEBA-0560-41C1-966B-23F7D03A5486} + {AD6FAA08-D6F5-4DBA-AF85-F4DA9F40C3B5} = {5A3EBEBA-0560-41C1-966B-23F7D03A5486} + {4980B743-B32F-4aba-AABD-45E2CAD3568D} = {5A3EBEBA-0560-41C1-966B-23F7D03A5486} + {2748AD25-9C63-4E12-877B-4DCE96FBED54} = {5A3EBEBA-0560-41C1-966B-23F7D03A5486} + {35CEF10F-2D4C-45F2-9DD1-161E0FEC583C} = {5A3EBEBA-0560-41C1-966B-23F7D03A5486} + {1152B71B-3C05-4598-B20D-823B5D40559E} = {5A3EBEBA-0560-41C1-966B-23F7D03A5486} EndGlobalSection EndGlobal diff --git a/src/SharpDevelop.sln b/src/SharpDevelop.sln index 805781b31e..8a39e2154c 100644 --- a/src/SharpDevelop.sln +++ b/src/SharpDevelop.sln @@ -1,176 +1,178 @@  Microsoft Visual Studio Solution File, Format Version 10.00 # Visual Studio 2008 -# SharpDevelop 3.0.0.2667 +# SharpDevelop 3.0.0.2693 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "AddIns", "AddIns", "{14A277EE-7DF1-4529-B639-7D1EF334C1C5}" ProjectSection(SolutionItems) = postProject EndProjectSection EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Misc", "Misc", "{CE5B42B7-6E8C-4385-9E97-F4023FC16BF2}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Display Bindings", "Display Bindings", "{4EA396ED-64AD-4AD0-A67A-AB363F3E0C79}" ProjectSection(SolutionItems) = postProject EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SearchAndReplace", "AddIns\Misc\SearchAndReplace\Project\SearchAndReplace.csproj", "{9196DD8A-B4D4-4780-8742-C5762E547FC2}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "WpfDesign", "WpfDesign", "{388C3979-2621-4839-A955-7E5C03BA0B63}" + ProjectSection(SolutionItems) = postProject + EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AddinScout", "AddIns\Misc\AddinScout\Project\AddinScout.csproj", "{4B8F0F98-8BE1-402B-AA8B-C8D548577B38}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WpfDesign.AddIn", "AddIns\DisplayBindings\WpfDesign\WpfDesign.AddIn\WpfDesign.AddIn.csproj", "{9A9D6FD4-6A2E-455D-ACC3-DDA775FE9865}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StartPage", "AddIns\Misc\StartPage\Project\StartPage.csproj", "{7D5C266F-D6FF-4D14-B315-0C0FC6C4EF51}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WpfDesign.XamlDom", "AddIns\DisplayBindings\WpfDesign\WpfDesign.XamlDom\Project\WpfDesign.XamlDom.csproj", "{88DA149F-21B2-48AB-82C4-28FB6BDFD783}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RegExpTk", "AddIns\Misc\RegExpTk\Project\RegExpTk.csproj", "{64A3E5E6-90BF-47F6-94DF-68C94B62C817}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WpfDesign.Designer", "AddIns\DisplayBindings\WpfDesign\WpfDesign.Designer\Project\WpfDesign.Designer.csproj", "{78CC29AC-CC79-4355-B1F2-97936DF198AC}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HighlightingEditor", "AddIns\Misc\HighlightingEditor\Project\HighlightingEditor.csproj", "{8A462940-E5E9-4E85-982D-D4C006EE31D4}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WpfDesign", "AddIns\DisplayBindings\WpfDesign\WpfDesign\Project\WpfDesign.csproj", "{66A378A1-E9F4-4AD5-8946-D0EC06C2902F}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FiletypeRegisterer", "AddIns\Misc\FiletypeRegisterer\Project\FiletypeRegisterer.csproj", "{D022A6CE-7438-41E8-AC64-F2DE18EC54C6}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WorkflowDesigner", "AddIns\DisplayBindings\WorkflowDesigner\Project\WorkflowDesigner.csproj", "{533F4684-DBA6-4518-B005-C84F22A2DD57}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Debugger", "Debugger", "{6604365C-C702-4C10-9BA8-637F1E3D4D0D}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ClassDiagram", "ClassDiagram", "{DB137F0B-9B62-4232-AE92-F7BE0280B8D3}" ProjectSection(SolutionItems) = postProject EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TreeListView", "AddIns\Misc\Debugger\TreeListView\Project\TreeListView.csproj", "{B08385CD-F0CC-488C-B4F4-EEB34B6D2688}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClassWizard", "AddIns\DisplayBindings\ClassDiagram\ClassWizard\ClassWizard.csproj", "{8C59E80D-C4E4-4F36-9AD8-47C40F6E58B4}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Debugger.Core", "AddIns\Misc\Debugger\Debugger.Core\Project\Debugger.Core.csproj", "{1D18D788-F7EE-4585-A23B-34DC8EC63CB8}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Diagrams", "AddIns\DisplayBindings\ClassDiagram\DiagramRouter\Diagrams.csproj", "{0991423A-DBF6-4C89-B365-A1DF1EB32E42}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Debugger.AddIn", "AddIns\Misc\Debugger\Debugger.AddIn\Project\Debugger.AddIn.csproj", "{EC06F96A-AEEC-49D6-B03D-AB87C6EB674C}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClassDiagramAddin", "AddIns\DisplayBindings\ClassDiagram\ClassDiagramAddin\ClassDiagramAddin.csproj", "{5A1354DF-4989-4BB4-BC6B-D627C2E9FA13}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HtmlHelp2", "AddIns\Misc\HtmlHelp2\Project\HtmlHelp2.csproj", "{918487B7-2153-4618-BBB3-344DBDDF2A2A}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClassEditor", "AddIns\DisplayBindings\ClassDiagram\ClassEditor\ClassEditor.csproj", "{F5E059BB-96C2-4398-BED0-8598CD434173}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AddInManager", "AddIns\Misc\AddInManager\Project\AddInManager.csproj", "{F93E52FD-DA66-4CE5-A0CB-BCD902811122}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClassCanvas", "AddIns\DisplayBindings\ClassDiagram\ClassCanvas\ClassCanvas.csproj", "{08F772A1-F0BE-433E-8B37-F6522953DB05}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PInvokeAddIn", "AddIns\Misc\PInvokeAddIn\Project\PInvokeAddIn.csproj", "{5EEB99CF-EA2B-4733-80A6-CE9192D68170}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SettingsEditor", "AddIns\DisplayBindings\SettingsEditor\Project\SettingsEditor.csproj", "{85226AFB-CE71-4851-9A75-7EEC663A8E8A}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MonoAddIn", "AddIns\Misc\MonoAddIn\Project\MonoAddIn.csproj", "{082DCD64-EE32-4151-A50F-E139CF754CC0}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "IconEditor", "IconEditor", "{0D37CE59-B0EF-4F3C-B9EB-8557E53A448B}" + ProjectSection(SolutionItems) = postProject + EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeCoverage", "AddIns\Misc\CodeCoverage\Project\CodeCoverage.csproj", "{08ce9972-283b-44f4-82fa-966f7dfa6b7a}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IconEditorAddIn", "AddIns\DisplayBindings\IconEditor\IconEditorAddIn\IconEditorAddIn.csproj", "{DFB936AD-90EE-4B4F-941E-4F4A636F0D92}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTesting", "AddIns\Misc\UnitTesting\UnitTesting.csproj", "{1F261725-6318-4434-A1B1-6C70CE4CD324}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IconEditor", "AddIns\DisplayBindings\IconEditor\IconEditor\IconEditor.csproj", "{DC1CCE11-CB91-40FA-9C47-4D9EB5D67BFD}" EndProject -Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "HtmlHelp2JScriptGlobals", "AddIns\Misc\HtmlHelp2\JScriptGlobals\HtmlHelp2JScriptGlobals.vbproj", "{E54A5AD2-418D-4A85-BA5E-CD803DE38715}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XmlEditor", "AddIns\DisplayBindings\XmlEditor\Project\XmlEditor.csproj", "{6B717BD1-CD5E-498C-A42E-9E6A4584DC48}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SubversionAddIn", "AddIns\Misc\SubversionAddIn\Project\SubversionAddIn.csproj", "{17F4D7E0-6933-4C2E-8714-FD7E98D625D5}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FormsDesigner", "AddIns\DisplayBindings\FormsDesigner\Project\FormsDesigner.csproj", "{7D7E92DF-ACEB-4B69-92C8-8AC7A703CD57}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeAnalysis", "AddIns\Misc\CodeAnalysis\CodeAnalysis.csproj", "{3EAA45A9-735C-4AC7-A799-947B93EA449D}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ResourceEditor", "AddIns\DisplayBindings\ResourceEditor\Project\ResourceEditor.csproj", "{CBC6C247-747B-4908-B09A-4D2E0F640B6B}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ComponentInspector", "ComponentInspector", "{BDDDCD01-D2FE-4EAD-9425-4B6B91922C7C}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Backends", "Backends", "{FEB825FA-4AD8-425D-8E4A-B5A18EE1B81C}" ProjectSection(SolutionItems) = postProject EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ComponentInspector", "AddIns\Misc\ComponentInspector\ComponentInspector\ComponentInspector.csproj", "{000E4F64-5D0D-4EB1-B0BF-1A62ADBC6EAD}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XamlBinding", "AddIns\BackendBindings\XamlBinding\Project\XamlBinding.csproj", "{7C96B65D-28A5-4F28-A35B-8D83CE831EE8}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ComponentInspector.AddIn", "AddIns\Misc\ComponentInspector\ComponentInspector.AddIn\ComponentInspector.AddIn.csproj", "{869951D5-A0D6-4DC6-9F1D-E6B9A12AC446}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WixBinding", "AddIns\BackendBindings\WixBinding\Project\WixBinding.csproj", "{e1b288a2-08ee-4318-8bbb-8ab72c69e33e}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ComponentInspector.Core", "AddIns\Misc\ComponentInspector\ComponentInspector.Core\ComponentInspector.Core.csproj", "{E6F4983F-DE41-4AEC-88E7-1FA9AFB4E6FF}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NRefactoryToBooConverter", "AddIns\BackendBindings\Boo\NRefactoryToBooConverter\Project\NRefactoryToBooConverter.csproj", "{DBCF20A1-BA13-4582-BFA9-74DE4D987B73}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ResourceToolkit", "AddIns\Misc\ResourceToolkit\Project\ResourceToolkit.csproj", "{461606BD-E824-4D0A-8CBA-01810B1F5E02}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BooBinding", "AddIns\BackendBindings\Boo\BooBinding\Project\BooBinding.csproj", "{4AC2D5F1-F671-480C-A075-6BF62B3721B2}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ILAsmBinding", "AddIns\BackendBindings\ILAsmBinding\Project\ILAsmBinding.csproj", "{6e59af58-f635-459a-9a35-c9ac41c00339}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VBNetBinding", "AddIns\BackendBindings\VBNetBinding\Project\VBNetBinding.csproj", "{BF38FB72-B380-4196-AF8C-95749D726C61}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CSharpBinding", "AddIns\BackendBindings\CSharpBinding\Project\CSharpBinding.csproj", "{1F1AC7CD-D154-45BB-8EAF-804CA8055F5A}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Misc", "Misc", "{CE5B42B7-6E8C-4385-9E97-F4023FC16BF2}" + ProjectSection(SolutionItems) = postProject + EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SharpServerTools", "SharpServerTools", "{6CEEC0D9-FA00-4EE3-9A1C-39B7ACC882FD}" ProjectSection(SolutionItems) = postProject EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServerBrowserTool", "AddIns\Misc\SharpServerTools\ServerBrowserTool\ServerBrowserTool.csproj", "{D721EAA4-8A40-4EF0-A011-5862159BE621}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DataTools.UI", "AddIns\Misc\SharpServerTools\DataTools.UI\DataTools.UI.csproj", "{87C0E3D9-0DFD-4F6D-8E38-408AAF73F4EE}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DataTools.Model", "AddIns\Misc\SharpServerTools\DataTools.Model\DataTools.Model.csproj", "{51783FC4-D8D2-4BFB-A1F1-AC8857CF3ED0}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DataTools.AddIn", "AddIns\Misc\SharpServerTools\SharpDbTools\DataTools.AddIn.csproj", "{93B2D6DF-7588-40C0-8A35-CA0DD7328FC3}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DataTools.Model", "AddIns\Misc\SharpServerTools\DataTools.Model\DataTools.Model.csproj", "{51783FC4-D8D2-4BFB-A1F1-AC8857CF3ED0}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServerBrowserTool", "AddIns\Misc\SharpServerTools\ServerBrowserTool\ServerBrowserTool.csproj", "{D721EAA4-8A40-4EF0-A011-5862159BE621}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DataTools.UI", "AddIns\Misc\SharpServerTools\DataTools.UI\DataTools.UI.csproj", "{87C0E3D9-0DFD-4F6D-8E38-408AAF73F4EE}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ResourceToolkit", "AddIns\Misc\ResourceToolkit\Project\ResourceToolkit.csproj", "{461606BD-E824-4D0A-8CBA-01810B1F5E02}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Backends", "Backends", "{FEB825FA-4AD8-425D-8E4A-B5A18EE1B81C}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ComponentInspector", "ComponentInspector", "{BDDDCD01-D2FE-4EAD-9425-4B6B91922C7C}" ProjectSection(SolutionItems) = postProject EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CSharpBinding", "AddIns\BackendBindings\CSharpBinding\Project\CSharpBinding.csproj", "{1F1AC7CD-D154-45BB-8EAF-804CA8055F5A}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VBNetBinding", "AddIns\BackendBindings\VBNetBinding\Project\VBNetBinding.csproj", "{BF38FB72-B380-4196-AF8C-95749D726C61}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ILAsmBinding", "AddIns\BackendBindings\ILAsmBinding\Project\ILAsmBinding.csproj", "{6e59af58-f635-459a-9a35-c9ac41c00339}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BooBinding", "AddIns\BackendBindings\Boo\BooBinding\Project\BooBinding.csproj", "{4AC2D5F1-F671-480C-A075-6BF62B3721B2}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ComponentInspector.Core", "AddIns\Misc\ComponentInspector\ComponentInspector.Core\ComponentInspector.Core.csproj", "{E6F4983F-DE41-4AEC-88E7-1FA9AFB4E6FF}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NRefactoryToBooConverter", "AddIns\BackendBindings\Boo\NRefactoryToBooConverter\Project\NRefactoryToBooConverter.csproj", "{DBCF20A1-BA13-4582-BFA9-74DE4D987B73}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ComponentInspector.AddIn", "AddIns\Misc\ComponentInspector\ComponentInspector.AddIn\ComponentInspector.AddIn.csproj", "{869951D5-A0D6-4DC6-9F1D-E6B9A12AC446}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WixBinding", "AddIns\BackendBindings\WixBinding\Project\WixBinding.csproj", "{e1b288a2-08ee-4318-8bbb-8ab72c69e33e}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ComponentInspector", "AddIns\Misc\ComponentInspector\ComponentInspector\ComponentInspector.csproj", "{000E4F64-5D0D-4EB1-B0BF-1A62ADBC6EAD}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XamlBinding", "AddIns\BackendBindings\XamlBinding\Project\XamlBinding.csproj", "{7C96B65D-28A5-4F28-A35B-8D83CE831EE8}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeAnalysis", "AddIns\Misc\CodeAnalysis\CodeAnalysis.csproj", "{3EAA45A9-735C-4AC7-A799-947B93EA449D}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Display Bindings", "Display Bindings", "{4EA396ED-64AD-4AD0-A67A-AB363F3E0C79}" - ProjectSection(SolutionItems) = postProject - EndProjectSection +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SubversionAddIn", "AddIns\Misc\SubversionAddIn\Project\SubversionAddIn.csproj", "{17F4D7E0-6933-4C2E-8714-FD7E98D625D5}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ResourceEditor", "AddIns\DisplayBindings\ResourceEditor\Project\ResourceEditor.csproj", "{CBC6C247-747B-4908-B09A-4D2E0F640B6B}" +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "HtmlHelp2JScriptGlobals", "AddIns\Misc\HtmlHelp2\JScriptGlobals\HtmlHelp2JScriptGlobals.vbproj", "{E54A5AD2-418D-4A85-BA5E-CD803DE38715}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FormsDesigner", "AddIns\DisplayBindings\FormsDesigner\Project\FormsDesigner.csproj", "{7D7E92DF-ACEB-4B69-92C8-8AC7A703CD57}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTesting", "AddIns\Misc\UnitTesting\UnitTesting.csproj", "{1F261725-6318-4434-A1B1-6C70CE4CD324}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XmlEditor", "AddIns\DisplayBindings\XmlEditor\Project\XmlEditor.csproj", "{6B717BD1-CD5E-498C-A42E-9E6A4584DC48}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeCoverage", "AddIns\Misc\CodeCoverage\Project\CodeCoverage.csproj", "{08ce9972-283b-44f4-82fa-966f7dfa6b7a}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "IconEditor", "IconEditor", "{0D37CE59-B0EF-4F3C-B9EB-8557E53A448B}" - ProjectSection(SolutionItems) = postProject - EndProjectSection +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MonoAddIn", "AddIns\Misc\MonoAddIn\Project\MonoAddIn.csproj", "{082DCD64-EE32-4151-A50F-E139CF754CC0}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IconEditor", "AddIns\DisplayBindings\IconEditor\IconEditor\IconEditor.csproj", "{DC1CCE11-CB91-40FA-9C47-4D9EB5D67BFD}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PInvokeAddIn", "AddIns\Misc\PInvokeAddIn\Project\PInvokeAddIn.csproj", "{5EEB99CF-EA2B-4733-80A6-CE9192D68170}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IconEditorAddIn", "AddIns\DisplayBindings\IconEditor\IconEditorAddIn\IconEditorAddIn.csproj", "{DFB936AD-90EE-4B4F-941E-4F4A636F0D92}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AddInManager", "AddIns\Misc\AddInManager\Project\AddInManager.csproj", "{F93E52FD-DA66-4CE5-A0CB-BCD902811122}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SettingsEditor", "AddIns\DisplayBindings\SettingsEditor\Project\SettingsEditor.csproj", "{85226AFB-CE71-4851-9A75-7EEC663A8E8A}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HtmlHelp2", "AddIns\Misc\HtmlHelp2\Project\HtmlHelp2.csproj", "{918487B7-2153-4618-BBB3-344DBDDF2A2A}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ClassDiagram", "ClassDiagram", "{DB137F0B-9B62-4232-AE92-F7BE0280B8D3}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Debugger", "Debugger", "{6604365C-C702-4C10-9BA8-637F1E3D4D0D}" ProjectSection(SolutionItems) = postProject EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClassCanvas", "AddIns\DisplayBindings\ClassDiagram\ClassCanvas\ClassCanvas.csproj", "{08F772A1-F0BE-433E-8B37-F6522953DB05}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClassEditor", "AddIns\DisplayBindings\ClassDiagram\ClassEditor\ClassEditor.csproj", "{F5E059BB-96C2-4398-BED0-8598CD434173}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClassDiagramAddin", "AddIns\DisplayBindings\ClassDiagram\ClassDiagramAddin\ClassDiagramAddin.csproj", "{5A1354DF-4989-4BB4-BC6B-D627C2E9FA13}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Debugger.AddIn", "AddIns\Misc\Debugger\Debugger.AddIn\Project\Debugger.AddIn.csproj", "{EC06F96A-AEEC-49D6-B03D-AB87C6EB674C}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Diagrams", "AddIns\DisplayBindings\ClassDiagram\DiagramRouter\Diagrams.csproj", "{0991423A-DBF6-4C89-B365-A1DF1EB32E42}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Debugger.Core", "AddIns\Misc\Debugger\Debugger.Core\Project\Debugger.Core.csproj", "{1D18D788-F7EE-4585-A23B-34DC8EC63CB8}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClassWizard", "AddIns\DisplayBindings\ClassDiagram\ClassWizard\ClassWizard.csproj", "{8C59E80D-C4E4-4F36-9AD8-47C40F6E58B4}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TreeListView", "AddIns\Misc\Debugger\TreeListView\Project\TreeListView.csproj", "{B08385CD-F0CC-488C-B4F4-EEB34B6D2688}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WorkflowDesigner", "AddIns\DisplayBindings\WorkflowDesigner\Project\WorkflowDesigner.csproj", "{533F4684-DBA6-4518-B005-C84F22A2DD57}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FiletypeRegisterer", "AddIns\Misc\FiletypeRegisterer\Project\FiletypeRegisterer.csproj", "{D022A6CE-7438-41E8-AC64-F2DE18EC54C6}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "WpfDesign", "WpfDesign", "{388C3979-2621-4839-A955-7E5C03BA0B63}" - ProjectSection(SolutionItems) = postProject - EndProjectSection +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HighlightingEditor", "AddIns\Misc\HighlightingEditor\Project\HighlightingEditor.csproj", "{8A462940-E5E9-4E85-982D-D4C006EE31D4}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WpfDesign", "AddIns\DisplayBindings\WpfDesign\WpfDesign\Project\WpfDesign.csproj", "{66A378A1-E9F4-4AD5-8946-D0EC06C2902F}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RegExpTk", "AddIns\Misc\RegExpTk\Project\RegExpTk.csproj", "{64A3E5E6-90BF-47F6-94DF-68C94B62C817}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WpfDesign.Designer", "AddIns\DisplayBindings\WpfDesign\WpfDesign.Designer\Project\WpfDesign.Designer.csproj", "{78CC29AC-CC79-4355-B1F2-97936DF198AC}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StartPage", "AddIns\Misc\StartPage\Project\StartPage.csproj", "{7D5C266F-D6FF-4D14-B315-0C0FC6C4EF51}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WpfDesign.XamlDom", "AddIns\DisplayBindings\WpfDesign\WpfDesign.XamlDom\Project\WpfDesign.XamlDom.csproj", "{88DA149F-21B2-48AB-82C4-28FB6BDFD783}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AddinScout", "AddIns\Misc\AddinScout\Project\AddinScout.csproj", "{4B8F0F98-8BE1-402B-AA8B-C8D548577B38}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WpfDesign.AddIn", "AddIns\DisplayBindings\WpfDesign\WpfDesign.AddIn\WpfDesign.AddIn.csproj", "{9A9D6FD4-6A2E-455D-ACC3-DDA775FE9865}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SearchAndReplace", "AddIns\Misc\SearchAndReplace\Project\SearchAndReplace.csproj", "{9196DD8A-B4D4-4780-8742-C5762E547FC2}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Libraries", "Libraries", "{9421EDF4-9769-4BE9-B5A6-C87DE221D73C}" ProjectSection(SolutionItems) = postProject EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NRefactory", "Libraries\NRefactory\Project\NRefactory.csproj", "{3A9AE6AA-BC07-4A2F-972C-581E3AE2F195}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Aga.Controls", "Libraries\TreeViewAdv\Aga.Controls\Aga.Controls.csproj", "{E73BB233-D88B-44A7-A98F-D71EE158381D}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.TextEditor", "Libraries\ICSharpCode.TextEditor\Project\ICSharpCode.TextEditor.csproj", "{2D18BE89-D210-49EB-A9DD-2246FBB3DF6D}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.Build.Tasks", "Libraries\ICSharpCode.Build.Tasks\Project\ICSharpCode.Build.Tasks.csproj", "{4139CCF6-FB49-4A9D-B2CF-331E9EA3198D}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WinFormsUI", "Libraries\DockPanel_Src\WinFormsUI\WinFormsUI.csproj", "{D3C782BA-178E-4235-A3BA-8C11DEBB6BEE}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.Build.Tasks", "Libraries\ICSharpCode.Build.Tasks\Project\ICSharpCode.Build.Tasks.csproj", "{4139CCF6-FB49-4A9D-B2CF-331E9EA3198D}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.TextEditor", "Libraries\ICSharpCode.TextEditor\Project\ICSharpCode.TextEditor.csproj", "{2D18BE89-D210-49EB-A9DD-2246FBB3DF6D}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Aga.Controls", "Libraries\TreeViewAdv\Aga.Controls\Aga.Controls.csproj", "{E73BB233-D88B-44A7-A98F-D71EE158381D}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NRefactory", "Libraries\NRefactory\Project\NRefactory.csproj", "{3A9AE6AA-BC07-4A2F-972C-581E3AE2F195}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Main", "Main", "{5A3EBEBA-0560-41C1-966B-23F7D03A5486}" ProjectSection(SolutionItems) = postProject EndProjectSection EndProject -Project("{00000000-0000-0000-0000-000000000000}") = "Tools", "Tools\Tools.build", "B13EFF7F-7EA4-4B68-A375-D112105E9182" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.SharpDevelop.Dom", "Main\ICSharpCode.SharpDevelop.Dom\Project\ICSharpCode.SharpDevelop.Dom.csproj", "{924EE450-603D-49C1-A8E5-4AFAA31CE6F3}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StartUp", "Main\StartUp\Project\StartUp.csproj", "{1152B71B-3C05-4598-B20D-823B5D40559E}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.SharpDevelop.Widgets", "Main\ICSharpCode.SharpDevelop.Widgets\Project\ICSharpCode.SharpDevelop.Widgets.csproj", "{8035765F-D51F-4A0C-A746-2FD100E19419}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.Core", "Main\Core\Project\ICSharpCode.Core.csproj", "{35CEF10F-2D4C-45F2-9DD1-161E0FEC583C}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.SharpDevelop.Sda", "Main\ICSharpCode.SharpDevelop.Sda\ICSharpCode.SharpDevelop.Sda.csproj", "{80318B5F-A25D-45AB-8A95-EF31D2370A4C}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.SharpDevelop", "Main\Base\Project\ICSharpCode.SharpDevelop.csproj", "{2748AD25-9C63-4E12-877B-4DCE96FBED54}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.SharpDevelop.Sda", "Main\ICSharpCode.SharpDevelop.Sda\ICSharpCode.SharpDevelop.Sda.csproj", "{80318B5F-A25D-45AB-8A95-EF31D2370A4C}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.Core", "Main\Core\Project\ICSharpCode.Core.csproj", "{35CEF10F-2D4C-45F2-9DD1-161E0FEC583C}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.SharpDevelop.Widgets", "Main\ICSharpCode.SharpDevelop.Widgets\Project\ICSharpCode.SharpDevelop.Widgets.csproj", "{8035765F-D51F-4A0C-A746-2FD100E19419}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StartUp", "Main\StartUp\Project\StartUp.csproj", "{1152B71B-3C05-4598-B20D-823B5D40559E}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.SharpDevelop.Dom", "Main\ICSharpCode.SharpDevelop.Dom\Project\ICSharpCode.SharpDevelop.Dom.csproj", "{924EE450-603D-49C1-A8E5-4AFAA31CE6F3}" +Project("{00000000-0000-0000-0000-000000000000}") = "Tools", "Tools\Tools.build", "B13EFF7F-7EA4-4B68-A375-D112105E9182" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.SharpDevelop.BuildWorker", "Main\ICSharpCode.SharpDevelop.BuildWorker\ICSharpCode.SharpDevelop.BuildWorker.csproj", "{C3CBC8E3-81D8-4C5B-9941-DCCD12D50B1F}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -502,77 +504,82 @@ Global {9196DD8A-B4D4-4780-8742-C5762E547FC2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {9196DD8A-B4D4-4780-8742-C5762E547FC2}.Release|Any CPU.Build.0 = Release|Any CPU {9196DD8A-B4D4-4780-8742-C5762E547FC2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C3CBC8E3-81D8-4C5B-9941-DCCD12D50B1F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C3CBC8E3-81D8-4C5B-9941-DCCD12D50B1F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C3CBC8E3-81D8-4C5B-9941-DCCD12D50B1F}.Release|Any CPU.Build.0 = Release|Any CPU + {C3CBC8E3-81D8-4C5B-9941-DCCD12D50B1F}.Release|Any CPU.ActiveCfg = Release|Any CPU EndGlobalSection GlobalSection(NestedProjects) = preSolution - {4EA396ED-64AD-4AD0-A67A-AB363F3E0C79} = {14A277EE-7DF1-4529-B639-7D1EF334C1C5} - {FEB825FA-4AD8-425D-8E4A-B5A18EE1B81C} = {14A277EE-7DF1-4529-B639-7D1EF334C1C5} {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} = {14A277EE-7DF1-4529-B639-7D1EF334C1C5} - {6CEEC0D9-FA00-4EE3-9A1C-39B7ACC882FD} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} - {461606BD-E824-4D0A-8CBA-01810B1F5E02} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} - {BDDDCD01-D2FE-4EAD-9425-4B6B91922C7C} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} - {3EAA45A9-735C-4AC7-A799-947B93EA449D} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} - {17F4D7E0-6933-4C2E-8714-FD7E98D625D5} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} - {E54A5AD2-418D-4A85-BA5E-CD803DE38715} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} - {1F261725-6318-4434-A1B1-6C70CE4CD324} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} - {08ce9972-283b-44f4-82fa-966f7dfa6b7a} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} - {082DCD64-EE32-4151-A50F-E139CF754CC0} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} - {5EEB99CF-EA2B-4733-80A6-CE9192D68170} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} - {F93E52FD-DA66-4CE5-A0CB-BCD902811122} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} - {918487B7-2153-4618-BBB3-344DBDDF2A2A} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} - {6604365C-C702-4C10-9BA8-637F1E3D4D0D} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} - {D022A6CE-7438-41E8-AC64-F2DE18EC54C6} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} - {8A462940-E5E9-4E85-982D-D4C006EE31D4} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} - {64A3E5E6-90BF-47F6-94DF-68C94B62C817} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} - {7D5C266F-D6FF-4D14-B315-0C0FC6C4EF51} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} - {4B8F0F98-8BE1-402B-AA8B-C8D548577B38} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} - {9196DD8A-B4D4-4780-8742-C5762E547FC2} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} - {EC06F96A-AEEC-49D6-B03D-AB87C6EB674C} = {6604365C-C702-4C10-9BA8-637F1E3D4D0D} - {1D18D788-F7EE-4585-A23B-34DC8EC63CB8} = {6604365C-C702-4C10-9BA8-637F1E3D4D0D} - {B08385CD-F0CC-488C-B4F4-EEB34B6D2688} = {6604365C-C702-4C10-9BA8-637F1E3D4D0D} - {E6F4983F-DE41-4AEC-88E7-1FA9AFB4E6FF} = {BDDDCD01-D2FE-4EAD-9425-4B6B91922C7C} - {869951D5-A0D6-4DC6-9F1D-E6B9A12AC446} = {BDDDCD01-D2FE-4EAD-9425-4B6B91922C7C} - {000E4F64-5D0D-4EB1-B0BF-1A62ADBC6EAD} = {BDDDCD01-D2FE-4EAD-9425-4B6B91922C7C} - {87C0E3D9-0DFD-4F6D-8E38-408AAF73F4EE} = {6CEEC0D9-FA00-4EE3-9A1C-39B7ACC882FD} - {51783FC4-D8D2-4BFB-A1F1-AC8857CF3ED0} = {6CEEC0D9-FA00-4EE3-9A1C-39B7ACC882FD} - {93B2D6DF-7588-40C0-8A35-CA0DD7328FC3} = {6CEEC0D9-FA00-4EE3-9A1C-39B7ACC882FD} - {D721EAA4-8A40-4EF0-A011-5862159BE621} = {6CEEC0D9-FA00-4EE3-9A1C-39B7ACC882FD} - {7C96B65D-28A5-4F28-A35B-8D83CE831EE8} = {FEB825FA-4AD8-425D-8E4A-B5A18EE1B81C} - {e1b288a2-08ee-4318-8bbb-8ab72c69e33e} = {FEB825FA-4AD8-425D-8E4A-B5A18EE1B81C} - {DBCF20A1-BA13-4582-BFA9-74DE4D987B73} = {FEB825FA-4AD8-425D-8E4A-B5A18EE1B81C} - {4AC2D5F1-F671-480C-A075-6BF62B3721B2} = {FEB825FA-4AD8-425D-8E4A-B5A18EE1B81C} - {6e59af58-f635-459a-9a35-c9ac41c00339} = {FEB825FA-4AD8-425D-8E4A-B5A18EE1B81C} - {BF38FB72-B380-4196-AF8C-95749D726C61} = {FEB825FA-4AD8-425D-8E4A-B5A18EE1B81C} - {1F1AC7CD-D154-45BB-8EAF-804CA8055F5A} = {FEB825FA-4AD8-425D-8E4A-B5A18EE1B81C} - {388C3979-2621-4839-A955-7E5C03BA0B63} = {4EA396ED-64AD-4AD0-A67A-AB363F3E0C79} - {533F4684-DBA6-4518-B005-C84F22A2DD57} = {4EA396ED-64AD-4AD0-A67A-AB363F3E0C79} - {DB137F0B-9B62-4232-AE92-F7BE0280B8D3} = {4EA396ED-64AD-4AD0-A67A-AB363F3E0C79} - {85226AFB-CE71-4851-9A75-7EEC663A8E8A} = {4EA396ED-64AD-4AD0-A67A-AB363F3E0C79} - {0D37CE59-B0EF-4F3C-B9EB-8557E53A448B} = {4EA396ED-64AD-4AD0-A67A-AB363F3E0C79} - {6B717BD1-CD5E-498C-A42E-9E6A4584DC48} = {4EA396ED-64AD-4AD0-A67A-AB363F3E0C79} - {7D7E92DF-ACEB-4B69-92C8-8AC7A703CD57} = {4EA396ED-64AD-4AD0-A67A-AB363F3E0C79} + {FEB825FA-4AD8-425D-8E4A-B5A18EE1B81C} = {14A277EE-7DF1-4529-B639-7D1EF334C1C5} + {4EA396ED-64AD-4AD0-A67A-AB363F3E0C79} = {14A277EE-7DF1-4529-B639-7D1EF334C1C5} {CBC6C247-747B-4908-B09A-4D2E0F640B6B} = {4EA396ED-64AD-4AD0-A67A-AB363F3E0C79} - {DFB936AD-90EE-4B4F-941E-4F4A636F0D92} = {0D37CE59-B0EF-4F3C-B9EB-8557E53A448B} - {DC1CCE11-CB91-40FA-9C47-4D9EB5D67BFD} = {0D37CE59-B0EF-4F3C-B9EB-8557E53A448B} - {8C59E80D-C4E4-4F36-9AD8-47C40F6E58B4} = {DB137F0B-9B62-4232-AE92-F7BE0280B8D3} - {0991423A-DBF6-4C89-B365-A1DF1EB32E42} = {DB137F0B-9B62-4232-AE92-F7BE0280B8D3} - {5A1354DF-4989-4BB4-BC6B-D627C2E9FA13} = {DB137F0B-9B62-4232-AE92-F7BE0280B8D3} - {F5E059BB-96C2-4398-BED0-8598CD434173} = {DB137F0B-9B62-4232-AE92-F7BE0280B8D3} - {08F772A1-F0BE-433E-8B37-F6522953DB05} = {DB137F0B-9B62-4232-AE92-F7BE0280B8D3} - {9A9D6FD4-6A2E-455D-ACC3-DDA775FE9865} = {388C3979-2621-4839-A955-7E5C03BA0B63} - {88DA149F-21B2-48AB-82C4-28FB6BDFD783} = {388C3979-2621-4839-A955-7E5C03BA0B63} - {78CC29AC-CC79-4355-B1F2-97936DF198AC} = {388C3979-2621-4839-A955-7E5C03BA0B63} + {7D7E92DF-ACEB-4B69-92C8-8AC7A703CD57} = {4EA396ED-64AD-4AD0-A67A-AB363F3E0C79} + {6B717BD1-CD5E-498C-A42E-9E6A4584DC48} = {4EA396ED-64AD-4AD0-A67A-AB363F3E0C79} + {0D37CE59-B0EF-4F3C-B9EB-8557E53A448B} = {4EA396ED-64AD-4AD0-A67A-AB363F3E0C79} + {85226AFB-CE71-4851-9A75-7EEC663A8E8A} = {4EA396ED-64AD-4AD0-A67A-AB363F3E0C79} + {DB137F0B-9B62-4232-AE92-F7BE0280B8D3} = {4EA396ED-64AD-4AD0-A67A-AB363F3E0C79} + {533F4684-DBA6-4518-B005-C84F22A2DD57} = {4EA396ED-64AD-4AD0-A67A-AB363F3E0C79} + {388C3979-2621-4839-A955-7E5C03BA0B63} = {4EA396ED-64AD-4AD0-A67A-AB363F3E0C79} {66A378A1-E9F4-4AD5-8946-D0EC06C2902F} = {388C3979-2621-4839-A955-7E5C03BA0B63} - {E73BB233-D88B-44A7-A98F-D71EE158381D} = {9421EDF4-9769-4BE9-B5A6-C87DE221D73C} - {4139CCF6-FB49-4A9D-B2CF-331E9EA3198D} = {9421EDF4-9769-4BE9-B5A6-C87DE221D73C} - {D3C782BA-178E-4235-A3BA-8C11DEBB6BEE} = {9421EDF4-9769-4BE9-B5A6-C87DE221D73C} - {2D18BE89-D210-49EB-A9DD-2246FBB3DF6D} = {9421EDF4-9769-4BE9-B5A6-C87DE221D73C} + {78CC29AC-CC79-4355-B1F2-97936DF198AC} = {388C3979-2621-4839-A955-7E5C03BA0B63} + {88DA149F-21B2-48AB-82C4-28FB6BDFD783} = {388C3979-2621-4839-A955-7E5C03BA0B63} + {9A9D6FD4-6A2E-455D-ACC3-DDA775FE9865} = {388C3979-2621-4839-A955-7E5C03BA0B63} + {08F772A1-F0BE-433E-8B37-F6522953DB05} = {DB137F0B-9B62-4232-AE92-F7BE0280B8D3} + {F5E059BB-96C2-4398-BED0-8598CD434173} = {DB137F0B-9B62-4232-AE92-F7BE0280B8D3} + {5A1354DF-4989-4BB4-BC6B-D627C2E9FA13} = {DB137F0B-9B62-4232-AE92-F7BE0280B8D3} + {0991423A-DBF6-4C89-B365-A1DF1EB32E42} = {DB137F0B-9B62-4232-AE92-F7BE0280B8D3} + {8C59E80D-C4E4-4F36-9AD8-47C40F6E58B4} = {DB137F0B-9B62-4232-AE92-F7BE0280B8D3} + {DC1CCE11-CB91-40FA-9C47-4D9EB5D67BFD} = {0D37CE59-B0EF-4F3C-B9EB-8557E53A448B} + {DFB936AD-90EE-4B4F-941E-4F4A636F0D92} = {0D37CE59-B0EF-4F3C-B9EB-8557E53A448B} + {1F1AC7CD-D154-45BB-8EAF-804CA8055F5A} = {FEB825FA-4AD8-425D-8E4A-B5A18EE1B81C} + {BF38FB72-B380-4196-AF8C-95749D726C61} = {FEB825FA-4AD8-425D-8E4A-B5A18EE1B81C} + {6e59af58-f635-459a-9a35-c9ac41c00339} = {FEB825FA-4AD8-425D-8E4A-B5A18EE1B81C} + {4AC2D5F1-F671-480C-A075-6BF62B3721B2} = {FEB825FA-4AD8-425D-8E4A-B5A18EE1B81C} + {DBCF20A1-BA13-4582-BFA9-74DE4D987B73} = {FEB825FA-4AD8-425D-8E4A-B5A18EE1B81C} + {e1b288a2-08ee-4318-8bbb-8ab72c69e33e} = {FEB825FA-4AD8-425D-8E4A-B5A18EE1B81C} + {7C96B65D-28A5-4F28-A35B-8D83CE831EE8} = {FEB825FA-4AD8-425D-8E4A-B5A18EE1B81C} + {9196DD8A-B4D4-4780-8742-C5762E547FC2} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} + {4B8F0F98-8BE1-402B-AA8B-C8D548577B38} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} + {7D5C266F-D6FF-4D14-B315-0C0FC6C4EF51} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} + {64A3E5E6-90BF-47F6-94DF-68C94B62C817} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} + {8A462940-E5E9-4E85-982D-D4C006EE31D4} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} + {D022A6CE-7438-41E8-AC64-F2DE18EC54C6} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} + {6604365C-C702-4C10-9BA8-637F1E3D4D0D} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} + {918487B7-2153-4618-BBB3-344DBDDF2A2A} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} + {F93E52FD-DA66-4CE5-A0CB-BCD902811122} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} + {5EEB99CF-EA2B-4733-80A6-CE9192D68170} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} + {082DCD64-EE32-4151-A50F-E139CF754CC0} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} + {08ce9972-283b-44f4-82fa-966f7dfa6b7a} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} + {1F261725-6318-4434-A1B1-6C70CE4CD324} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} + {E54A5AD2-418D-4A85-BA5E-CD803DE38715} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} + {17F4D7E0-6933-4C2E-8714-FD7E98D625D5} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} + {3EAA45A9-735C-4AC7-A799-947B93EA449D} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} + {BDDDCD01-D2FE-4EAD-9425-4B6B91922C7C} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} + {461606BD-E824-4D0A-8CBA-01810B1F5E02} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} + {6CEEC0D9-FA00-4EE3-9A1C-39B7ACC882FD} = {CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} + {D721EAA4-8A40-4EF0-A011-5862159BE621} = {6CEEC0D9-FA00-4EE3-9A1C-39B7ACC882FD} + {93B2D6DF-7588-40C0-8A35-CA0DD7328FC3} = {6CEEC0D9-FA00-4EE3-9A1C-39B7ACC882FD} + {51783FC4-D8D2-4BFB-A1F1-AC8857CF3ED0} = {6CEEC0D9-FA00-4EE3-9A1C-39B7ACC882FD} + {87C0E3D9-0DFD-4F6D-8E38-408AAF73F4EE} = {6CEEC0D9-FA00-4EE3-9A1C-39B7ACC882FD} + {000E4F64-5D0D-4EB1-B0BF-1A62ADBC6EAD} = {BDDDCD01-D2FE-4EAD-9425-4B6B91922C7C} + {869951D5-A0D6-4DC6-9F1D-E6B9A12AC446} = {BDDDCD01-D2FE-4EAD-9425-4B6B91922C7C} + {E6F4983F-DE41-4AEC-88E7-1FA9AFB4E6FF} = {BDDDCD01-D2FE-4EAD-9425-4B6B91922C7C} + {B08385CD-F0CC-488C-B4F4-EEB34B6D2688} = {6604365C-C702-4C10-9BA8-637F1E3D4D0D} + {1D18D788-F7EE-4585-A23B-34DC8EC63CB8} = {6604365C-C702-4C10-9BA8-637F1E3D4D0D} + {EC06F96A-AEEC-49D6-B03D-AB87C6EB674C} = {6604365C-C702-4C10-9BA8-637F1E3D4D0D} {3A9AE6AA-BC07-4A2F-972C-581E3AE2F195} = {9421EDF4-9769-4BE9-B5A6-C87DE221D73C} - {924EE450-603D-49C1-A8E5-4AFAA31CE6F3} = {5A3EBEBA-0560-41C1-966B-23F7D03A5486} - {8035765F-D51F-4A0C-A746-2FD100E19419} = {5A3EBEBA-0560-41C1-966B-23F7D03A5486} - {80318B5F-A25D-45AB-8A95-EF31D2370A4C} = {5A3EBEBA-0560-41C1-966B-23F7D03A5486} - {2748AD25-9C63-4E12-877B-4DCE96FBED54} = {5A3EBEBA-0560-41C1-966B-23F7D03A5486} - {35CEF10F-2D4C-45F2-9DD1-161E0FEC583C} = {5A3EBEBA-0560-41C1-966B-23F7D03A5486} - {1152B71B-3C05-4598-B20D-823B5D40559E} = {5A3EBEBA-0560-41C1-966B-23F7D03A5486} + {2D18BE89-D210-49EB-A9DD-2246FBB3DF6D} = {9421EDF4-9769-4BE9-B5A6-C87DE221D73C} + {D3C782BA-178E-4235-A3BA-8C11DEBB6BEE} = {9421EDF4-9769-4BE9-B5A6-C87DE221D73C} + {4139CCF6-FB49-4A9D-B2CF-331E9EA3198D} = {9421EDF4-9769-4BE9-B5A6-C87DE221D73C} + {E73BB233-D88B-44A7-A98F-D71EE158381D} = {9421EDF4-9769-4BE9-B5A6-C87DE221D73C} + {C3CBC8E3-81D8-4C5B-9941-DCCD12D50B1F} = {5A3EBEBA-0560-41C1-966B-23F7D03A5486} B13EFF7F-7EA4-4B68-A375-D112105E9182 = {5A3EBEBA-0560-41C1-966B-23F7D03A5486} + {1152B71B-3C05-4598-B20D-823B5D40559E} = {5A3EBEBA-0560-41C1-966B-23F7D03A5486} + {35CEF10F-2D4C-45F2-9DD1-161E0FEC583C} = {5A3EBEBA-0560-41C1-966B-23F7D03A5486} + {2748AD25-9C63-4E12-877B-4DCE96FBED54} = {5A3EBEBA-0560-41C1-966B-23F7D03A5486} + {80318B5F-A25D-45AB-8A95-EF31D2370A4C} = {5A3EBEBA-0560-41C1-966B-23F7D03A5486} + {8035765F-D51F-4A0C-A746-2FD100E19419} = {5A3EBEBA-0560-41C1-966B-23F7D03A5486} + {924EE450-603D-49C1-A8E5-4AFAA31CE6F3} = {5A3EBEBA-0560-41C1-966B-23F7D03A5486} EndGlobalSection EndGlobal