通过bash获取已编译/发布的dotnet应用程序的版本信息

时间:2017-12-23 07:28:56

标签: c# linux .net-core

我正在开发一个ASP.Net Core项目,其中 .csproj 文件如下所示:

<PropertyGroup>
  <OutputType>Exe</OutputType>
  <TargetFramework>netcoreapp2.0</TargetFramework>
    <PreserveCompilationContext>true</PreserveCompilationContext>
    <AssemblyName>dummyapp</AssemblyName>
        <Version>17.12.1</Version>
    <RuntimeIdentifiers>centos.7-x64;win7-x64</RuntimeIdentifiers>
</PropertyGroup>

Windows 发布此应用时,我可以从其属性中获取版本信息。其中显示了 17.12.1

或者我可以运行wmic datafile where name="filepath/app.exe" get Version /value并使用命令提示符获得相同的版本。

但有没有一种标准方法可以在Linux发行版中获得相同的内容?

我已经调查过:

在所有试验之后,似乎我需要在.csproj文件中实现其他内容,以便使用 bash 获取版本信息。有人可以指出需要做什么,或者给出相同的暗示。

Main 方法:

public static void Main(string[] args)
{
    var root = new Root();
    var config = new ConfigurationBuilder()
                     .SetBasePath(Directory.GetCurrentDirectory())
                     .AddJsonFile(SettingsFilename, optional: false,
                                  reloadOnChange: true)
                     .AddEnvironmentVariables()
                     .Build();

    config.Bind(root);

    //some codes

    var host = new WebHostBuilder()
                    .UseKestrel()
                    .UseUrls(root.AppUrl)
                    .UseConfiguration(config)
                    .UseContentRoot(Directory.GetCurrentDirectory())
                    .UseIISIntegration()
                    .ConfigureServices(s =>
                                     s.AddRouting().DetectTokenChange(config))
                    .UseSetting(WebHostDefaults.ApplicationKey, "dummyapp")
                    .Configure(app => app.UseRouter(r => r.MapPost("dumptoqueue", 
                                      async (context) => 
                                      await Task.Run(() => AddtoQueue(context)))))
                    .Build();
     host.Run();
}

使用命令行构建的应用程序:

dotnet publish -c release -r centos.7-x64

2 个答案:

答案 0 :(得分:4)

使用exiftool可能更容易,如果你需要通过bash做的就是找到一个dll文件的版本。

$ exiftool Foo.dll | grep -i Version
ExifTool Version Number         : 10.55
Linker Version                  : 48.0
OS Version                      : 4.0
Image Version                   : 0.0
Subsystem Version               : 4.0
File Version Number             : 17.12.1.0
Product Version Number          : 17.12.1.0
File Version                    : 17.12.1.0
Product Version                 : 17.12.1
Assembly Version                : 17.12.1.0

甚至只是:

$ exiftool -"ProductVersion" Foo.dll 
Product Version                 : 17.12.1

答案 1 :(得分:1)

首先,我们假设您的Linux程序已编译为yourprog executable,并且您正在从其源代码构建它(因此您可以稍微更改源代码和构建过程)。无论您的构建过程是什么,或者您使用哪种编程语言编写它都无关紧要。该yourprog文件可能是某些ELF可执行文件或execve(2)系统调用可理解的其他内容(例如脚本)。使用file(1),例如作为file yourprog,找出它的file format。另请参阅binfmt_misc并阅读about #! (shebang)。请注意,每个应用程序都是以execve启动的(通常由您的Unix shell完成,但可能由其他内容完成,例如systemd)。

您可以使用strings ./yourprog对该可执行文件使用strings(1);然后,您将获得其中的大多数多字节字符串。可能一些(许多)字符串包含版本信息(如果它已经在编译阶段放在那里)。

关于--version,它应该是约定,后跟您的程序。请参阅this回答。所以应该改进你的源代码,以便你的程序处理--version--help程序参数。没有魔法,你必须编写代码(也许你的build automation可以生成一些包含版本字符串的C#代码;应该怎么做才是一个不同的问题,并依赖于你使用的特定构建实用程序; makeninja您只需添加一些特定规则,例如在Makefilebuild.ninja中。因此,您需要了解并改进构建过程。如果您使用C#进行编码,则需要从Main处理,因此您需要改进Main以解析args并正确处理--help和{{1} (在Windows上,它可能是其他东西)。顺便说一句,恕我直言,即使在其他操作系统上,能够传递一些程序参数来查询版本并获得帮助是有帮助的(我不知道Windows,但也许它可能是--version/version而不是/help--version)。

请注意,software versioning 总是一个人类约定(即使使用某个version control系统,例如git,也很有帮助)。所以获得该版本不能是“标准”,即使它很容易(它也可能取决于你的项目的约定和编码习惯,也许你的版本控制系统)。我猜你可以在你的构建中生成一些--help生成的C#文件并对其进行适当的编译,让_timestamp_version.cs定义一些常量字符串从_timestamp_version.cs显示。在C Main中,这是一个真正的easy trick,您只需要将其调整为您的编程语言和构建过程(另请参阅this make及其{{1对于与Makefile)相关的更精细的事情;在Unix philosophy中,这样做是很常见的,我很惊讶你在问这个!

也许有一些API来查询C#中的某些版本元数据(可能与反射相关),但这是一个非常不同的问题。而且你应该通常编码以显示一些版本相关的字符串_timestamp.c ....

请记住(即使在Windows上,当然在POSIX和Linux上)compilers实际上与IDE不同。 IDE-甚至是Windows-只是source code editor能够运行外部程序(例如编译器,调试器,构建自动化工具......)。您可以(并且经常应该)在命令行上在IDE之外运行编译器。因此,您可以通过生成一些C#代码来执行基本metaprogramming(例如,生成定义与版本相关的一些字符串常量的文件等)。阅读Unix philosophy(恕我直言,甚至在微软内部使用)。

请记住,git文件不是IIRC,是C#规范(用英文撰写的技术报告)的一部分。另请参阅this