Czy możliwe jest programowe uzyskanie numeru wersji z dowolnej biblioteki DLL .NET?
Jeśli tak, w jaki sposób?
Czy możliwe jest programowe uzyskanie numeru wersji z dowolnej biblioteki DLL .NET?
Jeśli tak, w jaki sposób?
Odpowiedzi:
Assembly assembly = Assembly.LoadFrom("MyAssembly.dll");
Version ver = assembly.GetName().Version;
Ważne: należy zauważyć, że nie jest to najlepsza odpowiedź na pierwotne pytanie. Nie zapomnij przeczytać więcej na tej stronie.
Assemblyname.GetAssemblyNameunikać tych problemów
beforefieldinitinicjatorów typu, i po prostu nie jest wymagane w tym przypadku. Czy te powody są wystarczające?
FileVersionInfo.GetVersionInfo("foo.dll").FileVersiondobrze wykonuje swoją pracę i nie ładuje biblioteki DLL do aplikacji.
Działa to, jeśli dll to .net lub Win32 . Metody odbicia działają tylko wtedy, gdy dll to .net. Ponadto, jeśli używasz odbicia, masz narzut ładowania całej biblioteki dll do pamięci. Poniższa metoda nie ładuje zestawu do pamięci.
// 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);
Od: http://msdn.microsoft.com/en-us/library/system.diagnostics.fileversioninfo.fileversion.aspx
@"C:\MyAssembly.dll"powyżej), można użyć System.Reflection.Assembly.GetExecutingAssembly().Location(czy dll: Assembly.GetAssembly(typeof(AClassInTheDll)).Location)
Przede wszystkim istnieją dwie możliwe `` wersje '', które mogą Cię zainteresować:
Wersja systemu plików Windows, mająca zastosowanie do wszystkich plików wykonywalnych
Wersja kompilacji zestawu, która jest osadzana w zestawie .NET przez kompilator (oczywiście dotyczy tylko plików DLL zestawu .NET i plików exe)
W pierwszym przypadku powinieneś użyć odpowiedzi Bena Andersona; w tym drugim przypadku użyj AssemblyName.GetAssemblyName(@"c:\path\to\file.dll").Versionlub odpowiedz Tataro, na wypadek gdyby twój kod odwoływał się do zestawu.
Zauważ, że możesz zignorować wszystkie odpowiedzi, które używają .Load()/ .LoadFrom()metody, ponieważ w rzeczywistości ładują one zestaw w bieżącej domenie AppDomain - co jest analogiczne do wycinania drzewa, aby zobaczyć, ile ma lat.
Oto przyjemny sposób wykorzystania odrobiny refleksji w celu uzyskania wersji biblioteki DLL zawierającej określoną klasę:
var ver = System.Reflection.Assembly.GetAssembly(typeof(!Class!)).GetName().Version;
Wystarczy wymienić! Klasa! z nazwą klasy zdefiniowanej w bibliotece DLL, której wersję chcesz pobrać.
Jest to moja preferowana metoda, ponieważ jeśli przenoszę biblioteki DLL dla różnych wdrożeń, nie muszę zmieniać ścieżki pliku.
FileVersionInfo
Aby pobrać go dla uruchomionego zestawu (winform, aplikacja konsoli itp.)
using System.Reflection;
...
Assembly.GetEntryAssembly().GetName().Version
Kris, twoja wersja działa świetnie, gdy trzeba załadować zestaw z rzeczywistego pliku DLL (i jeśli biblioteka DLL tam jest!), Jednak pojawi się dużo niechciany błąd, jeśli biblioteka DLL jest wbudowana (tj. Nie jest plikiem, ale osadzonym DLL).
Inną rzeczą jest to, że jeśli ktoś używa schematu wersjonowania z czymś w rodzaju „ 1.2012.0508.0101 ”, kiedy otrzyma się ciąg wersji, w rzeczywistości otrzyma się „ 1.2012.518.101 ”; zanotuj brakujące zera .
Oto kilka dodatkowych funkcji umożliwiających uzyskanie wersji biblioteki DLL (osadzonej lub z pliku 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)
var versionAttrib = new AssemblyName(Assembly.GetExecutingAssembly().FullName);
Pomocna okazała się dla mnie odpowiedź @Ben. Musiałem jednak sprawdzić wersję produktu, ponieważ była to główna zmiana zachodząca w moim oprogramowaniu, a następnie wersjonowanie semantyczne.
myFileVersionInfo.ProductVersion
Ta metoda spełniła moje oczekiwania
Aktualizacja: Zamiast jawnie wymieniać ścieżkę dll w programie (w razie potrzeby w wersji produkcyjnej), możemy pobrać wersję produktu za pomocą Assembly.
Assembly assembly = Assembly.GetExecutingAssembly();
FileVersionInfo fileVersionInfo =FileVersionInfo.GetVersionInfo(assembly.Location);
string ProdVersion= fileVersionInfo.ProductVersion;
Chociaż pierwotne pytanie mogło nie być specyficzne dla usługi sieciowej, oto kompletna usługa testWebService, którą można dodać, aby wyświetlić odpowiedź niebuforowaną w usłudze sieciowej oraz wersję pliku. Używamy wersji pliku zamiast wersji zestawu, ponieważ chcemy znać wersję, ale przy wszystkich wersjach zestawu 1.0.0.0 witrynę internetową można łatwo załatać (łącze do podpisywania i żądania nadal jest aktywne!). Zastąp @ Class @ nazwą kontrolera internetowego interfejsu API, w którym jest osadzona ta usługa. Jest to dobre rozwiązanie dla go / nogo w usłudze sieciowej oraz szybkie sprawdzenie wersji.
[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;
}
Uznałem również, że konieczne jest dodanie następującego pliku do web.config w ramach konfiguracji, aby uczynić go prawdziwie anonimowym
<location path="api/testwebservice">
<system.web>
<authorization>
<allow users="*" />
</authorization>
</system.web>
</location>