C # how to edit the summary of an object,

Source: Internet
Author: User

C # how to edit the summary of an object,

My previous test report program needs to add some text similar to the copyright notice to the file Abstract After testing data reports are completed. therefore, you must edit the file summary information. in my memory, it seems that only office documents can provide abstract information. Now it seems that basically all files (Windows or above) can have abstract information ..

Search for some useful URLs on the web 1. How to edit the summary http://groups.google.com/group/microsoft.public.dotnet.framework/msg/99a5dd5c80c084b5 of the file? Hl = zh-CN & lr = & ie = UTF-8 & oe = UTF-8 & rnum = 4 2. description of functions in ole32.dll http://msdn2.microsoft.com/en-us/library/aa380328.aspx 3. newbie's understanding of COM and doubt http://www.cn-doc.com/_soft_visual_c_tech_doc/2005_08_18_23/20050818230216780.htm [original] http://dev.csdn.net/user/putongren

The following is a summary of the problem:

At the beginning, I thought the methods in shell32 could be completed. Therefore, Microsoft Shell Controls And Automation (shell32.dll) was referenced, but no related methods were found after analysis. shell32 is a COM-hosted reference. referencing shell32 can find out the summary information of the file, but it cannot be edited and saved. The following is the answer to this question. how to use C # To obtain file information and extended information

 

