在 Windows 上,我使用以下内容来获取可执行文件版本。
FileVersionInfo.GetVersionInfo("filepath.exe").FileVersion
但是当我在 Mac 上对 unix 可执行文件类型使用相同的文件时,它返回 null
(重新发布我的评论作为答案):
你不能。
该FileVersionInfo.GetVersionInfo()方法尝试VERSIONINFO从 Win32 PE 二进制可执行映像中读取资源数据。
VERSIONINFO结构。VERSIONINFO。
VERSIONINFO在其资源部分中包含一个结构。这意味着在 Mac 或 Linux 上,您可以使用FileVersionInfo.GetVersionInfo()仅读取 PE 可执行文件,另外需要注意的是(截至 2021 年 4 月)只能读取特定的 .NET 程序集,而非非 .NET 程序集 PE 可执行文件)可以读取. 因为 ELF 和 Mach-O 可执行文件不包含 Win32 资源部分,所以您不能FileVersionInfo.GetVersionInfo()在这些类型的可执行文件上使用。
Windows 的*.exe文件使用“PE”可执行映像格式:https ://docs.microsoft.com/en-us/windows/win32/debug/pe-format - .NET 程序集也使用这种格式。
这种格式能够将“资源”存储在文件的专用部分中,该部分可以选择包含VERSIONINFO记录结构(在内存中表示为VS_VERSIONINFO)。请注意,这VERSIONINFO是 Microsoft/Win32 特定的数据结构。
其他操作系统使用不同的可执行映像格式:Linux 和大多数 Unix 使用 ELF,而 macOS 使用“Mach-O”格式——两者都不使用VERSIONINFO.
请注意,在非 Windows 操作系统上使用 .NET Core 时,“.NET 程序集”文件仍然
是使用 PE 可执行格式*.exe的*.dll文件,但它们不会由非 Windows 操作系统直接执行:相反,它们将有一个加载程序,它启动 .NET 运行时,然后将 .NET 程序集加载到其中(就像您*.jar通过运行从 Windows 上的文件运行 Java 程序的方式一样java.exe yourJar.jar)。
因此,由于 .NET Core 始终对 .NET 程序集使用 PE 格式,即使在非 Windows 平台上,该FileVersionInfo.GetVersionInfoAPI 仍可用于从其他 .NET 程序集中提取版本信息,但不适用于非 PE可执行图像文件。
你不能(目前)。
正如 Dai 在他们的回答中解释的那样,版本信息 Api 依赖于底层的原生 Api,而后者又期望版本信息出现在 PE(可移植可执行文件)标头中。由于 Unix/macOS 可执行文件使用不同的可执行文件头,因此它们不受支持。
由于 Unix(和 macOS)可执行文件不使用 PE 标头格式,因此您不能FileVersionInfo在这些文件上使用,因为此 Api 当前依赖于 PE 标头格式。
遗憾的是,当 .net Core 在 Unix/maxOS 系统上运行时,也不可能在所有 PE 文件上使用,因为它是仅支持.net 程序集FileVersionInfo的实现决定。这更容易实现,因为它不需要基于资源的 PE 标头所需要的完整 PE 标头支持。VERSIONINFO
.net core 上的实现FileVersionInfo不支持 Unix/macOS 可执行文件使用的可执行文件头格式。 FileVersionInfo仅支持包含 CLI 元数据的 PE 文件。也就是说,.net 程序集。
源代码中有一些注释FileVersionInfo讨论了即使在这种级别的支持下的一些问题/限制。这说明这些问题应该很少出现,但如果有必要,可能会实现完整的 PE 资源解析器,并且这也将提供对本机(非 .net)Windows 可执行文件中的版本信息的支持。
评论继续认为,对此的需求预计也将极为罕见,因此我认为优先级不会很高。
令人沮丧的是,除了在这些源注释中之外没有记录,并且尝试在本机 EXE 图像上使用 Api 会默默地“失败”,产生一个基本上是空的FileVersionInfo对象,这可能与任何数量的失败相混淆。
为了完整起见,以下是相关FileVersionInfo.Unix.cs来源和评论:
private FileVersionInfo(string fileName)
{
_fileName = fileName;
// For managed assemblies, read the file version information from the assembly's metadata.
// This isn't quite what's done on Windows, which uses the Win32 GetFileVersionInfo to read
// the Win32 resource information from the file, and the managed compiler uses these attributes
// to fill in that resource information when compiling the assembly. It's possible
// that after compilation, someone could have modified the resource information such that it
// no longer matches what was or wasn't in the assembly. But that's a rare enough case
// that this should match for all intents and purposes. If this ever becomes a problem,
// we can implement a full-fledged Win32 resource parser; that would also enable support
// for native Win32 PE files on Unix, but that should also be an extremely rare case.
if (!TryLoadManagedAssemblyMetadata())
{
// We could try to parse Executable and Linkable Format (ELF) files, but at present
// for executables they don't store version information, which is typically just
// available in the filename itself. For now, we won't do anything special, but
// we can add more cases here as we find need and opportunity.
}
}