我的以前的測試報告程序需要在倒完測試數據報告后,在文件摘要中加上一些類似版權說明的文字等等. 因此需要對文件摘要信息進行編輯. 我的記憶中以前好像只有office文檔才可以又摘要信息, 現在看來基本上所有文件(windows2000以上的平臺)都可以有摘要信息..
在網絡上搜尋一番發現一些有用的網址 1.如何編輯文件的摘要 http://groups.google.com/group/microsoft.public.dotnet.framework/msg/99a5dd5c80c084b5?hl=zh-CN&lr=&ie=UTF-8&oe=UTF-8&rnum=4 2.微軟知識庫關于ole32.dll 中函數的說明 http://msdn2.microsoft.com/en-us/library/aa380328.aspx 3.新手對COM的認識及疑惑 http://www.cn-doc.com/_soft_visual_c_tech_doc/2005_08_18_23/20050818230216780.htm [原處]http://dev.csdn.net/user/putongren
下面是對本問題的總結:
剛開始,我以為是shell32里面的方法可以完成,因此引用了Microsoft Shell Controls And Automation, (shell32.dll),但經過分析后沒有找到相關的方法. shell32是COM可以托管引用. 引用shell32可以查出文件的摘要信息,但無法編輯保存,下面是關于這個問題的答案. 如何用C#獲得文件信息以及擴展信息
多次網上查詢后,我發現這篇在微軟討論組的文章(居然用google搜出來,沒有用msdn搜出),實際已經解決我的問題 setting file comment attribute PRogrammatically
開始我以為ole32.dll是一個COM,一直想引用,結果發現它只是一個函數庫, 必須對它進行dllimport.具體代碼可以看后面. 另外,我還發現以前微軟的virsual studio 6 里面的Depends工具,依然在virsual studio 2005中提供了,目錄在?:/Program Files/Microsoft Visual Studio 8/Common7/Tools 用這個工具可以查看一個函數庫有哪些公開方法.
補充點知識,先
調用方法SetProperty
/*pls visit this article * * http://msdn2.microsoft.com/en-us/library/aa380328.aspx * To open an existing file, use the StgOpenStorageEx function instead. notice: Applications written for Windows 2000, Windows Server 2003 and Windows xp must use StgCreateStorageEx rather than StgCreateDocfile to take advantage of the enhanced Windows 2000 and Windows XP Structured Storage features. * */ using System; using System.Collections.Generic; using System.Text; using StructuredStorageWrapper; namespace WindowsApplication8 { class FileSummary { public static void SetProperty(string filename,string msg , SummaryPropId summaryType) { // first you need to either create or open a file and its // property set stream //申明接口(指針) ipropertySetStorage propSetStorage = null; //com 組件的 clsid 參見IPropertySetStorage定義 Guid IID_PropertySetStorage = new Guid("0000013A-0000-0000-C000-000000000046"); //Applications written for Windows 2000, Windows Server 2003 and Windows XP must use StgCreateStorageEx rather than StgCreateDocfile to take advantage of the enhanced Windows 2000 and Windows XP Structured Storage features uint hresult = ole32.StgOpenStorageEx( filename, (int)(STGM.SHARE_EXCLUSIVE | STGM.READWRITE), (int)STGFMT.FILE, 0, (IntPtr)0, (IntPtr)0, ref IID_PropertySetStorage, ref propSetStorage); //返回指針 // next you need to create or open the Summary Information property set Guid fmtid_SummaryProperties = new Guid("F29F85E0-4FF9-1068-AB91-08002B27B3D9"); IPropertyStorage propStorage = null; hresult = propSetStorage.Create( ref fmtid_SummaryProperties, (IntPtr)0, (int)PROPSETFLAG.DEFAULT, (int)(STGM.CREATE | STGM.READWRITE | STGM.SHARE_EXCLUSIVE), ref propStorage); // next, you assemble a property descriptor for the property you // want to write to, in our case the Comment property PropSpec propertySpecification = new PropSpec(); propertySpecification.ulKind = 1; propertySpecification.Name_Or_ID = new IntPtr((int)summaryType); //now, set the value you want in a property variant PropVariant propertyValue = new PropVariant(); propertyValue.FromObject(msg); // Simply pass the property spec and its new value to the WriteMultiple // method and you're almost done propStorage.WriteMultiple(1, ref propertySpecification, ref propertyValue, 2); // the only thing left to do is commit your changes. Now you're done! hresult = propStorage.Commit((int)STGC.DEFAULT); //下面的很關鍵,如何關閉一個非托管的指針,如果不關閉,則本程序不關閉,文件被鎖定! System.Runtime.InteropServices.Marshal.ReleaseComObject(propSetStorage); propSetStorage = null; GC.Collect(); } } } 把ole32一些方法進行COM封裝 using System; using System.Text; using System.Runtime.InteropServices; namespace StructuredStorageWrapper { public enum SummaryPropId : int { Title = 0x00000002, Subject = 0x00000003, Author = 0x00000004, KeyWords = 0x00000005, Comments = 0x00000006, Template = 0x00000007, LastSavedBy = 0x00000008, RevisionNumber = 0x00000009, TotalEditingTime = 0x0000000A, LastPrinted = 0x0000000B, CreateDateTime = 0x0000000C, LastSaveDateTime = 0x0000000D, NumPages = 0x0000000E, NumWords = 0x0000000F, NumChars = 0x00000010, Thumbnail = 0x00000011, AppName = 0x00000012, Security = 0x00000013 } public enum STGC : int { DEFAULT = 0, OVERWRITE = 1, ONLYIFCURRENT = 2, DANGEROUSLYCOMMITMERELYTODISKCACHE = 4, CONSOLIDATE = 8 } public enum PROPSETFLAG : int { DEFAULT = 0, NONSIMPLE = 1, ANSI = 2, UNBUFFERED = 4, CASE_SENSITIVE = 8 } public enum STGM : int { READ = 0x00000000, WRITE = 0x00000001, READWRITE = 0x00000002, SHARE_DENY_NONE = 0x00000040, SHARE_DENY_READ = 0x00000030, SHARE_DENY_WRITE = 0x00000020, SHARE_EXCLUSIVE = 0x00000010, PRIORITY = 0x00040000, CREATE = 0x00001000, CONVERT = 0x00020000, FAILIFTHERE = 0x00000000, DIRECT = 0x00000000, TRANSACTED = 0x00010000, NOSCRATCH = 0x00100000, NOSNAPSHOT = 0x00200000, SIMPLE = 0x08000000, DIRECT_SWMR = 0x00400000, DELETEONRELEASE = 0x04000000 } public enum STGFMT : int { STORAGE = 0, FILE = 3, ANY = 4, DOCFILE = 5 } [StructLayout(LayoutKind.Explicit, Size = 8, CharSet = CharSet.Unicode)] public struct PropSpec { [FieldOffset(0)] public int ulKind; [FieldOffset(4)] public IntPtr Name_Or_ID; } [StructLayout(LayoutKind.Explicit, Size = 16)] public struct PropVariant { [FieldOffset(0)] public short variantType; [FieldOffset(8)] public IntPtr pointerValue; [FieldOffset(8)] public byte byteValue; [FieldOffset(8)] public long longValue; public void FromObject(object obj) { if (obj.GetType() == typeof(string)) { this.variantType = (short)VarEnum.VT_LPWSTR; this.pointerValue = Marshal.StringToHGlobalUni((string)obj); } } } [ComVisible(true), ComImport(), Guid("0000013A-0000-0000-C000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] public interface IPropertySetStorage { uint Create( [In, MarshalAs(UnmanagedType.Struct)] ref System.Guid rfmtid, [In] IntPtr pclsid, [In] int grfFlags, [In] int grfMode, ref IPropertyStorage propertyStorage); int Open( [In, MarshalAs(UnmanagedType.Struct)] ref System.Guid rfmtid, [In] int grfMode, [Out] IPropertyStorage propertyStorage); } [ComVisible(true), ComImport(), Guid("00000138-0000-0000-C000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] public interface IPropertyStorage { int ReadMultiple( uint numProperties, PropSpec[] propertySpecifications, PropVariant[] propertyValues); int WriteMultiple( uint numProperties, [MarshalAs(UnmanagedType.Struct)] ref PropSpec propertySpecification, ref PropVariant propertyValues, int propIDNameFirst); uint Commit( int commitFlags); } public enum HResults : uint { S_OK = 0, STG_E_FILEALREADYEXISTS = 0x80030050 } public class ole32 { [StructLayout(LayoutKind.Explicit, Size = 12, CharSet = CharSet.Unicode)] public struct STGOptions { [FieldOffset(0)] ushort usVersion; [FieldOffset(2)] ushort reserved; [FieldOffset(4)] uint uiSectorSize; [FieldOffset(8), MarshalAs(UnmanagedType.LPWStr)] string pwcsTemplateFile; } [DllImport("ole32.dll", CharSet = CharSet.Unicode)] public static extern uint StgCreateStorageEx( [MarshalAs(UnmanagedType.LPWStr)] string name, int accessMode, int storageFileFormat, int fileBuffering, IntPtr options, IntPtr reserved, ref System.Guid riid, [MarshalAs(UnmanagedType.Interface)] ref IPropertySetStorage propertySetStorage); [DllImport("ole32.dll", CharSet = CharSet.Unicode)] public static extern uint StgOpenStorageEx( [MarshalAs(UnmanagedType.LPWStr)] string name, int accessMode, int storageFileFormat, int fileBuffering, IntPtr options, IntPtr reserved, ref System.Guid riid, [MarshalAs(UnmanagedType.Interface)] ref IPropertySetStorage propertySetStorage); } }
新聞熱點
疑難解答