title: How to resolve this System.IO.FileNotFoundException
body: <ul>
  <li>The error only happens in production (not in debugging).</li>
  <li>The error only happens on the first application run after Windows login. </li>
  <li>The error occurs when we click BtnUseDesktop and thus fire the BtnUseDesktop_Click event (below).</li>
  <li>The Event Viewer stack starts with the The.Application.Name.Main() method...</li>
  <li>but our code does not have that method (it's a WPF application).</li>
  </ul>
  
  <p><strong>Event Viewer</strong></p>
  
  <pre><code> Application: The.Application.Name.exe
   Framework Version: v4.0.30319
   Description: The process was terminated due to an unhandled exception.
   Exception Info: System.IO.FileNotFoundException
   Stack:
  
     at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(
        System.Object, System.Delegate, System.Object, Int32, System.Delegate)
  
     at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(
        System.Windows.Threading.DispatcherPriority, System.TimeSpan, 
        System.Delegate, System.Object, Int32)
  
     at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr, Int32, IntPtr, IntPtr)
  
     at MS.Win32.UnsafeNativeMethods.DispatchMessage(System.Windows.Interop.MSG ByRef)
  
     at System.Windows.Threading.Dispatcher.PushFrameImpl(
        System.Windows.Threading.DispatcherFrame)
  
     at System.Windows.Threading.Dispatcher.PushFrame(
        System.Windows.Threading.DispatcherFrame)
  
     at System.Windows.Threading.Dispatcher.Run()
  
     at System.Windows.Application.RunDispatcher(System.Object)
  
     at System.Windows.Application.RunInternal(System.Windows.Window)
  
     at System.Windows.Application.Run(System.Windows.Window)
  
     at The.Application.Name.Main()
  </code></pre>
  
  <p><strong>BtnUseDesktop_Click</strong></p>
  
  <pre><code>private void BtnUseDesktop_Click(object sender, RoutedEventArgs e)
  {
      AvSwitcher switcher = new AvSwitcher();
      this.RunAsyncTask(() =&gt; 
          switcher.SwitchToDesktop(this.windowSyncSvc.ActiveLyncWindowHandle));
  }
  </code></pre>
  
  <p><strong>The AvSwitcher that the Click Event Calls Into</strong></p>
  
  <pre><code>public class AvSwitcher
  {
      private DeviceLocationSvc deviceLocationSvc;
      private UIAutomationSvc uiAutomationSvc;
      private WindowMovingSvc windowMovingSvc;
      private ManualResetEvent manualResetEvent;
      private Modality audioVideo;
      public static bool IsSwitching { get; set; }
  
      public AvSwitcher()
      {            
          this.deviceLocationSvc = new DeviceLocationSvc();
          this.uiAutomationSvc = new UIAutomationSvc();
          this.windowMovingSvc = new WindowMovingSvc();
      }
  
      public void SwitchToDesktop(IntPtr activeLyncConvWindowHandle)
      {
          this.BeginHold(DeviceLocation.Desktop, activeLyncConvWindowHandle);
      }
  
      public void SwitchToWall(IntPtr activeLyncConvWindowHandle)
      {
          this.BeginHold(DeviceLocation.Wall, activeLyncConvWindowHandle);
      }
  
      private Conversation GetLyncConversation()
      {
          Conversation conv = null;
          if (LyncClient.GetClient() != null)
          {
              conv = LyncClient.GetClient().ConversationManager.Conversations.FirstOrDefault();
          }
  
          return conv;
      }
  
      private void BeginHold(DeviceLocation targetLocation, IntPtr activeLyncConvWindowHandle)
      {
          AvSwitcher.IsSwitching = true;
  
          // make sure the class doesn't dispose of itself
          this.manualResetEvent = new ManualResetEvent(false);
  
          Conversation conv = this.GetLyncConversation();
          if (conv != null)
          {
              this.audioVideo = conv.Modalities[ModalityTypes.AudioVideo];
              ModalityState modalityState = this.audioVideo.State;
  
              if (modalityState == ModalityState.Connected)
              {
                  this.HoldCallAndThenDoTheSwitching(targetLocation, activeLyncConvWindowHandle);
              }
              else
              {
                  this.DoTheSwitching(targetLocation, activeLyncConvWindowHandle);
              }
          }
      }
  
      private void HoldCallAndThenDoTheSwitching(
          DeviceLocation targetLocation, 
          IntPtr activeLyncConvWindowHandle)
      {
          try
          {
              this.audioVideo.BeginHold(
                  this.BeginHold_callback,
                  new AsyncStateValues()
                  {
                      TargetLocation = targetLocation,
                      ActiveLyncConvWindowHandle = activeLyncConvWindowHandle
                  });
              this.manualResetEvent.WaitOne();
          }
          catch (UnauthorizedAccessException)
          {
              // the call is already on hold
              this.DoTheSwitching(targetLocation, activeLyncConvWindowHandle);
          }
      }
  
      private void BeginHold_callback(IAsyncResult ar)
      {
          if (ar.IsCompleted)
          {
              DeviceLocation targetLocation = ((AsyncStateValues)ar.AsyncState).TargetLocation;
              IntPtr activeLyncConvWindowHandle = 
                  ((AsyncStateValues)ar.AsyncState).ActiveLyncConvWindowHandle;
              this.DoTheSwitching(targetLocation, activeLyncConvWindowHandle);
          }
  
          Thread.Sleep(2000); // is this necessary
          this.audioVideo.BeginRetrieve(this.BeginRetrieve_callback, null);
      }
  
      private void DoTheSwitching(DeviceLocation targetLocation, IntPtr activeLyncConvWindowHandle)
      {
          DeviceLocationSvc.TargetDevices targetDevices = 
              this.deviceLocationSvc.GetTargetDevices(targetLocation);
  
          this.SwitchScreenUsingWinApi(targetDevices.Screen, activeLyncConvWindowHandle);
          this.SwitchVideoUsingLyncApi(targetDevices.VideoDevice);
          this.SwitchAudioUsingUIAutomation(
              targetDevices.MicName, 
              targetDevices.SpeakersName, 
              activeLyncConvWindowHandle);
  
          AvSwitcher.IsSwitching = false;
      }
  
      private void SwitchScreenUsingWinApi(Screen targetScreen, IntPtr activeLyncConvWindowHandle)
      {
          if (activeLyncConvWindowHandle != IntPtr.Zero)
          {
              WindowPosition wp = 
                  this.windowMovingSvc.GetTargetWindowPositionFromScreen(targetScreen);
              this.windowMovingSvc.MoveTheWindowToTargetPosition(activeLyncConvWindowHandle, wp);
          }
      }
  
      private void SwitchVideoUsingLyncApi(VideoDevice targetVideoDevice)
      {
          if (targetVideoDevice != null)
          {
              LyncClient.GetClient().DeviceManager.ActiveVideoDevice = targetVideoDevice;
          }
      }
  
      private void SwitchAudioUsingUIAutomation(
          string targetMicName, 
          string targetSpeakersName, 
          IntPtr activeLyncConvWindowHandle)
      {
          if (targetMicName != null &amp;&amp; targetSpeakersName != null)
          {
              AutomationElement lyncConvWindow = 
                  AutomationElement.FromHandle(activeLyncConvWindowHandle);
  
              AutomationElement lyncOptionsWindow =
                  this.uiAutomationSvc.OpenTheLyncOptionsWindowFromTheConvWindow(lyncConvWindow);
  
              this.uiAutomationSvc.SelectTheTargetMic(lyncOptionsWindow, targetMicName);
  
              this.uiAutomationSvc.SelectTheTargetSpeakers(lyncOptionsWindow, targetSpeakersName);
  
              this.uiAutomationSvc.InvokeOkayButton(lyncOptionsWindow);
          }
      }
  
      private void BeginRetrieve_callback(IAsyncResult ar)
      {
          this.audioVideo.EndRetrieve(ar);
          this.manualResetEvent.Set(); // allow the program to exit
      }
  
      private class AsyncStateValues
      {
          internal DeviceLocation TargetLocation { get; set; }
  
          internal IntPtr ActiveLyncConvWindowHandle { get; set; }
      }
  }
  </code></pre>