{"id":94065,"date":"2016-08-11T07:00:00","date_gmt":"2016-08-11T21:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/?p=94065"},"modified":"2019-03-13T11:05:24","modified_gmt":"2019-03-13T18:05:24","slug":"20160811-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20160811-00\/?p=94065","title":{"rendered":"On the importance of making sure WaitForInputIdle doesn&#8217;t think you&#8217;re idle, episode 1"},"content":{"rendered":"<p>A customer had a program that was originally designed back when DDE ruled the land, and it continues to support DDE for (yup) backward compatibility. <\/p>\n<p>Today and tomorrow are going to deal with DDE issues, but not because DDE is actually anything recommended. Quite the contrary: <a HREF=\"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/20070226-00\/?p=27863\">Please feel free to stop using DDE<\/a>. DDE is so obsolete that when somebody has a DDE question, it usually lands in the lap of some old-timer who starts the answer with &#8220;Kids these days&#8230;&#8221; and ends it with &#8220;I&#8217;m going to write a blog entry about this.&#8221; <\/p>\n<p>Anyway, the customer was making some changes to the program&#8217;s splash screen, and one of the changes broke DDE. &#8220;With my change, launching a file from Explorer displays the dreaded <i>There was a problem sending the command to the program<\/i>. What should I be looking out for?&#8221; <\/p>\n<p><a HREF=\"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/20060621-17\/?p=30793\">Recall that<\/a> launching documents via DDE is done by first looking for a DDE server and if none is found, launching a server manually and trying again. And the retry occurs after the manually-launched server goes input idle; in other words, after the shell launches the server, the shell calls <code>Wait&shy;For&shy;Input&shy;Idle<\/code>, and then when that call returns, the shell goes looking for the DDE server. If it can&#8217;t find the server the second time, you get the <i>There was a problem sending the command to the program<\/i> error. <\/p>\n<p><a HREF=\"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/20100325-00\/?p=14493\">We saw earlier<\/a> that the <code>Wait&shy;For&shy;Input&shy;Idle<\/code> function declares the process idle once any thread is &#8220;waiting for user input with no input pending.&#8221; In the customer&#8217;s case, the issue was not a background thread that went idle, but rather that their main UI thread was performing a <code>Co&shy;Create&shy;Instance<\/code> call to a local server. Cross-process method calls are performed by marshaling the request to the server, then waiting for the server to return a response. And in a single-threaded apartment, COM pumps messages while waiting. <\/p>\n<p>It is that COM message pump that was causing the process to be marked idle. <\/p>\n<p>The customer needs to get the DDE server window created and ready to accept incoming commands before the program does any cross-thread COM operations from a single-threaded apartment. <\/p>\n<p>Okay, that was basically a warm-up. Next time, a different angle on failed DDE startup. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>WaitForInputIdle is how the shell knows that your DDE server.<\/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-94065","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>WaitForInputIdle is how the shell knows that your DDE server.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/94065","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=94065"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/94065\/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=94065"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=94065"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=94065"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}