title: Determine which network adapter a process is using
body: <p>I've seen several similar questions on Google, but nothing exactly matches what I'm trying to do. I'm making a lag-reducing program (for a game) that basically lowers the user's MTU when a certain process is open, and restores it when the process is closed. However, MTU is a network-adapter specific setting, and some users have multiple connected network adapters. To this end, I thought it'd be nice to have the program also detect which adapter is being used by the game, and only change the MTU on that adapter.</p>
  
  <p>The game will only use <em>one</em> adapter at a time.</p>
  
  <p>I can't hardcode in end-server-IP addresses because they change fairly frequently. It seems to be there <strong>must</strong> be a way to determine which adapter the other process is using without knowing the end IP address, but I can't seem to find it.</p>
  
  <p><strong>EDIT</strong>:
  Thanks to Cicada and Remco, I've solved the problem.</p>
  
  <p>I used the ManagedIPHelper class that Remco linked to (<a href="http://www.timvw.be/2007/09/09/build-your-own-netstatexe-with-c/" rel="nofollow noreferrer">ManagedIpHelper</a>) and Cicada's comments led me to this article (<a href="https://stackoverflow.com/questions/359596/identifying-active-network-interface-in-net">Identifying active network interface</a>)</p>
  
  <p>Combining those with some (Nasty, horribly unoptimized) LINQ, I got this code snippet, which takes the process name and returns the Network Interface it's using, or null if it can't find one.</p>
  
  <pre><code>    private NetworkInterface getAdapterUsedByProcess(string pName)
      {
          Process[] candidates = Process.GetProcessesByName(pName);
          if (candidates.Length == 0)
              throw new Exception("Cannot find any running processes with the name " + pName + ".exe");
  
          IPAddress localAddr = null;
          using (Process p = candidates[0])
          {
              TcpTable table = ManagedIpHelper.GetExtendedTcpTable(true);
              foreach (TcpRow r in table)
                  if (r.ProcessId == p.Id)
                  {
                      localAddr = r.LocalEndPoint.Address;
                      break;
                  }
          }
  
          if (localAddr == null)
              throw new Exception("No routing information for " + pName + ".exe found.");
  
          foreach (NetworkInterface nic in NetworkInterface.GetAllNetworkInterfaces())
          {
              IPInterfaceProperties ipProps = nic.GetIPProperties();
              if (ipProps.UnicastAddresses.Any(new Func&lt;UnicastIPAddressInformation, bool&gt;((u) =&gt; { return u.Address.ToString() == localAddr.ToString(); })))
                  return nic;
          }
          return null;
      }
  </code></pre>
  
  <p>Testing confirms this works <em>perfectly</em>! Many thanks, guys!</p>
  
  <p><em>Side notes to anyone using this snippet:</em></p>
  
  <ul>
  <li>You'll need the ManagedIpHelper classes.</li>
  <li>Your app may need to request elevation, depending on the situation.</li>
  <li>Multiple running processes (think Chrome) will return an undefined result. If you're going to use this code with a multpile-process-candiate situation, I <em>highly</em> recommend you change  <strong>using (Process p = candidates[0])</strong> to a more specific filter, ie based on PID.</li>
  <li>You may also want to impliment new exception types, so you can, for example, catch "No routing info" more cleanly, the reason being that this error is often fixed by simply waiting a bit (to let the target process open a connection) and then retrying.</li>
  </ul>