2

さて、これが取引です...

.NET 2.0(C#)にWindows(XP)プログラムがあり、ユーザーは特定の.pdfファイルの名前を変更できます。(ファイル名は、ファイル自体の内容に関する簡単な情報をレイアウトするため、「構造的に説明的」です。)プログラムの唯一のフォームには、ユーザーが.pdf自体を開いて表示できるようにするLinkLabelオブジェクトがあります。彼らが名前を変更しているもの。

秘訣は、ユーザーが適切な変更を加えて[保存]ボタンをクリックすると、.pdfを表示するAcrobatウィンドウを閉じ、保存を実行し、「次の」ファイルを取得して、すぐに開く新しいウィンドウで、次のファイルが表示されます。

関連するコードスニペットは次のとおりです。

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

KillViewer()には、PDFビューアが完全にロックを解除するまで、プログラムが作業ファイルの名前を変更しようとしないようにするためのロック取得ループがあることに注意してください。

問題はこれです。これはすべてうまく機能する場合もあれば、KillViewerがCloseMainWindow()呼び出しで失敗し、InvalidOperationException、details = "プロセスが終了したため、要求された情報が利用できない場合もあります。" これは、2つのことがなければ、かなり簡単です...

1:pdfView.HasExited = true

2:とんでもないPDFビューアはまだ開いています!!!

これは世界でどのように可能ですか?ウィンドウを確実に閉じるために使用する必要があるプロセスコマンドはありますか?参考までに、プログラムはSystem。*名前空間、または最終的にSystem。*のみを参照する内部で構築されたクラスの外部には何も参照しません。

ありがとう。

4

2 に答える 2

0

さらに調査した結果、何が起こっているのかを特定できたと思います。

状況を確実に再現できなかったため、ワークフローの詳細については説明しませんでした。さらに試行を重ねた結果、信頼できる状況が 2 つ見つかりました...

  1. リンクを複数回クリックし、[保存] をクリックします。
  2. リンクをクリックし、ビューア ウィンドウを閉じて、[保存] をクリックします。

これらのケースのそれぞれで、問題は pdfViewer が指すプロセスがユーザーの操作と同期しなくなったことに要約されます。

  1. リンクが複数回クリックされた場合、アクティブなビューアは pdfViewer のプロセスに接続されていないプロセス上にあったため、上記で説明した一見不可能な状況です。

  2. リンクがクリックされてウィンドウが閉じられた場合、pdfViewer 変数が残り、HasExited = true のプロセスが残ります。

これらすべての教訓は次のとおりです。メインのユーザー インターフェイスとは別のプロセスを実行している場合は、外部プロセスで発生する可能性のあるすべての状況を確実にカバーしてください。

記録として、Nick Guerrera は、私にプロセス ID を教えてくれた点に値します。それは最終的にそれを解決しました。

于 2010-01-11T18:22:47.347 に答える
0

代わりにこれを試してください..

pdfView.Kill();
pdfView.WaitForExit();
于 2010-01-09T20:47:35.430 に答える