I wrote a function to compare file versions between what a client currently has and the latest version of the file on a server. The client passes the "quad" (Major.Minor.Build.Private) version number as a string to the server, and then the server uses FileVersionInfo:
// clientFileVersion will be in "quad" format, a la "3.1.4.1"
private bool ServerFileIsNewer(string clientFileVersion, FileVersionInfo serverFile)
{
// Don't say I never learned nuthin' from Steve McConnell
const int MAJOR_INDEX = 0;
const int MINOR_INDEX = 1;
const int BUILD_INDEX = 2;
const int PRIVATE_INDEX = 3;
string[] versionStrArray = clientFileVersion.Split('.');
int FileMajorPartClient;
Int32.TryParse(versionStrArray[MAJOR_INDEX], out FileMajorPartClient);
int FileMinorPartClient;
Int32.TryParse(versionStrArray[MINOR_INDEX], out FileMinorPartClient);
int FileBuildPartClient;
Int32.TryParse(versionStrArray[BUILD_INDEX], out FileBuildPartClient);
int FilePrivatePartClient;
Int32.TryParse(versionStrArray[PRIVATE_INDEX], out FilePrivatePartClient);
int FileMajorPartServer = serverFile.FileMajorPart;
int FileMinorPartServer = serverFile.FileMinorPart;
int FileBuildPartServer = serverFile.FileBuildPart;
int FilePrivatePartServer = serverFile.FilePrivatePart;
return ((FileMajorPartClient < FileMajorPartServer) ||
((FileMajorPartClient == FileMajorPartServer) && (FileMinorPartClient < FileMinorPartServer)) ||
((FileMinorPartClient == FileMinorPartServer) && (FileBuildPartClient < FileBuildPartServer)) ||
((FileBuildPartClient == FileBuildPartServer) && (FilePrivatePartClient < FilePrivatePartServer)));
}
But then I realized that my megaboolean return statement would fail if, say, the client version was 2.1.1.1 and the server version was 1.1.2.1
IOW, it would indicate that the server version was newer when, in fact (of course) it is not.
So then I thought I would add more boolean logic such as:
if (FileMajorClient > FileMajorServer) ||
((FileMajorClient == FileMajorServer) && (FileMinorClient > FileMinorServer)) ||
((FileMajorClient == FileMajorServer) && (FileMinorClient == FileMinorServer) && (FileBuildClient > FileBuildServer))
{
return false;
}
else
{
return ((FileMajorPartClient < FileMajorPartServer) ||
((FileMajorPartClient == FileMajorPartServer) && (FileMinorPartClient < FileMinorPartServer)) ||
((FileMinorPartClient == FileMinorPartServer) && (FileBuildPartClient < FileBuildPartServer)) ||
((FileBuildPartClient == FileBuildPartServer) && (FilePrivatePartClient < FilePrivatePartServer)));
}
...but as you can see, it's turning into a big ball of mad/spaghetti mess madness.
There has to a better, easier, more grokkable/maintainable way of comparing two file versions. But what/how?
UPDATE
Using Servy's answer, this is the method now:
private bool ServerFileIsNewer(string clientFileVersion, FileVersionInfo serverFile)
{
Version client = new Version(clientFileVersion);
Version server = new Version(string.Format("{0}.{1}.{2}.{3}", serverFile.FileMajorPart, serverFile.FileMinorPart, serverFile.FileBuildPart, serverFile.FilePrivatePart));
return server > client;
}
Clean as an unblown whistle, concise as Joe Friday's dream witness, and as elegant as Grace Kelley.
Version server = new Version(serverFile.FileMajorPart, serverFile.FileMinorPart, serverFile.FileBuildPart, serverFile.FilePrivatePart);
There's no need for a string-roundtrip. – Alexanderalexandr