Avatar ·

Как получить версию сборки (assembly file version) в C#?

Всем привет! Я новичок в C# и пишу простое приложение для Windows Forms. Мне нужно отобразить версию моей программы в заголовке окна (что-то вроде "МояПрограмма v1.2.3.4"). Я знаю, что в проекте есть файл AssemblyInfo.cs, где я задаю версию, но как её прочитать во время выполнения? Я пробовал использовать Assembly.GetExecutingAssembly().GetName().Version, но он возвращает 0.0.0.0, хотя в AssemblyInfo.cs у меня указано [assembly: AssemblyVersion("1.0.0.0")] и [assembly: AssemblyFileVersion("2.0.0.0")]. В чём разница между AssemblyVersion и AssemblyFileVersion? И как правильно получить FileVersion, чтобы отобразить его пользователю? Вот мой пример кода, который не работает как надо: ```csharp using System; using System.Reflection; class Program { static void Main() { var version = Assembly.GetExecutingAssembly().GetName().Version; Console.WriteLine($"Версия: {version}"); // Выводит: Версия: 0.0.0.0 } } ``` Подскажите, пожалуйста, правильный способ. Заранее спасибо! <<>>

Решение: используйте FileVersionInfo или атрибут AssemblyFileVersion

Проблема в том, что Assembly.GetName().Version возвращает AssemblyVersion (версию сборки для .NET CLR), а не AssemblyFileVersion (версию файла, которая отображается в проводнике Windows). Если AssemblyVersion не задан явно, он по умолчанию равен 0.0.0.0. Для получения FileVersion есть два основных подхода.

Способ 1: Через FileVersionInfo (рекомендуется)

Используйте класс System.Diagnostics.FileVersionInfo — он читает версию прямо из PE-заголовка файла (ту же, что видна в свойствах файла).

using System;
using System.Diagnostics;
using System.Reflection;

class Program
{
    static void Main()
    {
        // Получаем путь к текущей сборке
        var assembly = Assembly.GetExecutingAssembly();
        var location = assembly.Location; // или CodeBase для веб-приложений
        
        // Читаем FileVersionInfo
        var fileVersionInfo = FileVersionInfo.GetVersionInfo(location);
        var fileVersion = fileVersionInfo.FileVersion; // например, "2.0.0.0"
        
        Console.WriteLine($"FileVersion: {fileVersion}");
    }
}

Преимущества:

  • Работает для любого .NET-приложения (WinForms, WPF, консоль).
  • Возвращает именно AssemblyFileVersion, заданный в AssemblyInfo.cs.
  • Можно получить и другие метаданные: ProductVersion, CompanyName и т.д.

Способ 2: Через кастомный атрибут (без чтения файла)

Если вы не хотите читать физический файл, можно получить атрибут AssemblyFileVersionAttribute из метаданных сборки:

using System;
using System.Reflection;

class Program
{
    static void Main()
    {
        var assembly = Assembly.GetExecutingAssembly();
        var attribute = assembly.GetCustomAttribute<AssemblyFileVersionAttribute>();
        var fileVersion = attribute?.Version ?? "Не указан";
        
        Console.WriteLine($"FileVersion: {fileVersion}");
    }
}

Важно: Этот способ работает, только если атрибут явно указан в коде (например, в AssemblyInfo.cs). Если вы используете Directory.Build.props или генерацию версии через MSBuild, атрибут может отсутствовать — тогда лучше использовать FileVersionInfo.

Разница между AssemblyVersion и AssemblyFileVersion

  • AssemblyVersion — используется .NET runtime для разрешения зависимостей (strong naming). Его изменение считается breaking change.
  • AssemblyFileVersion — чисто информационная версия файла (отображается в проводнике Windows). Её можно менять при каждой сборке, не опасаясь сломать зависимости.
  • AssemblyInformationalVersion — ещё один атрибут, обычно содержит полную версию продукта (например, "1.0.0-beta.1").

Полный пример для WinForms

using System;
using System.Diagnostics;
using System.Reflection;
using System.Windows.Forms;

public partial class MainForm : Form
{
    public MainForm()
    {
        InitializeComponent();
        
        var assembly = Assembly.GetExecutingAssembly();
        var fileVersion = FileVersionInfo.GetVersionInfo(assembly.Location).FileVersion;
        var productName = ((AssemblyProductAttribute)assembly.GetCustomAttribute(typeof(AssemblyProductAttribute)))?.Product;
        
        this.Text = $"{productName ?? "Приложение"} v{fileVersion}";
    }
}

Примечание для .NET Core / .NET 5+

В современных проектах версия часто задаётся в .csproj через свойства <Version>, <FileVersion> и <AssemblyVersion>. Способ с FileVersionInfo работает и в этом случае.

<<>>

Альтернативный подход: использование Application.ProductVersion в WinForms

Если вы пишете Windows Forms приложение, есть ещё один простой способ — использовать свойство Application.ProductVersion из пространства имён System.Windows.Forms. Оно автоматически возвращает версию файла (AssemblyFileVersion) сборки, которая содержит точку входа.

using System;
using System.Windows.Forms;

class Program
{
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        
        string version = Application.ProductVersion; // "2.0.0.0"
        MessageBox.Show($"Версия приложения: {version}");
    }
}

Плюсы:

  • Минимум кода — одно свойство.
  • Не требует рефлексии или чтения файла.

Минусы:

  • Работает только в WinForms (не подойдёт для консольных или WPF-приложений).
  • Требует наличия Application.Run() или вызова Application.EnableVisualStyles().

Для универсального решения всё же рекомендую первый способ с FileVersionInfo — он работает везде.