26

大型程序的一个小功能检查文件夹中的程序集并用最新版本替换过时的程序集。为此,它需要读取现有程序集文件的版本号,而无需将这些程序集实际加载到执行进程中。

4

5 回答 5

44

在这篇文章中找到了以下内容。

using System.Reflection;
using System.IO;

...

// Get current and updated assemblies
AssemblyName currentAssemblyName = AssemblyName.GetAssemblyName(currentAssemblyPath);
AssemblyName updatedAssemblyName = AssemblyName.GetAssemblyName(updatedAssemblyPath);

// Compare both versions
if (updatedAssemblyName.Version.CompareTo(currentAssemblyName.Version) <= 0)
{
    // There's nothing to update
    return;
}

// Update older version
File.Copy(updatedAssemblyPath, currentAssemblyPath, true);
于 2008-10-09T16:21:53.833 回答
14

根据文件,一个选项可能是FileVersionInfo- 即

FileVersionInfo fvi = FileVersionInfo.GetVersionInfo(path)
string ver = fvi.FileVersion;

问题是这取决于具有[AssemblyFileVersion]属性的代码,并且它与属性匹配[AssemblyVersion]

不过,我想我会先看看其他人建议的 AssemblyName 选项。

于 2008-10-09T16:23:37.887 回答
9

使用AssemblyName.GetAssemblyName("assembly.dll");,然后解析名称。根据MSDN

这仅在文件包含程序集清单时才有效。此方法会导致文件被打开和关闭,但程序集不会添加到此域。

于 2008-10-09T16:21:33.383 回答
3

仅作记录:以下是在 C#.NET Compact Framework 中获取文件版本的方法。它基本上来自 OpenNETCF,但相当短且经过提取,因此可以通过复制粘贴。希望它会有所帮助...

public static Version GetFileVersionCe(string fileName)
{
    int handle = 0;
    int length = GetFileVersionInfoSize(fileName, ref handle);
    Version v = null;
    if (length > 0)
    {
        IntPtr buffer = System.Runtime.InteropServices.Marshal.AllocHGlobal(length);
        if (GetFileVersionInfo(fileName, handle, length, buffer))
        {
            IntPtr fixedbuffer = IntPtr.Zero;
            int fixedlen = 0;
            if (VerQueryValue(buffer, "\\", ref fixedbuffer, ref fixedlen))
            {
                byte[] fixedversioninfo = new byte[fixedlen];
                System.Runtime.InteropServices.Marshal.Copy(fixedbuffer, fixedversioninfo, 0, fixedlen);
                v = new Version(
                    BitConverter.ToInt16(fixedversioninfo, 10), 
                    BitConverter.ToInt16(fixedversioninfo,  8), 
                    BitConverter.ToInt16(fixedversioninfo, 14),
                    BitConverter.ToInt16(fixedversioninfo, 12));
            }
        }
        Marshal.FreeHGlobal(buffer);
    }
    return v;
}

[DllImport("coredll", EntryPoint = "GetFileVersionInfo", SetLastError = true)]
private static extern bool GetFileVersionInfo(string filename, int handle, int len, IntPtr buffer);
[DllImport("coredll", EntryPoint = "GetFileVersionInfoSize", SetLastError = true)]
private static extern int GetFileVersionInfoSize(string filename, ref int handle);
[DllImport("coredll", EntryPoint = "VerQueryValue", SetLastError = true)]
private static extern bool VerQueryValue(IntPtr buffer, string subblock, ref IntPtr blockbuffer, ref int len);
于 2014-02-13T13:18:48.553 回答
0

使用AssemblyLoadContext.netcore更新乔尔的答案:

using System.IO;
using System.Reflection;
using System.Runtime.Loader;

...

// Get current and updated assemblies
AssemblyName currentAssemblyName = AssemblyLoadContext.GetAssemblyName(currentAssemblyPath);
AssemblyName updatedAssemblyName = AssemblyLoadContext.GetAssemblyName(updatedAssemblyPath);

// Compare both versions
if (updatedAssemblyName.Version.CompareTo(currentAssemblyName.Version) <= 0)
{
    // There's nothing to update
    return;
}

// Update older version
File.Copy(updatedAssemblyPath, currentAssemblyPath, true);

我发现这在分析由 Windows 服务运行(和锁定)的 DLL 时很有用,这是一种比创建单独的AppDomain.

于 2021-02-26T17:44:43.370 回答