How to get .exe file version number from file path
In the accepted answer a reference is made to "pathToExe".
This path can be retrieved and used as follows:
var assembly = Assembly.GetExecutingAssembly();
var fvi = FileVersionInfo.GetVersionInfo(assembly.Location);
var version = fvi.FileVersion; // or fvi.ProductVersion
Hope this saves someone from doing some unnecessary extra steps.
Updated and modernized 2018 (e.g. string interpolation of C#6):
The accepted answer is partly not correct (ProductVersion is not typically returning three-part version) and a bit misleading:
Here is a more complete answer. To get the main text not too lengthy I splitted it in a short(er) summary which may be "enough" for a lot of people. You are not obliged to read the detailed second part, so please no tl;dr :-)
Short summary:
There are different versions (assembly version, file version, product version) of each file, but normally you will have them all equal to not get "version hell" already on file level (it will come early enough).
The file version (which is visible in Explorer and used in setups/installations) is, what I would name the most important to bother.
To achieve this, simply comment out fileversion in AssemblyInfo.cs file as below. This assures that the three possible different versions of one file are the same!
[assembly: AssemblyVersion("1.1.2.")]
//[assembly: AssemblyFileVersion("1.1.2.")]E.g. for Semantic versioning you want to get only 3 version parts out of possible 4 :
Having an automatic build counting for every Visual Studio build is useful. But this build counting is not always useful to tell your customers, internal or external. So for mentioning the file version to windows, in title dialogs, I would advice to show only three parts v1.2.3 (and of course with semantic versioning):
using System.Diagnostics;
...
var versInfo= FileVersionInfo.GetVersionInfo(pathToVersionedFile);
string fileVersionFull = versInfo.FileVersion; // No difference here for versinfo.ProductVersion if recommendation in AssemblyInfo.cs is followed
string fileVersionSemantic = $"V{versInfo.FileMajorPart}.{versInfo.FileMinorPart}.{versInfo.FileBuildPart}";
string fileVersionFull2 = $"V{versInfo.FileMajorPart}.{versInfo.FileMinorPart}.{versInfo.FileBuildPart}.{versInfo.FilePrivatePart}";
FileVersionFull2 is just showing how to handle all 4 parts, except the "V" it contains the same as FileVersionFull .
D e t a i l s:
First is a cheat sheet about how to get and set the three versions:
File version: [assembly: AssemblyFileVersion(..)] => System.Diagnostics.FileVersionInfo.FileVersion
Product version: [assembly: AssemblyInformationalVersion(..)] => System.Diagnostics.FileVersionInfo.ProductVersion
Assembly version: [assembly: AssemblyVersion(..)] => System.Reflection.Assembly.Version
Especially the defaulting may be confusing. Recommended SO link to understand details: FileVersionInfo and AssemblyInfo
EntryAssembly vs. ExecutingAssembly
For fully considering every case for getting the version of the running app, search elsewhere for more details, e.g. here:
Which is better for getting assembly location , GetAssembly().Location or GetExecutingAssembly().Location
Especially, there can be confusion, if EntryAssembly or ExecutingAssembly should be used. They both have advantages and caveats.
If you have the following code not in the same assembly as the .exe, e.g. in a helper assembly, things get more complicated. Usually you would use EntryAssembly then, to get the version of the .exe.
But: For unit tests in Visual Studio to test routines in a parallel .exe project, GetEntryAssembly() doesn´t work (my env: NUnit, VS2017). But GetExecutingAssembly() doesn´t crash at least, only during unit test you get the assembly version of the test project. Fine enough for me.There may be situations which are not as simple.
If wanted, you can omit the declaration as static making it really possible to get versions of several different assemblies in one program.
public static class AppInfo
{
public static string FullAssemblyName { get; }
..
static AppInfo()
{
Assembly thisAssembly = null;
try
{
thisAssembly = Assembly.GetEntryAssembly();
}
finally
{
if (thisAssembly is null)
thisAssembly = Assembly.GetExecutingAssembly();
}
FullAssemblyName = thisAssembly.Location;
var versInfo = FileVersionInfo.GetVersionInfo(FullAssemblyName);
..
}
}
Product version vs. file version:
ProductVersion of a file is shown in Windows Explorer too. I would recommend to maximally differentiate ProductVersion and FileVersion in the most "customer-visible" file (mostly the main .exe of application). But it could be of course a choice to differentiate for every file of the "main" app and let them all have them all the "marketing" ProductVersion which is seen by customer.
But experience shows that it is neither necessary nor cheap to try to synchronize technical versions and marketing versions too much. Confusion doesn´t decrease really, costs increase. So the solution described in the first part here should do it mostly.
History: Assembly version vs. file version: One reason for having different versions is also that one .NET assembly can originally consist of several files (modules)- theoretically. This is not used by Visual Studio and very seldom used elsewhere. This maybe one historical reason of giving the possibility to differentiate these two versions. Technically the assembly version is relevant for .NET related versioning as GAC and Side-by-side versions, the file version is more relevant for classic setups, e.g. overwriting during updates or for shared files.
You can use FileVersionInfo.FileVersion to fetch this from a path.
var versionInfo = FileVersionInfo.GetVersionInfo(pathToExe);
string version = versionInfo.FileVersion; // Will typically return "1.0.0.0" in your case