web-dev-qa-db-fra.com

Comment résoudre cette exception System.IO.FileNotFoundException

  • L'erreur ne survient qu'en production (pas en débogage).
  • L'erreur ne se produit que lors de la première application exécutée après la connexion à Windows. 
  • L'erreur se produit lorsque nous cliquons sur BtnUseDesktop et déclenchons ainsi l'événement BtnUseDesktop_Click (ci-dessous).
  • La pile de l'Observateur d'événements commence par la méthode The.Application.Name.Main () ...
  • mais notre code n'a pas cette méthode (c'est une application WPF).

Observateur d'événements

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

L'AvSwitcher dans lequel le clic est appelé

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

Je déteste signaler l'évidence, mais System.IO.FileNotFoundException signifie que le programme n'a pas trouvé le fichier que vous avez spécifié. Vous devez donc vérifier quel fichier votre code recherche en production. 

Pour voir quel fichier votre programme recherche en production (regardez la propriété FileName de l'exception), essayez les techniques suivantes:

Ensuite, regardez le système de fichiers sur la machine et voyez si le fichier existe. Le cas le plus probable est qu'il n'existe pas.

7
mason

Je suis tombé sur une situation similaire après la publication d'une application ClickOnce et l'un de mes collègues d'un autre domaine a signalé l'échec de son lancement.

Pour savoir ce qui se passait, j'ai ajouté une instruction try catch dans la méthode MainWindow en tant que @BradleyDotNET, mentionnée dans un commentaire sur le message d'origine, puis publiée à nouveau. 

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

Ensuite, mon collègue m'a signalé le détail de l'exception et il s'agissait d'une référence manquante d'un fichier DLL de framework tiers.

Ajout de la référence et du problème résolu.

3
usefulBee

J'ai été induit en erreur par cette erreur plus d'une fois. Après avoir passé des heures à googler, à mettre à jour les paquets de nugets, à vérifier les versions, puis après avoir utilisé une solution entièrement mise à jour, je me suis rendu compte d'une raison d'erreur parfaitement valide et plus simple.

S'il s'agit d'une intronisation par thread (par exemple, UI Dispatcher.Invoke), une exception System.IO.FileNotFoundException est levée si la DLL (fichier) du gestionnaire de thread ne parvient pas à être renvoyée. Donc, si votre thread principal de l'interface utilisateur A appelle le gestionnaire de threads système dll B et que B appelle votre code de thread C, pas de retour, et A blâme uniquement B avec FileNotFoundException pour être perdu ...

Avant de descendre le chemin de la version DLL ... Vérifiez plus près de chez vous et vérifiez que le code de votre thread ne jette pas.

2
Russ Ebbing

Vérifiez soigneusement toutes les références

  • La version reste la même sur la machine cible et la machine locale
  • Si Assembly est référencé à partir de GAC, assurez-vous que la version appropriée est chargée.

Pour moi, nettoyer toute la solution en supprimant manuellement, mettre à jour (supprimer et ajouter) de nouvelles références avec la version synchronisée avec la machine cible, puis créer avec les options Copie locale> Faux pour les assemblages GAC résout le problème.

0
vCillusion