Jakie są różnice między AssemblyVersion, AssemblyFileVersion i AssemblyInformationalVersion?

Istnieją trzy atrybuty wersji montażu. Czym są różnice? Czy mogę użyć AssemblyVersion i zignorować resztę?


MSDN says:

  • AssemblyVersion :

    Określa wersję przypisanego zestawu.

  • AssemblyFileVersion :

    Nakazuje kompilatorowi użycie określonego numeru wersji dla zasobu wersji pliku Win32. Wersja pliku Win32 nie musi być taki sam jak numer wersji zespołu.

  • AssemblyInformationalVersion :

    Definiuje dodatkowe informacje o wersji manifestu zestawu.


jest to kontynuacja jakie są najlepsze praktyki korzystania z atrybutów złożenia?

Author: Ian Kemp, 2008-09-15

7 answers

AssemblyVersion

Gdzie będą wyglądały inne zespoły odwołujące się do Twojego zespołu. Jeśli liczba ta ulegnie zmianie, inne zespoły będą musiały zaktualizować swoje odniesienia do Twojego zespołu! AssemblyVersion jest wymagane.

Używam formatu: major.minor . Wynikałoby to z:

[assembly: AssemblyVersion("1.0")]

AssemblyFileVersion

Używany do rozmieszczenia. Możesz zwiększyć tę liczbę dla każdego wdrożenia. Jest używany przez programy instalacyjne. Użyj go do oznaczania zespołów, które mają te same AssemblyVersion, ale są generowane z różnych buildów.

W systemie Windows można go przeglądać we właściwościach pliku.

Jeśli to możliwe, Niech zostanie wygenerowana przez MSBuild. AssemblyFileVersion jest opcjonalny. Jeśli nie podano, używana jest wersja AssemblyVersion.

Używam formatu: major.drobne.rewizja.build , gdzie używam wersji dla etapu rozwoju (Alpha, Beta, RC i RTM), service Pack i hot fixes. Wynikałoby to in:

[assembly: AssemblyFileVersion("1.0.3100.1242")]

AssemblyInformationalVersion

Wersja produktu zespołu. Jest to wersja, której można użyć podczas rozmowy z klientami lub do wyświetlania na swojej stronie internetowej. Ta wersja może być ciągiem znaków, jak " 1.0 Release Candidate ".

Analiza kodu będzie narzekać na to (CA2243) -- zgłoszone do Microsoft (nie naprawiono w VS2013).

AssemblyInformationalVersion jest opcjonalne. Jeśli nie podano, używana jest AssemblyFileVersion.

Używam format: minor [revision as string] . Wynikałoby to z:

[assembly: AssemblyInformationalVersion("1.0 RC1")]
 830
Author: Rémy van Duijkeren,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-20 18:07:38

Wersjonowanie zestawów w. Net może być mylącą perspektywą, biorąc pod uwagę, że obecnie istnieją co najmniej trzy sposoby określenia wersji zestawu.

Oto trzy główne atrybuty montażu związane z wersją:

// Assembly mscorlib, Version 2.0.0.0
[assembly: AssemblyFileVersion("2.0.50727.3521")]
[assembly: AssemblyInformationalVersion("2.0.50727.3521")]
[assembly: AssemblyVersion("2.0.0.0")]

Zgodnie z konwencją, cztery części wersji są określane jako wersja główna, Wersja Minor, Build , and Revision.

{[3] } ma na celu jednoznaczne zidentyfikowanie budowy montaż indywidualny

Zazwyczaj ręcznie ustawiasz Asemblyfileversion Major i Minor tak, aby odzwierciedlała wersję Asembly, a następnie zwiększasz kompilację i / lub rewizję za każdym razem, gdy Twój system kompilacji kompiluje Asembly. AssemblyFileVersion powinno pozwalać na unikalną identyfikację kompilacji, tak aby można było jej używać jako punktu wyjścia do debugowania wszelkich problemów.

W moim obecnym projekcie mamy serwer build kodujący numer listy zmian z nasze repozytorium kontroli źródeł do części kompilacji i rewizji AssemblyFileVersion. To pozwala nam mapować bezpośrednio z zestawu do jego kodu źródłowego, dla dowolnego zestawu wygenerowanego przez serwer kompilacji (bez konieczności używania etykiet lub gałęzi w kontroli źródła, lub ręcznego przechowywania jakichkolwiek zapisów wydanych wersji).

Ten numer wersji jest przechowywany w zasobie wersji Win32 i można go zobaczyć podczas przeglądania stron właściwości Eksploratora Windows dla montaż.

CLR nie dba ani nie bada Assemblyfileversji.

AssemblyInformationalVersion jest przeznaczony do reprezentowania wersji całego produktu

