A test by changing the title of a MP3 with IPropertyStore :
Add at beginning :
Imports System.Runtime.InteropServices
Main code :
Dim sFileName As String = "E:\01. IMANY - Don't Be so Shy (Filatov & Karas Remix).mp3"
Dim sNewTitle As String = "New Title"
Dim pPropertyStore As IPropertyStore = Nothing
Dim hr As HRESULT = SHGetPropertyStoreFromParsingName(sFileName, IntPtr.Zero, GETPROPERTYSTOREFLAGS.GPS_READWRITE, GetType(IPropertyStore).GUID, pPropertyStore)
If hr = HRESULT.S_OK Then
Dim pv As PROPVARIANT = New PROPVARIANT()
hr = pPropertyStore.GetValue(PKEY_Title, pv)
Dim sTitle As String = Marshal.PtrToStringUni(pv.pwszVal)
Console.WriteLine("Original Title : {0}", sTitle)
Dim pvNew As PROPVARIANT = New PROPVARIANT()
pvNew.varType = CUShort(VT.VT_LPWSTR)
pvNew.pwszVal = Marshal.StringToHGlobalUni(sNewTitle)
hr = pPropertyStore.SetValue(PKEY_Title, pvNew)
hr = pPropertyStore.Commit()
Marshal.ReleaseComObject(pPropertyStore)
End If
with declarations :
Public Enum HRESULT As Integer
S_OK = 0
S_FALSE = 1
E_NOINTERFACE = &H80004002
E_NOTIMPL = &H80004001
E_FAIL = &H80004005
E_UNEXPECTED = &H8000FFFF
E_OUTOFMEMORY = &H8007000E
End Enum
<DllImport("Shell32.dll", SetLastError:=True, CharSet:=CharSet.Unicode)>
Public Shared Function SHGetPropertyStoreFromParsingName(pszPath As String, pbc As IntPtr, flags As GETPROPERTYSTOREFLAGS,
ByRef iid As Guid, <[Out](), MarshalAs(UnmanagedType.Interface)> ByRef propertyStore As IPropertyStore) As HRESULT
End Function
Public Enum GETPROPERTYSTOREFLAGS
GPS_DEFAULT = 0
GPS_HANDLERPROPERTIESONLY = &H1
GPS_READWRITE = &H2
GPS_TEMPORARY = &H4
GPS_FASTPROPERTIESONLY = &H8
GPS_OPENSLOWITEM = &H10
GPS_DELAYCREATION = &H20
GPS_BESTEFFORT = &H40
GPS_NO_OPLOCK = &H80
GPS_PREFERQUERYPROPERTIES = &H100
GPS_EXTRINSICPROPERTIES = &H200
GPS_EXTRINSICPROPERTIESONLY = &H400
GPS_VOLATILEPROPERTIES = &H800
GPS_VOLATILEPROPERTIESONLY = &H1000
GPS_MASK_VALID = &H1FFF
End Enum
<ComImport, Guid("886D8EEB-8CF2-4446-8D02-CDBA1DBDCF99"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)>
Interface IPropertyStore
Function GetCount(<Out> ByRef propertyCount As UInteger) As HRESULT
Function GetAt(<[In]> propertyIndex As UInteger, <Out, MarshalAs(UnmanagedType.Struct)> ByRef key As PROPERTYKEY) As HRESULT
Function GetValue(<[In], MarshalAs(UnmanagedType.Struct)> ByRef key As PROPERTYKEY, <Out, MarshalAs(UnmanagedType.Struct)> ByRef pv As PROPVARIANT) As HRESULT
Function SetValue(<[In], MarshalAs(UnmanagedType.Struct)> ByRef key As PROPERTYKEY, <[In], MarshalAs(UnmanagedType.Struct)> ByRef pv As PROPVARIANT) As HRESULT
Function Commit() As HRESULT
End Interface
<StructLayout(LayoutKind.Sequential, Pack:=4)>
Public Structure PROPERTYKEY
Private fmtid As Guid
Private pid As Integer
Public ReadOnly Property FormatId As Guid
Get
Return Me.fmtid
End Get
End Property
Public ReadOnly Property PropertyId As Integer
Get
Return Me.pid
End Get
End Property
Public Sub New(formatId As Guid, propertyId As Integer)
Me.fmtid = formatId
Me.pid = propertyId
End Sub
End Structure
<StructLayout(LayoutKind.Sequential)>
Public Structure PROPARRAY
Public cElems As UInteger
Public pElems As IntPtr
End Structure
<StructLayout(LayoutKind.Explicit, Pack:=1)>
Public Structure PROPVARIANT
<FieldOffset(0)>
Public varType As UShort
<FieldOffset(2)>
Public wReserved1 As UShort
<FieldOffset(4)>
Public wReserved2 As UShort
<FieldOffset(6)>
Public wReserved3 As UShort
<FieldOffset(8)>
Public bVal As Byte
<FieldOffset(8)>
Public cVal As SByte
<FieldOffset(8)>
Public uiVal As UShort
<FieldOffset(8)>
Public iVal As Short
<FieldOffset(8)>
Public uintVal As UInt32
<FieldOffset(8)>
Public intVal As Int32
<FieldOffset(8)>
Public ulVal As UInt64
<FieldOffset(8)>
Public lVal As Int64
<FieldOffset(8)>
Public fltVal As Single
<FieldOffset(8)>
Public dblVal As Double
<FieldOffset(8)>
Public boolVal As Short
<FieldOffset(8)>
Public pclsidVal As IntPtr
<FieldOffset(8)>
Public pszVal As IntPtr
<FieldOffset(8)>
Public pwszVal As IntPtr
<FieldOffset(8)>
Public punkVal As IntPtr
<FieldOffset(8)>
Public ca As PROPARRAY
<FieldOffset(8)>
Public filetime As System.Runtime.InteropServices.ComTypes.FILETIME
End Structure
Public Enum VT As Short
VT_EMPTY = 0
VT_NULL = 1
VT_I2 = 2
VT_I4 = 3
VT_R4 = 4
VT_R8 = 5
VT_CY = 6
VT_DATE = 7
VT_BSTR = 8
VT_DISPATCH = 9
VT_ERROR = 10
VT_BOOL = 11
VT_VARIANT = 12
VT_UNKNOWN = 13
VT_DECIMAL = 14
VT_I1 = 16
VT_UI1 = 17
VT_UI2 = 18
VT_UI4 = 19
VT_I8 = 20
VT_UI8 = 21
VT_INT = 22
VT_UINT = 23
VT_VOID = 24
VT_HRESULT = 25
VT_PTR = 26
VT_SAFEARRAY = 27
VT_CARRAY = 28
VT_USERDEFINED = 29
VT_LPSTR = 30
VT_LPWSTR = 31
VT_RECORD = 36
VT_FILETIME = 64
VT_BLOB = 65
VT_STREAM = 66
VT_STORAGE = 67
VT_STREAMED_OBJECT = 68
VT_STORED_OBJECT = 69
VT_BLOB_OBJECT = 70
VT_CF = 71
VT_CLSID = 72
VT_BSTR_BLOB = 4095
VT_VECTOR = 4096
VT_ARRAY = 8192
VT_BYREF = 16384
VT_RESERVED = &H8000S
VT_ILLEGAL = &HFFFFS
VT_ILLEGALMASKED = 4095
VT_TYPEMASK = 4095
End Enum
Public Shared ReadOnly PKEY_Title As PROPERTYKEY = New PROPERTYKEY(New Guid("F29F85E0-4FF9-1068-AB91-08002B27B3D9"), 2)