如何解决此System.IO.FileNotFoundException

时间:2014-03-31 23:29:44

标签: c# wpf .net

  • 错误仅发生在生产中(不在调试中)。
  • 错误仅发生在Windows登录后的第一个应用程序上。
  • 当我们点击BtnUseDesktop并因此触发BtnUseDesktop_Click事件(如下)时会发生错误。
  • 事件查看器堆栈以The.Application.Name.Main()方法...
  • 开头
  • 但我们的代码没有该方法(它是WPF应用程序)。

事件查看器

 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));
}

Click事件调用的AvSwitcher

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; }
    }
}

4 个答案:

答案 0 :(得分:8)

我不想指出明显的,但System.IO.FileNotFoundException表示程序找不到您指定的文件。所以你需要做的是检查代码在生产中寻找的文件。

要查看您的程序在生产中查找的文件(查看异常的FileName属性),请尝试以下技术:

然后查看计算机上的文件系统并查看该文件是否存在。最有可能的情况是它不存在。

答案 1 :(得分:4)

我在发布ClickOnce应用程序后遇到了类似的情况,并且我在不同域名的一位同事报告说它无法启动。

为了找出发生了什么,我在MainWindow方法中添加了一个try catch语句,在原始帖子的一个评论中提到了@BradleyDotNET,然后再次发布。

public MainWindow()
{
    try
    {
        InitializeComponent();
    }
    catch (Exception exc)
    {
        MessageBox.Show(exc.ToString());
    }
}

然后我的同事向我报告了异常细节,它缺少对第三方框架dll文件的引用。

添加了参考和解决的问题。

答案 2 :(得分:2)

我多次被这个错误误导。花了几个小时进行谷歌搜索,更新nuget软件包,检查版本,然后坐在一个完全更新的解决方案之后,我重新认识到了错误的完全有效,更简单的原因。

如果在线程继承(例如UI Dispatcher.Invoke)中,如果线程管理器dll(文件)无法返回,则抛出System.IO.FileNotFoundException。因此,如果您的主UI线程A调用了系统线程管理器dll B,并且B调用了线程代码C,但是C由于某种不相关的原因(例如,在本例中为空引用)而抛出,那么C不会返回,B会返回不会返回,并且A只将FileNotFoundException怪B丢了...

在查找dll版本路径之前...靠近家检查并确认线程代码没有抛出。

答案 3 :(得分:0)

仔细检查所有参考文献

  • 版本在目标计算机和本地计算机上保持相同
  • 如果从GAC引用程序集,请确保加载了正确的版本
  

我通过手动删除来清理整个解决方案,再次使用与目标计算机同步的版本更新(删除和添加)引用,然后使用Copy Local>进行构建。 GAC程序集的False解决了这个问题。