Advanced File/Folder Properties Viewer

Today we will see what it takes to display the file/folder properties in VB.NET. We will also display the the extended file properties along with the general properties too. If you are not sure, what I’m talking about, have a look at the screenshots below.

generalfileproperties summaryfileproperties customfileproperties

For simple file/folder properties, .NET has many classes built into it. But there is none for the extended properties.
So we will use the DsoFile.dll provided by Microsoft for this task.The Dsofile.dll files lets you view and edit Office document properties when you do not have Office installed. The Dsofile.dll sample file is an in-process ActiveX component for programmers that use Microsoft Visual Basic .NET or the Microsoft .NET Framework. You can use this in your custom applications to read and to edit the OLE document properties that are associated with Microsoft Office files

The Problem

Build an advanced file/folder properties viewer. The viewer should be able to display the extended properties along with the general properties too.

The Solution

Download the Dsofile.dll setup from http://support.microsoft.com/?kbid=224351 and extract the files to any folder of your choice.

Add a reference to the DsoFile.dll to your project. You will need to browse for the file and choose it from the location where you installed the downloaded setup.

Add a form to your application. Add 3 labels, 3 buttons, 1 textbox and two ListView controls to the form. Name these controls Label1, Label2, Label3, BrowseFileButton, BrowseFolderButton , ShowPropertiesButton , FileNameTextBox, FilePropertiesLV, ExtendedPropertiesLV respectively.

Arrange the controls as shown in the screenshot below and set the control captions (Text property) as shown.

advancedfileproperties

Set the following properties for both the ListView controls:

FullRowSelect  = True
GridLines      = True
View           = Details

Add two columns and set their Text property to Property Name and Value respectively.

Now your form should look like that shown in the screenshot above.

Open the form’s code window and add the following code:

Private Sub BrowseButton_Click(ByVal sender As System.Object, _
                               ByVal e As System.EventArgs) _
                               Handles BrowseFileButton.Click
    Dim ofd As New OpenFileDialog
    ofd.CheckFileExists = True
    ofd.ShowDialog()
    If Not String.IsNullOrEmpty(ofd.FileName) Then
        FileNameTextBox.Text = ofd.FileName
        ShowPropertiesButton.PerformClick()
    End If
End Sub

Private Sub BrowseFolderButton_Click(ByVal sender As System.Object, _
                                     ByVal e As System.EventArgs) _
                                     Handles BrowseFolderButton.Click
    Dim fbd As New FolderBrowserDialog
    fbd.ShowDialog()
    If Not String.IsNullOrEmpty(fbd.SelectedPath) Then
        FileNameTextBox.Text = fbd.SelectedPath
        ShowPropertiesButton.PerformClick()
    End If
End Sub

Private Sub ShowPropertiesButton_Click(ByVal sender As System.Object, _
                                       ByVal e As System.EventArgs) _
                                       Handles ShowPropertiesButton.Click
    '' populate the File Properties ListView
    FilePropertiesLV.Items.Clear()
    FillPropertiesListView()

    '' populate the Extended File Properties ListView
    ExtendedPropertiesLV.Items.Clear()
    FillExtendedPropertiesListView()
End Sub

Private Sub FillPropertiesListView()
    'TODO: Add code here to get file properties and populate the ListView
End Sub

Private Sub FillExtendedPropertiesListView()
    'TODO: Add code here to get file properties and populate the ListView
End Sub

Run the project and see how it goes. Click the browse buttons and select file/folder. Of course the ListViews won’t display anything as we haven’t added any code for that yet.

Next we will get the standard file properties and populate our FilePropertiesLV with that data. For this we will use the System.IO.FileInfo and System.IO.DirectoryInfo classes.

Replace the FillPropertiesListView stub with the following code:

