使用C#获取文件详情

有对应的需求,需要获取文件的详细信息内容。该页面信息大部分来源于文件的版本信息,使用FileInfo类并不能获取到。
VERSIONINFO 资源 - Win32 apps | Microsoft Learn
信息格式:
1 VERSIONINFO
FILEVERSION 1,0,0,323
PRODUCTVERSION 1,0,0,0
FILEOS 0x4
FILETYPE 0x1
{
BLOCK "StringFileInfo"
{
BLOCK "000004B0"
{
VALUE "Comments", "这是一个示例库,由张三编写。"
VALUE "CompanyName", "webre"
VALUE "FileDescription", "webre"
VALUE "FileVersion", "1.0.0.323"
VALUE "InternalName", "webre.dll"
VALUE "LegalCopyright", "版权所有 \xA9 2024 张三"
VALUE "LegalTrademarks", ""
VALUE "OriginalFilename", "webre.dll"
VALUE "ProductName", "webre"
VALUE "ProductVersion", "1.0.0"
VALUE "Assembly Version", "1.0.0.323"
VALUE "Test", "Test"//自定义属性
}
}
BLOCK "VarFileInfo"
{
VALUE "Translation", 0x0000 0x04B0
}
}
为了获取versioninfo信息,需要使用version.dll内的api进行指定段内的信息获取。参考如下:
GetFileVersionInfoA function (winver.h) - Win32 apps | Microsoft Learn
GetFileVersionInfoSizeA function (winver.h) - Win32 apps | Microsoft Learn
VerQueryValueW function (winver.h) - Win32 apps | Microsoft Learn
调用代码如下:
//需要引入win32api
[DllImport("version.dll", CharSet = CharSet.Unicode)]
private static extern bool GetFileVersionInfo(string fileName, int handle, int len, byte[] data);
[DllImport("version.dll", CharSet = CharSet.Unicode)]
private static extern int GetFileVersionInfoSize(string fileName, out int handle);
[DllImport("version.dll", CharSet = CharSet.Unicode)]
private static extern bool VerQueryValue(byte[] data, string subBlock, out IntPtr buffer, out int len);
var attrs = new string[] {
"Comments","InternalName","ProductName",
"CompanyName","LegalCopyright","ProductVersion",
"FileDescription","LegalTrademarks","PrivateBuild",
"FileVersion","OriginalFilename","SpecialBuild","Test"
};
// 获取文件版本信息的大小
int handle;
int infoSize = GetFileVersionInfoSize(dllPath, out handle);
if (infoSize == 0)
{
throw new Exception("Failed to get file version info size. Error: " + Marshal.GetLastWin32Error());
}
// 分配缓冲区
byte[] infoBuffer = new byte[infoSize];
// 获取文件版本信息
if (!GetFileVersionInfo(dllPath, 0, infoSize, infoBuffer))
{
throw new Exception("Failed to get file version info. Error: " + Marshal.GetLastWin32Error());
}
// 获取所有语言代码
IntPtr buffer;
int len;
if (!VerQueryValue(infoBuffer, @"\VarFileInfo\Translation", out buffer, out len))
{
throw new Exception("Failed to get language codes. Error: " + Marshal.GetLastWin32Error());
}
// 解析语言代码
List<string> languageCodes = new List<string>();
for (int i = 0; i < len / 4; i++)
{
int langCode = Marshal.ReadInt16(buffer, i * 4);
int subLangCode = Marshal.ReadInt16(buffer, i * 4 + 2);
string languageCode = $"{langCode:X4}{subLangCode:X4}";//win下小端存储
languageCodes.Add(languageCode);
}
// 输出所有语言代码
Console.WriteLine("Available Language Codes:");
foreach (string languageCode in languageCodes)
{
Console.WriteLine(languageCode);
}
// 选择第一个语言代码
string selectedLanguageCode = languageCodes.Count > 0 ? languageCodes[0] : "040904B0";//默认为英文
foreach (var attr in attrs)
{
if (!VerQueryValue(infoBuffer, $@"\StringFileInfo\{selectedLanguageCode}\{attr}", out buffer, out len))
{
Console.WriteLine($"Failed to get {attr}. Error: " + Marshal.GetLastWin32Error());
}
else
{
string value = Marshal.PtrToStringUni(buffer);
Console.WriteLine($"{attr}: " + value);
}
}
在调用VerQueryValue后,通过buffer获取到内存地址,观察一下内存数据。

