How to convert string into version in .net 3.5?

2019-04-08 04:46发布

问题:

I want to compare the software version created in 3.5 with the older one. If I try to compare version in 4.0 then it's easy by using Version.Parse but in earlier version this facility is not there. I tried to compare it by using string comparison but still not able get the desired output because string comparison doesn't allow to me compare with minor version or major version. Thanks in advance.

回答1:

I ran into a similar problem - I had to parse and sort build numbers so they could be displayed to the user in descending order. I ended up writing my own class to wrap the parts of a build number, and implemented IComparable for sorting. Also ended up overloading the greater than and less than operators, as well as the Equals method. I think it has most of the functionality of the Version class, except for MajorRevision and MinorRevision, which I never used.

In fact, you could probably rename it to 'Version' and use it exactly like you've done with the 'real' class.

Here's the code:

public class BuildNumber : IComparable
{
    public int Major { get; private set; }
    public int Minor { get; private set; }
    public int Build { get; private set; }
    public int Revision { get; private set; }

    private BuildNumber() { }

    public static bool TryParse(string input, out BuildNumber buildNumber)
    {
        try
        {
            buildNumber = Parse(input);
            return true;
        }
        catch
        {
            buildNumber = null;
            return false;
        }
    }

    /// <summary>
    /// Parses a build number string into a BuildNumber class
    /// </summary>
    /// <param name="buildNumber">The build number string to parse</param>
    /// <returns>A new BuildNumber class set from the buildNumber string</returns>
    /// <exception cref="ArgumentException">Thrown if there are less than 2 or 
    /// more than 4 version parts to the build number</exception>
    /// <exception cref="FormatException">Thrown if string cannot be parsed 
    /// to a series of integers</exception>
    /// <exception cref="ArgumentOutOfRangeException">Thrown if any version 
    /// integer is less than zero</exception>
    public static BuildNumber Parse(string buildNumber)
    {
        if (buildNumber == null) throw new ArgumentNullException("buildNumber");

        var versions = buildNumber
            .Split(new[] {'.'},
                   StringSplitOptions.RemoveEmptyEntries)
            .Select(v => v.Trim())
            .ToList();

        if (versions.Count < 2)
        {
            throw new ArgumentException("BuildNumber string was too short");
        }

        if (versions.Count > 4)
        {
            throw new ArgumentException("BuildNumber string was too long");
        }

        return new BuildNumber
            {
                Major = ParseVersion(versions[0]),
                Minor = ParseVersion(versions[1]),
                Build = versions.Count > 2 ? ParseVersion(versions[2]) : -1,
                Revision = versions.Count > 3 ? ParseVersion(versions[3]) : -1
            };
    }

    private static int ParseVersion(string input)
    {
        int version;

        if (!int.TryParse(input, out version))
        {
            throw new FormatException(
                "buildNumber string was not in a correct format");
        }

        if (version < 0)
        {
            throw new ArgumentOutOfRangeException(
                "buildNumber",
                "Versions must be greater than or equal to zero");
        }

        return version;
    }

    public override string ToString()
    {
        return string.Format("{0}.{1}{2}{3}", Major, Minor, 
                             Build < 0 ? "" : "." + Build,
                             Revision < 0 ? "" : "." + Revision);
    }

    public int CompareTo(object obj)
    {
        if (obj == null) return 1;
        var buildNumber = obj as BuildNumber;
        if (buildNumber == null) return 1;
        if (ReferenceEquals(this, buildNumber)) return 0;

        return (Major == buildNumber.Major)
                   ? (Minor == buildNumber.Minor)
                         ? (Build == buildNumber.Build)
                               ? Revision.CompareTo(buildNumber.Revision)
                               : Build.CompareTo(buildNumber.Build)
                         : Minor.CompareTo(buildNumber.Minor)
                   : Major.CompareTo(buildNumber.Major);
    }

    public static bool operator >(BuildNumber first, BuildNumber second)
    {
        return (first.CompareTo(second) > 0);
    }

    public static bool operator <(BuildNumber first, BuildNumber second)
    {
        return (first.CompareTo(second) < 0);
    }

    public override bool Equals(object obj)
    {
        return (CompareTo(obj) == 0);
    }

    public override int GetHashCode()
    {
        unchecked
        {
            var hash = 17;
            hash = hash * 23 + Major.GetHashCode();
            hash = hash * 23 + Minor.GetHashCode();
            hash = hash * 23 + Build.GetHashCode();
            hash = hash * 23 + Revision.GetHashCode();
            return hash;
        }
    }
}


回答2:

Forgive me if im missing something but can't you use the version object constructor passing your version string:

http://msdn.microsoft.com/en-us/library/y0hf9t2e%28v=vs.90%29.aspx?cs-save-lang=1&cs-lang=csharp#code-snippet-1

string str = "0.1.2.3";
Version v = new Version(str);


回答3:

You could always try to decompile the .NET 4.0 Version class - you might be lucky, that it just works in .NET 3.5.

Otherwise you should look into string split or regular expressions.



回答4:

It seems like you're asking about how to get the versions of any local .NET installations. MSDN has an article about this: http://msdn.microsoft.com/en-us/library/hh925568%28v=vs.110%29.aspx.

They include the following function therein:

private static void GetVersionFromRegistry()
{
     // Opens the registry key for the .NET Framework entry. 
        using (RegistryKey ndpKey = 
            RegistryKey.OpenRemoteBaseKey(RegistryHive.LocalMachine, "").
            OpenSubKey(@"SOFTWARE\Microsoft\NET Framework Setup\NDP\"))
        {
            // As an alternative, if you know the computers you will query are running .NET Framework 4.5  
            // or later, you can use: 
            // using (RegistryKey ndpKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine,  
            // RegistryView.Registry32).OpenSubKey(@"SOFTWARE\Microsoft\NET Framework Setup\NDP\"))
        foreach (string versionKeyName in ndpKey.GetSubKeyNames())
        {
            if (versionKeyName.StartsWith("v"))
            {

                RegistryKey versionKey = ndpKey.OpenSubKey(versionKeyName);
                string name = (string)versionKey.GetValue("Version", "");
                string sp = versionKey.GetValue("SP", "").ToString();
                string install = versionKey.GetValue("Install", "").ToString();
                if (install == "") //no install info, must be later.
                    Console.WriteLine(versionKeyName + "  " + name);
                else
                {
                    if (sp != "" && install == "1")
                    {
                         Console.WriteLine(versionKeyName + "  " + name + "  SP" + sp);
                    }
                }
                if (name != "")
                {
                    continue;
                }
                foreach (string subKeyName in versionKey.GetSubKeyNames())
                {
                    RegistryKey subKey = versionKey.OpenSubKey(subKeyName);
                    name = (string)subKey.GetValue("Version", "");
                    if (name != "")
                        sp = subKey.GetValue("SP", "").ToString();
                    install = subKey.GetValue("Install", "").ToString();
                    if (install == "") //no install info, must be later.
                        Console.WriteLine(versionKeyName + "  " + name);
                    else
                    {
                        if (sp != "" && install == "1")
                        {
                            Console.WriteLine("  " + subKeyName + "  " + name + "  SP" + sp);
                        }
                        else if (install == "1")
                        {
                            Console.WriteLine("  " + subKeyName + "  " + name);
                        }

                    }

                }

            }
        }
    }
}


标签: c# .net version