如何解决此System.IO.FileNotFoundException错误

12 浏览
0 Comments

如何解决此System.IO.FileNotFoundException错误

  • 该错误只在生产环境中发生(在调试中没有发生)。
  • 该错误只在Windows登录后的第一次应用程序运行时发生。
  • 当我们点击BtnUseDesktop并触发BtnUseDesktop_Click事件时,该错误发生(如下所示)。
  • 事件查看器堆栈从The.Application.Name.Main()方法开始...
  • 但我们的代码中没有这个方法(它是一个WPF应用程序)。

事件查看器

 应用程序:The.Application.Name.exe
框架版本:v4.0.30319
描述:由于未处理的异常,进程终止。
异常信息:System.IO.FileNotFoundException
堆栈:
   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; }
    }
}

0
0 Comments

在解决System.IO.FileNotFoundException的问题上,我曾经被误导过不止一次。花费了几个小时进行谷歌搜索、更新nuget包、版本检查,然后坐在一个完全更新的解决方案旁边,我重新意识到了产生这个错误的一个完全有效、更简单的原因。

如果在一个多线程的环境中(例如UI Dispatcher.Invoke),当线程管理器dll(文件)无法返回时,就会抛出System.IO.FileNotFoundException。所以,如果你的主UI线程A调用系统线程管理器dll B,而B调用你的线程代码C,但C由于一些不相关的原因(例如我遇到的空引用)而抛出异常,那么C就无法返回,B也无法返回,而A只会因为B丢失而责怪B抛出了FileNotFoundException。

在走上dll版本的路径之前...更仔细地检查一下你的线程代码是否抛出异常。

0
0 Comments

如何解决System.IO.FileNotFoundException问题

System.IO.FileNotFoundException意味着程序找不到指定的文件。因此,您需要检查代码在生产环境中要查找的文件。为了查看程序在生产环境中要查找的文件(查看异常的FileName属性),可以尝试以下技术:

1.写入调试日志(debug log);

2.使用Visual Studio Attach to Process;

3.使用Visual Studio Remote Debugging。

然后,查看计算机上的文件系统,看看文件是否存在。很可能的情况是文件不存在。

我将这个答案标记为正确答案,因为它引导我使用了"attach to process"。然后我编辑了答案,将"attach to process"作为生产调试选项。

“写入调试日志”是什么意思以及要写什么?

这意味着您需要存储一些记录,记录发生了什么以及调试时有用的相关信息。您可以自己开发日志记录解决方案,但强烈建议查看现有的日志库,如Serilog、NLog等。

这是否意味着无法从事件查看器提供的数据中找出缺失的文件?

这取决于事件查看器中的内容。我肯定不会依赖它的内容。将日志记录掌握在自己手中,这样您可以完全控制记录了哪些信息。

0
0 Comments

在发布一个ClickOnce应用程序后,我遇到了类似的情况,我的一个不同域的同事报告说它无法启动。为了找出问题所在,我在MainWindow方法中添加了一个try catch语句,正如原帖中的一条评论中提到的那样,然后再次发布。

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

然后我的同事向我报告了异常的详细信息,发现是一个第三方框架dll文件的引用丢失了。添加了引用后问题解决了。

0