{"id":91461,"date":"2015-10-02T07:00:00","date_gmt":"2015-10-02T21:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/20151002-00\/?p=91461\/"},"modified":"2019-03-13T12:20:12","modified_gmt":"2019-03-13T19:20:12","slug":"20151002-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20151002-00\/?p=91461","title":{"rendered":"Calling ShutdownBlockReasonCreate from my service doesn&#8217;t stop the user from shutting down"},"content":{"rendered":"<p>A customer had a <a HREF=\"http:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/ms685141(v=vs.85).aspx\">service application<\/a> that needs to perform a sequence of operations that cannot be interrupted by a system shutdown. <\/p>\n<blockquote CLASS=\"q\">\n<p>The service starts performing those operations when it starts up, but we found that group policy or other shenanigans can trigger other actions that ultimately lead to a system reboot. We would like to delay the reboot until our service completes its critical sequence of operations. <\/p>\n<p>We created a simple test application that <a HREF=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2012\/06\/14\/10319617.aspx\">calls <code>Shutdown&shy;Block&shy;Reason&shy;Create<\/code><\/a>, and it works. If we try to reboot the computer, the shutdown dialog appears indicating that it is waiting for the test application to complete. <\/p>\n<p>We ported this code into the service, and even though the call succeeds, there is no message shown to the user at reboot, and the reboot proceeds anyway. <\/p>\n<p>Is <code>Shutdown&shy;Block&shy;Reason&shy;Create<\/code> expected to work when called from a service? If so, then what we are doing wrong? If not, what alternative designs are available? <\/p>\n<\/blockquote>\n<p>Shutdown blocks apply only to the session in which they are created. This is sort-of implied by the fact that the <code>Shutdown&shy;Block&shy;Reason&shy;Create<\/code> function is exported from <code>user32.dll<\/code>, and it takes a window handle parameter, and window handles are valid only in the desktop from which they were created. Since the interactive session is session&nbsp;1 and services are in session&nbsp;0, the block request has no effect. (This is just another application of the principle <a HREF=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2011\/10\/01\/10217445.aspx\"><i>Does this work in a service? The default answer is NO<\/i><\/a>.) <\/p>\n<p>Note also that the shutdown block is not a hard block. The user could click &#8220;Shut down anyway&#8221;. Besides, the system assumes &#8220;Shut down anyway&#8221; if the user takes no action within some number of seconds. <\/p>\n<p>Note also that if the system is shut down remotely, there is nobody present to answer the question, and it&#8217;s not clear where to display the message anyway. <\/p>\n<p>The correct way to delay shutdown indefinitely from a service is to set the <code>SERVICE_ACCEPT_PRE&shy;SHUTDOWN<\/code> flag in its service status. This <a HREF=\"http:\/\/msdn.microsoft.com\/en-us\/magazine\/cc164252.aspx\">registers the service for preshutdown notifications<\/a>, at which point it can finish up your critical actions before releasing shutdown to continue. <\/p>\n<p>Note that long shutdown times is one of the major points of end-user frustration, so you should do what you can to wrap things up quickly. Otherwise, you&#8217;re going to be another data point in the &#8220;Windows sucks&#8221; database. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>That&#8217;s not how to do it from a service.<\/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-91461","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>That&#8217;s not how to do it from a service.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/91461","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=91461"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/91461\/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=91461"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=91461"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=91461"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}