IEnumIDList.Next メソッドで取得した pidl を保持するコードを紹介します。
概要
IEnumIDList.Next メソッドで取得した pidlを保存する場合は、代入では保存できません。これは、IEnumIDList.Next で取得されたpidlはCoTaskMemFree() (C#の場合はMarshal.FreeCoTaskMem())により解放されてしまうためです。
代入している場合は、CoTaskMemFree()呼び出し後は実体が解放されるため、メモリアクセスエラーになります。
pidlを保持する場合は、pidlを複製する必要があります。IEnumIDList.Next で取得されるPIDLは相対PIDLのため、複製には、ILClone() APIを利用します。もしくは、ILCombine APIで第一引数にNULLを与える方法でも動作します。
補足:絶対 PIDLを複製する場合
絶対PIDLを複製する場合は、ILCloneFull APIを利用します。または、ILCombine APIで第二引数にNULLを与える方法でも動作します。
コード例
WindowsAPI.IEnumIDList pEnum = null;
WindowsAPI.SHCONTF flags = WindowsAPI.SHCONTF.SHCONTF_FOLDERS | WindowsAPI.SHCONTF.SHCONTF_NONFOLDERS | WindowsAPI.SHCONTF.SHCONTF_INCLUDEHIDDEN;
uint hRes = ShellFolder.EnumObjects(IntPtr.Zero, flags, out pEnum);
if (hRes != 0) Marshal.ThrowExceptionForHR((int)hRes);
IntPtr[] pIDL = new IntPtr[1];//IntPtr.Zero;
Int32 iGot = 0;
// Grab the first enumeration.
pEnum.Next(1, pIDL, out iGot);
// Then continue with all the rest.
while (!pIDL.Equals(IntPtr.Zero) && iGot == 1) {
// Free the PIDL and reset counters.
Marshal.FreeCoTaskMem(pIDL[0]);
//SavePidl
pidl_store = WindowsAPI.ILClone(pIDL[0]);
//pIDL = null;// IntPtr.Zero;
iGot = 0;
// Grab the next item.
pEnum.Next(1, pIDL, out iGot);
}
// Free the interface pointer.
if (pEnum != null) Marshal.ReleaseComObject(pEnum);
著者
iPentecのメインプログラマー
C#, ASP.NET の開発がメイン、少し前まではDelphiを愛用
最終更新日: 2024-01-07
作成日: 2015-06-12