Программно получить номер версии DLL


151

Можно ли программно получить номер версии из любой .NET DLL?

Если да, то как?


10
Не могу поверить, что об этом спросили 6 минут назад, собирался спросить то же самое!
— tpower

2
проверьте эту ссылку также для автоинкрементной версии - blog.mbcharbonneau.com/2007/03/13/…
— JL.

Ответы:


119
Assembly assembly = Assembly.LoadFrom("MyAssembly.dll");
Version ver = assembly.GetName().Version;

Важно: следует отметить, что это не лучший ответ на исходный вопрос. Не забудьте прочитать больше на этой странице.


28
Это загружает MyAssembly.dll в работающий AppDomain ... плохая идея.
— Staafl

12
Я рекомендую Assemblyname.GetAssemblyNameизбегать этих проблем
— staafl

7
загрузка сборки в домен приложения медленная, необратимая (вы не можете выгрузить ее без уничтожения домена), требует разрешений и может вызвать побочные эффекты, такие как выполнение beforefieldinitинициализаторов типов, и в этом случае просто не требуется. Достаточно ли обоснованы эти причины?
— Staafl

7
@staafl: Да; не только для меня, но и для всех остальных, читающих эту страницу в будущем.
— Крис

6
FileVersionInfo.GetVersionInfo("foo.dll").FileVersionхорошо выполняет свою работу и не загружает DLL в приложение.
— Джек,

181

Это работает, если dll .net или Win32 . Методы отражения работают только если dll .net. Кроме того, если вы используете отражение, у вас есть накладные расходы на загрузку всей DLL в память. Приведенный ниже метод не загружает сборку в память.

// Get the file version.
FileVersionInfo myFileVersionInfo = FileVersionInfo.GetVersionInfo(@"C:\MyAssembly.dll");

// Print the file name and version number.
Console.WriteLine("File: " + myFileVersionInfo.FileDescription + '\n' +
                  "Version number: " + myFileVersionInfo.FileVersion);

От: http://msdn.microsoft.com/en-us/library/system.diagnostics.fileversioninfo.fileversion.aspx

первоисточник


5
Мне это нравится. Зачем вам загружать dll, а затем использовать отражение, чтобы получить версию, когда все, что вы действительно хотите сделать, это ???
— aggieNick02

@ben, не могли бы вы отредактировать пост? Я видел, что потерял -1 повторение от добавления понижающего голоса, что я не помню, как делал. это не позволит мне изменить его, если вы не отредактируете сообщение. ура!
— Люк Даддридж

9
Если вы хотите , чтобы убедиться , что вы получите исполняемый / DLL фактически используется в данный момент: вместо статического файла ( @"C:\MyAssembly.dll"выше), вы можете использовать System.Reflection.Assembly.GetExecutingAssembly().Location(или , если в DLL: Assembly.GetAssembly(typeof(AClassInTheDll)).Location)
— Конрад

4
Это разница между атрибутами AssemblyVersion и AssemblyFileVersion. AssemblyFileVersion помечается таким образом, чтобы Windows API мог получить значение. AssemblyVersion является частью строгого имени и не обязательно совпадает с AssemblyFileVersion.
— Дочь

51

Прежде всего, есть две возможные «версии», которые могут вас заинтересовать:

  • Версия файловой системы Windows, применимая ко всем исполняемым файлам

  • Версия сборки сборки, которая встроена компилятором в сборку .NET (очевидно, применима только к файлам dll и exe сборки .NET)

В первом случае вы должны использовать ответ Бена Андерсона; в последнем случае используйте AssemblyName.GetAssemblyName(@"c:\path\to\file.dll").Versionили ответ Татаро, если на сборку ссылается ваш код.

Обратите внимание, что вы можете игнорировать все ответы, которые используют .Load()/ .LoadFrom()методы, так как они фактически загружают сборку в текущий AppDomain - что аналогично вырубке дерева, чтобы увидеть, сколько ему лет.


32

Вот хороший способ использовать немного размышлений для получения версии DLL, содержащей определенный класс:

var ver = System.Reflection.Assembly.GetAssembly(typeof(!Class!)).GetName().Version;

Просто замени! Класс! с именем класса, который определен в DLL, для которой вы хотите получить версию.

