Secara terprogram mendapatkan nomor versi DLL

151

Apakah mungkin untuk mendapatkan nomor versi secara terprogram dari. NET DLL?

Jika ya, bagaimana?

JL.
sumber
10
Tidak percaya ini diminta 6 menit yang lalu, baru saja akan menanyakan hal yang sama!
tpower
2
lihat tautan ini juga untuk versi peningkatan otomatis - blog.mbcharbonneau.com/2007/03/13/…
JL.

Jawaban:

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

Penting: Perlu dicatat bahwa ini bukan jawaban terbaik untuk pertanyaan awal. Jangan lupa membaca lebih lanjut di halaman ini.

Keris
sumber
28
Ini memuat MyAssembly.dll ke dalam AppDomain yang sedang berjalan ... ide buruk.
staafl
12
Saya sarankan Assemblyname.GetAssemblyNameuntuk menghindari masalah ini
staafl
7
memuat rakitan ke dalam appdomain lambat, tidak dapat dibatalkan (Anda tidak dapat menurunkannya tanpa mematikan domain), memerlukan izin dan dapat menyebabkan efek samping, seperti mengeksekusi beforefieldinitinisialisasi tipe, dan tidak diperlukan dalam kasus ini. Apakah alasan ini cukup masuk akal?
staafl
7
@staafl: Ya; tidak hanya untuk saya, tetapi juga untuk semua orang yang membaca halaman ini di masa depan.
Kris
6
FileVersionInfo.GetVersionInfo("foo.dll").FileVersionmelakukan pekerjaan dengan baik dan tidak memuat dll ke dalam aplikasi.
Jack
181

Ini berfungsi jika dll adalah .net atau Win32 . Metode refleksi hanya berfungsi jika dll adalah .net. Juga, jika Anda menggunakan refleksi, Anda memiliki overhead untuk memuat seluruh dll ke dalam memori. Metode di bawah ini tidak memuat unit ke dalam memori.

// 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);

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

sumber asli

Ben Anderson
sumber
5
Saya suka ini. Mengapa Anda repot-repot memuat dll dan kemudian menggunakan refleksi hanya untuk mendapatkan versi, ketika semua yang Anda benar-benar ingin lakukan adalah ini ???
aggieNick02
@ Ben, bisakah Anda mengedit posting? Saya melihat saya telah kehilangan -1 rep karena menambahkan downvote, yang saya tidak ingat lakukan. itu tidak akan membiarkan saya mengubahnya, kecuali jika Anda mengedit posting. Bersulang!
Luke Duddridge
9
Jika Anda ingin memastikan Anda mendapatkan executable / dll sebenarnya sedang digunakan: bukan nama file statis ( @"C:\MyAssembly.dll"di atas), Anda dapat menggunakan System.Reflection.Assembly.GetExecutingAssembly().Location(atau jika dll a: Assembly.GetAssembly(typeof(AClassInTheDll)).Location)
Conrad
4
Ini perbedaan antara atribut AssemblyVersion dan AssemblyFileVersion. AssemblyFileVersion dicap sedemikian rupa sehingga Windows API bisa mendapatkan nilai. AssemblyVersion adalah bagian dari nama yang kuat dan tidak harus sama dengan AssemblyFileVersion.
daughey
51

Pertama-tama, ada dua 'versi' yang mungkin Anda minati:

  • Versi file sistem file Windows, berlaku untuk semua file yang dapat dieksekusi

  • Versi build assembly, yang tertanam dalam perakitan .NET oleh kompiler (jelas hanya berlaku untuk .NET assembly dll dan file exe)

Dalam kasus sebelumnya, Anda harus menggunakan jawaban Ben Anderson; dalam kasus terakhir, gunakan AssemblyName.GetAssemblyName(@"c:\path\to\file.dll").Version, atau jawaban Tataro, seandainya majelis dirujuk oleh kode Anda.

Perhatikan bahwa Anda dapat mengabaikan semua jawaban yang menggunakan .Load()/ .LoadFrom()metode, karena ini sebenarnya memuat rakitan di AppDomain saat ini - yang analog dengan menebang pohon untuk melihat berapa umurnya.

staafl
sumber
32

Berikut cara yang baik menggunakan sedikit refleksi untuk mendapatkan versi DLL yang berisi kelas tertentu:

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

