在尝试将现有的 32 位应用程序转换为 64 位时,我在让一些 COM 互操作代码正常工作时遇到了麻烦。该代码使用我从各种 Windows SDK 标头/IDL 文件翻译的托管代码访问结构化存储 API。
当我尝试调用IPropertyStorage.ReadMultiple()
,时代码失败STG_E_INVALIDPARAMETER
。之前的互操作调用StgOpenStorageEx
和IPropertySetStorage.Open
似乎工作正常。MSDN 声称此错误意味着我的 PROPSPEC 参数有问题,但相同的参数值在编译为 32 位应用程序时可以正常工作,并且我返回的值是指定属性的正确字符串值。
以下是我认为相关的部分:
// PropertySpecKind enumeration.
public enum PropertySpecKind : uint
{
Lpwstr = 0,
PropId = 1
}
// PropertySpec structure:
[StructLayout(LayoutKind.Explicit)]
public struct PropertySpec
{
[FieldOffset(0)] public PropertySpecKind kind;
[FieldOffset(4)] public uint propertyId;
[FieldOffset(4)] public IntPtr name;
}
// PropertyVariant Structure:
[StructLayout(LayoutKind.Explicit)]
public struct PropertyVariant
{
[FieldOffset(0)] public Vartype vt;
[FieldOffset(8)] public IntPtr pointerValue;
}
// IPropertyStorage interface
[ComImport]
[Guid("00000138-0000-0000-C000-000000000046")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IPropertyStorage
{
int ReadMultiple(
uint count,
[MarshalAs(UnmanagedType.LPArray, SizeConst = 0)] PropertySpec[] properties,
[Out, MarshalAs(UnmanagedType.LPArray, SizeConst = 0)] PropertyVariant[] values);
void WriteMultiple(
uint count,
[MarshalAs(UnmanagedType.LPArray, SizeConst = 0)] PropertySpec[] properties,
[MarshalAs(UnmanagedType.LPArray, SizeConst = 0)] PropertyVariant[] values,
uint miniumumPropertyId);
}
var properties = new PropertySpec[1];
properties[0].kind = PropertySpecKind.PropId;
properties[0].propertyId = 2;
var propertyValues = new PropertyVariant[1];
// This helper method just calls StgOpenStorageEx with appropriate parameters.
var propertySetStorage = StorageHelper.GetPropertySetStorageReadOnly(fileName);
var propertyStorage = propertySetStorage.Open(StoragePropertySets.PSGUID_SummaryInformation, StorageMode.Read | StorageMode.ShareExclusive);
propertyStorage.ReadMultiple(1, properties, propertyValues); // Exception is here.