From 6139a17a8b5c895e434911ef9031ce848918d5f4 Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Sat, 21 Jun 2008 15:57:49 +0000 Subject: [PATCH] Add C++ backend binding to samples. There's no support for editing project options and no templates; it's just a minimalist sample on how to write backend bindings for non-MSBuild project formats. git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@3126 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61 --- .../Configuration/AssemblyInfo.cs | 31 ++ .../CppBackendBinding/CppBackendBinding.addin | 44 +++ .../CppBackendBinding.csproj | 69 +++++ .../CppBackendBinding/CppBackendBinding.sln | 18 ++ .../CppBackendBinding/CppLanguageBinding.cs | 36 +++ samples/CppBackendBinding/CppProject.cs | 287 ++++++++++++++++++ samples/CppBackendBinding/FileGroup.cs | 45 +++ samples/CppBackendBinding/FileItem.cs | 57 ++++ .../Project/ICSharpCode.SharpDevelop.csproj | 1 + .../Project/Src/Gui/Pads/TaskList/TaskView.cs | 2 + .../Project/Src/Project/Items/ItemType.cs | 1 + .../Project/Src/Project/Items/ProjectItem.cs | 2 +- .../Src/Project/MSBuildBasedProject.cs | 12 +- .../Src/Project/ProjectLoadException.cs | 35 +++ .../LanguageBinding/LanguageBindingService.cs | 8 +- .../Src/Services/FileUtility/FileUtility.cs | 55 ++-- 16 files changed, 673 insertions(+), 30 deletions(-) create mode 100644 samples/CppBackendBinding/Configuration/AssemblyInfo.cs create mode 100644 samples/CppBackendBinding/CppBackendBinding.addin create mode 100644 samples/CppBackendBinding/CppBackendBinding.csproj create mode 100644 samples/CppBackendBinding/CppBackendBinding.sln create mode 100644 samples/CppBackendBinding/CppLanguageBinding.cs create mode 100644 samples/CppBackendBinding/CppProject.cs create mode 100644 samples/CppBackendBinding/FileGroup.cs create mode 100644 samples/CppBackendBinding/FileItem.cs create mode 100644 src/Main/Base/Project/Src/Project/ProjectLoadException.cs diff --git a/samples/CppBackendBinding/Configuration/AssemblyInfo.cs b/samples/CppBackendBinding/Configuration/AssemblyInfo.cs new file mode 100644 index 0000000000..4e476f6a87 --- /dev/null +++ b/samples/CppBackendBinding/Configuration/AssemblyInfo.cs @@ -0,0 +1,31 @@ +#region Using directives + +using System; +using System.Reflection; +using System.Runtime.InteropServices; + +#endregion + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("C++ Backend Binding for SharpDevelop")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("CppBackendBinding")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// This sets the default COM visibility of types in the assembly to invisible. +// If you need to expose a type to COM, use [ComVisible(true)] on that type. +[assembly: ComVisible(false)] + +// The assembly version has following format : +// +// Major.Minor.Build.Revision +// +// You can specify all the values or you can use the default the Revision and +// Build Numbers by using the '*' as shown below: +[assembly: AssemblyVersion("1.0.*")] diff --git a/samples/CppBackendBinding/CppBackendBinding.addin b/samples/CppBackendBinding/CppBackendBinding.addin new file mode 100644 index 0000000000..0d86a9bc0e --- /dev/null +++ b/samples/CppBackendBinding/CppBackendBinding.addin @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/samples/CppBackendBinding/CppBackendBinding.csproj b/samples/CppBackendBinding/CppBackendBinding.csproj new file mode 100644 index 0000000000..e33d996c2e --- /dev/null +++ b/samples/CppBackendBinding/CppBackendBinding.csproj @@ -0,0 +1,69 @@ + + + {F279DD27-21A9-4D69-AAE3-00DB403257CB} + Debug + AnyCPU + Library + CppBackendBinding + CppBackendBinding + v3.5 + ..\..\AddIns\Samples\CppBinding\ + False + False + 4 + false + + + true + Full + False + True + DEBUG;TRACE + + + False + None + True + False + TRACE + + + False + Auto + 4194304 + AnyCPU + 4096 + + + + + D:\SD\3.0\SharpDevelop\bin\ICSharpCode.Core.dll + False + + + D:\SD\3.0\SharpDevelop\bin\ICSharpCode.SharpDevelop.dll + False + + + D:\SD\3.0\SharpDevelop\bin\ICSharpCode.SharpDevelop.Dom.dll + False + + + + 3.5 + + + + + + + + Always + + + + + + + + \ No newline at end of file diff --git a/samples/CppBackendBinding/CppBackendBinding.sln b/samples/CppBackendBinding/CppBackendBinding.sln new file mode 100644 index 0000000000..01233e0d15 --- /dev/null +++ b/samples/CppBackendBinding/CppBackendBinding.sln @@ -0,0 +1,18 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +# SharpDevelop 3.0.0.3075 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CppBackendBinding", "CppBackendBinding.csproj", "{F279DD27-21A9-4D69-AAE3-00DB403257CB}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F279DD27-21A9-4D69-AAE3-00DB403257CB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F279DD27-21A9-4D69-AAE3-00DB403257CB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F279DD27-21A9-4D69-AAE3-00DB403257CB}.Release|Any CPU.Build.0 = Release|Any CPU + {F279DD27-21A9-4D69-AAE3-00DB403257CB}.Release|Any CPU.ActiveCfg = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/samples/CppBackendBinding/CppLanguageBinding.cs b/samples/CppBackendBinding/CppLanguageBinding.cs new file mode 100644 index 0000000000..045cd0ba7a --- /dev/null +++ b/samples/CppBackendBinding/CppLanguageBinding.cs @@ -0,0 +1,36 @@ +// +// +// +// +// $Revision$ +// + +using System; +using ICSharpCode.Core; +using ICSharpCode.SharpDevelop.Internal.Templates; +using ICSharpCode.SharpDevelop.Project; +using System.IO; + +namespace CppBackendBinding +{ + public class CppLanguageBinding : ILanguageBinding + { + public const string LanguageName = "C++"; + + public string Language { + get { + return LanguageName; + } + } + + public IProject LoadProject(IMSBuildEngineProvider provider, string fileName, string projectName) + { + return new CppProject(fileName, projectName); + } + + public IProject CreateProject(ProjectCreateInformation info) + { + throw new NotImplementedException(); + } + } +} diff --git a/samples/CppBackendBinding/CppProject.cs b/samples/CppBackendBinding/CppProject.cs new file mode 100644 index 0000000000..a7758de691 --- /dev/null +++ b/samples/CppBackendBinding/CppProject.cs @@ -0,0 +1,287 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; +using System.Xml; + +using ICSharpCode.Core; +using ICSharpCode.SharpDevelop.Project; + +namespace CppBackendBinding +{ + /// + /// C++ project class. Handlings project loading and saving. + /// + public class CppProject : AbstractProject, IProjectItemListProvider, IProjectAllowChangeConfigurations + { + XmlDocument document = new XmlDocument(); + List groups = new List(); + List items = new List(); + + /// + /// Create a new C++ project that loads the specified .vcproj file. + /// + public CppProject(string fileName, string projectName) + { + this.Name = projectName; + this.FileName = fileName; + this.TypeGuid = "{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}"; + + using (StreamReader r = new StreamReader(fileName, Encoding.Default)) { + try { + document.Load(r); + } catch (Exception ex) { + throw new ProjectLoadException(ex.Message, ex); + } + } + if (document.DocumentElement.Name != "VisualStudioProject") + throw new ProjectLoadException("The project is not a visual studio project."); + XmlElement filesElement = document.DocumentElement["Files"]; + if (filesElement != null) { + foreach (XmlElement filterElement in filesElement.ChildNodes.OfType()) { + if (filterElement.Name == "Filter") { + FileGroup group = new FileGroup(this, filterElement); + groups.Add(group); + foreach (XmlElement fileElement in filterElement.ChildNodes.OfType()) { + if (fileElement.Name == "File" && fileElement.HasAttribute("RelativePath")) { + items.Add(new FileItem(group, fileElement)); + } + } + } + } + } + } + + public override string Language { + get { return CppLanguageBinding.LanguageName; } + } + + public override void Save(string fileName) + { + lock (SyncRoot) { + // file item types may have changed, so remove all items from their parent elements + // and re-add them to the correct Filter elements + foreach (FileItem item in items) { + item.SaveChanges(); + if (item.XmlElement.ParentNode != null) + item.XmlElement.ParentNode.RemoveChild(item.XmlElement); + } + foreach (FileItem item in items) { + FileGroup group = groups.Find(fg => fg.ItemType == item.ProjectItem.ItemType); + if (groups != null) { + group.XmlElement.AppendChild(item.XmlElement); + } else { + LoggingService.Warn("Couldn't find filter for item type " + item.ProjectItem.ItemType + ", the item was not saved!"); + } + } + document.Save(fileName); + } + } + + /// + /// Gets the list of available file item types. This member is thread-safe. + /// + public override ICollection AvailableFileItemTypes { + get { + lock (SyncRoot) { + return groups.ConvertAll(fg => fg.ItemType).AsReadOnly(); + } + } + } + + /// + /// Gets the list of items in the project. This member is thread-safe. + /// The returned collection is guaranteed not to change - adding new items or removing existing items + /// will create a new collection. + /// + public override ReadOnlyCollection Items { + get { + lock (SyncRoot) { + return new ReadOnlyCollection(items.ConvertAll(fi => fi.ProjectItem)); + } + } + } + + #region IProjectAllowChangeConfigurations + // TODO: Configuration/Platform handling + bool IProjectAllowChangeConfigurations.RenameProjectConfiguration(string oldName, string newName) + { + throw new NotImplementedException(); + } + + bool IProjectAllowChangeConfigurations.RenameProjectPlatform(string oldName, string newName) + { + throw new NotImplementedException(); + } + + bool IProjectAllowChangeConfigurations.AddProjectConfiguration(string newName, string copyFrom) + { + throw new NotImplementedException(); + } + + bool IProjectAllowChangeConfigurations.AddProjectPlatform(string newName, string copyFrom) + { + throw new NotImplementedException(); + } + + bool IProjectAllowChangeConfigurations.RemoveProjectConfiguration(string name) + { + throw new NotImplementedException(); + } + + bool IProjectAllowChangeConfigurations.RemoveProjectPlatform(string name) + { + throw new NotImplementedException(); + } + #endregion + + #region IProjectItemListProvider + void IProjectItemListProvider.AddProjectItem(ProjectItem item) + { + if (item == null) + throw new ArgumentNullException("item"); + lock (SyncRoot) { + if (items.Exists(fi => fi.ProjectItem == item)) + throw new ArgumentException("Project item already exists in project!"); + items.Add(new FileItem(document, item)); + } + } + + bool IProjectItemListProvider.RemoveProjectItem(ProjectItem item) + { + lock (SyncRoot) { + return items.RemoveAll(fi => fi.ProjectItem == item) > 0; + } + } + #endregion + + public override void StartBuild(ProjectBuildOptions options, IBuildFeedbackSink feedbackSink) + { + string commonTools = Environment.GetEnvironmentVariable("VS90COMNTOOLS"); + if (string.IsNullOrEmpty(commonTools)) { + commonTools = Environment.GetEnvironmentVariable("VS80COMNTOOLS"); + } + if (!string.IsNullOrEmpty(commonTools)) { + commonTools = Path.Combine(commonTools, "vsvars32.bat"); + if (!File.Exists(commonTools)) + commonTools = null; + } + + Process p = new Process(); + p.StartInfo.FileName = "cmd.exe"; + p.StartInfo.Arguments = "/C"; + if (commonTools != null) { + p.StartInfo.Arguments += " call \"" + commonTools + "\" &&"; + } + p.StartInfo.Arguments += " vcbuild"; + if (options.Target == BuildTarget.Build) { + // OK + } else if (options.Target == BuildTarget.Clean) { + p.StartInfo.Arguments += " /clean"; + } else if (options.Target == BuildTarget.Rebuild) { + p.StartInfo.Arguments += " /rebuild"; + } + p.StartInfo.Arguments += " /showenv"; + p.StartInfo.Arguments += " \"" + this.FileName + "\""; + p.StartInfo.Arguments += " \"/error:Error: \""; + p.StartInfo.Arguments += " \"/warning:Warning: \""; + + p.StartInfo.WorkingDirectory = this.Directory; + p.StartInfo.RedirectStandardOutput = true; + p.StartInfo.RedirectStandardError = true; + p.StartInfo.CreateNoWindow = true; + p.StartInfo.UseShellExecute = false; + p.StartInfo.EnvironmentVariables["VCBUILD_DEFAULT_CFG"] = options.Configuration + "|" + options.Platform; + + p.EnableRaisingEvents = true; + p.OutputDataReceived += delegate(object sender, DataReceivedEventArgs e) { + if (!string.IsNullOrEmpty(e.Data)) { + BuildError error = ParseError(e.Data); + if (error != null) + feedbackSink.ReportError(error); + else + feedbackSink.ReportMessage(e.Data); + } + }; + p.ErrorDataReceived += delegate(object sender, DataReceivedEventArgs e) { + if (!string.IsNullOrEmpty(e.Data)) { + BuildError error = ParseError(e.Data); + if (error != null) + feedbackSink.ReportError(error); + else + feedbackSink.ReportError(new BuildError(null, e.Data)); + } + }; + p.Exited += delegate(object sender, EventArgs e) { + p.CancelErrorRead(); + p.CancelOutputRead(); + feedbackSink.Done(p.ExitCode == 0); + p.Dispose(); + }; + + feedbackSink.ReportMessage("Building " + this.Name); + feedbackSink.ReportMessage(p.StartInfo.FileName + " " + p.StartInfo.Arguments); + p.Start(); + p.BeginOutputReadLine(); + p.BeginErrorReadLine(); + } + + static readonly Regex errorRegex = new Regex(@"^Error: " + + @"([^(:]+?)" + // group 1: file name + @"(?:\((\d+)\))?" + // group 2: line number + @"\s*:\s*" + // first separator + @"(?:error ([^:]+):)?" + // group 3: error code + @"\s*(.*)$" // group 4: error message + ); + + + static readonly Regex warningRegex = new Regex(@"^(?:\d+\>)?Warning: " + + @"([^(:]+?)" + // group 1: file name + @"(?:\((\d+)\))?" + // group 2: line number + @"\s*:\s*" + // first separator + @"(?:warning ([^:]+):)?" + // group 3: error code + @"\s*(.*)$" // group 4: error message + ); + + + /// + /// Parses an error or warning message and returns a BuildError object for it. + /// + BuildError ParseError(string text) + { + bool isWarning = false; + Match match = errorRegex.Match(text); + if (!match.Success) { + match = warningRegex.Match(text); + isWarning = true; + } + if (match.Success) { + int line = -1; + try { + if (match.Groups[2].Length > 0) { + line = int.Parse(match.Groups[2].Value); + } + } catch (FormatException) { + } catch (OverflowException) { + } + return new BuildError(Path.Combine(Directory, match.Groups[1].Value), line, 0, + match.Groups[3].Value, match.Groups[4].Value) { + IsWarning = isWarning + }; + } else { + return null; + } + } + } +} diff --git a/samples/CppBackendBinding/FileGroup.cs b/samples/CppBackendBinding/FileGroup.cs new file mode 100644 index 0000000000..ab0033bbf3 --- /dev/null +++ b/samples/CppBackendBinding/FileGroup.cs @@ -0,0 +1,45 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.Xml; +using ICSharpCode.SharpDevelop.Project; + +namespace CppBackendBinding +{ + /// + /// Represents a {Filter} element in the .vcproj file. + /// + sealed class FileGroup + { + public readonly CppProject Project; + public readonly ItemType ItemType; + public readonly string[] Extensions; + public readonly XmlElement XmlElement; + + public FileGroup(CppProject project, XmlElement filterElement) + { + this.Project = project; + this.XmlElement = filterElement; + switch (filterElement.GetAttribute("UniqueIdentifier")) { + case "{4FC737F1-C7A5-4376-A066-2A32D752A2FF}": + ItemType = ItemType.Compile; + break; + case "{93995380-89BD-4b04-88EB-625FBE52EBFB}": + ItemType = ItemType.Header; + break; + case "{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}": + ItemType = ItemType.Resource; + break; + default: + ItemType = new ItemType(filterElement.GetAttribute("Name")); + break; + } + Extensions = filterElement.GetAttribute("Filter").Split(';'); + } + } +} diff --git a/samples/CppBackendBinding/FileItem.cs b/samples/CppBackendBinding/FileItem.cs new file mode 100644 index 0000000000..93598d3ea2 --- /dev/null +++ b/samples/CppBackendBinding/FileItem.cs @@ -0,0 +1,57 @@ +// +// +// +// +// $Revision$ +// + +using ICSharpCode.Core; +using System; +using System.Linq; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.IO; +using System.Text; +using System.Xml; +using ICSharpCode.SharpDevelop.Project; + +namespace CppBackendBinding +{ + /// + /// Represents a {File} element in the .vcproj file. + /// + sealed class FileItem + { + public readonly ProjectItem ProjectItem; + public readonly XmlElement XmlElement; + + /// + /// Loads a file item from XML. + /// + public FileItem(FileGroup group, XmlElement fileElement) + { + this.XmlElement = fileElement; + string relativePath = fileElement.GetAttribute("RelativePath"); + if (relativePath.StartsWith(".\\")) { + // SharpDevelop doesn't like paths starting with ".\", so strip it away: + relativePath = relativePath.Substring(2); + } + this.ProjectItem = new FileProjectItem(group.Project, group.ItemType, relativePath); + } + + /// + /// Creates a new file item. + /// + public FileItem(XmlDocument document, ProjectItem item) + { + this.ProjectItem = item; + this.XmlElement = document.CreateElement("File"); + SaveChanges(); + } + + public void SaveChanges() + { + this.XmlElement.SetAttribute("RelativePath", this.ProjectItem.Include); + } + } +} diff --git a/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj b/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj index 5d8d07e26f..38ed35a65a 100644 --- a/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj +++ b/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj @@ -124,6 +124,7 @@ + diff --git a/src/Main/Base/Project/Src/Gui/Pads/TaskList/TaskView.cs b/src/Main/Base/Project/Src/Gui/Pads/TaskList/TaskView.cs index d8ae6458ac..f690efbf76 100644 --- a/src/Main/Base/Project/Src/Gui/Pads/TaskList/TaskView.cs +++ b/src/Main/Base/Project/Src/Gui/Pads/TaskList/TaskView.cs @@ -306,6 +306,8 @@ namespace ICSharpCode.SharpDevelop.Gui /// A formatted task list description. string FormatDescription(string description) { + if (string.IsNullOrEmpty(description)) + return string.Empty; string FormattedDescription = description.Replace("\r", " "); FormattedDescription = FormattedDescription.Replace("\t", " "); return FormattedDescription.Replace("\n", " "); diff --git a/src/Main/Base/Project/Src/Project/Items/ItemType.cs b/src/Main/Base/Project/Src/Project/Items/ItemType.cs index f5a1242589..73b9552eb2 100644 --- a/src/Main/Base/Project/Src/Project/Items/ItemType.cs +++ b/src/Main/Base/Project/Src/Project/Items/ItemType.cs @@ -36,6 +36,7 @@ namespace ICSharpCode.SharpDevelop.Project public static readonly ItemType ApplicationDefinition = new ItemType("ApplicationDefinition"); public static readonly ItemType Page = new ItemType("Page"); public static readonly ItemType BootstrapperFile = new ItemType("BootstrapperFile"); + public static readonly ItemType Header = new ItemType("Header"); /// /// Gets a collection of item types that are used for files. diff --git a/src/Main/Base/Project/Src/Project/Items/ProjectItem.cs b/src/Main/Base/Project/Src/Project/Items/ProjectItem.cs index 3b0ea16a2f..81781975a1 100644 --- a/src/Main/Base/Project/Src/Project/Items/ProjectItem.cs +++ b/src/Main/Base/Project/Src/Project/Items/ProjectItem.cs @@ -100,7 +100,7 @@ namespace ICSharpCode.SharpDevelop.Project /// Gets if the item is added to it's owner project. /// [Browsable(false)] - public bool IsAddedToProject { + internal bool IsAddedToProject { get { return buildItem != null; } diff --git a/src/Main/Base/Project/Src/Project/MSBuildBasedProject.cs b/src/Main/Base/Project/Src/Project/MSBuildBasedProject.cs index 36f83c727e..1f5c04850a 100644 --- a/src/Main/Base/Project/Src/Project/MSBuildBasedProject.cs +++ b/src/Main/Base/Project/Src/Project/MSBuildBasedProject.cs @@ -916,10 +916,16 @@ namespace ICSharpCode.SharpDevelop.Project // MSB4075 is: // "The project file must be opened in VS IDE and converted to latest version // before it can be build by MSBuild." - Converter.PrjxToSolutionProject.ConvertVSNetProject(fileName); - project.Load(fileName); + try { + Converter.PrjxToSolutionProject.ConvertVSNetProject(fileName); + project.Load(fileName); + } catch (System.Xml.XmlException ex2) { + throw new ProjectLoadException(ex2.Message, ex2); + } catch (MSBuild.InvalidProjectFileException ex2) { + throw new ProjectLoadException(ex2.Message, ex2); + } } else { - throw; + throw new ProjectLoadException(ex.Message, ex); } } this.ActiveConfiguration = GetEvaluatedProperty("Configuration") ?? this.ActiveConfiguration; diff --git a/src/Main/Base/Project/Src/Project/ProjectLoadException.cs b/src/Main/Base/Project/Src/Project/ProjectLoadException.cs new file mode 100644 index 0000000000..6894f7346c --- /dev/null +++ b/src/Main/Base/Project/Src/Project/ProjectLoadException.cs @@ -0,0 +1,35 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.Runtime.Serialization; + +namespace ICSharpCode.SharpDevelop.Project +{ + /// + /// Exception used when loading of a project fails. + /// + [Serializable()] + public class ProjectLoadException : Exception + { + public ProjectLoadException() : base() + { + } + + public ProjectLoadException(string message) : base(message) + { + } + + public ProjectLoadException(string message, Exception innerException) : base(message, innerException) + { + } + + protected ProjectLoadException(SerializationInfo info, StreamingContext context) : base(info, context) + { + } + } +} diff --git a/src/Main/Base/Project/Src/Services/LanguageBinding/LanguageBindingService.cs b/src/Main/Base/Project/Src/Services/LanguageBinding/LanguageBindingService.cs index 693625e4eb..b6b3322f85 100644 --- a/src/Main/Base/Project/Src/Services/LanguageBinding/LanguageBindingService.cs +++ b/src/Main/Base/Project/Src/Services/LanguageBinding/LanguageBindingService.cs @@ -118,13 +118,7 @@ namespace ICSharpCode.SharpDevelop location = FileUtility.NormalizePath(location); try { newProject = binding.LoadProject(provider, location, title); - } catch (XmlException ex) { - LoggingService.Warn("Project load error", ex); - if (progressMonitor != null) progressMonitor.ShowingDialog = true; - newProject = new UnknownProject(location, title, ex.Message, true); - newProject.TypeGuid = projectTypeGuid; - if (progressMonitor != null) progressMonitor.ShowingDialog = false; - } catch (Microsoft.Build.BuildEngine.InvalidProjectFileException ex) { + } catch (ProjectLoadException ex) { LoggingService.Warn("Project load error", ex); if (progressMonitor != null) progressMonitor.ShowingDialog = true; newProject = new UnknownProject(location, title, ex.Message, true); diff --git a/src/Main/Core/Project/Src/Services/FileUtility/FileUtility.cs b/src/Main/Core/Project/Src/Services/FileUtility/FileUtility.cs index 52fa2e181b..e67a5ca534 100644 --- a/src/Main/Core/Project/Src/Services/FileUtility/FileUtility.cs +++ b/src/Main/Core/Project/Src/Services/FileUtility/FileUtility.cs @@ -85,36 +85,49 @@ namespace ICSharpCode.Core /// public static string NetSdk20InstallRoot { get { - if (netSdk20InstallRoot == null) { + if (netSdk20InstallRoot == null) { netSdk20InstallRoot = GetPathFromRegistry(@"SOFTWARE\Microsoft\.NETFramework", "sdkInstallRootv2.0") ?? string.Empty; } return netSdk20InstallRoot; } } - static string netSdk30InstallRoot = null; + static string windowsSdk60InstallRoot = null; /// /// Location of the .NET 3.0 SDK (Windows SDK 6.0) install root. /// - public static string NetSdk30InstallRoot { + public static string WindowsSdk60InstallRoot { get { - if (netSdk30InstallRoot == null) { - netSdk30InstallRoot = GetPathFromRegistry(@"SOFTWARE\Microsoft\Microsoft SDKs\Windows\v6.0", "InstallationFolder") ?? string.Empty; + if (windowsSdk60InstallRoot == null) { + windowsSdk60InstallRoot = GetPathFromRegistry(@"SOFTWARE\Microsoft\Microsoft SDKs\Windows\v6.0", "InstallationFolder") ?? string.Empty; } - return netSdk30InstallRoot; + return windowsSdk60InstallRoot; } } - static string netSdk35InstallRoot = null; + static string windowsSdk60aInstallRoot = null; /// - /// Location of the .NET 3.5 SDK (Windows SDK 6.0a) install root. + /// Location of the Windows SDK Components in Visual Studio 2008 (.NET 3.5; Windows SDK 6.0a). /// - public static string NetSdk35InstallRoot { + public static string WindowsSdk60aInstallRoot { get { - if (netSdk35InstallRoot == null) { - netSdk35InstallRoot = GetPathFromRegistry(@"SOFTWARE\Microsoft\Microsoft SDKs\Windows\v6.0a", "InstallationFolder") ?? string.Empty; + if (windowsSdk60aInstallRoot == null) { + windowsSdk60aInstallRoot = GetPathFromRegistry(@"SOFTWARE\Microsoft\Microsoft SDKs\Windows\v6.0a", "InstallationFolder") ?? string.Empty; } - return netSdk35InstallRoot; + return windowsSdk60aInstallRoot; + } + } + + static string windowsSdk61InstallRoot = null; + /// + /// Location of the .NET 3.5 SDK (Windows SDK 6.1) install root. + /// + public static string WindowsSdk61InstallRoot { + get { + if (windowsSdk61InstallRoot == null) { + windowsSdk61InstallRoot = GetPathFromRegistry(@"SOFTWARE\Microsoft\Microsoft SDKs\Windows\v6.1", "InstallationFolder") ?? string.Empty; + } + return windowsSdk61InstallRoot; } } @@ -165,7 +178,7 @@ namespace ICSharpCode.Core } /// - /// Searches all the .net sdk bin folders and return the path of the + /// Searches all the .net sdk bin folders and return the path of the /// exe from the latest sdk. /// /// The EXE to search for. @@ -175,16 +188,20 @@ namespace ICSharpCode.Core /// public static string GetSdkPath(string exeName) { string execPath; - if (Directory.Exists(NetSdk35InstallRoot)) { - execPath = Path.Combine(NetSdk35InstallRoot + @"\bin", exeName); + if (!string.IsNullOrEmpty(WindowsSdk61InstallRoot)) { + execPath = Path.Combine(WindowsSdk61InstallRoot, "bin\\" + exeName); + if (File.Exists(execPath)) { return execPath; } + } + if (!string.IsNullOrEmpty(WindowsSdk60aInstallRoot)) { + execPath = Path.Combine(WindowsSdk60aInstallRoot, "bin\\" + exeName); if (File.Exists(execPath)) { return execPath; } } - if (Directory.Exists(NetSdk30InstallRoot)) { - execPath = Path.Combine(NetSdk30InstallRoot + @"\bin", exeName); + if (!string.IsNullOrEmpty(WindowsSdk60InstallRoot)) { + execPath = Path.Combine(WindowsSdk60InstallRoot, "bin\\" + exeName); if (File.Exists(execPath)) { return execPath; } } - if (Directory.Exists(NetSdk20InstallRoot)) { - execPath = Path.Combine(NetSdk20InstallRoot + @"\bin", exeName); + if (!string.IsNullOrEmpty(NetSdk20InstallRoot)) { + execPath = Path.Combine(NetSdk20InstallRoot, "bin\\" + exeName); if (File.Exists(execPath)) { return execPath; } } throw new FileNotFoundException(StringParser.Parse("${res:Fileutility.CantFindExecutableError}", new string[,] { {"EXECUTABLE", exeName} }));