Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

  • The error only happens in production (not in debugging).
  • The error only happens on the first application run after Windows login.
  • The error occurs when we click BtnUseDesktop and thus fire the BtnUseDesktop_Click event (below).
  • The Event Viewer stack starts with the The.Application.Name.Main() method...
  • but our code does not have that method (it's a WPF application).

Event Viewer

 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()

BtnUseDesktop_Click

private void BtnUseDesktop_Click(object sender, RoutedEventArgs e)
{
    AvSwitcher switcher = new AvSwitcher();
    this.RunAsyncTask(() => 
        switcher.SwitchToDesktop(this.windowSyncSvc.ActiveLyncWindowHandle));
}

The AvSwitcher that the Click Event Calls Into

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 && 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; }
    }
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
224 views
Welcome To Ask or Share your Answers For Others

1 Answer

I hate to point out the obvious, but System.IO.FileNotFoundException means the program did not find the file you specified. So what you need to do is check what file your code is looking for in production.

To see what file your program is looking for in production (look at the FileName property of the exception), try these techniques:

Then look at the file system on the machine and see if the file exists. Most likely the case is that it doesn't exist.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...