如何在不加载程序集的情况下获取程序集的版本?

发布于 2024-07-06 06:32:20 字数 90 浏览 8 评论 0原文

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

One small function of a large program examines assemblies in a folder and replaces out-of-date assemblies with the latest versions. To accomplish this, it needs to read the version numbers of the existing assembly files without actually loading those assemblies into the executing process.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

花海 2024-07-13 06:32:20

我发现以下 在本文中

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

I found the following 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);
流星番茄 2024-07-13 06:32:20

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

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

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

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

Depending on the files, one option might be FileVersionInfo - i.e.

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

The problem is that this depends on the code having the [AssemblyFileVersion] attribute, and it matching the [AssemblyVersion] attribute.

I think I'd look at the AssemblyName options suggested by others first, though.

蓝咒 2024-07-13 06:32:20

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

只有当文件
包含程序集清单。 这
方法导致文件被打开
并关闭,但装配未
添加到此域。

Use AssemblyName.GetAssemblyName("assembly.dll");, then parse the name. According to MSDN:

This will only work if the file
contains an assembly manifest. This
method causes the file to be opened
and closed, but the assembly is not
added to this domain.

可遇━不可求 2024-07-13 06:32:20

仅供记录:以下是如何在 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);

Just for the record: Here's how to get the file version in C#.NET Compact Framework. It's basically from OpenNETCF but quite shorter and exctacted so it can by copy'n'pasted. Hope it'll help...

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);
落在眉间の轻吻 2024-07-13 06:32:20

使用 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 的更简洁的替代方案。

A .netcore update to Joel's answer, using 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);

I found this useful in analyzing DLLs running (and locked) by a Windows Service, a much cleaner alternative to creating a separate AppDomain.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文