Это мой предпочтительный метод, потому что если я перемещаю библиотеки DLL для разных развертываний, мне не нужно менять путь к файлу.


3
Обратите внимание, что это работает только в том случае, если текущая сборка ссылается на данную сборку.
— Staafl

2
Это лучший ответ, так как DLL не обязательно является сборкой ввода, даже не сборкой, из которой она вызывается
— CAD bloke

1
См. Stackoverflow.com/a/909583/492 для получения различных типов информации о версии. напр.FileVersionInfo
— CAD bloke

22

Чтобы получить его для сборки, которая была запущена (winform, консольное приложение и т. Д.)

using System.Reflection;
...
Assembly.GetEntryAssembly().GetName().Version

6
GetExecutingAssembly () также может помочь.
— Гром

10

Крис, твоя версия прекрасно работает, когда нужно загрузить сборку из фактического файла DLL (и, если она там есть!), Однако, будет получена очень нежелательная ошибка, если DLL врезана (т. Е. Не файл, а встроенный файл). DLL).

Другое дело, если кто-то использует схему управления версиями с чем-то вроде « 1.2012.0508.0101 », когда вы получаете строку версии, вы фактически получаете « 1.2012.518.101 »; обратите внимание на пропущенные нули .

Итак, вот несколько дополнительных функций для получения версии DLL (встроенной или из файла DLL):

    public static System.Reflection.Assembly GetAssembly(string pAssemblyName)
    {
        System.Reflection.Assembly tMyAssembly = null;

        if (string.IsNullOrEmpty(pAssemblyName)) { return tMyAssembly; }
        tMyAssembly = GetAssemblyEmbedded(pAssemblyName);
        if (tMyAssembly == null) { GetAssemblyDLL(pAssemblyName); }

        return tMyAssembly;
    }//System.Reflection.Assembly GetAssemblyEmbedded(string pAssemblyDisplayName)


    public static System.Reflection.Assembly GetAssemblyEmbedded(string pAssemblyDisplayName)
    {
        System.Reflection.Assembly tMyAssembly = null;

        if(string.IsNullOrEmpty(pAssemblyDisplayName)) { return tMyAssembly; }
        try //try #a
        {
            tMyAssembly = System.Reflection.Assembly.Load(pAssemblyDisplayName);
        }// try #a
        catch (Exception ex)
        {
            string m = ex.Message;
        }// try #a
        return tMyAssembly;
    }//System.Reflection.Assembly GetAssemblyEmbedded(string pAssemblyDisplayName)


    public static System.Reflection.Assembly GetAssemblyDLL(string pAssemblyNameDLL)
    {
        System.Reflection.Assembly tMyAssembly = null;

        if (string.IsNullOrEmpty(pAssemblyNameDLL)) { return tMyAssembly; }
        try //try #a
        {
            if (!pAssemblyNameDLL.ToLower().EndsWith(".dll")) { pAssemblyNameDLL += ".dll"; }
            tMyAssembly = System.Reflection.Assembly.LoadFrom(pAssemblyNameDLL);
        }// try #a
        catch (Exception ex)
        {
            string m = ex.Message;
        }// try #a
        return tMyAssembly;
    }//System.Reflection.Assembly GetAssemblyFile(string pAssemblyNameDLL)


    public static string GetVersionStringFromAssembly(string pAssemblyDisplayName)
    {
        string tVersion = "Unknown";
        System.Reflection.Assembly tMyAssembly = null;

        tMyAssembly = GetAssembly(pAssemblyDisplayName);
        if (tMyAssembly == null) { return tVersion; }
        tVersion = GetVersionString(tMyAssembly.GetName().Version.ToString());
        return tVersion;
    }//string GetVersionStringFromAssemblyEmbedded(string pAssemblyDisplayName)


    public static string GetVersionString(Version pVersion)
    {
        string tVersion = "Unknown";
        if (pVersion == null) { return tVersion; }
        tVersion = GetVersionString(pVersion.ToString());
        return tVersion;
    }//string GetVersionString(Version pVersion)


    public static string GetVersionString(string pVersionString)
    {
        string tVersion = "Unknown";
        string[] aVersion;

        if (string.IsNullOrEmpty(pVersionString)) { return tVersion; }
        aVersion = pVersionString.Split('.');
        if (aVersion.Length > 0) { tVersion = aVersion[0]; }
        if (aVersion.Length > 1) { tVersion += "." + aVersion[1]; }
        if (aVersion.Length > 2) { tVersion += "." + aVersion[2].PadLeft(4, '0'); }
        if (aVersion.Length > 3) { tVersion += "." + aVersion[3].PadLeft(4, '0'); }

        return tVersion;
    }//string GetVersionString(Version pVersion)


    public static string GetVersionStringFromAssemblyEmbedded(string pAssemblyDisplayName)
    {
        string tVersion = "Unknown";
        System.Reflection.Assembly tMyAssembly = null;

        tMyAssembly = GetAssemblyEmbedded(pAssemblyDisplayName);
        if (tMyAssembly == null) { return tVersion; }
        tVersion = GetVersionString(tMyAssembly.GetName().Version.ToString());
        return tVersion;
    }//string GetVersionStringFromAssemblyEmbedded(string pAssemblyDisplayName)


    public static string GetVersionStringFromAssemblyDLL(string pAssemblyDisplayName)
    {
        string tVersion = "Unknown";
        System.Reflection.Assembly tMyAssembly = null;

        tMyAssembly = GetAssemblyDLL(pAssemblyDisplayName);
        if (tMyAssembly == null) { return tVersion; }
        tVersion = GetVersionString(tMyAssembly.GetName().Version.ToString());
        return tVersion;
    }//string GetVersionStringFromAssemblyEmbedded(string pAssemblyDisplayName)


