Jaafar Tribak

Well-known Member
Joined
Dec 5, 2002
Messages
9,779
Office Version
  1. 2016
Platform
  1. Windows
Hi,

I was spurred to explore this subject further after this recent thread

As far as I can see, there seems to be no easy way to edit file properties programmatically without needing to resort to external components such as CDDBControl.dll or CDDBControlRoxio.dll (which by the way these two dlls don't seem to work in x64 anyway, plus they are a nightmare to install & register).There may be other 3rd party libraries that could be used but it would be great if we could read and edit file properties hassle-free and with vba alone.

So, to this end, I have been experimenting with relevant interfaces (PropertyStore, IPropertyDescription, IPropertyDescriptionList, IPropertySystem) and I seem to have come up with some pretty good results when testing in x32 and x64... I just hope it works consistently accross diff systems.

File Demo:
FileMetadataProperties.xlsm





This vba project code offers esay to use functions for reading and editing properties of all kind of files (not just media MP3s)
VBA Code:
Public Function GetPropertyValue( _
    ByVal sPathFile As String, _
    ByVal Prop As Property_Name _
) As String

And
VBA Code:
Public Function SetPropertyValue( _
    ByVal sPathFile As String, _
    ByVal Prop As Property_Name, _
    ByVal Property_NewValue As Variant _
) As Boolean

VBA Code:
Public Function PropertyDump() As String()

VBA Code:
Public Function GetAllFileProperties(sPathFile As String) As String()

Useful headers for reference:
propsys.h
propKey.h

The code is quite long so I will be splitting it into two sections and post them in the next two following posts.
 
I tried to modify the attributes of a PNG file. Only the date taken attribute was set. I honestly have no idea if that's by design, but it does set the attributes when it's a JPG.

I also have no idea of where you get all of this boilerplate code to do these low level things, mind giving me a few pointers? hehe
A feature of the JPG file format is the ability to have EXIF metadata. PNG files have 'some of the same metadata fields you can change (I think the Comment field, might be one for example), but nothing near on the same scale as JPGs.
 
Upvote 0

Excel Facts

Format cells as currency
Select range and press Ctrl+Shift+4 to format cells as currency. (Shift 4 is the $ sign).
It's hardly boilerplate - Jaafar wrote it!
I guess my wording was shamefully wrong. My bad.

@Jaafar Tribak I didn't mean you copied the code, I know you engineered it, it's why I'm always following your posts, I just chose my words wrong.

What I meant by "boilerplate code" is: how do you determine which pieces of code are necessary for everything to function properly? As I understand it, if you want to change a property, you would first locate a built-in function that modifies that property, then analyze its parameters, and finally figure out how to set those parameters correctly by referencing other functions and do the whole thing again to set its parameters. That would be a strategy I could grasp. However, if you're moving pieces of memory and arranging them in a way that the OS understands, that seems much more complex and low-level, but also very interesting.

For instance, I randomly copied these lines:

VBA Code:
    Case ContentType°
    PropNameToPropKey = DEFINE_PROPERTYKEY(&HD5CDD502, &H2E9C, &H101B, &H93, &H97, &H8, &H0, &H2B, &H2C, &HF9, &HAE, 26)

Code:
    Select Case DisplyName
        Case AcquisitionID°: DisplayNameToCanonicalName = "System.AcquisitionID"
        Case Attributes°: DisplayNameToCanonicalName = "System.FileAttributes"

So, how do you know you have to include those arguments in the DEFINE_PROPERTYKEY function, in particular, where do you get that you need &H93, for example, in the 4th argument. Or how do you come up with "System.AcquisitionID" as the value for DisplayNameToCanonicalName when DisplyName is AcquisitionID°? Also, where do you draw a line between the things you can "name" and the things the OS demands you to use as "name".

How or where do you get that information in general?

I hope what I wrote makes sense.
 
Last edited:
Upvote 0
A feature of the JPG file format is the ability to have EXIF metadata. PNG files have 'some of the same metadata fields you can change (I think the Comment field, might be one for example), but nothing near on the same scale as JPGs.
Then I understand now that this is by design, being how the JPG file format operates. I was trying to figure out if you could enforce attributes in a file with this method.

I appreciate the clarification.
 
Upvote 0
@Edgar_
So, how do you know you have to include those arguments in the DEFINE_PROPERTYKEY function, in particular, where do you get that you need &H93, for example, in the 4th argument.
PKEY values are defined in the header file: Propkey.h.

The DEFINE_PROPERTYKEY function takes 2 arguments: (a guid and a pid) which are both required for building\returning a PROPERTYKEY structure. This structure will be later on needed by the IPropertyStore Interface in order to read and write file attributes\metadata.

So in the case of the ContentType attribute you asked about, I first built the propkey using the DEFINE_PROPERTYKEY function ... I obtained the required guid and pid from the above mentioned PropKey header file where all the propkey values are defined. This is the one for ContentType propkey\attribute:
DEFINE_PROPERTYKEY(PKEY_ContentType, 0xd5cdd502,0x2e9c,0x101b,0x93,0x97,0x08,0x00,0x2b,0x2c,0xf9,0xae,26);

Once I have the correct PropKey and the correct file pathname, I can then read and write the file extended attributes\metadata\props via the IPropertyStore and IPropertyDescription Interfaces using low level virtual table stdcalls with the help of the handy DispCallFunc api that is exported by the OLEAUT32 dll.

Similarly with the "System.AcquisitionID" and "System.FileAttributes", I used the DisplayNameToCanonicalName function to get the attributes canonical names whose definitions are documented here or here.

So, as you can probably see by now, it is not magic. It is all documented. One just needs to find & follow the relevant documentation, although it's not that easy to find and not that easy to understand when first reading it and it can sometimes be tricky when trying to put the pieces together I must admit.

I tried to modify the attributes of a PNG file. Only the date taken attribute was set. I honestly have no idea if that's by design, but it does set the attributes when it's a JPG.
Like Dan_W said, not all Windows codecs support property writing ... For example, IPropertyStore::SetValue returns the error: WINCODEC_ERR_PROPERTYNOTSUPPORTED 0x88982F41 for PNG images when trying to edit their DateCreated property ... I guess, restricted user permissions can also prevent editing file attributes\props but I haven't fully explored that bit.

I was trying to figure out if you could enforce attributes in a file with this method.
Don't know how to do that wit code. Can you try Attribute Changer and see if it can?

Regards.
 
Last edited:
Upvote 0
So, as you can probably see by now, it is not magic. It is all documented. One just needs to find & follow the relevant documentation, although it's not that easy to find and not that easy to understand when first reading it and it can sometimes be tricky when trying to put the pieces together I must admit.
I see. I will investigate further to see if there is some way to reverse engineer it, for now I'll try to understand your code to see if I can make some changes.

Don't know how to do that wit code. Can you try Attribute Changer and see if it can?
I've been using version 9 of AC for a few years, it has done wonders in the past for me. In the version I have installed, I can not set those JPG attributes in a PNG file.

Thanks for the explanations, again. It is all very interesting.
 
Upvote 0

Forum statistics

Threads
1,223,227
Messages
6,170,853
Members
452,361
Latest member
d3ad3y3

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top