{"id":45054,"date":"2015-05-22T07:00:00","date_gmt":"2015-05-22T21:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2015\/05\/22\/so-you-decided-to-call-shfileoperation-from-a-service-at-least-remember-to-disable-copy-hooks\/"},"modified":"2019-03-13T12:15:38","modified_gmt":"2019-03-13T19:15:38","slug":"20150522-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20150522-00\/?p=45054","title":{"rendered":"So you decided to call SHFileOperation from a service, at least remember to disable copy hooks"},"content":{"rendered":"<p>I noted some time ago that <a HREF=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2013\/12\/06\/10474322.aspx\">it is highly inadvisable to call <code>SHFile&shy;Operation<\/code> from a service<\/a>, and then I thought about it some more and concluded, <a HREF=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2014\/11\/21\/10574758.aspx\">it&#8217;s flat-out wrong, at least in the case where you call it while impersonating<\/a>. <\/p>\n<p>Now, I&#8217;m sure that my opinion won&#8217;t dissuade many of you, but if you decide to do it anyway, at least disable shell copy hooks by passing the <code>FOFX_NO&shy;COPY&shy;HOOKS<\/code> flag to <a HREF=\"http:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/bb775799(v=vs.85).aspx\"><code>IFile&shy;Operation::Set&shy;Operation&shy;Flags<\/code><\/a>. (We&#8217;ve <a HREF=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2014\/08\/21\/10551659.aspx\">met this flag before<\/a>.) <\/p>\n<p>By default, shell copy hooks are active during shell file operations, and this creates a number of problems when called from a service. <\/p>\n<p>First of all, those copy hooks are unlikely to be designed to handle being run in a service. (When you write your own shell extension, <a HREF=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2011\/09\/28\/10217445.aspx\">do you make sure it also works when run in a service<\/a>?) They&#8217;re probably going to try to log the file activity, possibly to a back-end service, or maybe check with a back-end service whether this file copy should be allowed, and if not, they&#8217;re probably going to display a dialog box saying &#8220;The file cannot be moved\/copied\/deleted <strike>because I&#8217;m a mean person who hates you<\/strike> due to restrictions imposed by your administrator.&#8221; (Or worse, they may secretly copy the file to an undisclosed location before allowing the operation through.) <\/p>\n<p>Second of all, you probably don&#8217;t want those copy hooks intefering with your file operation, whatever it is. Your service is trying to clean up files, or it&#8217;s moving files around for its own internal purposes, and if a copy hook showed up and blocked the operation, your service is now in a weird inconsistent state. <\/p>\n<p>Note that I still consider <code>SHFile&shy;Operation<\/code> inadvisable from a service. I&#8217;m just trying to stop you from digging your hole any deeper than it already is. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>Mitigating the disaster.<\/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-45054","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>Mitigating the disaster.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/45054","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=45054"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/45054\/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=45054"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=45054"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=45054"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}