Private Sub FillPropertiesListView()
    Dim propertiesList As New Dictionary(Of String, Object)
    Dim fi As New IO.FileInfo(FileNameTextBox.Text)
    Dim di As New IO.DirectoryInfo(FileNameTextBox.Text)
    If fi.Exists OrElse di.Exists Then
        propertiesList.Add("File/Folder Name", fi.Name)
        propertiesList.Add("In Folder", fi.DirectoryName)
        propertiesList.Add("Creation Time", fi.CreationTime.ToString)
        propertiesList.Add("Last Access Time", fi.LastAccessTime.ToString)
        propertiesList.Add("Last Write Time", fi.LastWriteTime.ToString)
        If fi.Exists Then
            propertiesList.Add("File Size", (fi.Length / 1024).ToString("0.00") & " KB")
        Else

            propertiesList.Add("Folder Contents", di.GetDirectories.Count & " Folders, " & _
                                                  di.GetFiles.Count.ToString & " files")

        End If
        For Each attr In [Enum].GetValues(fi.Attributes.GetType)
            Dim value As String = If((fi.Attributes And attr) = attr, "Yes", "No")
            propertiesList.Add(attr.ToString, value)
        Next
        Dim lvi = From item In propertiesList _
                  Select New ListViewItem(New String() {item.Key, item.Value.ToString})
        FilePropertiesLV.Items.AddRange(lvi.ToArray)
    Else

        MessageBox.Show("Invalid filename or path!", "Error", _
                        MessageBoxButtons.OK, MessageBoxIcon.Exclamation)

        Exit Sub
    End If
End Sub


Run the project. Browse for any file/folder and it should show you all the properties related to that file/folder.

Next, we will populate our ExtendedPropertiesLV ListView with the extended file properties. We will use the DsoFile.dll to our task here. Note that these properties are only valid for files (NOT folders). And all files may not have extended properties too. Usually Ms-Office files and a few others.

Replace the FillExtendedPropertiesListView stub with the following code.

Private Sub FillExtendedPropertiesListView()
    Dim propertiesList As New Dictionary(Of String, Object)
    Dim fi As New IO.FileInfo(FileNameTextBox.Text)
    Dim di As New IO.DirectoryInfo(FileNameTextBox.Text)
    propertiesList.Clear()
    If fi.Exists Then
        Dim dsoDocument As New DSOFile.OleDocumentProperties

        dsoDocument.Open(fi.FullName, True, _

                         DSOFile.dsoFileOpenOptions.dsoOptionOpenReadOnlyIfNoWriteAccess)



        On Error Resume Next    '' These properties may or maynot be implemented.
                                 '' We ignore them in the latter case.

        With dsoDocument.SummaryProperties
            propertiesList.Add("Application Name", .ApplicationName)
            propertiesList.Add("Author", .Author)
            propertiesList.Add("Byte Count", .ByteCount)
            propertiesList.Add("Category", .Category)
            propertiesList.Add("Character Count", .CharacterCount)
            propertiesList.Add("Character Count With Spaces", .CharacterCountWithSpaces)
            propertiesList.Add("Comments", .Comments)
            propertiesList.Add("Company", .Company)
            propertiesList.Add("Date Created", .DateCreated)
            propertiesList.Add("Date Last Printed", .DateLastPrinted)
            propertiesList.Add("Date Last Saved", .DateLastSaved)
            propertiesList.Add("Digital Signature", .DigitalSignature)
            propertiesList.Add("Document Security", .DocumentSecurity)
            propertiesList.Add("Hidden Slide Count", .HiddenSlideCount)
            propertiesList.Add("Keywords", .Keywords)
            propertiesList.Add("Last Saved By", .LastSavedBy)
            propertiesList.Add("Line Count", .LineCount)
            propertiesList.Add("Manager", .Manager)
            propertiesList.Add("Multimedia Clip Count", .MultimediaClipCount)
            propertiesList.Add("Note Count", .NoteCount)
            propertiesList.Add("Page Count", .PageCount)
            propertiesList.Add("Paragraph Count", .ParagraphCount)
            propertiesList.Add("Presentation Format", .PresentationFormat)
            propertiesList.Add("Revision Number", .RevisionNumber)
            propertiesList.Add("Shared Document", .SharedDocument)
            propertiesList.Add("Slide Count", .SlideCount)
            propertiesList.Add("Subject", .Subject)
            propertiesList.Add("Template", .Template)
            propertiesList.Add("Thumbnail", .Thumbnail)
            propertiesList.Add("Title", .Title)
            propertiesList.Add("Total Edit Time", .TotalEditTime)
            propertiesList.Add("Version", .Version)
            propertiesList.Add("Word Count", .WordCount)
        End With
        propertiesList.Add("Icon", dsoDocument.Icon)
        propertiesList.Add("Is Dirty", dsoDocument.IsDirty)
        propertiesList.Add("Is OLE File", dsoDocument.IsOleFile)
        propertiesList.Add("Is ReadOnly", dsoDocument.IsReadOnly)
        propertiesList.Add("Name", dsoDocument.Name)
        propertiesList.Add("Path", dsoDocument.Path)
        If dsoDocument.IsOleFile Then
            propertiesList.Add("OLE Document Format", dsoDocument.OleDocumentFormat)
            propertiesList.Add("OLE Document Type", dsoDocument.OleDocumentType)
            propertiesList.Add("Prog ID", dsoDocument.ProgID)
        End If
        On Error GoTo 0
        dsoDocument.Close()

        Dim lvi = From item In propertiesList _
                  Select New ListViewItem(New String() {item.Key, _
                                                        If(item.Value Is Nothing, "", _
                                                           item.Value.ToString)})

        ExtendedPropertiesLV.Items.AddRange(lvi.ToArray)
    End If