AssemblyInformationalVersion ma na celu umożliwienie spójnego wersjonowania całego produktu, które może składać się z wielu zestawów, które są niezależnie wersjonowane, być może z różnymi politykami wersjonowania i potencjalnie rozwijane przez różne zespoły.

" na przykład Wersja 2.0 o produkcie może zawierać kilka zespołów; jeden z tych zespołów jest oznaczony jako Wersja 1.0 ponieważ jest to nowy montaż który nie pojawił się w wersji 1.0 z ten sam produkt. Zazwyczaj ustawia się główne i pomniejsze części tej wersji numer do reprezentowania wersji publicznej Twojego produktu. Następnie zwiększasz części budowy i rewizji za każdym razem pakujesz kompletny produkt z wszystkich zgromadzeń." - Jeffrey Richter, [CLR via C #(Second Edition)] P. 57

CLR nie dba ani nie bada AssemblyInformationalVersion.

Jest to jedyna wersja, na której zależy CLR (ale dba o całą AssemblyVersion)

AssemblyVersion jest używany przez CLR do wiązania z silnie nazwanymi złożeniami. Jest on przechowywany w tabeli metadanych manifestu assemblydef zbudowanego zestawu oraz w tabeli AssemblyRef dowolnego zestawu, który się do niego odwołuje.

Jest to bardzo ważne, ponieważ oznacza że gdy odwołujesz się do silnie nazwanego zestawu, jesteś ściśle związany z konkretną wersją zestawu tego zestawu. Cała AssemblyVersion musi być dokładnie dopasowana, aby Wiązanie się powiodło. Na przykład, jeśli odwołujesz się do wersji 1.0.0.0 silnie nazwanego zestawu w czasie kompilacji, ale tylko Wersja 1.0.0.1 tego zestawu jest dostępna w czasie wykonywania, powiązanie nie powiedzie się! (Będziesz musiał obejść to za pomocą przekierowania wiązania do montażu.)

Zamieszanie nad czy całość {[5] } musi się zgadzać. (Tak, to prawda.)

Istnieje małe zamieszanie wokół tego, czy cała AssemblyVersion musi być dokładnie dopasowana, aby zespół mógł zostać załadowany. Niektórzy ludzie są pod fałszywym przekonaniem, że tylko główne i pomniejsze Części Zgromadzenia muszą pasować, aby Wiązanie się powiodło się. Jest to rozsądne założenie, jednak ostatecznie jest nieprawidłowe (od.NET 3.5) i jest trywialne, aby zweryfikować to dla swojej wersji CLR. Just wykonaj ten przykładowy kod .

Na mojej maszynie drugie obciążenie montażowe zawodzi, a ostatnie dwie linie dziennika fuzji wyjaśniają doskonale, dlaczego:

.NET Framework Version: 2.0.50727.3521
---
Attempting to load assembly: Rhino.Mocks, Version=3.5.0.1337, Culture=neutral, PublicKeyToken=0b3305902db7183f
Successfully loaded assembly: Rhino.Mocks, Version=3.5.0.1337, Culture=neutral, PublicKeyToken=0b3305902db7183f
---
Attempting to load assembly: Rhino.Mocks, Version=3.5.0.1336, Culture=neutral, PublicKeyToken=0b3305902db7183f
Assembly binding for  failed:
System.IO.FileLoadException: Could not load file or assembly 'Rhino.Mocks, Version=3.5.0.1336, Culture=neutral, 
PublicKeyToken=0b3305902db7183f' or one of its dependencies. The located assembly's manifest definition 
does not match the assembly reference. (Exception from HRESULT: 0x80131040)
File name: 'Rhino.Mocks, Version=3.5.0.1336, Culture=neutral, PublicKeyToken=0b3305902db7183f'

=== Pre-bind state information ===
LOG: User = Phoenix\Dani
LOG: DisplayName = Rhino.Mocks, Version=3.5.0.1336, Culture=neutral, PublicKeyToken=0b3305902db7183f
 (Fully-specified)
LOG: Appbase = [...]
LOG: Initial PrivatePath = NULL
Calling assembly : AssemblyBinding, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null.
===
LOG: This bind starts in default load context.
LOG: No application configuration file found.
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework64\v2.0.50727\config\machine.config.
LOG: Post-policy reference: Rhino.Mocks, Version=3.5.0.1336, Culture=neutral, PublicKeyToken=0b3305902db7183f
LOG: Attempting download of new URL [...].
WRN: Comparing the assembly name resulted in the mismatch: Revision Number
ERR: Failed to complete setup of assembly (hr = 0x80131040). Probing terminated.

Myślę, że źródłem tego zamieszania jest prawdopodobnie to, że Microsoft pierwotnie zamierzał być nieco bardziej pobłażliwy w tym ścisłym dopasowaniu pełnej wersji AssemblyVersion, dopasowując tylko główne i pomniejsze części wersji: {]}

