Question

D'accord, voici l'affaire ...

J'ai un programme .NET 2.0 (C #) (Windows XP) qui permet aux utilisateurs de renommer un fichier .pdf donné. (Le nom de fichier est « structurellement descriptive », car il dispose d'informations simples sur ce qui est dans le fichier lui-même.) Sur la forme que du programme, il y a un objet LinkLabel qui permet à l'utilisateur d'ouvrir le .pdf lui-même, afin qu'ils puissent voir ce qu'ils renomme.

L'astuce est que, lorsque l'utilisateur effectue les changements appropriés (s) et clique sur le bouton « Enregistrer », je veux la fenêtre dans Acrobat .pdf pour fermer, la sauvegarde effectuée, un fichier « suivant » à récupérer et une nouvelle fenêtre immédiatement ouvert afficher ce fichier suivant.

Voici les extraits de code pertinents:

    private void OpenViewer()
    {
        // NOTE: pdfView is of type Process, in case you're not familiar with
        // Process.Start().
        pdfView = System.Diagnostics.Process.Start(lnkFile.Links[0].LinkData.ToString());
    }

    private bool KillViewer()
    {
        bool result = (pdfView != null);

        if (pdfView != null)
        {
            pdfView.CloseMainWindow();
            pdfView.Close();
            pdfView.Dispose();
            pdfView = null;
            GC.Collect();

            // Verify that the lock is available before you return, as returning basically says:
            // "Yup, the file's available."
            bool locked = false;
            StreamWriter sw = null;
            do
            {
                try
                {
                    sw = new StreamWriter(new FileStream(lnkFile.Links[0].LinkData.ToString(), FileMode.Open));
                    locked = false;
                }
                catch (Exception)
                {
                    locked = true;
                }
            } while (locked);

            sw.Dispose();
        }

        return result;
    }

    private void SomeButtonEvent
    {
        // Record whether a viewer was open in the first place.
        bool viewerActive = KillViewer(); 

        PerformFileLockingMethod();
        GetNextFile()

        if(viewerActive)
        {
            OpenViewer();
        }
    }

Avis dans KillViewer () qu'il ya essentiellement une boucle accaparement verrouillage pour vous assurer que le programme ne cherche pas à renommer le fichier de travail jusqu'à ce que le lecteur de pdf a complètement libéré le verrou.

Le problème est le suivant: parfois tout cela fonctionne à merveille, et parfois KillViewer tombe en panne sur l'appel CloseMainWindow (), avec un InvalidOperationException, les détails = « Le processus a quitté, de sorte que les informations demandées ne sont pas disponibles. ». Ce serait assez simple s'il n'y avait pas deux choses ...

1: pdfView.HasExited = true

2: Le spectateur reprisés pdf est toujours ouverte !!!

Comment dans le monde est-ce possible? Y at-il une commande de processus que je devrais utiliser pour assurer la fermeture du fenêtre? Pour votre information, les références de programme rien en dehors de ces deux systèmes. * Namespaces, ou en interne classe construite qui référence aussi en fin de compte système uniquement. *.

Merci.

Était-ce utile?

La solution 2

Après une enquête plus poussée, je pense que je suis déterminé à ce qui se passait.

Je n'ai pas détaillé les détails de workflow parce que je ne pouvais pas reproduire de façon fiable la situation. Après d'autres tentatives, j'ai trouvé deux situations fiables ...

  1. Cliquez sur le lien plusieurs fois et puis cliquez sur Enregistrer.
  2. Cliquez sur le lien, fermez la fenêtre de la visionneuse, puis cliquez sur Enregistrer.

Dans chacun de ces cas, le problème se résumait au processus pointé par PDFViewer devenir désynchronisés avec ce que l'utilisateur a fait.

  1. Si le lien a été cliqué plusieurs fois, le spectateur actif était un processus non connecté au processus de PDFViewer, d'où la situation semble impossible détaillée ci-dessus.

  2. Si le lien a été cliqué et la fenêtre fermée, la variable PDFViewer resterait, en laissant un processus avec HasExited = true.

La leçon de TAKE maison tout cela est la suivante: Si vous utilisez un processus distinct de l'interface utilisateur principale, assurez-vous ABSOLUMENT vous que vous couvrez toutes les situations possibles qui pourraient se produire avec le processus externe

.

Pour mémoire, Nick Guerrera mérite des points pour me diriger vers les ID de processus. En définitive, cela a résolu le problème.

Autres conseils

Essayez plutôt ..

pdfView.Kill();
pdfView.WaitForExit();
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top