title: C++ Windows Executable is targeted to Win7 using _WIN32_WINNT but resulting exe imports incorrect API Set Dlls
body: <p>I'm developing a c++ desktop application that needs to support Windows 7+. Testing on a Windows Server 2012 The binary produced is failing with not being able to find an apiset dll, specifically api-ms-win-core-processthreads-l1-1-2.dll. On other OS's it may be a different dll.</p>
  <ol>
  <li>targetver.h header is set with the appropriate preprocessor directive _WIN32_WINNT 0x0601 before including SDKDDKVer.h. I include targetver.h first in stdafx.h as it is standard in Visual Studio 2019 standard template. I'm using precompiled headers and Windows SDK version 8.1. The Platform Toolset is set to v141 but I'm using Visual Studio 2019 IDE. v141 is used for compatibility with Amazon AWS nuget packages.</li>
  </ol>
  <pre><code>#pragma once
  
  // Including SDKDDKVer.h defines the highest available Windows platform.
  
  // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
  // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
  
  #include &lt;Winsdkver.h&gt;
  
  #define _WIN32_WINNT 0x0601
  
  #include &lt;SDKDDKVer.h&gt;
  </code></pre>
  <ol start="2">
  <li>Running dumpbin /imports on the executable I clearly see it importing:</li>
  </ol>
  <pre><code>    api-ms-win-core-processthreads-l1-1-2.dll
               141189280 Import Address Table
               14118AEC8 Import Name Table
                       0 time date stamp
                       0 Index of first forwarder reference
  
                            23 GetThreadPriority
                            25 GetThreadTimes
                             C GetCurrentProcessId
                            1A GetProcessTimes
                            31 ResumeThread
                             8 ExitThread
                            29 OpenProcess
                            13 GetExitCodeThread
                            3B SetThreadPriority
                            43 TlsAlloc
                            45 TlsGetValue
                            46 TlsSetValue
                            44 TlsFree
                            10 GetCurrentThreadId
                             F GetCurrentThread
                             B GetCurrentProcess
                             5 CreateThread
                             7 ExitProcess
                            41 TerminateProcess
                            28 IsProcessorFeaturePresent
                            40 SwitchToThread
                            1C GetStartupInfoW
  </code></pre>
  <ol start="3">
  <li>This executable uses boost headers and I include them before including Windows.h but after targetver.h in the stdafx.h header. This is because the boost headers appear to need to be placed first from other searches.</li>
  </ol>
  <pre><code>#pragma once
  
  #include &quot;targetver.h&quot;
  struct IUnknown; // needed for earlier version of Windows
  
  
  #include &lt;boost/asio/ip/address.hpp&gt;
  #include &lt;boost/interprocess/ipc/message_queue.hpp&gt;
  #include &lt;boost/archive/text_iarchive.hpp&gt;
  #include &lt;boost/algorithm/string.hpp&gt;
  #include &lt;boost/lexical_cast.hpp&gt;
  #include &lt;boost/program_options.hpp&gt;
  
  #define _WINSOCKAPI_
  #define WIN32_LEAN_AND_MEAN
  #include &lt;Windows.h&gt;
  </code></pre>
  <ol start="4">
  <li>I also define BOOST_USE_WINDOWS_H as a preprocessor definition in the solution properties. I've tried with and without this definition.</li>
  <li>I verified _WIN32_WINNT is being set properly after all the boost includes with the statement in an entrypoint cpp file.</li>
  </ol>
  <pre><code>#if _WIN32_WINNT == 0x0601
  #pragma message(&quot;_WIN32_WINNT is set correctly&quot;)
  #else
  #pragma message(&quot;ERROR: _WIN32_WINNT is not set correctly&quot;)
  #endif
  </code></pre>
  <ol start="6">
  <li><p>I have another binary as part of this project that is set up the same way that works correctly on earlier OS's and there's no imports of apiset 'win-core' dlls. However, it does not use boost interprocess nor boost asio address.</p>
  </li>
  <li><p>The program is statically linked with '/MT' and the nuget packages for AWS is set to static.</p>
  </li>
  <li><p>I believe all my Windows API calls should be compatible with Win7+.</p>
  </li>
  </ol>
  <p>Questions:</p>
  <ul>
  <li>Any solutions to debug or try to get this executable to work on the target system?</li>
  <li>With _WIN32_WINNT macro set to 0x0601 and the 8.1 SDK, shouldn't the compiler error on an API calls not available for the target system?</li>
  <li>Because it fails on different apiset dlls, I'm trying not to concentrate on processthreads. However, looking at the processthreadsapi.h file, I can see where there's the following gets set; however, I don't know what sets _APISET_PROCESSTHREADS_VER in the Windows headers. Is there any other preprocessor definitions I need to set or check to get the appropriate apiset?</li>
  </ul>
  <pre><code>#ifndef _APISET_PROCESSTHREADS_VER
  #ifdef _APISET_MINWIN_VERSION
  #if _APISET_MINWIN_VERSION &gt;= 0x0102
  #define _APISET_PROCESSTHREADS_VER 0x0102
  #elif _APISET_MINWIN_VERSION == 0x0101
  #define _APISET_PROCESSTHREADS_VER 0x0101
  #elif _APISET_MINWIN_VERSION == 0x0100
  #define _APISET_PROCESSTHREADS_VER 0x0100
  #endif
  #endif
  #endif
  </code></pre>
  <ul>
  <li>Is there a way to force the compiler not to use the apisets? The executable that works, still calls API calls like OpenProcess but it does not require: api-ms-win-core-processthreads-l1-1-2.dll.</li>
  </ul>