Ganti saja! Kelas! dengan nama kelas yang didefinisikan dalam DLL Anda ingin mendapatkan versi.

Ini adalah metode yang saya sukai karena jika saya memindahkan DLL untuk penyebaran yang berbeda, saya tidak perlu mengubah filepath.

Totero
sumber
3
Perhatikan bahwa ini hanya berfungsi jika rakitan yang dimaksud dirujuk secara statis oleh yang sekarang.
staafl
2
Ini adalah jawaban terbaik karena DLL belum tentu entri perakitan bahkan perakitan ini disebut dari
CAD bloke
1
Lihat stackoverflow.com/a/909583/492 untuk mendapatkan berbagai jenis info versi. misalnyaFileVersionInfo
CAD cowok
22

Untuk mendapatkannya untuk perakitan yang dimulai (winform, aplikasi konsol, dll ...)

using System.Reflection;
...
Assembly.GetEntryAssembly().GetName().Version
Agent_9191
sumber
6
GetExecutingAssembly () juga dapat membantu.
Bolt Thunder
10

Kris, versi Anda berfungsi dengan baik ketika perlu memuat perakitan dari file DLL yang sebenarnya (dan jika DLL ada di sana!), Namun, seseorang akan mendapatkan kesalahan yang tidak diinginkan jika DLL EMBEDDED (yaitu, bukan file tetapi tertanam DLL).

Hal lain adalah, jika seseorang menggunakan skema versi dengan sesuatu seperti " 1.2012.0508.0101 ", ketika seseorang mendapatkan string versi Anda akan benar-benar mendapatkan " 1.2012.518.101 "; perhatikan nol yang hilang .

Jadi, inilah beberapa fungsi tambahan untuk mendapatkan versi DLL (disematkan atau dari file 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)
MacSpudster
sumber
2
var versionAttrib = new AssemblyName(Assembly.GetExecutingAssembly().FullName);
Tak terkalahkan
sumber
2

Jawaban oleh @Ben terbukti bermanfaat bagi saya. Tetapi saya perlu memeriksa versi produk karena itu adalah peningkatan utama yang terjadi dalam perangkat lunak saya dan mengikuti versi semantik.

myFileVersionInfo.ProductVersion

Metode ini memenuhi harapan saya

Pembaruan: Alih-alih secara eksplisit menyebutkan jalur dll dalam program (seperti yang diperlukan dalam versi produksi), kita bisa mendapatkan versi produk menggunakan Assembly.

Assembly assembly = Assembly.GetExecutingAssembly();
FileVersionInfo fileVersionInfo =FileVersionInfo.GetVersionInfo(assembly.Location); 
string ProdVersion= fileVersionInfo.ProductVersion;
Prasan Dutt
sumber
Catatan: jika versi berisi tanda bintang untuk nilai tambah otomatis metode ini akan mengembalikan tanda bintang bukannya angka yang sebenarnya dihasilkan (yaitu tidak berfungsi jika Anda menempatkan 1.0. * Di info perakitan Anda).
Ronen Ness
Iya! Namun, saya memilih otomatisasi Jeniks untuk meningkatkan versi sehingga perakitan selalu memiliki kombinasi sempurna dari versi dll.
Prasan Dutt
1

Anda dapat menggunakan metode System.Reflection.Assembly.Load * () dan kemudian ambil AssemblyInfo mereka.

Ariel
sumber
0

Meskipun pertanyaan awal mungkin tidak spesifik untuk layanan web, berikut ini adalah testWebService lengkap yang dapat Anda tambahkan untuk menampilkan respons layanan non-cache layanan web plus versi file. Kami menggunakan versi file alih-alih versi perakitan karena kami ingin mengetahui versi, tetapi dengan semua versi perakitan 1.0.0.0, situs web dapat dengan mudah ditambal (penandatanganan dan tautan permintaan masih aktif!). Ganti @ Class @ dengan nama pengontrol api web layanan ini tertanam. Baik untuk go / nogo pada layanan web plus versi cek cepat.

  [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;
  }

Saya merasa perlu juga untuk menambahkan yang berikut ke web.config dalam konfigurasi agar benar-benar anonim

<location path="api/testwebservice">
    <system.web>
        <authorization>
            <allow users="*" />
        </authorization>
    </system.web>
</location>
Wray Smallwood
sumber