Tuesday, June 10, 2008

How to set custom attributes / file properties on a file in C# .Net

In the office here we have developed a document management system, which uses Custom Properties on PDF and DWG files to keep a track of what revision etc they are. In my Revit API development, we required an easy way of settings these from inside of Revit, so I set about creating a plotting external command using the new Print methods in the 2009 API and PDF995's ini file.

Once I'd printed the documents, I wanted to rename them and set the custom properties such as Revision, drawer, designer etc. After much searching, I discovered what you need to get is "DSOFile" from Microsoft, it is intended for editing Microsoft Word document properties, but works on anything. There is an easy to understand VB.Net example included in the download.

DSO File works by adding a reference to the DLL and creating a new DSOFile.OleDocumentPropertiesClass, and then performing actions on that. So, I created a new: private DSOFile.OleDocumentPropertiesClass m_file; Then in my constructor for my ParamaterSetter class I created an instance of OleDocumentPropertiesClass and then called the Open() Method with my filename:

 //create new isntance of OleDocumentPropertiesClass
m_file = new DSOFile.OleDocumentPropertiesClass();
// select the file you would like to open
m_file.Open(path, false, DSOFile.dsoFileOpenOptions.dsoOptionDefault);

From there you can perform actions such as : m_file.CustomProperties.Add(key, ref valueForKey); where key is the name of your property, and valueForKey is the value. For more standard properties, such as the "Summary" properties (in summary tab when you go properties on the file), you can access them directly, such as: m_file.SummaryProperties.Comments = value;

For reference, here is the utility class I use:

class FileParameterSetter {

        //DSOFile document
        private DSOFile.OleDocumentPropertiesClass m_file;

        
        public FileParameterSetter(string path) {
            //create new isntance of OleDocumentPropertiesClass
            m_file = new DSOFile.OleDocumentPropertiesClass();

            // select the file you would like to open
            m_file.Open(path, false, DSOFile.dsoFileOpenOptions.dsoOptionDefault);

        }

        /// <summary>
        /// Sets a custom property in the file.
        /// </summary>
        /// <param name="key">key to set</param>
        /// <param name="value">value to set to key</param>
        public void SetCustomproperty(string key, string value) {
            try {
                object valueForKey; 

                //check for valid inputs
                if ((key == null) || (value == null) || (key.Length == 0) || (value.Length == 0)) {
                    //Error, no key or value.
                    return;
                }

                valueForKey = value;

                //write to file
                m_file.CustomProperties.Add(key, ref valueForKey);

                //save change
                m_file.Save();
            } catch(Exception ex) {

                System.Windows.Forms.MessageBox.Show("There was an error adding properties to PDF file: " +
                                                        ex);

            }
        }

        /// <summary>
        /// Saves and closes document
        /// </summary>
        public void Close() {
           m_file.Close(true);
        }

        /// <summary>
        /// Sets a standard property, such as Comments, Subject, Title etc
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        public void SetStandardProperty(string key, string value) {

            if (key.Equals("Comments")) {
                m_file.SummaryProperties.Comments = value;
            }
            if (key.Equals("Subject")) {
                m_file.SummaryProperties.Subject = value;
            }
            if (key.Equals("Title")) {
                m_file.SummaryProperties.Title = value;
            }
        }
        
    }

12 comments:

Anonymous said...

brillient.

Leave it to the office devs to fix a problem in the MS development framework.

this is going to make workign with media files so much easier!

Thanks!

Anonymous said...

Thanks a lot!! thats exactly what I was looking for.

Hach75

Wayne E. Pfeffer said...

I have quite a few image files from cameras and scanners that are not OLE files. Do you know of anyway to read and / or write the file details for these types of files?

Anonymous said...
This comment has been removed by a blog administrator.
Mitali said...

I have a similar application...I have used the same code/logic...the program runs successfully...however I am not able to see the custom properties when I right click the pdf document....can you please help....
If I try to add the properties again to the same document I am getting error saying that the item already exists meaning that the property got added last time....but how to view this property???

Unknown said...

Hello Rod,

I am trying to perform this on an AutoCad (.dwg) drawing. The first time the code runs fine, and the second time I get an exception because the property exists. This is behaviour as expected. However, when I look at the properties of the file and go to the "custom" tab, it does not list the property.
Any idea why?

thanks in advance
Jeroen

Leon said...

This methodology does not always work.
You can add properties to text files, for example, and as long as you don't update them, or copy them to a new disk, the attributes stay. When you move or copy, these attributes dissappear.
Do PDF files behave properly (copy the properties as well?)

Rod Howarth said...

@Leon:
PDF files do not generally get updated/saved like text files do, so no problems there. The properties will stay as long as they remain on NTFS file systems. If you email the files or copy to a FAT32 file system they will lose their properties. This methodology is useful for using in intranet scenarios, copying around network drives etc.

Uwe said...

Very good!
But how do I read a custom property?

Anonymous said...

I just tried you suggested solution on JPG file in Vista 32 and it did not set any of the custom propeties like, Camera Maker....

Does this solution still valid for any type of file in NTFS systesm, event the new ones, Windows 7, Vista....?

Thanks
SSh

Anonymous said...

Hi

Im getting the below error

Interop type 'DSOFile.OleDocumentPropertiesClass' cannot be embedded. Use the applicable interface instead.

Also it is not working with *.sdf files.

Anonymous said...

Interop type 'DSOFile.OleDocumentPropertiesClass' cannot be embedded. Use the applicable interface instead : remove the word "Class" from the above and it will work.