question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

IFolderView.SelectAndPositionItems -> MarshalDirectiveException

See original GitHub issue

Describe the bug

Vanara.PInvoke.Shell32.IFolderView (SelectAndPositionItems) Vanara.PInvoke.Shell32.IFolderView2 (SelectAndPositionItems)

System.Runtime.InteropServices.MarshalDirectiveException : ‘Cannot marshal ‘parameter 2’: Invalid managed/unmanaged type combination (Arrays of SafeHandles are not supported).’

What code is involved

...
PIDL[] pIDLs = { pidlsub };
Point[] points = { pt };

FolderView.SelectAndPositionItems(1, pIDLs, points, SVSIF.SVSI_POSITIONITEM);

Expected behavior No MarshalDirectiveException

Note pidlsub is valid, and work well with other PIDL related function. He is from IEnumIdList.Next

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:7 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
dahallcommented, Dec 13, 2019

Thanks for testing my committed code. Glad it works for you. On you second post, I’m not sure what you are freeing with Marshal.FreeCoTaskMem(pidlSub); Using the implicit conversion from IntPtr to PIDL on the second line, you are telling PIDL to own the pointer and the allocated memory behind it. Calling Dispose on it frees all the memory allocated by the call to IStream_ReadPidl. Below is how I would have written the loop:

while (IStream_ReadPidl(stream, out IntPtr ppidlOut).Succeeded)
{
   using (PIDL pIDL = ppidlOut)
   {
      Point pt;
      byte[] ptByte = new byte[155];
      stream.Read(ptByte, ptByte.Length, IntPtr.Zero);

      BinaryFormatter bf = new BinaryFormatter();
      using (MemoryStream ms = new MemoryStream(ptByte))
      {
         object obj = (Point)bf.Deserialize(ms);
         ms.Position = 0;
         pt = (Point)obj;
      }

      ((NativeMethods.IFolderView)FolderView1).SelectAndPositionItems(1, new[] { ppidlOut }, new[] { pt }, SVSIF.SVSI_POSITIONITEM);
   }
}
0reactions
Sherulezcommented, Dec 13, 2019

Using the implicit conversion from IntPtr to PIDL on the second line, you are telling PIDL to own the pointer and the allocated memory behind it.

That’s what I thought but I was not sure, thank you for clarifying things.

using (PIDL pIDL = ppidlOut)

Ho I see, you are using using, this way pIDL will Dipose() itself.

Thank you for the code cleanup 😃

Read more comments on GitHub >

github_iconTop Results From Across the Web

IFolderView::SelectAndPositionItems (shobjidl_core.h)
Allows the selection and positioning of items visible in the folder's view.
Read more >
IFolderView (shobjidl_core.h) - Win32 apps
IFolderView ::SelectAndPositionItems. Allows the selection and positioning of items visible in the folder's view. IFolderView::SelectItem
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found