{"id":9083,"date":"2011-11-18T07:00:00","date_gmt":"2011-11-18T07:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2011\/11\/18\/why-does-internet-explorer-not-call-dll_process_detach-on-my-dll-when-i-call-exitprocess\/"},"modified":"2011-11-18T07:00:00","modified_gmt":"2011-11-18T07:00:00","slug":"why-does-internet-explorer-not-call-dll_process_detach-on-my-dll-when-i-call-exitprocess","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20111118-00\/?p=9083","title":{"rendered":"Why does Internet Explorer not call DLL_PROCESS_DETACH on my DLL when I call ExitProcess?"},"content":{"rendered":"<p>\nA customer asked a question,\nbut as is often the case,\nthe question was much more telling than the answer.\n<\/p>\n<blockquote CLASS=\"q\"><p>\nWe have an Internet Explorer plug-in which calls\n<code>Exit&shy;Process<\/code>\nto force Internet Explorer to exit.\nWe found that when we do this, our plug-in does not receive a\n<code>DLL_PROCESS_DETACH<\/code> notification.\nWhat could be preventing our plug-in from receiving the\n<code>DLL_PROCESS_DETACH<\/code> notification?\n<\/p><\/blockquote>\n<p>\nAs we saw some time ago when we looked at\n<a HREF=\"http:\/\/blogs.msdn.com\/oldnewthing\/archive\/2007\/05\/03\/2383346.aspx\">\nthe way processes shut down<\/a>\n(plus\n<a HREF=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2010\/01\/22\/9951750.aspx\">\nan important follow-up<\/a>\n<a HREF=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2011\/10\/07\/10221348.aspx\">\nor two<\/a>),\nall a process has to do to thwart proper delivery of\n<code>DLL_PROCESS_DETACH<\/code> notifications is to do something\nuntoward during shutdown, at which point the kernel\n<a HREF=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2008\/05\/06\/8461730.aspx\">\njust gives up and calls <code>Terminate&shy;Process<\/code><\/a>.\n<\/p>\n<p>\nBut like I said, the answer is much less interesting than the question.\nWhat if the user had an unsaved email message at the time you decided\nto exit Internet Explorer?\nRecall that\n<a HREF=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2009\/12\/02\/9931183.aspx\">\nplug-ins are a guest in the host process; don&#8217;t go changing the carpet<\/a>.\nWhen we asked the customer why they were exiting Internet Explorer from\ntheir plug-in, we received the explanation,\n&#8220;The reason I am calling <code>Exit&shy;Process<\/code>\nis that I do not know another good way to exit Internet Explorer\nfrom a plug-in.&#8221;\n<\/p>\n<p>\nIn this case, the guest is doing far more than just changing\nthe carpet.\nThe guest called in a\n<a HREF=\"http:\/\/www.amazon.com\/dp\/B0045HCJGC\/?tag=tholneth-20\">\ndemolition company<\/a>!\n<\/p>\n<p>\n&#8220;Why did you call the demolition company to destroy my house?&#8221;<br \/>\n&#8220;I couldn&#8217;t think of a good way to destroy your house.&#8221;\n<\/p>\n<p>\nThe point isn&#8217;t that it&#8217;s bad to use a telephone call to hire a demolition\ncompany to destroy somebody&#8217;s house and that you should use some other\nmethod to contact them (like, say, a text message).\nThe point is that\n<i>it&#8217;s bad to destroy somebody else&#8217;s house in the first place<\/i>.\n<\/p>\n<p>\nUpon further investigation, the customer was writing a test\nfor their plug-in.\nThey open Internet Explorer and navigate to a page that uses\nthe plug-in.\nWhen they are satisfied that the plug-in operated correctly,\nthey want to exit the copy of Internet Explorer in order to conclude\nthe test.\n<\/p>\n<p>\nIf you want to destroy a house, then destroy your own house.\nCall\n<code>Co&shy;Create&shy;Instance(CLSID_Internet&shy;Explorer)<\/code>\nto build a house,\nnavigate to your test page with\n<code>IWeb&shy;Browser2::Navigate<\/code>,\nand when you&#8217;re done, you can destroy the house with\n<code>IWeb&shy;Browser2::Quit()<\/code>.\n<a HREF=\"http:\/\/msdn.microsoft.com\/library\/aa752127.aspx\">\nThere is sample code to do exactly this in the documentation for\nthe <code>IWeb&shy;Browser2<\/code> interface<\/a>.\n<\/p>\n<p>\n<b>Bonus chatter<\/b>:\nThe <code>IWeb&shy;Browser2<\/code> interface is scriptable.\n<\/p>\n<pre>\nvar ie = new ActiveXObject(\"InternetExplorer.Application\");\nie.Visible = true;\nie.Navigate(\"http:\/\/www.microsoft.com\/\");\nWScript.Sleep(5000); \/\/ five seconds, say\nie.Quit();\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>A customer asked a question, but as is often the case, the question was much more telling than the answer. We have an Internet Explorer plug-in which calls Exit&shy;Process to force Internet Explorer to exit. We found that when we do this, our plug-in does not receive a DLL_PROCESS_DETACH notification. What could be preventing our [&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-9083","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>A customer asked a question, but as is often the case, the question was much more telling than the answer. We have an Internet Explorer plug-in which calls Exit&shy;Process to force Internet Explorer to exit. We found that when we do this, our plug-in does not receive a DLL_PROCESS_DETACH notification. What could be preventing our [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/9083","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=9083"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/9083\/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=9083"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=9083"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=9083"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}