}//method: GetFormatVersion /// <summary> /// Checks whether or not the solution is a valid solution file /// </summary> /// <param name="FilePath"></param> /// <returns>double containing the solution's format version</returns> public double CheckValidSolution(string FilePath) { string buf = null; int linecount = 0; double ans = 0.0; //Remove the Read-Only Flag from the Solution file if it exists FileOps.RemoveReadOnlyFlag(FilePath); ParseVSSolutionFile(); ans = this.FormatVersion; if (ans == 0) { throw new ApplicationException("This doesn't appear to be a valid solution file"); } else if (ans == 7.0) { throw new ApplicationException("Conversion of VS.Net (v7.0) solutions is not supported"); } else if (ans == 8.0) { throw new ApplicationException("Conversion of VS2003 (v7.1) solutions is not supported"); } return(ans); }//method: CheckValidSolution
} //property: ProjectList /// <summary> /// Gets the Solution file "format version". /// Also verifies we have a valid solution file /// </summary> /// <param name="FilePath">string containing the file path to the Solution File</param> /// <returns>double containing the Solution Format Version</returns> public double GetFormatVersion(string FilePath) { string buf = null; int linecount = 0; double ans = 0.0; //Remove the Read-Only Flag from the Solution file if it exists FileOps.RemoveReadOnlyFlag(FilePath); using (FileStream fs = new FileStream(FilePath, FileMode.Open)) { StreamReader sr = new StreamReader(fs); while (!sr.EndOfStream) { buf = sr.ReadLine(); // is this a valid header? if (buf.StartsWith("Microsoft Visual Studio Solution File, Format Version")) { ans = double.Parse(buf.Substring(54), System.Globalization.CultureInfo.GetCultureInfo("en-US")); break; } linecount += 1; // A valid solution should have a header at the 1st or 2nd line if (linecount > 2) { break; } } sr.Close(); fs.Close(); }//using //INSTANT C# NOTE: The following VB 'Select Case' included either a non-ordinal switch expression or non-ordinal, range-type, or non-constant 'Case' expressions and was converted to C# 'if-else' logic: // Select Case ans //ORIGINAL LINE: Case 0 if (ans == 0) { throw new ApplicationException("This doesn't appear to be a valid solution file"); } //ORIGINAL LINE: Case 7.0 else if (ans == 7.0) { throw new ApplicationException("Conversion of VS.Net (v7.0) solutions is not supported"); } //ORIGINAL LINE: Case 8.0 else if (ans == 8.0) { throw new ApplicationException("Conversion of VS2003 (v7.1) solutions is not supported"); } return(ans); }//method: GetFormatVersion
}//method: ConvertVSSolution() /// <summary> /// Performs the conversion of the Visual Studio Solution /// </summary> public void ConvertVSSolution() { FileStream fs = null; List <string> arrLines = new List <string>(); //Remove Read-Only Flag from Solution FileOps.RemoveReadOnlyFlag(this.SolnFilePath); // OK now it's time to save the converted Solution file using (fs = new FileStream(this.SolnFilePath, FileMode.Open)) { StreamReader sr = new StreamReader(fs); while (sr.Peek() >= 0) { string strLine = sr.ReadLine(); if (strLine.StartsWith(VSSolutionFormat.Format_Header)) { arrLines.Add(this.SolnFileFormatHeader); }//if else if (strLine.StartsWith("# Visual")) { arrLines.Add(this.SolnFileVersionHeader); }//if else { arrLines.Add(strLine); } //else } //while //Close the file stream fs.Close(); }//using using (StreamWriter sw = new StreamWriter(this.SolnFilePath, false)) { foreach (var arrLine in arrLines) { sw.WriteLine(arrLine); } //foreach } //using } //method: ConvertVSSolution
/// <summary> /// Convert VB.Net and C# Visual Studio project files /// </summary> /// <param name="ProjFile"></param> /// <param name="ConvertTo"></param> /// <param name="blnRemoveSccBindings"></param> /// <returns></returns> public static bool ConvertProject(string ProjFile, Versions ConvertTo, bool blnRemoveSccBindings = false) { //Declare the base namespace for Visual Studio project files const string VSProjNamespace = "http://schemas.microsoft.com/developer/msbuild/2003"; const string TargetFrameworkNode = "TargetFrameworkVersion"; const string PropertyGroupNode = "PropertyGroup"; const string ToolsNode = "ToolsVersion"; const string ProductVersionNode = "ProductVersion"; const string OldToolsVersionNode = "OldToolsVersion"; //Get all of the settings for the appropriate version of Visual Studio var vsProjectVersionInfo = VSProjectCreator.VSProjectFactory(ConvertTo); //Read in the settings from the existing Visual Studio project file VSProjectInfo vsProjectInfo = new VSProjectInfo(ProjFile); //Load the Xml into a XElement XElement xmlVSProjFile = XElement.Load(ProjFile); //Declare the namespace for the Visual Studio project file XNamespace xns = VSProjNamespace; //Query for all of the necessary elements var oldToolsElement = GetVSProjElement(xmlVSProjFile, OldToolsVersionNode); //Use a Linq query to obtain the TargetFrameworkVersion var targetFrameworkElement = GetVSProjElement(xmlVSProjFile, TargetFrameworkNode); var productVersionElement = GetVSProjElement(xmlVSProjFile, ProductVersionNode); var toolsVersionAttrib = xmlVSProjFile.Attribute("ToolsVersion"); //Get the 1st PropertyGroup in the project var propGroup = xmlVSProjFile.Element(xns + PropertyGroupNode); //Make sure that the root element of the file is a Visual Studio project file if (xmlVSProjFile.Name.LocalName.Equals("Project")) { //TODO: Re-analyze this logic since it is not true in all cases, esp. VS 2012 if (toolsVersionAttrib != null) { // converting to VS2008, but project is already at VS2008 if (ConvertTo == Versions.Version9 && toolsVersionAttrib.Value.Equals(vsProjectVersionInfo.ToolsVersion)) { // exit quietly return(false); } // converting to VS2010, but project is already at VS2010 if (ConvertTo == Versions.Version10 && toolsVersionAttrib.Value.Equals(vsProjectVersionInfo.ToolsVersion)) { // exit quietly return(false); }//if } else { // If converting to VS2005, but project is already at VS2005 if (ConvertTo == Versions.Version8) { // exit quietly return(false); } } } else { // no such node? That's bad, very bad... throw new ApplicationException("Invalid project file"); } // the OldToolsVersion element in the first PropertyGoup string strOldToolsVersion = string.Empty; //Local variable for storing the existing Target Framework Version var existingTargetFrameworkVersion = string.Empty; switch (ConvertTo) { case Versions.Version8: // it gets removed xmlVSProjFile.Attribute(ToolsNode).Remove(); //OldToolsVersion oldToolsElement.Remove(); //TargetFrameworkVersion targetFrameworkElement.Remove(); //Product Version //Product Version element does not exist in VS 2012 if (productVersionElement.Count() == 0) { propGroup.Add(new XElement(xns + ProductVersionNode, Settings.Default.VS2005_Version)); } else if (productVersionElement.Count() > 0) { productVersionElement.ElementAtOrDefault(0).Value = Settings.Default.VS2005_Version; } break; case Versions.Version9: if (toolsVersionAttrib != null) { xmlVSProjFile.SetAttributeValue(ToolsNode, vsProjectVersionInfo.ToolsVersion); } //if else { // add the attribute xmlVSProjFile.Add(new XAttribute(ToolsNode, vsProjectVersionInfo.ToolsVersion)); } //Product Version element does not exist in VS 2012 if (productVersionElement.Count() == 0) { propGroup.Add(new XElement(xns + ProductVersionNode, vsProjectVersionInfo.ProductVersion)); } else if (productVersionElement.Count() > 0) { productVersionElement.ElementAtOrDefault(0).Value = vsProjectVersionInfo.ProductVersion; } // add a new element //Use the coalescing operator to determine which value to use strOldToolsVersion = vsProjectInfo.OldToolsVersion ?? vsProjectVersionInfo.OldToolsVersion; if (oldToolsElement.ElementAtOrDefault(0) != null) { oldToolsElement.ElementAtOrDefault(0).Value = strOldToolsVersion; } //if else { propGroup.Add(new XElement(xns + OldToolsVersionNode, strOldToolsVersion)); } //else existingTargetFrameworkVersion = vsProjectVersionInfo.CheckFrameworkVersion(vsProjectInfo.TargetFrameworkVersion); //Set the target Framework Version if (targetFrameworkElement.ElementAtOrDefault(0) != null) { targetFrameworkElement.ElementAtOrDefault(0).Value = existingTargetFrameworkVersion; } //if else { propGroup.Add(new XElement(xns + TargetFrameworkNode, existingTargetFrameworkVersion)); } //else break; case Versions.Version10: if (toolsVersionAttrib != null) { xmlVSProjFile.SetAttributeValue(ToolsNode, vsProjectInfo.ToolsVersion); } //if else { // add the attribute xmlVSProjFile.Add(new XAttribute(ToolsNode, vsProjectVersionInfo.ToolsVersion)); } if (productVersionElement.Count() > 0) { //Retain the product version if it exists, otherwise it is not needed for VS 2010 Support productVersionElement.ElementAtOrDefault(0).Value = vsProjectVersionInfo.ProductVersion; } //if //Use the coalescing operator to determine which value to use strOldToolsVersion = vsProjectInfo.OldToolsVersion ?? vsProjectVersionInfo.OldToolsVersion; if (oldToolsElement.ElementAtOrDefault(0) != null) { oldToolsElement.ElementAtOrDefault(0).Value = strOldToolsVersion; } //if else { propGroup.Add(new XElement(xns + OldToolsVersionNode, strOldToolsVersion)); } //else existingTargetFrameworkVersion = vsProjectVersionInfo.CheckFrameworkVersion(vsProjectInfo.TargetFrameworkVersion); //Set the target Framework Version if (targetFrameworkElement.ElementAtOrDefault(0) != null) { targetFrameworkElement.ElementAtOrDefault(0).Value = existingTargetFrameworkVersion; } //if else { propGroup.Add(new XElement(xns + TargetFrameworkNode, existingTargetFrameworkVersion)); } //else break; case Versions.Version11: if (toolsVersionAttrib != null) { xmlVSProjFile.SetAttributeValue(ToolsNode, vsProjectVersionInfo.ToolsVersion); } //if else { // add the attribute xmlVSProjFile.Add(new XAttribute(ToolsNode, vsProjectVersionInfo.ToolsVersion)); } //Product Version information is no longer used in VS 2012 productVersionElement.Remove(); //Use the coalescing operator to determine which value to use strOldToolsVersion = vsProjectInfo.OldToolsVersion ?? vsProjectVersionInfo.OldToolsVersion; if (oldToolsElement.ElementAtOrDefault(0) != null) { oldToolsElement.ElementAtOrDefault(0).Value = strOldToolsVersion; } //if else { propGroup.Add(new XElement(xns + OldToolsVersionNode, strOldToolsVersion)); } //else existingTargetFrameworkVersion = vsProjectVersionInfo.CheckFrameworkVersion(vsProjectInfo.TargetFrameworkVersion); //Set the target Framework Version if (targetFrameworkElement.ElementAtOrDefault(0) != null) { targetFrameworkElement.ElementAtOrDefault(0).Value = existingTargetFrameworkVersion; } //if else { propGroup.Add(new XElement(xns + TargetFrameworkNode, existingTargetFrameworkVersion)); } //else break; }//switch // The MSBuildToolsPath vs MSBuildBinPath environmental variable. Oddly enough a fully patched VS2005 // uses the newer MSBuildToolsPath. So, this should only be required if you don't have VS2005 SP1 installed. // However, I can't detect that, so we take the worst case scenario, and use the older version var vsImportElement = from vsImportElements in xmlVSProjFile.Elements() where vsImportElements.Name.LocalName.StartsWith("Import") && vsImportElements.FirstAttribute.Name.LocalName.Equals("Project") && vsImportElements.FirstAttribute.Value.StartsWith("$(MS") select vsImportElements; //Project should always be the first attribute for the Import element var msBuildPathValue = vsImportElement.ElementAtOrDefault(0).FirstAttribute.Value; string strMSBuildPath = string.Empty; if (ConvertTo >= Versions.Version9) { // convert it to the newer MSBuildToolsPath if (msBuildPathValue.Contains("MSBuildBinPath")) { strMSBuildPath = msBuildPathValue.Replace("MSBuildBinPath", "MSBuildToolsPath"); vsImportElement.ElementAtOrDefault(0).FirstAttribute.Value = strMSBuildPath; } //if } //if else { // convert it to the older MSBuildBinPath if (msBuildPathValue.Contains("MSBuildToolsPath")) { strMSBuildPath = msBuildPathValue.Replace("MSBuildToolsPath", "MSBuildBinPath"); vsImportElement.ElementAtOrDefault(0).FirstAttribute.Value = strMSBuildPath; } //if } //else //Check if there is a requirement to remove the Scc Bindings //from the Visual Studio project file if (blnRemoveSccBindings) { //Obtain a handle to the Source Control elements in the Visual Studio project file var sccProjElement = from sccElements in xmlVSProjFile.Elements(xns + "PropertyGroup").Elements() where sccElements.Name.LocalName.StartsWith("Scc") select sccElements; //Remove the SccElements from the collection sccProjElement.Remove(); }//if //Attempt to save the changes back to the Visual Studio file try { //Save the changes back to the Visual Studio project file xmlVSProjFile.Save(ProjFile); }//try catch (UnauthorizedAccessException ex) { FileOps.RemoveReadOnlyFlag(ProjFile); //Save the changes back to the Visual Studio project file xmlVSProjFile.Save(ProjFile); } // catch return(true); }