Domanda

D'accordo, ecco l'affare ...

Ho un programma per Windows (XP) in .NET 2.0 (C #), che permette agli utenti di rinominare un dato file .pdf. (Il nome del file è "strutturalmente descrittiva", come si delinea semplice informazioni su ciò che è nel file stesso.) Sulla unica forma del programma, c'è un oggetto LinkLabel che permette all'utente di aprire il .pdf stesso, in modo che possano vedere quello che stanno rinominando.

Il trucco è che, quando l'utente effettua il cambiamento (s) appropriato e fa clic sul pulsante "Salva", voglio che la finestra di Acrobat che mostra il .pdf per chiudere, il salvataggio eseguito, un file "next" per essere recuperati , e una nuova finestra per immediatamente aperto mostrando il file successivo.

Ecco i frammenti di codice rilevanti:

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

Si noti nella KillViewer () che ci sia fondamentalmente un ciclo di lock-afferrare per assicurarsi che il programma non tenta di rinominare il file di lavoro fino a dopo il visualizzatore di PDF ha pienamente rilasciato il blocco.

Il problema è questo: a volte tutto questo funziona benissimo, e talvolta KillViewer rompe sulla chiamata CloseMainWindow (), con un InvalidOperationException, dettagli = "processo è terminato, quindi le informazioni richieste non sono disponibili.". Questo sarebbe abbastanza semplice, se non fosse per due cose ...

1: pdfView.HasExited = true

E

2: Il visualizzatore PDF dannatamente è ancora aperto !!!

Come nel mondo è possibile? C'è un comando processo dovrei usare per garantire i Chiude la finestra? Cordiali saluti, il programma riferimenti nulla al di fuori di entrambi i sistemi. * Spazi dei nomi, o internamente classe costruzione che anche in ultima analisi, di riferimento unico sistema. *.

Grazie.

È stato utile?

Soluzione 2

Dopo ulteriori indagini, credo di aver determinato che cosa stava succedendo.

Non ho particolare particolari del flusso di lavoro perché non riuscivo a riprodurre in modo affidabile la situazione. Dopo ulteriori tentativi, ho trovato due situazioni affidabili ...

  1. Clicca sul link più volte e quindi fare clic su Salva.
  2. Fare clic sul collegamento, chiudere la finestra di visualizzazione, e scegliere Salva.

In ciascuno di questi casi, il problema si riduceva al Processo puntato da PDFViewer diventando fuori sincronia con ciò che l'utente stava facendo.

  1. Se il collegamento è stato cliccato più volte, quindi lo spettatore attiva era su un processo non collegato con le procedure di PDFViewer, da qui la situazione apparentemente impossibile dettagliato sopra.

  2. Se il collegamento è stato cliccato e la finestra chiusa, la variabile PDFViewer rimarrebbe, lasciando un processo con HasExited = true.

La lezione portare a casa di tutto questo è la seguente: se si sta eseguendo un processo separato dall'interfaccia utente principale, assolutamente certi che si coprono ogni possibile situazione che potrebbe verificarsi con il processo esterno

.

Per la cronaca, Nick Guerrera merita punti per me dirigere verso gli ID di processo. Che alla fine risolto.

Altri suggerimenti

Prova a modificare ..

pdfView.Kill();
pdfView.WaitForExit();
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top