End Sub

That’s all. Run the code and enjoy!

 

How & Why this Works

The general file properties are picked up using the classes in System.IO namespace. The extended properties are picked up using the DsoFile.dll provided by Microsoft. The rest of the code is self-explanatory. But if you still have any doubts, feel free to ask.

Don’t try to compare the speeds of General Properties retrieval with the Advanced Properties retrieval. There is no comparison between the two. The General file attributes are stored in the file system (FAT/NTFS) table whereas the advanced properties are stored inside the file. So the latter would always be way too slow. Moreover, depending on the file, the advanced properties may or may not be available, since the file can have anything in it. Mostly the Ms-Office files (and a few others) will have these properties.

Future Enhancements

The application can be enhanced in many ways. Here are a few ideas.

  • I have not put in any error handling code, so that the code is simple to understand for this demo. Worse, I have used unstructured exception handling which is usually considered bad. Ideally, you should add appropriate error handlers wherever necessary.
  • Put the ListViews in a tab control and put properties in labels etc. to give a feel of the Windows file properties box we are accustomed to see. It will also give you more room to display the properties.
  • The application can be enhanced to adapt to a good file/folder searcher utility.
  • For this demo, I have not shown any file properties editing capabilities. Both, the System.IO classes as well as the DsoFile.dll supports these capabilities and can be incorporated into the application with slight modifications to it.
  • I haven’t added any code to show “Custom” properties. But the dsofile supports that too.
Advertisements

5 Responses to “Advanced File/Folder Properties Viewer”

  1. Diabetes Diet Says:

    Very good post. Anticipating the next.

  2. Anonymous Says:

    thanks for posting this.

  3. Rik Says:

    Hi thanks for this, but i cannot seem to get the last section of code working is there something i am doing wrong
    Select New ListViewItem(New String() {Item.Key, If(Item.Value Is Nothing, “”, Item.Value.ToString)}) ‘Select Case’ must end with a matching ‘End Select’. and ExtendedPropertiesLV.Items.AddRange(lvi.ToArray) Error 6 Overload resolution failed because no accessible ‘AddRange’ can be called with these arguments:
    ‘Public Sub AddRange(items As System.Windows.Forms.ListView.ListViewItemCollection)’: Value of type ‘1-dimensional array of System.Collections.Generic.KeyValuePair(Of String, Object)’ cannot be converted to ‘System.Windows.Forms.ListView.ListViewItemCollection’.
    ‘Public Sub AddRange(items() As System.Windows.Forms.ListViewItem)’: Value of type ‘1-dimensional array of System.Collections.Generic.KeyValuePair(Of String, Object)’ cannot be converted to ‘1-dimensional array of System.Windows.Forms.ListViewItem’ because ‘System.Collections.Generic.KeyValuePair(Of String, Object)’ is not derived from ‘System.Windows.Forms.ListViewItem’.

    • pradeep1210 Says:

      There was somehow an extra blank line-break there. There should not be blank lines between two lines where a line-continuation character has been used.
      I’ve corrected that now. So try again with that extra blank line removed.

  4. sashi Says:

    I want to get the summary properties of a font file.
    i gave the below code and it returns NULL value

    dsodocument.Open(“D:\FontName_Extract\Albany Std\AlbanyStd.otf”, False, DSOFile.dsoFileOpenOptions.dsoOptionOpenReadOnlyIfNoWriteAccess)
    MsgBox(dsodocument.SummaryProperties.company)

    Let me know what is the issue


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: