.NET C# how to make version more readable automatically? - c#

I will start from example: I have an version of my app which looks like this
1.0.3450.26573 (it is hard to read and looks nasty). Code to take this version is:
String Version = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString();
I want to see version 1.0.12, 1.0.13, 1.0.14 where 1.0.[BUILD], where BUILD is auto increasing on each build.
How can I do this in a best way?

Actually, build number will not do you any good unless you'll be able to track which build number corresponds to which version of source code your application was built from. Rather, consider using revision number from your repository (if your SCM tool is anything similar to Subversion; to do so try svnversion).

Versioning Controlled Build

You have to integrate that with your build environment. For us, CruiseControl.net increments the version number on each build. But you could also use a SVN revision number etc. There are several possibilities.
If you only want 3 digits instead of 4, you have to format the string yourself.

Yeah, revision number would be great, but how I can get it, I use SourceGear Vault.

Related

.NET: Version string number and length with ClickOnce

If you're using ClickOnce to manage your deployments and updates it may be configured to actively query a URL/manifest for the latest version of your project and then comparing its current version to this to determine if an update needs to be done. Does anyone know what the numerical limits are of the comparison routine? Because I have an automated process doing the builds, we're dropping a timestamp into the four-component of the version (e.g. 1.0.0.x; it's just digits without any symbols). However, I'm concerned that there being an eight-digit number in this spot might potentially crash the comparison. Microsoft no no do so good with unexpected requirements.
Does anyone have experience with this?
Thanks.
Let's walk the trail. If you start plugging in larger numbers, eventually setup.exe will poll for the latest version and then fail with "Cannot continue. The application is improperly formatted. Contact the application vendor for assistance."
If you look at the details, you'll see a log which may say the following:
+ The 'version' attribute is invalid - The value '1.0.0.161739' is invalid according to its datatype 'urn:schemas-microsoft-com:asm.v1:fourPartVersionType' - The Pattern constraint failed.
+ The Pattern constraint failed.
If you Google for "fourPartVersionType", you'll find yourself at FourPartVersionType Simple Type, which provides the following regular expression:
([0-9]{1,4}|[0-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\.([0-9]{1,4}|[0-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){3}
This basically limits each component to four- or five-digits and, essentially, no greater than 65536 in the latter.

Hash of source codes at compile time in C#

Having a server that other devs use, I currently log the version of the dll they use. I do that by having the client that use Reflection to retrieve its version:
Assembly.GetEntryAssembly().GetName().Version.ToString();
It's nice, but since it come from dev that uses TFS and do themself the build, I can not see if they have the latest version of the sources. Is there a trick, like a compilation tag, that would easily allow a hash of the generating source code?
Note: I have try to send the MD5 of the dll (using assembly.Location), but it is useless since the hash value changes between 2 compilations (I suppose there is some compilation timestamp inside the generated dll).
This is most collaboraton issue then a coding.
In the moment that you find out that the version is old one.notify them about it.
If the real version is not old one, that means that developers before making buold did not increment the version ID, which is mistake.
In other words, ordanize it among people, and not relly on these kind of tools (if there is any). You trying to create a complicated tool, that will help you avoid mistakes, but humans will find a way to make them again.
So it's better to create solid relation structure among you, imo.
Create a tool on pre build event to hash/last-write-time your code files.
Write the result to a cs file or a embedded resource file.
The result file must exclude in above action.
For prevent skip build (up-to-date) feature not work,Compare the file before write.
And if youre opening the file in IDE will get a prompt `changed from out side' when build.
Seem there is no easy way to do it.

Find all source hardcoded strings

I need to move all the hard coded strings in my source code in .resx files. Is there a tool that could help me find all the hardcoded strings within C# code?
ReSharper 5 is obvious a choice, but many tips must be set so as to achieve your goals,
Turn on solution wide analysis.
Go to ReSharper|Options|Code Inspection|Inspection Severity|Potential Code Quality Issues|Element is localizable set to Show as error.
Go back to Solution Explorer and click on the project (csproj).
In Properties panel under ReSharper category, set Localizable to Yes, Localizable Inspector to Pessimistic.
Then you can find almost all you need in Errors in Solution panel.
Hope this helps.
Or do a search based upon a regular expression like discussed here:
https://vosseburchttechblog.azurewebsites.net/index.php/2014/12/16/find-all-string-literals-in-c-code-files-but-not-the-ones-in-comments/
(?=(^((?!///).)*$)).*((".+?")|('.+?')).*
You could always do a search for the " sign in all the .cs files. That should get you to most of them, without too much noise.
This tool http://visuallocalizer.codeplex.com/ allows for batch-move strings to resources, together with other features. It is FOSS so maybe you can give it a try.
(I am involved)
Resharper 5.0 (Beta) allows you to move strings to resources (it has built in Localization feature). Give it a try. Beta works fine, i use it every day and have no problems. Best of all it's free until out of beta. I even recommend using night builds as they seem to be stable.
Software localization and globalization have always been tough and at times unwanted tasks for developers. ReSharper 5 greatly simplifies working with resources by providing a full stack of features for resx files and resource usages in C# and VB.NET code, as well as in ASP.NET and XAML markup.
Dedicated features include Move string to resource, Find usages of resource and other navigation actions. Combined with refactoring support, inspections and fixes, you get a convenient localization environment.
Some are found by FxCop. Not sure what its limits are, I think it depends on parameter and property names (eg: a property called "Text" is considered to be localized).

Is it possible to change the version format of a C# project?

Instead of the major.minor.build.revision format, I'd like to use date and time for version numbers. Something more like day.month.year.time. Is there a way to change the format of the AssemblyVersion attribute in AssemblyInfo.cs?
You can put whatever numbers you want in there (as long as they don't overflow the data types that contain them in memory) and call them whatever you wish. I am not sure why you would want to do this, however, as the standard format usually has some form of the date stored in the build field.
For example, here is the assembly version format that we use where I work:
5.1.729.1
This tells me that this is an assembly from version 5.1 of the library, built on July 29th, and was the first build of the day. Subsequent builds on the same day simply increment the revision field.
The easiest approach is to write you own build task that handles this and then have the .csproj file call your task to update it with your default rules. There's an article on using a custom MSBuild task to increment version numbers that could serve as a guide. We have done a similar thing here in the past and found it to work well.
I don't believe there are any tools included in VS2005 for doing this, though.
I would suggest sticking to the existing scheme for the version numbers as used by AssemblyVersion etc - they have well-known meanings and it might confuse people to go against them.
However, you can easily create your own assembly-level attribute and use that for your date/time. Unfortunately the DateTime type can't be embedded in metadata so you'd probably be best off using a string - but your attribute could convert that to a DateTime for you at execution time.
You could build the relevant fragment of assemblyinfo code in a build script -- it's easy enough using IronPython or F# as a scripting tool.
If you would like to automatically change these versions with a script or something similar. I would suggest using http://www.codeproject.com/KB/macros/versioningcontrolledbuild.aspx
It can be ran from the command line also.

C# put date into program when compiled

I was thinking about how to create a program that would only be valid for X period of time, (within a C# app).
What I was thinking was that you would have the current date as a constant inside the program and it would check to see if it is X days older than that. Naturally I do not want to store the date, or the X outside of the program as it can be tampered with.
What I also do not want to manually change this regularly and recompile and deploy it. So is there a way to set a variable to be the current date when it is compiled?
I could have a batch file that would compile it and deploy the new exe to the distribution server.
Thanks
Precompilation directives are your key here. You could create a constant in your application and have it set when you compile.
Make sure you obfuscate your code, however. Someone could disassemble it easily and tamper with the constant. Another solution is to have your software "phone home" to register itself. That way, the registration info is stored on your server and not their machine. There are also third party packages that perform the same security as you're looking for, but they are expensive!
Check out AssemblyInfo.cs file in the Properties folder in your project:
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
Change this to:
[assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyFileVersion("1.0.0.0")]
Then, elsewhere in the assembly, use this:
System.Version MyVersion = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;
// MyVersion.Build = days after 2000-01-01
// MyVersion.Revision*2 = seconds after 0-hour (NEVER daylight saving time)
DateTime MyTime = new DateTime(2000, 1, 1).AddDays(MyVersion.Build).AddSeconds(MyVersion.Revision * 2);
return string.Format("Version:{0} Compiled:{1:s}", MyVersion, MyTime);
I would go with the "Phone home"-variant. And make that call important. ;)
I mean, some important function in your program (some calculation maybe?) will take place on the server. So if the user decompile the program and remove that "call home" it will render the program useless.
I know that not all programs have those specifications that makes this possible but more than you think in general.
From within your automated build process (you do use an automated build process, right?), had a simple app which generates a 1-line C# class
public struct TimeLimit { public DateTime Date = new DateTime(2009,1,1); }
changing the date automatically, and compile.
Then just refer to TimeLimit.Date in your app.
I know this is a 3 year old question, but just to add my 2 cents. We use a "DateLimit" hard coded in a structure as suggested by James Curran.
But we also use that same "Date" as a simple key to "crypt" and "Decrypt" (more Code and decode) all strings, labels, messages. If some people (We call them Cheaters) want to change the expiration date, They will have to go thru the whole assembly to reenter all those string correctly for the new expiration date. It's not perfect, but the cost to us is now near zero and the cost for the Cheaters is high.
I'd suggest that you have the date in a separate, strong named assembly - then at least the malevolent user will find it hard to disassemble, edit and get your program to use it. Is there a way to have two assemblies validating each other based on strong names?
We kind of use this as a first step in our license control for one of our components. If the calling assembly has the same fingerprint as the license controlled one, we assume that it's being used within our own software and licensing is bypassed. If the calling assembly has a different fingerprint or no print at all, normal license checka are carried through. When I come to think of it, our users could probably disassemble, compile without strong naming and bypass licensing. But then again, all our assemblies are shipped as x86, not CIL - would that change anything?
Our experience is that if you're dealing with corporate customers, no-one can bear the hassle of tampering with your stuff, especially since there is a risk in getting caught. A little goes a long way, our current licensing solution is pretty outdated (the package includes examples for VC5!) but has been a high enough hurdle so far. With consumers, on the other hand, I can imagine that it's a bigger threat.
My initial suggestion seems to spawn more questions that answers - perhaps not that helpful after all. :)
The problem with .Net is that it would be easy to decompile and change the date you want to use has constant. You might need to think to something else.
You could write it in the registry but then the people will edit this value.
They aren't a perfect solution but to have an account that validate with an external (web) server is a good idea.

Categories

Resources