" podczas ładowania zestawu, CLR automatycznie znajdzie najnowsze zainstalowana wersja serwisowa, która pasuje do wersji major/minor wymagane Zgromadzenie." - Jeffrey Richter, [CLR via C #(Second Edition)] str. 56

W wersji 1.0 CLR, ta funkcja została usunięta przed wydaniem wersji 1.0 i nie udało się jej ponownie wynurzyć w. NET 2.0: [10]}

"Uwaga: właśnie opisałem, jak trzeba pomyśleć o numerach wersji. Niestety CLR nie leczy wersja numery tędy. [W. NET 2.0], CLR traktuje numer wersji jako nieprzezroczystą wartość, a jeśli skład zależy od wersji 1.2.3.4 innego montaż, CLR próbuje załadować tylko w wersji 1.2.3.4 (chyba że Wiązanie przekierowanie jest na miejscu). Jednakże, Microsoft planuje zmienić Ładowarka CLR w przyszłej wersji tak że ładuje najnowsze Budowa / rewizja dla danego major / minor wersja zestawu . Na przykład, na przyszłą wersję CLR, jeśli loader próbuje znaleźć wersję 1.2.3.4 montażu i wersji 1.2.5.0 istnieje, Ładowarka Z automatycznie odebrać najnowsze wersja serwisowa. To będzie bardzo Witam zmiana w ładowarce CLR-I nie można się doczekać." - Jeffrey Richter, [CLR via C #(Second Edition)] str. 164 (podkreślenie moje)

Ponieważ ta zmiana nadal nie została zaimplementowana, myślę, że można bezpiecznie założyć, że Microsoft cofnął się w tej intencji i być może jest już za późno, aby zmień to teraz. Próbowałem przeszukać sieć, aby dowiedzieć się, co się stało z tymi planami, ale nie mogłem znaleźć żadnych odpowiedzi. Nadal chciałem się dowiedzieć.

Więc wysłałem Jeffa Richtera i zapytałem go wprost - pomyślałem, że jeśli ktoś wie, co się stało, to będzie to on. [9]}odpowiedział w ciągu 12 godzin, nie mniej niż w sobotę rano, i wyjaśnił, że ładowarka. NET 1.0 Beta 1 zaimplementowała ten mechanizm "automatycznego przewijania do przodu", odbierając najnowsze dostępne Budowanie i rewizja zestawu, ale to zachowanie zostało przywrócone przed wydaniem. NET 1.0. Później zamierzano to ożywić, ale nie udało się to przed wydaniem CLR 2.0. Potem przyszedł Silverlight, który miał pierwszeństwo dla zespołu CLR, więc ta funkcjonalność została opóźniona. W międzyczasie większość ludzi, którzy byli w pobliżu w czasach CLR 1.0 Beta 1, ruszyła dalej, więc jest mało prawdopodobne, że ujrzy to światło dzienne, pomimo całej ciężkiej pracy, która została już wykonana w to. Wygląda na to, że obecne zachowanie zostanie tutaj.

Warto również zauważyć z mojej dyskusji z Jeffem, że AssemblyFileVersion został dodany dopiero po usunięciu mechanizmu "automatycznego przewijania" - ponieważ po 1.0 Beta 1, jakakolwiek zmiana w AssemblyVersion była przełomową zmianą dla Twoich klientów, nie było wtedy gdzie bezpiecznie przechowywać Twój numer kompilacji. AssemblyFileVersion jest tą bezpieczną przystanią, ponieważ nigdy nie jest automatycznie sprawdzana przez CLR. Może jest to jaśniejsze w ten sposób, mając dwa oddzielne numery wersji, z oddzielnymi znaczeniami, zamiast próbować dokonać tego rozdziału między główną/małą (łamanie) i częścią kompilacji/rewizji (niełamanie) AssemblyVersion.

Podsumowując: zastanów się uważnie, kiedy zmienisz swój AssemblyVersion

Morał jest taki, że jeśli wysyłasz Zespoły, do których będą odwoływać się inni deweloperzy, musisz być bardzo ostrożny, gdy zmienisz (i nie zmienisz) Montaż tych zespołów. Wszelkie zmiany w AssemblyVersion będą oznaczać, że deweloperzy aplikacji będą musieli albo ponownie skompilować nową wersję (aby zaktualizować te wpisy AssemblyRef), albo użyć przekierowań wiązania Asembly, aby ręcznie nadpisać powiązanie.

  • nie zmieniaj wersji AssemblyVersion dla wersji serwisowej, która ma być kompatybilna wstecz.
  • do Zmień AssemblyVersion dla Wydania, o którym wiesz, że ma przełomowe zmiany.

Po prostu spójrz jeszcze raz na atrybuty wersji na mscorlib:

// Assembly mscorlib, Version 2.0.0.0
[assembly: AssemblyFileVersion("2.0.50727.3521")]
[assembly: AssemblyInformationalVersion("2.0.50727.3521")]
[assembly: AssemblyVersion("2.0.0.0")]

