title: Programmatically adding a directory to Windows PATH environment variable
body: <p>I'm writing a Win32 DLL with a function that adds a directory to the Windows PATH environment variable (to be used in an installer).</p>
  
  <p>Looking at the environment variables in Regedit or the Control Panel after the DLL has run shows me that my DLL has succeeded in adding the path to <code>HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment</code> and <code>HKEY_CURRENT_USER\Environment</code>.</p>
  
  <p>But when I start up a new Command Prompt (after running the DLL), the directory I added does not show up in the output of <code>echo %PATH%</code> and I can not access the executable that lives in that directory by typing its name.</p>
  
  <p>I think my program is not doing a good job of notifying the system that the PATH has changed, or maybe it is notifying them before the change has fully taken effect.  I read an <a href="http://support.microsoft.com/kb/104011" rel="noreferrer">article by Microsoft</a> that says to broadcast the <code>WM_SETTINGCHANGE</code> message after changing an environment variable, and I am doing that with this code:</p>
  
  <pre><code>DWORD result2 = 0;
  LRESULT result = SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0,
      (LPARAM)"Environment", SMTO_ABORTIFHUNG, 5000, &amp;result2);
  if (result == 0){ /* ... Display error message to user ... */ }
  </code></pre>
  
  <p>The order of my calls is: <code>RegCreateKeyEx</code>, <code>RegSetValueEx</code>, <code>RegCloseKey</code>, <code>SendMessageTimeout</code></p>
  
  <p>If I press "OK" in the Control Panel "Environment Variables" window,  the changes made by my DLL to the PATH show up in newly-created command prompts, so there is something that the Control Panel is doing to propagate PATH changes; I want to figure out what it is and do the same thing.</p>
  
  <p>Does anyone know what I should do?</p>
  
  <p>I'm running 64-bit Windows Vista but I want this to work on all Windows XP, Vista and Windows 7 operating systems.</p>
  
  <p><strong>Update:</strong>  The problem with the code I posted above is that I did not put the L prefix on the "Environment" string.  Although it does not say it explicitly anywhere in the Microsoft documentation that I can find, the LPARAM needs to be a pointer to a WCHAR string (2-byte characters) as opposed to a CHAR string, which is what Visual Studio's compiler generates by default when I write a string literal.  The solution to my problem was to change "Environment" to L"Environment".  (I thought I already tried that before posting this question, but apparently I didn't try it correctly!)  But anyone who wants a complete C++ solution for this task should look at Dan Moulding's answer.</p>