version信息映射到一段连续内存中存储。
另外还有更简单的方式,通过封装好的FileVersionInfo类进行信息获取,通过各种属性即可获取版本信息。不过,自定义的属性就获取不到了。
FileVersionInfo fileVersionInfo = FileVersionInfo.GetVersionInfo(dllPath);
FileVersionInfo win平台的实现,内部也是调用了version.dll内的相关api,不过调用的都是Ex方法,并对codepage做了处理。
使用C#获取文件详情的更多相关文章
- 获取文件的缩略图Thumbnail和通过 AQS - Advanced Query Syntax 搜索本地文件
演示如何获取文件的缩略图 FileSystem/ThumbnailAccess.xaml <Page x:Class="XamlDemo.FileSystem.ThumbnailAcc ...
- FastDFS 通过文件名获取文件信息
/** * 获取文件信息 * * param string group_name 文件所在的组名 * param string file_id 文件id(如: M00/09/BE/rBBZolgj6O ...
- c# .net获取文件夹下的所有文件(多层递归),并获取区间数据(Jsion,xml等数据)写出到处理文件,学习分享~
static void Main(string[] args) { string path = string.Format(@"C:\Users\Administrator\D ...
- java 获取文件列表,并按照文件名称排序
需求:获取全部的日志文件,并按照文件名称倒序排列,把最新的文件放在最前1.获取全部的日志文件:(方法:public List<String> ergodic(File file,List& ...
- Windows Store App JavaScript 开发:获取文件和文件夹列表
在应用程序中有时可能需要获取用户库中的内容,以便执行相关的操作.如果要获取某个用户库中的内容,需要先获取到这个用户库,获得用户库可以通过Windows.Storage命名空间中的KnownFolder ...
- ftpget 从Windows FTP服务端获取文件
/********************************************************************************* * ftpget 从Windows ...
- C# 获取文件路径
1.C# 获取文件路径:http://www.cnblogs.com/bq-blog/archive/2012/09/01/2666394.html
- C#获取文件MD5字符串
备注 哈希函数将任意长度的二进制字符串映射为固定长度的小型二进制字符串.加密哈希函数有这样一个属性:在计算不大可能找到散列为相同的值的两个不同的输入:也就是说,两组数据的哈希值仅在对应的数据也匹配时才 ...
- [Android Pro] 关于inputStream.available()方法获取文件的总大小
reference to :http://hold-on.iteye.com/blog/1017449 如果用inputStream对象的available()方法获取流中可读取的数据大小,通常我们调 ...
- php获取文件夹下面的文件列表和文件夹列表
function getDir($dir) { $dirArray[] = NULL; if (false != ($handle = opendir( $dir ))) { $i=0; while ...
随机推荐
- HTML – script async defer
参考 Youtube – #3 JavaScript Loading Strategies (async and defer) | JavaScript Full Tutorial no async ...
- Blazor静态服务端呈现(静态SSR)身份认证
本文介绍 Blazor 静态服务端呈现(静态 SSR)模式下,用户登录身份认证是如何实现的. 1. SSR 简介 SSR 是服务器侧呈现,HTML 是由服务器上的 ASP.NET Core 运行时生成 ...
- .NET常见的几种项目架构模式,你知道几种?(附带使用情况投票)
前言 项目架构模式在软件开发中扮演着至关重要的角色,它们为开发者提供了一套组织和管理代码的指导原则,以提高软件的可维护性.可扩展性.可重用性和可测试性. 假如你有其他的项目架构模式推荐,欢迎在文末留言 ...
- js中数据的基本类型
有5种基本数据类型分类 : 1. 数字型 number 2. 字符型 string 3. 布尔型 boolean 4. undefined 未定义 就是声明了但是没有赋值 5. null 空指针 ...
- 最详细CentOS7.6安装openGauss5.0.3教程
一.环境准备 1.1 主机信息 项目 内容 操作系统 CentOS7.6 IP 192.168.4.201 主机名 opgs201 CPU 8core 内存 16GB 磁盘1 100GB 1.2 操作 ...
- 01 Eclipse使用Maven慢的问题解决
1. Eclipse 使用的是内置的 Maven Eclipse 有可能使用了内置的 Maven,而不是独立安装的 Maven.如果使用 Eclipse 内置的 Maven,默认的 settings. ...
- Tony Bai · Go语言第一课 _个人笔记 04|初窥门径:一个Go程序的结构是怎样的?
Tony Bai · Go语言第一课 _个人笔记 04|初窥门径:一个Go程序的结构是怎样的? 1.配置国内的Go模块的镜像 配置国内镜像代理(使用阿里云镜像) go env -w GOPROXY=h ...
- Marklogic学习 系列专栏整理
Marklogic学习 系列专栏整理 本人就是个松鼠怪,见到好东西都想收藏,在CSDN发现了这位博主写的一系列MarkLogic相关专栏觉得不错,今天已经看到第六个了,反正很好吃,趁着最近项目使用Ma ...
- .NET + 微信小程序开源多功能电商系统
前言 推荐一款基于微信小程序.LayUI 和 .NET 平台的多功能电商系统,支持二次开发和扩展,帮助大家轻松快速搭建一个功能全面且易于管理的在线商城. 项目介绍 该项目不仅包含了微信小程序前端,还配 ...
- VMware安装Ubuntu操作系统 2024.9.27
1.安装 Ubuntu的官方网站是:https://www.ubuntu.com/download 点进去可以直接下载 文件下载会比较慢,我这点用了约5分钟 然后就可以打开vmware,选择: 就可以 ...