4

It is trivial to get Assembly information at run-time using reflection:

System.Reflection.Assembly assembly = System.Reflection.Assembly.GetExecutingAssembly();
System.Diagnostics.FileVersionInfo fvi = System.Diagnostics.FileVersionInfo.GetVersionInfo(assembly.Location);

However, I cannot use reflection in my project due to restricted execution environment. In limited trust environment this code will not work.

I want to use some attributes from AssemblyInfo.cs at compile time to show product name, version etc. without invoking reflection mechanism.

Most primitive way would be just duplicating strings from AssemblyInfo.cs file as constant strings somewhere else. But maybe there exist some more elegant solutions?

Of course, some essential info on assembly can be properly resolved only at run-time through reflection. Say, assembly path, execution context etc. But info about name and version is written in project code and should be normally available at compile time.

Any comments and ideas are appreciated. Thank you.

Boris Zinchenko
  • 2,142
  • 1
  • 24
  • 34
  • 2
    As far as I know, there are only three ways how to 'get' assembly version. 1st is using reflection, 2nd is using 'executable file analysation' *(this is the way I use to get version of C/C++ libraries in C/C++ applications)*. Both are only usable at runtime. And at least the 3rd is a reverse approach. You do not 'get the version', but use a constant string to 'set the version'. And you can use this constant string already at compile time, since it is a constant. – Julo Mar 25 '18 at 08:39
  • 1
    https://stackoverflow.com/a/27822637/585968 –  Mar 25 '18 at 08:41
  • @Julo, Thank you. Of your variants, I suppose 3rd is most close to what I want to achieve. Exactly because it is a constant. Is it the only way possible? I see no reason make analysis of my executable file, as far as it is exactly the file I m compiling. It looks unnatural that you should first compile your code into exe or dll and then get round way through reflection to get the info you just compiled! – Boris Zinchenko Mar 25 '18 at 08:44
  • 1
    Unfortunately you can use only constant values in `Attributes`, therefore this is the only way. I saw a project, that used this approach. The constant was generated by a script outside *(makefile/shell/automake/e.t.c.)* and used in the `AssemblyVersionAttribute`. It is not the same as my suggestion, but there should not be a big problem *(except the way how Visual Studio will react to this not standard way of using version number)*. – Julo Mar 25 '18 at 08:48
  • @MickyD, Your suggestion will not work because it uses reflection. – Boris Zinchenko Mar 25 '18 at 08:49
  • @Julo, Thank you for comments. I will consider it as an answer, unless somebody else suggests an alternative. – Boris Zinchenko Mar 25 '18 at 08:51
  • @BorisZinchenko there is only one reason, why you should check the version at runtime. The version number can be changed using a external application *(e.g. Resource Hacker)*. And unfortunately, the assemblies can be changed even more, there even the 'version check' at compile time can be bypassed. But let's leave the hacking... It should be not a problem for the standard user... – Julo Mar 25 '18 at 08:53
  • @Julo, I definitely do not have such elaborate hacking scenarios. So, I consider declaring version and name of assembly in static strings and then passing them to assembly attributes at compile time as the optimal way, based on your opinion. – Boris Zinchenko Mar 25 '18 at 08:59
  • 2
    @BorisZinchenko _"Your suggestion will not work because it uses reflection"_ - utter nonsense! [`FileVersionInfo.GetVersionInfo`](https://msdn.microsoft.com/en-us/library/system.diagnostics.fileversioninfo.getversioninfo(v=vs.110).aspx) is part of ** System.Diagnostics** and does not use reflection. Did you even bother to read it properly? It reads the FILEVERSION that is part of every DLL and EXE and has nothing to do with .NET; .NET APIs let alone reflection. –  Mar 25 '18 at 09:06
  • @MickyD, Sorry on evident confusion. Maybe your variant is an alternative to what Julo advised. However, let me notice that it is not exactly in the context of my question. I asked about the way to it at compile time. But I will weight it as an alternative because it seems it avoids reflection really. – Boris Zinchenko Mar 25 '18 at 09:12
  • @MickyD, Although FileVersionInfo.GetVersionInfo does not require reflection as such, it then relies on assembly path, which is available only at run-time through reflection and is blocked to query in my environment. It is exactly the code you referenced, which I ve used previously and which failed. Thus, I tend to the idea by Julo. – Boris Zinchenko Mar 25 '18 at 09:29
  • When you say "at compile time" what process is meant to retrieve and display that information? Are you writing a custom build script? I think your question is unclear. – McGuireV10 Mar 25 '18 at 09:42
  • @McGuireV10, I m compiling exe and plan to use version info from the same exe I m compiling. Based on answers above, I decided for static strings defined in a separate class and then passed into AssemblyInfo.cs. I just tested it. It works fine. – Boris Zinchenko Mar 25 '18 at 09:45

1 Answers1

2

Since nobody posted an answer so far, I will publish a variant, to which I came based on comments to the question. As @Julo advised, I took way exactly opposite to getting info from attributes and, instead, decided for constant definitions in a class:

public class Resource
{
    public const string VERSION = "1.0.0.0";
    public const string COMPANY = "Company";
    public const string APPICATION = "App";
}

Then I pass these values to assembly attributes:

[assembly: AssemblyTitle(Resource.APPICATION)]
[assembly: AssemblyCompany(Resource.COMPANY)]
[assembly: AssemblyVersion(Resource.VERSION)]
[assembly: AssemblyFileVersion(Resource.VERSION)]

Of course, I can also access these in my code at compile time:

string tool = null, version = null;
//System.Reflection.Assembly assembly = System.Reflection.Assembly.GetExecutingAssembly();
//System.Diagnostics.FileVersionInfo fvi = System.Diagnostics.FileVersionInfo.GetVersionInfo(assembly.Location);
//if (string.IsNullOrEmpty(tool) && fvi != null) tool = fvi.ProductName;
//if (string.IsNullOrEmpty(version) && fvi != null) version = fvi.FileVersion;
tool = Resource.APPICATION;
version = Resource.VERSION;

Drawback here can be that automatic version increment tools in build environments will not be able to access these constants. Advantage can be that constants can be shared between many projects as a single file to enable cetralised version management for the whole solution.

Boris Zinchenko
  • 2,142
  • 1
  • 24
  • 34