.NET 7 获取扩展文件属性的现代化方法咨询
.NET 7 读取文件扩展属性及照片拍摄日期的现代化实现
一、替代Shell32读取通用文件扩展属性
方案1:使用Microsoft.WindowsAPICodePack-Shell NuGet包
这个包是微软官方封装的Shell API,相比旧的Shell32 COM互操作,更适配.NET现代开发模式,支持.NET 5+版本。
安装命令:
Install-Package Microsoft.WindowsAPICodePack-Shell
读取扩展属性示例代码:
using Microsoft.WindowsAPICodePack.Shell; using Microsoft.WindowsAPICodePack.Shell.PropertySystem; public static string GetFileExtendedProperty(string filePath, string propertyKey) { using var shellFile = ShellFile.FromFilePath(filePath); var property = shellFile.Properties.GetProperty(propertyKey); return property?.ValueAsObject?.ToString(); } // 调用示例:获取文件"备注"属性 var comment = GetFileExtendedProperty(@"C:\test.jpg", SystemProperties.System.Comment);
常用属性可通过SystemProperties类直接引用,避免硬编码字符串。
方案2:直接调用WinRT StorageFile API(Windows平台)
.NET 7支持直接调用WinRT API,无需额外NuGet包,适合纯Windows环境开发:
using Windows.Storage; using Windows.Storage.FileProperties; public static async Task<DateTimeOffset?> GetPhotoTakenDateAsync(string filePath) { var file = await StorageFile.GetFileFromPathAsync(filePath); var properties = await file.Properties.GetImagePropertiesAsync(); return properties.DateTaken; }
该方式原生支持异步,契合现代异步编程模型。
二、获取照片拍摄日期的专用方案
如果仅需处理照片拍摄日期,除上述Shell/WinRT方式外,还有跨平台方案可选:
方案1:使用ImageSharp(跨平台)
ImageSharp是跨平台.NET图像处理库,无需依赖Windows特定组件,可直接读取EXIF元数据:
安装命令:
Install-Package SixLabors.ImageSharp Install-Package SixLabors.ImageSharp.Metadata.Profiles.Exif
读取拍摄日期示例:
using SixLabors.ImageSharp; using SixLabors.ImageSharp.Metadata.Profiles.Exif; public static DateTime? GetPhotoTakenDate(string filePath) { using var image = Image.Load(filePath); var exifProfile = image.Metadata.ExifProfile; if (exifProfile == null) return null; var dateTakenTag = exifProfile.GetValue(ExifTag.DateTimeOriginal); return dateTakenTag != null ? DateTime.Parse(dateTakenTag.Value.ToString()) : null; }
此方案完全跨平台,适配Windows、Linux、macOS多环境。
方案2:使用System.Drawing.Common(Windows平台)
若应用仅运行在Windows上,可通过System.Drawing.Common读取EXIF数据:
安装命令:
Install-Package System.Drawing.Common
示例代码:
using System.Drawing; using System.Drawing.Imaging; public static DateTime? GetPhotoTakenDate(string filePath) { using var image = Image.FromFile(filePath); var propItems = image.PropertyItems; foreach (var propItem in propItems) { // Exif标签DateTimeOriginal的ID为0x9003 if (propItem.Id == 0x9003) { var dateString = System.Text.Encoding.ASCII.GetString(propItem.Value).Trim('\0'); return DateTime.ParseExact(dateString, "yyyy:MM:dd HH:mm:ss", null); } } return null; }
三、迁移注意事项
- 弃用旧Shell32 COM互操作:COM互操作在.NET Core/.NET 5+中虽仍可用,但存在性能及版本兼容风险,建议替换为上述现代方案。
- 跨平台需求优先选ImageSharp:若应用需跨平台,避免使用Windows专属API或库。
- 优先使用异步API:WinRT和ImageSharp均提供异步方法,I/O密集型场景下使用异步可提升性能。
内容的提问来源于stack exchange,提问作者blcamp
相关产品推荐
相关产品推荐

