รับหมายเลขรุ่นของ 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
การโหลดแอสเซมบลีลงใน appdomain นั้นช้าไม่สามารถย้อนกลับได้ (คุณไม่สามารถยกเลิกการโหลดโดยไม่ฆ่าโดเมน) ต้องได้รับการอนุญาตและมีแนวโน้มที่จะทำให้เกิดผลข้างเคียงเช่นการbeforefieldinitเริ่มต้นประเภท initializers และไม่จำเป็นในกรณีนี้ เหตุผลเหล่านี้ฟังดูสมเหตุสมผลหรือไม่
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 ตัวแทนจากการเพิ่ม downvote ซึ่งฉันจำไม่ได้ว่าทำ มันจะไม่ให้ฉันเปลี่ยนแปลงเว้นแต่คุณจะแก้ไขโพสต์ ไชโย!
ลุคดุดริดจ์

9
หากคุณต้องการเพื่อให้แน่ใจว่าคุณได้รับการปฏิบัติการ / dll จริงที่ใช้ในปัจจุบัน: แทนที่จะเป็นชื่อไฟล์แบบคงที่ ( @"C:\MyAssembly.dll"ด้านบน) คุณสามารถใช้System.Reflection.Assembly.GetExecutingAssembly().Location(หรือถ้า dll A: Assembly.GetAssembly(typeof(AClassInTheDll)).Location)
คอนราด

4
ความแตกต่างระหว่างแอตทริบิวต์ AssemblyVersion และ AssemblyFileVersion AssemblyFileVersion ได้รับการประทับตราในลักษณะที่ Windows API สามารถรับค่าได้ AssemblyVersion เป็นส่วนหนึ่งของชื่อที่แข็งแกร่งและไม่จำเป็นต้องเหมือนกับ AssemblyFileVersion
daughey

51

ก่อนอื่นมี 'รุ่น' ที่เป็นไปได้สองอย่างที่คุณอาจสนใจ:

  • เวอร์ชันไฟล์ระบบไฟล์ Windows ใช้ได้กับไฟล์ที่ปฏิบัติการได้ทั้งหมด

  • แอสเซมบลีบิวด์เวอร์ชั่นซึ่งฝังอยู่ในแอสเซมบลี. NET โดยคอมไพเลอร์ (เห็นได้ชัดว่าใช้ได้เฉพาะกับแอสเซมบลี. dll dll และไฟล์ exe

ในกรณีก่อนหน้านี้คุณควรใช้คำตอบของ Ben Anderson ในกรณีหลังให้ใช้AssemblyName.GetAssemblyName(@"c:\path\to\file.dll").Versionหรือคำตอบของ Tataro ในกรณีที่รหัสของคุณถูกอ้างอิง

โปรดทราบว่าคุณสามารถละเว้นคำตอบทั้งหมดที่ใช้.Load()/ .LoadFrom()วิธีการได้เนื่องจากสิ่งเหล่านี้โหลดแอสเซมบลีใน AppDomain ปัจจุบัน - ซึ่งคล้ายคลึงกับการตัดทรีเพื่อดูว่าอายุเท่าไหร่


32

นี่เป็นวิธีที่ดีในการใช้การสะท้อนเล็กน้อยเพื่อรับรุ่นของ DLL ที่มีคลาสเฉพาะ:

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

เพียงแค่เปลี่ยน! Class! ด้วยชื่อของคลาสที่กำหนดไว้ใน DLL ที่คุณต้องการรับรุ่น

นี่เป็นวิธีที่ฉันชอบเพราะถ้าฉันย้าย DLLs ไปรอบ ๆ สำหรับการปรับใช้ที่แตกต่างกันฉันไม่จำเป็นต้องเปลี่ยนพา ธ


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 () อาจช่วยได้เช่นกัน
Bolt Thunder

10

คริสรุ่นของคุณใช้งานได้ดีเมื่อต้องการโหลดแอสเซมบลีจากไฟล์ DLL ที่เกิดขึ้นจริง (และหากมี DLL!) อย่างไรก็ตามหนึ่งจะได้รับข้อผิดพลาดที่ไม่พึงประสงค์มากถ้า DLL เป็น EMBEDDED (เช่นไม่ใช่ไฟล์ 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.GetExecutingAssembly();
FileVersionInfo fileVersionInfo =FileVersionInfo.GetVersionInfo(assembly.Location); 
string ProdVersion= fileVersionInfo.ProductVersion;

หมายเหตุ: หากรุ่นมีเครื่องหมายดอกจันสำหรับค่าที่เพิ่มโดยอัตโนมัติวิธีนี้จะส่งคืนเครื่องหมายดอกจันแทนหมายเลขที่สร้างขึ้นจริง (เช่นไม่ทำงานหากคุณใส่ 1.0. * ในข้อมูลการประกอบของคุณ)
Ronen Ness

ใช่ อย่างไรก็ตามฉันเลือกระบบอัตโนมัติ Jeniks สำหรับการอัพเกรดเวอร์ชั่นดังนั้นแอสเซมบลีมักจะมีการรวมกันที่สมบูรณ์แบบของรุ่น dll
Dutt


0

ในขณะที่คำถามดั้งเดิมอาจไม่เฉพาะเจาะจงสำหรับบริการเว็บนี่คือ testWebService ที่สมบูรณ์ที่คุณสามารถเพิ่มเพื่อแสดงการตอบกลับที่ไม่ใช่แคชของเว็บเซอร์วิสรวมถึงเวอร์ชันของไฟล์ เราใช้เวอร์ชันไฟล์แทนเวอร์ชั่นประกอบเพราะเราต้องการทราบรุ่น แต่ด้วยแอสเซมบลีเวอร์ชัน 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>
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.