Как получить версию сборки (assembly file version) в C#?
Решение: используйте 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 — он работает везде.
Ответов пока нет.
Войдите чтобы оставить ответ
Блоги
Безопасность Swift приложений: топ-10 уязвимостей для iOS/macOS
Clean Code на C#: принципы и примеры для .NET разработчика