diff --git a/VDProjectXml.sln b/VDProjectXml.sln index 37e9422..145f79e 100644 --- a/VDProjectXml.sln +++ b/VDProjectXml.sln @@ -1,7 +1,9 @@  -Microsoft Visual Studio Solution File, Format Version 10.00 -# Visual Studio 2008 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VDProjectXml", "VDProjectXml\VDProjectXml.csproj", "{5A8370C6-742B-48F9-8D65-15F4CB69FC25}" +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.24720.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VDProject2Xml", "VDProjectXml\VDProject2Xml.csproj", "{5A8370C6-742B-48F9-8D65-15F4CB69FC25}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/VDProjectXml/Program.cs b/VDProjectXml/Program.cs index 8148c2f..4cb401f 100644 --- a/VDProjectXml/Program.cs +++ b/VDProjectXml/Program.cs @@ -6,19 +6,34 @@ using System.Xml; using System.Text.RegularExpressions; -namespace VDProjectXml +namespace VDProject2Xml { class Program { - /// - /// Matches "key" [= "8:value"] with support for backslash escapes. - /// - private static readonly Regex ElementRegex = new Regex(@"^""([^""\\]*(?:\\.[^""\\]*)*)""(?:\s*=\s*""(\d+):([^""\\]*(?:\\.[^""\\]*)*)"")?$", RegexOptions.Singleline); - - private const string Indent = " "; - - static void Main(string[] args) + /// + /// Matches "key" [= "8:value"] with support for backslash escapes. + /// + private static readonly Regex ElementRegex = new Regex(@"^""([^""\\]*(?:\\.[^""\\]*)*)""(?:\s*=\s*""(\d+):([^""\\]*(?:\\.[^""\\]*)*)"")?$", RegexOptions.Singleline); + + /// + /// Mataches "value:value" for keyless entries like "{EDC2488A-8267-493A-A98E-7D9C3B36CDF3}:.NETFramework,Version=v4.5.2" + /// or "BootstrapperCfg:{63ACBE69-63AA-4F98-B2B6-99F9E24495F2}". + /// + private static readonly Regex NoKeyEntry = new Regex(@"^""([^""]*?):([^""]*)""$", RegexOptions.Singleline); + + private const string Indent = " "; + private const string NoKeyEntryName = "NoKeyEntry"; + private const string ValueTypeAttribute = "valueType"; + private const string ValueAttribute = "value"; + + static int Main(string[] args) { + if (args.Length == 0 || args.Length > 3) + { + ShowHelp(); + return -1; + } + string inputFile = args[0]; string outputFile = args.Length > 1 ? args[1] : null; @@ -33,14 +48,43 @@ static void Main(string[] args) break; default: - throw new Exception("Unknown file type: " + inputFile); + ShowHelp(); + return -2; } + + return 0; } - static void ConvertVDProjToXml(string vdrpojFile, string xmlFile) - { + private static void ShowHelp() + { + Console.WriteLine("VDProject2Xml - A Visual Studio installer to XML converter."); + Console.WriteLine("Usage: VDProject2Xml installerProject.vdproj [installerProject.xml]"); + Console.WriteLine(" VDProject2Xml installerProject.xml [installerProject.vdproj]"); + Console.WriteLine("If no output file path is provided the program will use the input filename with the extension changed to .xml"); + Console.WriteLine("Set the environment variable VDPROJECT2XML_INDENT to \"{0}\" to make the outputed XML use newlines and indenting.", Boolean.TrueString); + } + + public static bool CheckIfShouldIndent() + { + var indentString = Environment.GetEnvironmentVariable("VDPROJECT2XML_INDENT"); + bool result; + if (!Boolean.TryParse(indentString, out result)) + { + result = false; + } + return result; + } + + static void ConvertVDProjToXml(string vdrpojFile, string xmlFile) + { + + XmlWriterSettings settings = new XmlWriterSettings() + { + Indent = CheckIfShouldIndent() + }; + using (StreamReader reader = File.OpenText(vdrpojFile)) - using (XmlWriter writer = XmlWriter.Create(xmlFile)) + using (XmlWriter writer = XmlWriter.Create(xmlFile, settings)) { string line; bool prevLineElement = false; @@ -52,23 +96,33 @@ static void ConvertVDProjToXml(string vdrpojFile, string xmlFile) Match match = ElementRegex.Match(line); - if (match.Success) + if (match.Success) { if (prevLineElement) writer.WriteEndElement(); - string elementName = Unescape(match.Groups[1].Value); - string fixedElementName = XmlConvert.EncodeLocalName(elementName); - - writer.WriteStartElement(fixedElementName); - - if (match.Groups[2].Success) - { - writer.WriteAttributeString("valueType", match.Groups[2].Value); - writer.WriteAttributeString("value", Unescape(match.Groups[3].Value)); - } - - prevLineElement = true; + Match noKeyMatch = NoKeyEntry.Match(line); + if (noKeyMatch.Success) + { + writer.WriteStartElement(NoKeyEntryName); + writer.WriteAttributeString(ValueTypeAttribute, Unescape(noKeyMatch.Groups[1].Value)); + writer.WriteAttributeString(ValueAttribute, Unescape(noKeyMatch.Groups[2].Value)); + } + else + { + string elementName = Unescape(match.Groups[1].Value); + string fixedElementName = XmlConvert.EncodeLocalName(elementName); + + writer.WriteStartElement(fixedElementName); + + if (match.Groups[2].Success) + { + writer.WriteAttributeString(ValueTypeAttribute, match.Groups[2].Value); + writer.WriteAttributeString(ValueAttribute, Unescape(match.Groups[3].Value)); + } + } + + prevLineElement = true; } else { @@ -91,7 +145,7 @@ static void ConvertVDProjToXml(string vdrpojFile, string xmlFile) } } - static void ConvertXmlVDProj(string vdrpojFile, string xmlFile) + static void ConvertXmlVDProj(string xmlFile, string vdrpojFile) { int indentLevel = -1; @@ -125,17 +179,26 @@ static void ConvertXmlVDProj(string vdrpojFile, string xmlFile) } private static void WriteElement(XmlReader reader, TextWriter writer) - { - string elementName = Escape(XmlConvert.DecodeName(reader.LocalName)); - - writer.Write("\"{0}\"", elementName); - - string value = reader.GetAttribute("value"); - - if (value != null) - { - writer.Write(" = \"{0}:{1}\"", reader.GetAttribute("valueType"), Escape(value)); - } + { + string valueType = reader.GetAttribute(ValueTypeAttribute); + string value = reader.GetAttribute(ValueAttribute); + + if (reader.LocalName == NoKeyEntryName) + { + writer.Write("\"{0}:{1}\"", Escape(valueType), Escape(value)); + } + else + { + string elementName = Escape(XmlConvert.DecodeName(reader.LocalName)); + + writer.Write("\"{0}\"", elementName); + + if (value != null) + { + writer.Write(" = \"{0}:{1}\"", valueType, Escape(value)); + } + } + writer.WriteLine(); } diff --git a/VDProjectXml/VDProjectXml.csproj b/VDProjectXml/VDProject2Xml.csproj similarity index 62% rename from VDProjectXml/VDProjectXml.csproj rename to VDProjectXml/VDProject2Xml.csproj index 699c7c1..c6c9ea7 100644 --- a/VDProjectXml/VDProjectXml.csproj +++ b/VDProjectXml/VDProject2Xml.csproj @@ -1,59 +1,89 @@ - - - - Debug - AnyCPU - 9.0.30729 - 2.0 - {5A8370C6-742B-48F9-8D65-15F4CB69FC25} - Exe - Properties - VDProjectXml - VDProjectXml - v3.5 - 512 - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - - 3.5 - - - 3.5 - - - 3.5 - - - - - - - - - - + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {5A8370C6-742B-48F9-8D65-15F4CB69FC25} + Exe + Properties + VDProject2Xml + VDProject2Xml + v3.5 + 512 + + + + + 3.5 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + VDProject2Xml.Program + + + + + 3.5 + + + 3.5 + + + 3.5 + + + + + + + + + + + False + .NET Framework 3.5 SP1 + true + + + + \ No newline at end of file