在Windows上,我使用下面的内容来获得一个可执行文件版本。
FileVersionInfo.GetVersionInfo("filepath.exe").FileVersion但是,当我在Mac上使用相同的unix可执行文件时,它返回null。
发布于 2020-09-09 04:46:34
(重新张贴我的评论作为答复):
最短答案:
你不能。
简短答覆:
FileVersionInfo.GetVersionInfo()方法尝试从VERSIONINFO PE二进制可执行映像读取Win32资源数据。- On Windows, most executables are PE images which _may or may not_ contain a `VERSIONINFO` structure.
- On macOS and Linux, _most_ (but not all) executables are Mach-O and ELF images respectively, which _do not contain_ a `VERSIONINFO` structure at all.
- .NET assemblies always use the PE format, however, which means they can contain a `VERSIONINFO` structure in their resources section.FileVersionInfo.GetVersionInfo()只读取PE可执行文件,附加的警告是,只能专门读取(截至2021年4月) .NET程序集,而不能读取非.NET程序集PE可执行文件)。因为ELF和Mach-O可执行文件不包含Win32资源部分,所以不能对这些可执行文件使用FileVersionInfo.GetVersionInfo()。较长的答覆:
Windows的*.exe文件使用"PE“可执行图像格式:https://learn.microsoft.com/en-us/windows/win32/debug/pe-format -- .NET程序集也使用这种格式。
这种格式能够将“资源”存储在记录结构 (代表VS_VERSIONINFO)的文件的专用部分中。请注意,VERSIONINFO是微软/Win32 32特有的数据结构。
其他操作系统使用不同的可执行映像格式: Linux和大多数Unixes使用ELF,macOS使用"Mach-O“格式--这两种格式都不使用VERSIONINFO。
请注意,在非Windows上使用.NET Core时,".NET程序集“文件仍然是使用PE可执行格式的*.exe和*.dll文件,但它们不是由非Windows直接执行的:相反,它们将有一个加载程序程序启动.NET运行时,然后将.NET程序加载到其中(与运行java.exe yourJar.jar从*.jar文件中运行.NET程序的方式完全一样)。
因此,由于.NET核心总是对.NET程序集使用PE格式,即使在非Windows平台上,FileVersionInfo.GetVersionInfo API仍然可用于从其他.NET程序集中提取版本信息,但它不适用于非PE可执行映像文件。
发布于 2021-04-25 01:30:02
最短答案
你不能(目前)。
简短的回答
正如Dai在他们的回答中所解释的,版本信息Api依赖于底层的、本地的Api,这反过来又期望版本信息出现在PE (可移植的可执行文件)头中。由于Unix/macOS可执行文件使用不同的可执行标头,因此不支持它们。
简短回答
由于Unix (和macOS)可执行文件不使用PE头格式,因此不能对这些文件使用FileVersionInfo,因为此Api当前依赖PE头格式。
遗憾的是,在Unix/maxOS系统上运行FileVersionInfo Core时,也不可能在所有PE文件上使用.net,因为这是一个实现决定,即只支持 .net程序集。这更容易实现,因为它不需要完全支持基于VERSIONINFO资源的PE标头。
完整的答案
FileVersionInfo在.net核心上的实现不支持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.
}
}https://stackoverflow.com/questions/63773485
复制相似问题