在Word / Excel中,您必须添加自定义属性. (见图)
Custom Properties.
你可以看到有一个字段:“属性:”,你可以添加任何你想要的信息.
当您保存文件并转到文件夹中的文件位置时,可以右键单击 – >属性,您具有所有选项卡:常规/安全性/详细信息/以前的版本.使用该功能添加选项卡自定义.
Custom Properties.
你可以看到有一个字段:“属性:”,你可以添加任何你想要的信息.
当您保存文件并转到文件夹中的文件位置时,可以右键单击 – >属性,您具有所有选项卡:常规/安全性/详细信息/以前的版本.使用该功能添加选项卡自定义.
现在我想通过编码获得这些信息:Custom Properties information.然后将其解压缩到记事本.
到目前为止,我使用的是Shell32,但是我只得到“详细信息”选项卡中的信息.我做了一些研究,并看到了DSOfile.dll的一些可能性.但是我想知道是否有可能在不安装其他DLL的情况下执行此操作?
这是我的代码到目前为止的Shell32.
static void Main(string[] args) { //using (StreamWriter writer = new StreamWriter(@"filepathhere")) //{ //Console.SetOut(writer); ReadProperties(); //} } static void ReadProperties() { List<string> arrHeaders = new List<string>(); Shell shell = new Shell(); Folder objFolder = shell.NameSpace(@"filepathhere"); FolderItem objFolderItem = objFolder.ParseName("filehere.doc"); for (int i = 0; i < short.MaxValue; i++) { string header = objFolder.GetDetailsOf(objFolder,i); if (String.IsNullOrEmpty(header)) break; arrHeaders.Add(header); } for ( int i = 0; i < arrHeaders.Count; i++) { Console.WriteLine("{0}\t{1}: {2}",i,arrHeaders[i],objFolder.GetDetailsOf(objFolderItem,i)); } Console.ReadKey(); }
提前致谢!
德苏
历史上,这些属性由称为“结构化存储”的技术定义.第一个结构化存储实现是古代(但还是很活跃)的
Compound File Format
之后,Microsoft添加了结构化存储功能directly into NTFS.这允许您在任何文件(甚至.txt)文件上定义属性,如作者或标题.尽管资源管理器UI不会因为某种原因让你这样做,但我认为它仍然以编程方式工作.
然后,随着Vista,微软重新启动所有这一切,并引入了所有这一切的超集:Windows Property System.
不幸的是,在所有这一切的框架中没有.NET API.但Microsoft创建了一个名为Windows API CodePack的开源.NET库.所以,您最简单的方法来提取属性是添加对WindowsAPICodePack Core NugetPackage的引用,您可以使用它:
static void Main(string[] args) { foreach (var prop in new ShellPropertyCollection(@"mypath\myfile")) { Console.WriteLine(prop.CanonicalName + "=" + prop.ValueAsObject); } }
如果您不想添加额外的DLL,则可以从WindowsAPICodePack源(Windows API Code Pack: Where is it?)中提取ShellPropertyCollection代码.这是一个很好的工作,但可行.
在您的情况下的另一个解决方案是使用旧的Structure Storage原生API.我提供了一个这样做的示例.这是你如何使用它:
static void Main(string[] args) { foreach (var prop in new StructuredStorage(@"mypath\myfile").Properties) { Console.WriteLine(prop.Name + "=" + prop.Value); } } public sealed class StructuredStorage { public static readonly Guid SummaryInformationFormatId = new Guid("{F29F85E0-4FF9-1068-AB91-08002B27B3D9}"); public static readonly Guid DocSummaryInformationFormatId = new Guid("{D5CDD502-2E9C-101B-9397-08002B2CF9AE}"); public static readonly Guid UserDefinedPropertiesId = new Guid("{D5CDD505-2E9C-101B-9397-08002B2CF9AE}"); private List<StructuredProperty> _properties = new List<StructuredProperty>(); public StructuredStorage(string filePath) { if (filePath == null) throw new ArgumentNullException("filePath"); FilePath = filePath; IPropertySetStorage propertySetStorage; int hr = StgOpenStorageEx(FilePath,STGM.STGM_READ | STGM.STGM_SHARE_DENY_NONE | STGM.STGM_DIRECT_SWMR,STGFMT.STGFMT_ANY,IntPtr.Zero,typeof(IPropertySetStorage).GUID,out propertySetStorage); if (hr == STG_E_FILENOTFOUND || hr == STG_E_PATHNOTFOUND) throw new FileNotFoundException(null,FilePath); if (hr != 0) throw new Win32Exception(hr); try { LoadPropertySet(propertySetStorage,SummaryInformationFormatId); LoadPropertySet(propertySetStorage,DocSummaryInformationFormatId); } finally { Marshal.ReleaseComObject(propertySetStorage); } // for some reason we can't read this one on the same COM ref? LoadProperties(UserDefinedPropertiesId); } public string FilePath { get; private set; } public IReadOnlyList<StructuredProperty> Properties { get { return _properties; } } private void LoadPropertySet(IPropertySetStorage propertySetStorage,Guid fmtid) { IPropertyStorage propertyStorage; int hr = propertySetStorage.Open(fmtid,STGM.STGM_READ | STGM.STGM_SHARE_EXCLUSIVE,out propertyStorage); if (hr == STG_E_FILENOTFOUND || hr == STG_E_ACCESSDENIED) return; if (hr != 0) throw new Win32Exception(hr); IEnumSTATPROPSTG es; propertyStorage.Enum(out es); if (es == null) return; try { var stg = new STATPROPSTG(); int fetched; do { hr = es.Next(1,ref stg,out fetched); if (hr != 0 && hr != 1) throw new Win32Exception(hr); if (fetched == 1) { string name = GetPropertyName(fmtid,propertyStorage,stg); var propsec = new PROPSPEC[1]; propsec[0] = new PROPSPEC(); propsec[0].ulKind = stg.lpwstrName != null ? PRSPEC.PRSPEC_LPWSTR : PRSPEC.PRSPEC_PROPID; IntPtr lpwstr = IntPtr.Zero; if (stg.lpwstrName != null) { lpwstr = Marshal.StringToCoTaskMemUni(stg.lpwstrName); propsec[0].union.lpwstr = lpwstr; } else { propsec[0].union.propid = stg.propid; } var vars = new PROPVARIANT[1]; vars[0] = new PROPVARIANT(); try { hr = propertyStorage.ReadMultiple(1,propsec,vars); if (hr != 0) throw new Win32Exception(hr); } finally { if (lpwstr != IntPtr.Zero) { Marshal.FreeCoTaskMem(lpwstr); } } object value; try { switch (vars[0].vt) { case VARTYPE.VT_BOOL: value = vars[0].union.boolVal != 0 ? true : false; break; case VARTYPE.VT_BSTR: value = Marshal.PtrToStringUni(vars[0].union.bstrVal); break; case VARTYPE.VT_CY: value = decimal.FromOACurrency(vars[0].union.cyVal); break; case VARTYPE.VT_DATE: value = DateTime.FromOADate(vars[0].union.date); break; case VARTYPE.VT_DECIMAL: IntPtr dec = IntPtr.Zero; Marshal.StructureToPtr(vars[0],dec,false); value = Marshal.PtrToStructure(dec,typeof(decimal)); break; case VARTYPE.VT_DISPATCH: value = Marshal.GetObjectForIUnknown(vars[0].union.pdispVal); break; case VARTYPE.VT_ERROR: case VARTYPE.VT_HRESULT: value = vars[0].union.scode; break; case VARTYPE.VT_FILETIME: value = DateTime.FromFileTime(vars[0].union.filetime); break; case VARTYPE.VT_I1: value = vars[0].union.cVal; break; case VARTYPE.VT_I2: value = vars[0].union.iVal; break; case VARTYPE.VT_I4: value = vars[0].union.lVal; break; case VARTYPE.VT_I8: value = vars[0].union.hVal; break; case VARTYPE.VT_INT: value = vars[0].union.intVal; break; case VARTYPE.VT_LPSTR: value = Marshal.PtrToStringAnsi(vars[0].union.pszVal); break; case VARTYPE.VT_LPWSTR: value = Marshal.PtrToStringUni(vars[0].union.pwszVal); break; case VARTYPE.VT_R4: value = vars[0].union.fltVal; break; case VARTYPE.VT_R8: value = vars[0].union.dblVal; break; case VARTYPE.VT_UI1: value = vars[0].union.bVal; break; case VARTYPE.VT_UI2: value = vars[0].union.uiVal; break; case VARTYPE.VT_UI4: value = vars[0].union.ulVal; break; case VARTYPE.VT_UI8: value = vars[0].union.uhVal; break; case VARTYPE.VT_UINT: value = vars[0].union.uintVal; break; case VARTYPE.VT_UNKNOWN: value = Marshal.GetObjectForIUnknown(vars[0].union.punkVal); break; default: value = null; break; } } finally { PropVariantClear(ref vars[0]); } var property = new StructuredProperty(fmtid,name,stg.propid); property.Value = value; _properties.Add(property); } } while (fetched == 1); } finally { Marshal.ReleaseComObject(es); } } private static string GetPropertyName(Guid fmtid,IPropertyStorage propertyStorage,STATPROPSTG stg) { if (!string.IsNullOrEmpty(stg.lpwstrName)) return stg.lpwstrName; var propids = new int[1]; propids[0] = stg.propid; var names = new string[1]; names[0] = null; int hr = propertyStorage.ReadPropertyNames(1,propids,names); if (hr == 0) return names[0]; return null; } public void LoadProperties(Guid formatId) { IPropertySetStorage propertySetStorage; int hr = StgOpenStorageEx(FilePath,formatId); } finally { Marshal.ReleaseComObject(propertySetStorage); } } private const int STG_E_FILENOTFOUND = unchecked((int)0x80030002); private const int STG_E_PATHNOTFOUND = unchecked((int)0x80030003); private const int STG_E_ACCESSDENIED = unchecked((int)0x80030005); private enum PRSPEC { PRSPEC_LPWSTR = 0,PRSPEC_PROPID = 1 } private enum STGFMT { STGFMT_ANY = 4,} [Flags] private enum STGM { STGM_READ = 0x00000000,STGM_READWRITE = 0x00000002,STGM_SHARE_DENY_NONE = 0x00000040,STGM_SHARE_DENY_WRITE = 0x00000020,STGM_SHARE_EXCLUSIVE = 0x00000010,STGM_DIRECT_SWMR = 0x00400000 } // we only define what we handle private enum VARTYPE : short { VT_I2 = 2,VT_I4 = 3,VT_R4 = 4,VT_R8 = 5,VT_CY = 6,VT_DATE = 7,VT_BSTR = 8,VT_DISPATCH = 9,VT_ERROR = 10,VT_BOOL = 11,VT_UNKNOWN = 13,VT_DECIMAL = 14,VT_I1 = 16,VT_UI1 = 17,VT_UI2 = 18,VT_UI4 = 19,VT_I8 = 20,VT_UI8 = 21,VT_INT = 22,VT_UINT = 23,VT_HRESULT = 25,VT_LPSTR = 30,VT_LPWSTR = 31,VT_FILETIME = 64,} [StructLayout(LayoutKind.Explicit)] private struct PROPVARIANTunion { [FieldOffset(0)] public sbyte cVal; [FieldOffset(0)] public byte bVal; [FieldOffset(0)] public short iVal; [FieldOffset(0)] public ushort uiVal; [FieldOffset(0)] public int lVal; [FieldOffset(0)] public uint ulVal; [FieldOffset(0)] public int intVal; [FieldOffset(0)] public uint uintVal; [FieldOffset(0)] public long hVal; [FieldOffset(0)] public ulong uhVal; [FieldOffset(0)] public float fltVal; [FieldOffset(0)] public double dblVal; [FieldOffset(0)] public short boolVal; [FieldOffset(0)] public int scode; [FieldOffset(0)] public long cyVal; [FieldOffset(0)] public double date; [FieldOffset(0)] public long filetime; [FieldOffset(0)] public IntPtr bstrVal; [FieldOffset(0)] public IntPtr pszVal; [FieldOffset(0)] public IntPtr pwszVal; [FieldOffset(0)] public IntPtr punkVal; [FieldOffset(0)] public IntPtr pdispVal; } [StructLayout(LayoutKind.Sequential)] private struct PROPSPEC { public PRSPEC ulKind; public PROPSPECunion union; } [StructLayout(LayoutKind.Explicit)] private struct PROPSPECunion { [FieldOffset(0)] public int propid; [FieldOffset(0)] public IntPtr lpwstr; } [StructLayout(LayoutKind.Sequential)] private struct PROPVARIANT { public VARTYPE vt; public ushort wReserved1; public ushort wReserved2; public ushort wReserved3; public PROPVARIANTunion union; } [StructLayout(LayoutKind.Sequential)] private struct STATPROPSTG { [MarshalAs(UnmanagedType.LPWStr)] public string lpwstrName; public int propid; public VARTYPE vt; } [StructLayout(LayoutKind.Sequential)] private struct STATPROPSETSTG { public Guid fmtid; public Guid clsid; public uint grfFlags; public System.Runtime.InteropServices.ComTypes.FILETIME mtime; public System.Runtime.InteropServices.ComTypes.FILETIME ctime; public System.Runtime.InteropServices.ComTypes.FILETIME atime; public uint dwOSVersion; } [DllImport("ole32.dll")] private static extern int StgOpenStorageEx([MarshalAs(UnmanagedType.LPWStr)] string pwcsName,STGM grfMode,STGFMT stgfmt,int grfAttrs,IntPtr pStgOptions,IntPtr reserved2,[MarshalAs(UnmanagedType.LPStruct)] Guid riid,out IPropertySetStorage ppObjectOpen); [DllImport("ole32.dll")] private static extern int PropVariantClear(ref PROPVARIANT pvar); [Guid("0000013B-0000-0000-C000-000000000046"),InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] private interface IEnumSTATPROPSETSTG { [PreserveSig] int Next(int celt,ref STATPROPSETSTG rgelt,out int pceltFetched); // rest ommited } [Guid("00000139-0000-0000-C000-000000000046"),InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] private interface IEnumSTATPROPSTG { [PreserveSig] int Next(int celt,ref STATPROPSTG rgelt,out int pceltFetched); // rest ommited } [Guid("00000138-0000-0000-C000-000000000046"),InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] private interface IPropertyStorage { [PreserveSig] int ReadMultiple(uint cpspec,[MarshalAs(UnmanagedType.LPArray,SizeParamIndex = 0)] PROPSPEC[] rgpspec,[Out,MarshalAs(UnmanagedType.LPArray,SizeParamIndex = 0)] PROPVARIANT[] rgpropvar); [PreserveSig] int WriteMultiple(uint cpspec,SizeParamIndex = 0)] PROPSPEC[] rgpspec,SizeParamIndex = 0)] PROPVARIANT[] rgpropvar,uint propidNameFirst); [PreserveSig] int DeleteMultiple(uint cpspec,SizeParamIndex = 0)] PROPSPEC[] rgpspec); [PreserveSig] int ReadPropertyNames(uint cpropid,SizeParamIndex = 0)] int[] rgpropid,ArraySubType = UnmanagedType.LPWStr,SizeParamIndex = 0)] string[] rglpwstrName); [PreserveSig] int NotDeclared1(); [PreserveSig] int NotDeclared2(); [PreserveSig] int Commit(uint grfCommitFlags); [PreserveSig] int NotDeclared3(); [PreserveSig] int Enum(out IEnumSTATPROPSTG ppenum); // rest ommited } [Guid("0000013A-0000-0000-C000-000000000046"),InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] private interface IPropertySetStorage { [PreserveSig] int Create([MarshalAs(UnmanagedType.LPStruct)] Guid rfmtid,[MarshalAs(UnmanagedType.LPStruct)] Guid pclsid,uint grfFlags,out IPropertyStorage ppprstg); [PreserveSig] int Open([MarshalAs(UnmanagedType.LPStruct)] Guid rfmtid,out IPropertyStorage ppprstg); [PreserveSig] int NotDeclared3(); [PreserveSig] int Enum(out IEnumSTATPROPSETSTG ppenum); } } public sealed class StructuredProperty { public StructuredProperty(Guid formatId,string name,int id) { FormatId = formatId; Name = name; Id = id; } public Guid FormatId { get; private set; } public string Name { get; private set; } public int Id { get; private set; } public object Value { get; set; } public override string ToString() { return Name; } }