{"id":6553,"date":"2012-09-20T07:00:00","date_gmt":"2012-09-20T07:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2012\/09\/20\/how-do-i-invoke-a-verb-on-an-ishellitemarray\/"},"modified":"2012-09-20T07:00:00","modified_gmt":"2012-09-20T07:00:00","slug":"how-do-i-invoke-a-verb-on-an-ishellitemarray","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20120920-00\/?p=6553","title":{"rendered":"How do I invoke a verb on an IShellItemArray?"},"content":{"rendered":"<p>\nA customer wanted to invoke a command on multiple items at once.\n<\/p>\n<blockquote class=\"q\">\n<p>\nI have an <code>IShellItemArray<\/code>,\nand I want to invoke a verb with that array as the parameter.\nI know that I can invoke a verb on a single <code>IShellItem<\/code>\nby the code below, but how do I pass an entire array?\n<\/p>\n<pre>\nvoid InvokeVerbOnItem(__in IShellItem *psi,\n                      __in_opt PCWSTR pszVerb)\n{\n PIDLIST_ABSOLUTE pidl;\n HRESULT hr = SHGetIDListFromObject(psi, &amp;pidl);\n if (SUCCEEDED(hr)) {\n  SHELLEXECUTEINFO sei = { sizeof(sei) };\n  sei.fMask = SEE_MASK_UNICODE |\n              SEE_MASK_INVOKEIDLIST |\n              SEE_MASK_IDLIST;\n  sei.lpIDList = pidl;\n  sei.lpVerb = pszVerb;\n  sei.nShow = SW_SHOWNORMAL;\n  ShellExecuteEx(&amp;sei);\n  CoTaskMemFree(pidl);\n }\n}\n<\/pre>\n<\/blockquote>\n<p>\nThe function <code>Invoke&shy;Verb&shy;On&shy;Item<\/code>\ninvokes the command by extracting the pidl,\nthen asking <code>Shell&shy;Execute&shy;Ex<\/code> to invoke\nthe command on the pidl.\nA limitation of <code>Shell&shy;Execute*<\/code> is that\nit can invoke on only one pidl.\nWhat if you want to invoke it on a bunch of pidls at once?\n(Doing it all at once gives the target program the opportunity\nto optimize the multi-target invoke.)\n<\/p>\n<p>\n<a HREF=\"http:\/\/msdn.microsoft.com\/en-us\/library\/bb759784(VS.85).aspx\">\nAs noted in the documentation<\/a>,\npassing\n<code>SEE_MASK_INVOKE&shy;ID&shy;LIST<\/code> flag\ntells the\n<code>Shell&shy;Execute&shy;Ex<\/code>\nto\n&#8220;use the <b>IContextMenu<\/b> interface of the selected item&#8217;s\nshortcut menu handler.&#8221;\n<\/p>\n<p>\nSo if you are frustrated by the limitations of the middle man,\nthen cut out the middle man!\n<\/p>\n<pre>\nvoid InvokeVerbOnItemArray(__in IShellItemArray *psia,\n                           __in_opt PCWSTR pszVerb)\n{\n IContextMenu *pcm;\n HRESULT hr = psia-&gt;BindToHandler(BHID_SFUIObject,\n                                  IID_PPV_ARGS(&amp;pcm));\n if (SUCCEEDED(hr)) {\n  ... <a HREF=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2004\/09\/20\/231739.aspx\">context menu invoke incorporated by reference<\/a> ...\n  pcm-&gt;Release();\n }\n}\n<\/pre>\n<p>\nIf you think about it, the original\n<code>Invoke&shy;Verb&shy;On&shy;Item<\/code>\nfunction could&#8217;ve avoid the middle man too.\nIt converted an <code>IShellItem<\/code>\n(a live object which encapsulates an\n<code>IShell&shy;Folder<\/code> and a child pidl)\ninto an absolute pidl (a dead object),\nwhich then passed it to\n<code>Shell&shy;Execute&shy;Ex<\/code>,\nwhich had to reanimate the object back into an\n<code>IShell&shy;Folder<\/code> and child pidl\nso it could call\n<code>Get&shy;UI&shy;Object&shy;Of<\/code>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A customer wanted to invoke a command on multiple items at once. I have an IShellItemArray, and I want to invoke a verb with that array as the parameter. I know that I can invoke a verb on a single IShellItem by the code below, but how do I pass an entire array? void InvokeVerbOnItem(__in [&hellip;]<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-6553","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>A customer wanted to invoke a command on multiple items at once. I have an IShellItemArray, and I want to invoke a verb with that array as the parameter. I know that I can invoke a verb on a single IShellItem by the code below, but how do I pass an entire array? void InvokeVerbOnItem(__in [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/6553","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=6553"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/6553\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=6553"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=6553"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=6553"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}