Is this the right group for this?
From: smith (rcsTAKEOUT_at_smithvoiceTAKEOUT.com)
Date: 03/20/04
- Next message: smith: "Re: Is this the right group for this?"
- Previous message: Galan Bridgman [MVP-Digital Media]: "Re: starttime - endtime, help me!"
- Next in thread: smith: "Re: Is this the right group for this?"
- Reply: smith: "Re: Is this the right group for this?"
- Reply: smith: "ah well, whim of the languages"
- Messages sorted by: [ date ] [ thread ]
Date: Sat, 20 Mar 2004 20:01:22 GMT
Maybe this question could go to a .net api group but I know that you folks
here in the Windows Media SDK group would better understand the reason
behind the code so...
Looking for assistance in a port of one of the functions in the Managed
WMFormat Metadata C# code to vb.net.
I have the ShowAttributes working fine and that was the one I thought would
be the pain. But no matter how I slice it I keep getting "invalid
parameter" returned from AddAttribute.
I have C# and VB.net open side by side and every single parameter debugs
*exactly* the same at the byte level but the call fails.
Please no snobby C# vs VB non-answers. We need it working in VB.net because
we don't feel like including a C# dll in the distribution of this VB.net app
just for this one function and it's not opur fault that Microsoft has
decided not to get their WMFormat SDK act together for the majority of
developers who buy their language tools.
Anyone has a clue why the VB.net code that appears to do the same thing in
the same way with the same values fails?
Thanks, if you can figure it out.
-Robert Smith
Kirkland WA
First: C# and ported VB.net declarations:
C#:
using System;
using System.Runtime.InteropServices;
public class WMFSDKFunctions
{
[DllImport("WMVCore.dll", EntryPoint="WMCreateEditor", SetLastError=true,
CharSet=CharSet.Unicode, ExactSpelling=true,
CallingConvention=CallingConvention.StdCall)]
public static extern uint WMCreateEditor(
[Out, MarshalAs(UnmanagedType.Interface)]out IWMMetadataEditor
ppMetadataEditor );
[Guid("96406BD9-2B2B-11d3-B36B-00C04F6108FF"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IWMMetadataEditor
{
uint Open( [In,MarshalAs(UnmanagedType.LPWStr)] string pwszFilename );
uint Close();
uint Flush();
}
[Guid("15CC68E3-27CC-4ecd-B222-3F5D02D80BD5"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IWMHeaderInfo3
{
uint GetAttributeCount(
[In] ushort wStreamNum,
[Out] out ushort pcAttributes );
uint GetAttributeByIndex(
[In] ushort wIndex,
[Out,In] ref ushort pwStreamNum,
[Out, MarshalAs(UnmanagedType.LPWStr)] string pwszName,
[Out,In] ref ushort pcchNameLen,
[Out] out WMT_ATTR_DATATYPE pType,
[Out, MarshalAs(UnmanagedType.LPArray)] byte[] pValue,
[Out,In] ref ushort pcbLength );
}
}
public enum WMT_ATTR_DATATYPE
{
WMT_TYPE_DWORD = 0,
WMT_TYPE_STRING = 1,
WMT_TYPE_BINARY = 2,
WMT_TYPE_BOOL = 3,
WMT_TYPE_QWORD = 4,
WMT_TYPE_WORD = 5,
WMT_TYPE_GUID = 6,
}
}
VB.net:
Imports System
Imports System.Runtime.InteropServices
Public Class WMFFunctions
Public Declare Auto Function WMCreateEditor Lib "WMVCore.dll" Alias
"WMCreateEditor" _
(ByRef ppMetadataEditor As IWMMetadataEditor) As UInt32
<Guid("96406BD9-2B2B-11d3-B36B-00C04F6108FF"), _
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)> _
Public Interface IWMMetadataEditor
Function Open(ByVal pwszFilename As String) As UInt32
Function Close() As UInt32
Function Flush() As UInt32
End Interface
<Guid("15CC68E3-27CC-4ecd-B222-3F5D02D80BD5"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)> _
Public Interface IWMHeaderInfo3
Function GetAttributeCount(ByVal wStreamNum As UInt16, _
ByRef pcAttributes As UInt16) As UInt32
Function GetAttributeByIndex(ByVal wIndex As UInt16, _
ByRef pwStreamNum As UInt16, _
<MarshalAs(UnmanagedType.LPWStr)> ByVal pwszName As String, _
ByRef pcchNameLen As UInt16, _
ByRef pType As WMT_ATTR_DATATYPE, _
<MarshalAs(UnmanagedType.LPArray)> ByVal pValue As Byte(), _
ByRef pcbLength As UInt16) As UInt32
end interface
Public Enum WMT_ATTR_DATATYPE
WMT_TYPE_DWORD = 0
WMT_TYPE_STRING = 1
WMT_TYPE_BINARY = 2
WMT_TYPE_BOOL = 3
WMT_TYPE_QWORD = 4
WMT_TYPE_WORD = 5
WMT_TYPE_GUID = 6
End Enum
End Class
Working Methods:
C#:
bool ShowAttributes3( string pwszFileName, ushort wStreamNum )
{
try
{
IWMMetadataEditor MetadataEditor;
IWMHeaderInfo3 HeaderInfo3;
ushort wAttributeCount = 0;
WMFSDKFunctions.WMCreateEditor( out MetadataEditor );
MetadataEditor.Open( pwszFileName ) ;
HeaderInfo3 = ( IWMHeaderInfo3 )MetadataEditor;
HeaderInfo3.GetAttributeCountEx( wStreamNum, out wAttributeCount );
for( ushort wAttribIndex = 0; wAttribIndex < wAttributeCount;
wAttribIndex++)
{
WMT_ATTR_DATATYPE wAttribType;
ushort wLangIndex = 0;
string pwszAttribName = null;
byte[] pbAttribValue = null;
ushort wAttribNameLen = 0;
uint dwAttribValueLen = 0;
HeaderInfo3.GetAttributeByIndexEx( wStreamNum,
wAttribIndex,
pwszAttribName,
ref wAttribNameLen,
out wAttribType,
out wLangIndex,
pbAttribValue,
ref dwAttribValueLen);
pwszAttribName = new String( ( char )0, wAttribNameLen );
pbAttribValue = new byte[ dwAttribValueLen ];
HeaderInfo3.GetAttributeByIndexEx( wStreamNum,
wAttribIndex,
pwszAttribName,
ref wAttribNameLen,
out wAttribType,
out wLangIndex,
pbAttribValue,
ref dwAttribValueLen );
//The following just prints to console ... works fine
//PrintAttribute( wAttribIndex, wStreamNum,
pwszAttribName, wAttribType, 0, pbAttribValue,
dwAttribValueLen );
}
}
catch( Exception e )
{
Console.WriteLine( e.Message );
return( false );
}
return( true );
}
VB.Net version:
Public Function ReadAttributes(ByVal pwszFileName As String, ByVal
wStreamNum As Integer) As Boolean
Dim MetadataEditor As WMFFunctions.IWMMetadataEditor
Dim HeaderInfo3 As IWMHeaderInfo3
Dim wAttributeCount As UInt16
Try
WMFFunctions.WMCreateEditor(MetadataEditor)
MetadataEditor.Open(pwszFileName)
HeaderInfo3 = MetadataEditor
HeaderInfo3.GetAttributeCount(Convert.ToUInt16(wStreamNum),
wAttributeCount)
For wAttribIndex As Integer = 0 To
Convert.ToInt16(wAttributeCount) - 1
Dim wAttribType As WMT_ATTR_DATATYPE
Dim pwszAttribName As String = Nothing
Dim pbAttribValue As Byte() = Nothing
Dim wAttribNameLen As UInt16
Dim wAttribValueLen As UInt16
'get the attribute "filler" information
HeaderInfo3.GetAttributeByIndex(Convert.ToUInt16(wAttribIndex), _
Convert.ToUInt16(wStreamNum), _
pwszAttribName, _
wAttribNameLen, _
wAttribType, _
pbAttribValue, _
wAttribValueLen)
Dim arAttribTemp As Byte()
ReDim arAttribTemp(Convert.ToInt16(wAttribValueLen))
pbAttribValue = arAttribTemp
pwszAttribName = New String("0",
Convert.ToInt16(wAttribNameLen))
'now get the actual values
HeaderInfo3.GetAttributeByIndex(Convert.ToUInt16(wAttribIndex), _
Convert.ToUInt16(wStreamNum), _
pwszAttribName, _
Convert.ToUInt16(wAttribNameLen), _
wAttribType, _
pbAttribValue, _
Convert.ToUInt16(wAttribValueLen))
Dim MyVal As String = ""
'for our needs, just convert all to strings
Select Case wAttribType
Case WMT_ATTR_DATATYPE.WMT_TYPE_STRING
MyVal = bytearraytostring(pbAttribValue)
Case WMT_ATTR_DATATYPE.WMT_TYPE_BOOL
If BitConverter.ToBoolean(pbAttribValue, 0) Then
MyVal = "True"
Else
MyVal = "False"
End If
Case WMT_ATTR_DATATYPE.WMT_TYPE_DWORD
Dim dwValue As UInt32 =
BitConverter.ToUInt32(pbAttribValue, 0)
MyVal = dwValue.ToString()
Case WMT_ATTR_DATATYPE.WMT_TYPE_QWORD
Dim qwValue As UInt64 =
BitConverter.ToUInt64(pbAttribValue, 0)
MyVal = qwValue.ToString
Case Else
MyVal = "nadda" 'ok for me
End Select
Dim Attributename As String = pwszAttribName.Substring(0,
pwszAttribName.Length - 1)
'the following just sticks the values in the right
variables, works fine
PutPropertyValue(Attributename, MyVal)
Next
Return True
Catch ex As System.Runtime.InteropServices.COMException
Throw ex
Return False
Catch ex As Exception
'Todo: remove after final testing
Throw ex
Return False
Finally
If Not MetadataEditor Is Nothing Then
MetadataEditor.Close()
End If
End Try
End Function
The above work great, and the above calls to GetAttributeByIndex should be
way more involved than the one that sets an attribute.
Here is that code:
C# (works):
bool AddAttrib( string pwszFileName, ushort wStreamNum, string
pwszAttribName,
ushort wAttribType, string pwszAttribValue, ushort
wLangIndex )
{
try
{
IWMMetadataEditor MetadataEditor;
IWMHeaderInfo3 HeaderInfo3;
byte[] pbAttribValue;
int nAttribValueLen;
WMT_ATTR_DATATYPE AttribDataType = ( WMT_ATTR_DATATYPE ) wAttribType;
ushort wAttribIndex = 0;
ushort nValueLength = ( ushort )( ( pwszAttribValue.Length + 1 ) * 2 );
byte[] pbValue = new Byte[ nValueLength ];
char[] c = pwszAttribValue.ToCharArray();
Buffer.BlockCopy(c, 0, pbValue, 0, pwszAttribValue.Length * 2 );
pbValue[ nValueLength - 2 ] = 0;
pbValue[ nValueLength - 1 ] = 0;
WMFSDKFunctions.WMCreateEditor( out MetadataEditor );
MetadataEditor.Open( pwszFileName ) ;
HeaderInfo3 = ( IWMHeaderInfo3 )MetadataEditor;
HeaderInfo3.AddAttribute( wStreamNum,
pwszAttribName,
out wAttribIndex,
AttribDataType,
wLangIndex,
pbValue,
(uint)nValueLength);
MetadataEditor.Flush();
MetadataEditor.Close();
}
catch( Exception e )
{
Console.WriteLine( e.Message );
return( false );
}
return( true );
}
VB.Net port of above Fails at AddAttribute call with Invalid Parameter But
The Parameters Are Exactly The Same:
Public Function AddStringAttrib(ByVal pwszFileName As String, _
ByVal wStreamNum As UInt16, _
ByVal pwszAttribName As String, _
ByVal pwszAttribValue As String, _
ByVal wLangIndex As UInt16) As Boolean
Dim MetadataEditor As WMFFunctions.IWMMetadataEditor
Dim HeaderInfo3 As IWMHeaderInfo3
Try
Dim wAttribIndex As Int16 = 0
'convert the string to the valid array settings:
Dim arTempAttrib As Byte()
ReDim arTempAttrib (((Convert.ToInt16(pwszAttribValue.Length) + 1) *
2) - 1)
Dim nValueLength As Integer = ((pwszAttribValue.Length + 1) * 2)
Dim c As Char() = pwszAttribValue.ToCharArray
Buffer.BlockCopy(pwszAttribValue.ToCharArray, 0, arTempAttrib , 0,
pwszAttribValue.Length * 2)
arTempAttrib (x.Length - 2) = 0
arTempAttrib (x.Length - 1) = 0
WMFFunctions.WMCreateEditor(MetadataEditor)
MetadataEditor.Open(pwszFileName)
HeaderInfo3 = MetadataEditor
'FAILS HERE but debugging shows every Byte the same as the C# version
HeaderInfo3.AddAttribute(Convert.ToUInt16(0), _
pwszAttribName, _
Convert.ToUInt16(wAttribIndex), _
WMT_ATTR_DATATYPE.WMT_TYPE_STRING, _
Convert.ToUInt16(0), _
arTempAttrib, _
Convert.ToUInt16(arTempAttrib.Length))
Return True
Catch e As Exception
MsgBox(e.ToString)
Return False
Finally
if not MetadataEditor Is Nothing then
MetadataEditor.Flush()
MetadataEditor.Close()
end if
End Try
End Function
- Next message: smith: "Re: Is this the right group for this?"
- Previous message: Galan Bridgman [MVP-Digital Media]: "Re: starttime - endtime, help me!"
- Next in thread: smith: "Re: Is this the right group for this?"
- Reply: smith: "Re: Is this the right group for this?"
- Reply: smith: "ah well, whim of the languages"
- Messages sorted by: [ date ] [ thread ]
Relevant Pages
|