嘗試將現有的32位應用程序轉換爲64位時,我遇到了一些麻煩,使一些COM Interop代碼正常工作。代碼訪問結構化存儲API,使用從各種Windows SDK頭/ IDL文件翻譯的託管代碼。Windows結構化存儲 - 32位與64位COM互操作
當我嘗試撥打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.
SizeConst = 0肯定是不正確的,這需要SizeParamIndex。 PropertySpec.name在64位模式下有錯誤的偏移量,它是8。用C++/CLI編寫這段代碼的好理由。 –
這就是ShellAPI的PROPSPEC結構,我只是用了更友好的名字。根據MSDN的說法,「kind」(ulKind)是一種ULONG,它在32位和64位都是相同的大小;和「propertyId」(propid)和「name」(lpwstr)是一個聯合,所以它們都應該從4開始。我在那裏弄錯了嗎? –
(此外,在SizeConst好抓,說不上怎麼我錯過了,但它似乎沒有任何區別...) –