After multiple online queries, I found this article in the Microsoft discussion group (I used google to search for it, but I didn't use msdn to search for it). It has actually solved my problem: setting file comment attribute programmatically

Main IdeasIntroduce ole32.dll to define the relevant struct (defined in interface mode) and enumeration values of input parameters, and define static methods. corresponding functions return interfaces through static methods, this interface is actually a pointer (which can call its function) to call the interface function.

 

At first, I thought ole32.dll was a COM and I always wanted to reference it. As a result, I found it was just a function library and I had to perform dllimport on it. the specific code can be viewed later. in addition, I also found that the Depends tool in Microsoft's virsual studio 6 was still provided in virsual studio 2005? :/Program Files/Microsoft Visual Studio 8/Common7/Tools use this tool to view the public methods of a function library.

Add some knowledge, first

For a summary of using COM or function libraries, here (http://dev.csdn.net/user/putongren), reference part

1. Find a way to know the clsid of the com component (a number, 16 bytes long, globally unique); if you do not know the clsid, you need to know the name (progid), such as excel. application.

2. Start dealing with ole32.dll! If the process has not loaded it, loadlibrary, and then getprocaddress...

3. Run a function in coinitializeex and ole32.dll to record the corresponding data in ole32.dll and allow you to call other functions in ole32.dll.

4. skip this step if you already know clsid. Otherwise, call clsidfromprogid to calculate the clsid according to the name.

The functions in ole32.dll are actually searched in the registry at/hkey_classes_root/Name (progid). There is a/clsid under it, which is clsid, in fact, you can go to the Registry to find it yourself. Clsid of excel. application = {00024500-0000-0000-c000-000000000046 }.

5. Call cogetclassobject in ole32.dll to create a clsid object. You can also call cocreateinstance/cocreateinstanceex.

This object can be imagined as if the operating system loads a dynamic link library in the memory or starts a process independently. It does not return the object handle, therefore, do not use a handle for further access-like getwindow (hwnd ,...), the idea of getting the function entry location through getprocaddress for further access was also abandoned early. How can I access it? Let's look down...

6. when you call cogetclassobject to create a clsid object... (unified and fixed numbers all over the world) returns an interface pointer, which can be considered as a set of functions.

Objects generated based on clsid may have several different function sets. Each function set has an interface number corresponding to it, and the iunknown number corresponds to each object. The first three functions of each function set are the same: queryinterface, addref, and release. Call queryinterface as a parameter to find the corresponding function set.

7. About clsid and interface iid

Clsid is a globally unique 16-byte number. ole32.dll searches for the corresponding dll file (or exe file) in the registry ). According to the concept of programs and processes, the instantiation of clsid is to load a dll or run an exe process. After a dll or exe is loaded by ole32.dll, a number of function entry address tables are created for ole32.dll in the address space (according to the dll or exe definition ), create a pointer for each function entry table to save its start address (this pointer is a long word in the address ).

Iid -- interface, which is also a globally unique 16-byte number. ole32.dll finds a corresponding value in the pointer of all function entry address tables of the clsid instance and returns it. Therefore, the instance of the interface is the pointer returned.

C programmers can think of interfaces as a structure with several functions. c ++ programmers can think of interfaces as a class.

For how to call the functions in the function entry table found through iid, see the dll or exe development interface documentation. When calling a specific function, you can press the parameter into the stack and call the function. However, this seems to be a low-level approach in assembly, which is troublesome, define a class pointer in vc to save the pointer returned by the interface, and then define the class member, which is more convenient to use-the problem of parameter pushing into the stack is solved by the compiler for you.

8. com

So com, in summary, is to use two-level numbers to call a function provided by a dll or exe through ole32.dll.

Of course, there are also automation on this basis, and more standard interface numbers and access methods are defined to complete more complex functions.

Call method 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 StructuredStorageWrapp Er; 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 // declarative interface (pointer) IPropertySetStorage propSetStorage = null; // For the clsid of the com component, see IPropertySetStorage to define 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 = partition (filename, (int) (STGM. performance_exclusive | STGM. READWRITE), (int) STGFMT. FILE, 0, (IntPtr) 0, (IntPtr) 0, ref IID_PropertySetStorage, ref propSet Storage); // return pointer // 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. __exclusive), ref propStorage); // next, you ass Emble 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 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); // the following key is: how to close an unmanaged pointer. If it is not closed, the program will not be closed and the file will be locked! System. runtime. interopServices. marshal. releaseComObject (propSetStorage); propSetStorage = null; GC. collect () ;}} encapsulate some ole32 methods in COM and 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, topology = 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, 1_lidate = 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, pai_deny_none = 0x00000040, export _deny_read = 0x00000030, export _deny_write = 0x00000020, export _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, financialas (UnmanagedType. struct)] ref System. guid rfmtid, [In] IntPtr pclsid, [In] int grfFlags, [In] int grfMode, ref IPropertyStorage propertyStorage); int Open ([In, financialas (UnmanagedType. struct)] ref System. guid rfmtid, [In] int grfMode, [Out] IPropertyStorage propertyStorage);} [ComVisible (true), ComImport (), Guid ("identifier"), InterfaceType (ComInterfaceType. public interface IPropertyStorage {int ReadMultiple (uint numProperties, PropSpec [] propertySpecifications, PropVariant [] propertyValues); int WriteMultiple (uint numProperties, [financialas (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 ), financialas (UnmanagedType. LPWStr)] string pwcsTemplateFile;} [DllImport ("ole32.dll", CharSet = CharSet. unicode)] public static extern uint StgCreateStorageEx ([financialas (UnmanagedType. LPWStr)] string name, int accessMode, int storageFileFormat, int fileBuffering, IntPtr options, IntPtr reserved, ref System. guid riid, [financialas (UnmanagedType. interface)] ref IPropertySetStorage propertySetStorage); [DllImport ("ole32.dll", CharSet = CharSet. unicode)] public static extern uint StgOpenStorageEx ([financialas (UnmanagedType. LPWStr)] string name, int accessMode, int storageFileFormat, int fileBuffering, IntPtr options, IntPtr reserved, ref System. guid riid, [financialas (UnmanagedType. interface)] ref IPropertySetStorage propertySetStorage );}}

 


C Language & |! What are

& Is the address fetch operator used to extract the address of a variable.
For example, if you define a variable, the system will allocate a space in the memory during compilation.
The location of the space in the memory is its address. & Extract its address.
E. g int a; assign an address to it during compilation, for example, 2000; & a is 2000.
If an integer pointer Variable p, p = & a; is defined, the address 2000 of a is assigned to p. P = 2000 after running.
Another example is scanf ("% d", & a). When you enter 3, it first knows the address of a according to & a, and finds the space of a in the memory by the address, write 3 to this space.
* Is a pointer operator, which is opposite to &. It extracts the value of a Variable Based on the address of the variable.
For example, * the value of a is 3 of variable.
The following is a summary of the pointer used in the definition and description.
Int * p; defines a pointer to integer data.
Int * p [n]; defines the pointer array p, which consists of n pointer elements pointing to integer data.
Int (* p) [n]; p is the pointer variable pointing to a one-dimensional array containing n elements.
Int * p (); p is the function that returns a pointer pointing to integer data.
Int (* p) (); p is the pointer to the function. This function returns an integer value.
Int ** p; p is a pointer variable that points to an integer Data Pointer variable.
If you want to learn more about the system, you can refer to tan haoqiang's c Programming (the third edition), which is easy to understand. Is a good C language learning material.

C Language & |! What are

& Is the address fetch operator used to extract the address of a variable.
For example, if you define a variable, the system will allocate a space in the memory during compilation.
The location of the space in the memory is its address. & Extract its address.
E. g int a; assign an address to it during compilation, for example, 2000; & a is 2000.
If an integer pointer Variable p, p = & a; is defined, the address 2000 of a is assigned to p. P = 2000 after running.
Another example is scanf ("% d", & a). When you enter 3, it first knows the address of a according to & a, and finds the space of a in the memory by the address, write 3 to this space.
* Is a pointer operator, which is opposite to &. It extracts the value of a Variable Based on the address of the variable.
For example, * the value of a is 3 of variable.
The following is a summary of the pointer used in the definition and description.
Int * p; defines a pointer to integer data.
Int * p [n]; defines the pointer array p, which consists of n pointer elements pointing to integer data.
Int (* p) [n]; p is the pointer variable pointing to a one-dimensional array containing n elements.
Int * p (); p is the function that returns a pointer pointing to integer data.
Int (* p) (); p is the pointer to the function. This function returns an integer value.
Int ** p; p is a pointer variable that points to an integer Data Pointer variable.
If you want to learn more about the system, you can refer to tan haoqiang's c Programming (the third edition), which is easy to understand. Is a good C language learning material.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.