Zauważ, że to AssemblyFileVersion zawiera wszystkie interesujące informacje serwisowe (to część Revision tej wersji mówi ci, na którym dodatku Service Pack się znajdujesz), tymczasem AssemblyVersion jest naprawiony w nudnym starym 2.0.0.0. Każda zmiana w AssemblyVersion wymusiłaby każdą aplikację. NET odwołującą się do mscorlib.dll do ponownej kompilacji z nowym wersja!

 544
Author: Daniel Fortunov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-06 18:06:33

AssemblyVersion praktycznie pozostaje wewnętrznie w. NET, podczas gdy AssemblyFileVersion jest tym, co widzi Windows. Jeśli przejdziesz do właściwości złożenia znajdującego się w katalogu i przełączysz się na kartę Wersja, AssemblyFileVersion jest tym, co zobaczysz u góry. Jeśli sortujesz pliki według wersji, jest to używane przez Eksploratora.

AssemblyInformationalVersion mapuje do "wersji produktu" i ma być czysto "używany przez człowieka".

AssemblyVersion to z pewnością najważniejsze, ale ja też nie pominąłbym AssemblyFileVersion. Jeśli nie podasz AssemblyInformationalVersion, kompilator dodaje go dla Ciebie, usuwając fragment "revision" z numeru wersji i pozostawiając major.drobne.buduj.

 39
Author: Bob King,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-10 21:33:15

AssemblyInformationalVersion i AssemblyFileVersion są wyświetlane podczas wyświetlania informacji o "wersji" pliku za pomocą Eksploratora Windows, przeglądając właściwości pliku. Atrybuty te są kompilowane do zasobu VERSION_INFO tworzonego przez kompilator.

AssemblyInformationalVersion jest wartością "Wersja produktu". AssemblyFileVersion jest wartością "File version".

The {[5] } jest specyficzny dla. NET assemblies i jest używany przez. Net assembly loader, aby wiedzieć, która wersja złożenia ładować/wiązać w czasie wykonywania.

Z te, jedynym, który jest absolutnie wymagany przez. Net jest atrybut AssemblyVersion. Niestety może również powodować najwięcej problemów, gdy zmienia się masowo, zwłaszcza jeśli jesteś silny nazywając swoje zespoły.

 21
Author: Scott Dorman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-24 00:08:33

Warto zwrócić uwagę na kilka innych rzeczy:

1) Jak pokazano w oknie dialogowym Właściwości Eksploratora Windows dla wygenerowanego pliku złożenia, istnieją dwa miejsca o nazwie "Wersja pliku". Ten widoczny w nagłówku okna dialogowego pokazuje AssemblyVersion, a nie AssemblyFileVersion.

W sekcji Informacje o innych wersjach znajduje się inny element o nazwie "File Version". Tutaj możesz zobaczyć, co zostało wprowadzone jako AssemblyFileVersion.

2) AssemblyFileVersion jest po prostu zwykły tekst. Nie musi być zgodny z ograniczeniami schematu numeracji, które stosuje AssemblyVersion(np. ., jeśli chcesz. Twój system budowania będzie musiał wypełnić żetony.

Co więcej, nie podlega wymianie wieloznacznej, jaką jest AssemblyVersion. Jeśli masz tylko wartość " 3.0.1.* "w AssemblyInfo.cs, czyli dokładnie to co pokaże w innej wersji informacja- > element Wersja pliku.

3) I nie znam jednak wpływu na Instalator używania czegoś innego niż numeryczne numery wersji plików.

 7
Author: DavidM,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-21 10:40:44

Aby zachować aktualność tego pytania, warto podkreślić, że {[2] } jest używany przez NuGet i odzwierciedla wersję pakietu wraz z każdym prefiksem przed wydaniem.

Na przykład AssemblyVersion 1.0.3.* pakowane z asp.net core dotnet-cli

dotnet pack --version-suffix ci-7 src/MyProject

Tworzy pakiet z wersją 1.0.3-ci-7, który można sprawdzić z odbiciem używając:

CustomAttributeExtensions.GetCustomAttribute<AssemblyInformationalVersionAttribute>(asm);
 6
Author: KCD,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-23 04:51:15

Gdy assemblyversion jest zmieniony, Jeśli ma silną nazwę, zespoły odwołujące się muszą zostać przekompilowane, w przeciwnym razie zespół nie ładuje się! Jeśli nie ma silnej nazwy, jeśli nie jest wyraźnie dodany do pliku projektu, nie zostanie skopiowany do katalogu wyjściowego podczas budowania, więc możesz przegapić zależności złożeń, zwłaszcza po wyczyszczeniu katalogu wyjściowego.

 2
Author: linquize,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-17 05:21:50