2

Ответ @Ben оказался для меня полезным. Но мне нужно было проверить версию продукта, так как это было основным шагом в моем программном обеспечении и следовал за семантическим версионированием.

myFileVersionInfo.ProductVersion

Этот метод оправдал мои ожидания

Обновление: вместо явного упоминания пути dll в программе (как требуется в рабочей версии), мы можем получить версию продукта, используя Assembly.

Assembly assembly = Assembly.GetExecutingAssembly();
FileVersionInfo fileVersionInfo =FileVersionInfo.GetVersionInfo(assembly.Location); 
string ProdVersion= fileVersionInfo.ProductVersion;

Примечание: если версия содержит звездочку для автоинкрементного значения, этот метод вернет звездочку вместо фактического сгенерированного числа (т.е. не будет работать, если вы введете 1.0. * В информацию о сборке).
— Ронен Несс

Да! Однако я выбрал автоматизацию Jeniks для обновления версии, поэтому сборка всегда имеет идеальное сочетание версии dll.
— Прасан Датт

1

Вы можете использовать методы System.Reflection.Assembly.Load * (), а затем получить их AssemblyInfo.


0

Хотя первоначальный вопрос, возможно, не относился только к веб-службе, вот полный тестовый веб-сервис, который вы можете добавить для отображения не кэшированного ответа веб-службы плюс версия файла. Мы используем версию файла вместо версии сборки, потому что мы хотим знать версию, но со всеми версиями сборки 1.0.0.0, веб-сайт может быть легко исправлен (ссылка для подписи и запроса по-прежнему активна!). Замените @ Class @ на имя контроллера веб-API, в который встроен этот сервис. Это хорошо для go / nogo в веб-сервисе плюс быстрая проверка версии.

  [Route("api/testWebService")]
  [AllowAnonymous]
  [HttpGet]
  public HttpResponseMessage TestWebService()
  {
      HttpResponseMessage responseMessage = Request.CreateResponse(HttpStatusCode.OK);
      string loc = Assembly.GetAssembly(typeof(@Class@)).Location;
      FileVersionInfo versionInfo = FileVersionInfo.GetVersionInfo(loc);
      responseMessage.Content = new StringContent($"<h2>The XXXXX web service GET test succeeded.</h2>{DateTime.Now}<br/><br/>File Version: {versionInfo.FileVersion}");
      responseMessage.Content.Headers.ContentType = new MediaTypeHeaderValue("text/html");
      Request.RegisterForDispose(responseMessage);
      return responseMessage;
  }

Я также счел необходимым добавить следующее в web.config в конфигурации, чтобы сделать его действительно анонимным

<location path="api/testwebservice">
    <system.web>
        <authorization>
            <allow users="*" />
        </authorization>
    </system.web>
</location>
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.