我正在实现一个基于C#中的IShellItem/IShellItem2
COM接口的对象模型,目前正在处理项目枚举。我想避免使用BindToHandler
,因为它被认为会对性能产生显着影响,这就是为什么我想使用IParentAndItem
接口及其基础缓存机制。实现IParentAndItem COM接口的正确方法
根据MSDN的IParentAndItem
接口的方法被定义如下:
HRESULT GetParentAndItem(
[out, optional] PIDLIST_ABSOLUTE *ppidlParent,
[out, optional] IShellFolder **ppsf,
[out, optional] PITEMID_CHILD *ppidlChild
);
HRESULT SetParentAndItem(
[in] PCIDLIST_ABSOLUTE pidlParent,
[in] IShellFolder *psf,
[in] PCUITEMID_CHILD pidlChild
);
然而以下翻译成C#COM互界面导致一个AccessViolationException
:
[ComImport,
Guid("B3A4B685-B685-4805-99D9-5DEAD2873236"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IParentAndItem
{
void GetParentAndItem(out IntPtr ppidlParent, out IShellFolder ppsf, out IntPtr ppidlChild);
void SetParentAndItem(IntPtr pidlParent, ref IShellFolder psf, IntPtr pidlChild);
}
我使用接口从IShellItem2
进行投射以使用其GetParentAndItem
方法获得IShellFolder
表示法:
IParentAndItem pni = si as IParentAndItem; // 'si' is the IShellItem2
if(pni != null)
{
IntPtr ppidlParent, ppidlChild;
IShellFolder ppsf;
pni.GetParentAndItem(out ppidlParent, out ppsf, out ppidlChild); // <-- throws AccessViolationException
// Work with ppsf, e.g. EnumObjects
}
UPDATE
的IParentAndItem
正确的声明由汉斯帕桑特指出:
[ComImport,
Guid("B3A4B685-B685-4805-99D9-5DEAD2873236"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IParentAndItem
{
void SetParentAndItem(IntPtr pidlParent, IShellFolder psf, IntPtr pidlChild);
void GetParentAndItem(out IntPtr ppidlParent, out IShellFolder ppsf, out IntPtr ppidlChild);
}
实施IParentAndItem
与GetParentAndItem
更换BindToHandler
我只能说,这是真的值得去这条路线后性能明智。
请确保在完成这些操作后,通过调用Marshal.FreeCoTaskMem
为两个PIDL释放在GetParentAndItem
中分配的内存。
你是对的,只需检查并首先声明SetParentAndItem。不知道这个裁判是从哪里来的,因为它清楚地指出在参数 - 谢谢指出。我也错过了释放分配给2个PIDL的内存。 – atomicode 2015-03-31 19:04:37