大型程序的一个小功能检查文件夹中的程序集,并用最新版本替换过时的程序集。要实现这一点,它需要读取现有程序集文件的版本号,而不是将这些程序集实际加载到执行过程中。
答案 0 :(得分:33)
我找到了以下in this article。
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);
答案 1 :(得分:11)
根据文件的不同,一个选项可能是FileVersionInfo
- 即
FileVersionInfo fvi = FileVersionInfo.GetVersionInfo(path)
string ver = fvi.FileVersion;
问题在于,这取决于具有[AssemblyFileVersion]
属性的代码,并且它与[AssemblyVersion]
属性匹配。
我想我会首先看一下其他人建议的AssemblyName选项。
答案 2 :(得分:9)
使用AssemblyName.GetAssemblyName("assembly.dll");
,然后解析名称。根据{{3}}:
这仅适用于文件 包含程序集清单。这个 方法导致文件打开 并关闭,但装配不是 添加到此域。
答案 3 :(得分:2)
仅供记录:以下是如何在C#.NET Compact Framework中获取文件版本。它基本上来自OpenNETCF,但相当短,并且可以通过copy'n'pasted来实现。希望它会有所帮助...
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);
答案 4 :(得分:0)
乔尔回答的 .netcore
更新,使用 AssemblyLoadContext:
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
的更简洁的替代方法。