c# - C#OpenFileDialog打开包含单个文件的zip文件夹?

标签 c# wpf pdf encryption openfiledialog

我有一个应用程序,该应用程序当前为用户提供以下功能:使用File-> Open查看应用程序内部的PDF文件,使用Microsoft.Win32.OpenFileDialog浏览至PDF文件的位置,然后在< cc>在GUI中。

我正在创建System.Windows.Controls.WebBrowser并设置可以使用以下文件打开的文件扩展名:

/*Create Open File dialog */
        Microsoft.Win32.OpenFileDialog OFDlg = new Microsoft.Win32.OpenFileDialog();

        /*Set filter for file extension and default file extension */
        OFDlg.DefaultExt = ".pdf";
        OFDlg.Filter = "PDF Documents (.pdf)|*.pdf";


我现在想扩展它,以便用户可以打开一个包含单个PDF文档的ZIP文件夹,并以与我上面相同的方式显示该PDF文档。

我尝试更改过滤器以允许.zip文件,即

OFDlg.DefaultExt = ".pdf|.zip";
OFDlg.Filter = "PDF Documents (.pdf)|*.pdf|ZIP|*.zip";


但是当我浏览到OpenFileDialog中的.zip文件的位置时,不会显示.zip文件夹-仅显示普通文件夹和PDF文档(该目录中的其他文档,例如.doc和.xls不会显示在OpenFileDialog中)。

我之所以希望能够直接从.zip打开.zip文件的内容,而不是导航至该文件本身,是因为我可以向.zip添加公钥/私钥加密,以便其内容只能安全地读取。

我知道如果.zip包含多个文件,从理论上讲可能会出现问题,但是我打算将每个加密文件发送到其自己的zip文件夹中,因此可以假定用户尝试打开的任何zip文件都包含单个.pdf,仅此而已。

所以我的问题是:


如何使中的.zip文件夹可见?
如何选择该.zip文件夹自动打开并在我当前用于在GUI中显示PDF的OpenFileDialog中显示其内容(单个PDF文件)?


编辑1

我尝试将OpenFileDialog方法更改为以下代码:

/*Set filter for file extension and default file extension */
        OFDlg.DefaultExt = ".pdf";
        OFDlg.DefaultExt = ".zip";
        OFDlg.Filter = "PDF Documents (.pdf)|*.pdf";
        OFDlg.Filter = "ZIP Folders (.ZIP)|*.zip";


但是,当我现在运行我的应用程序并浏览到相同的位置时,尽管.zip文件夹现在显示在System.Window.Controls.WebBrowser中,但.pdf文件不再存在...并且如果我双击.zip文件夹,应用程序中断,并且在运行时收到运行时错误

PdfPanel.OpenFile(docFP);


其中说:


  MoonPdfLib.dll中发生了'System.AccessViolationException'类型的未处理异常
  
  附加信息:尝试读取或写入受保护的内存。这通常表明其他内存已损坏。


我想这与我用来读取无法处理.zip扩展名的PDF的MoonPDF库有关吗?

我该如何解决才能在ZIP内打开PDF?

编辑2

好的,因此,通过将功能移动到两种不同的方法中,我已经解决了只能查看PDF文件或.ZIP文件夹(不能同时看到)的问题-一种方法是直接从PDF的文件路径,另一个用于显示包含它的.ZIP文件夹路径中的PDF。

当前直接显示PDF的方法有效(本质上是我引用的第一部分代码中的代码)。但是,从ZIP中显示PDF的方法目前不起作用...

我了解此的原因-这是因为我正在将OpenFile()文件夹传递给OpenFileDialog方法...该方法的代码当前如下所示:

private void openZipMenuItem_click(object sender, RoutedEventArgs e)
    {
        Microsoft.Win32.OpenFileDialog OZipDlg = new Microsoft.Win32.OpenFileDialog();

        OZipDlg.DefaultExt = ".zip";
        OZipDlg.Filter = "ZIP Folder (.zip)|*.zip";

        Nullable<bool> result = OZipDlg.ShowDialog();

        if (result == true)
        {
            /*Open document */
            string filename = OZipDlg.FileName;
            //fnTextBox.Text = filename;
            zipFP = OZipDlg.FileName;
            /*browser.Navigate(docFP); ERF (27/05/2016 @ 0935) Comment this line- I want to use PdfPanel to open docFP, not browser */

            Console.WriteLine("Panel height: " + PdfPanel.ActualHeight);
            PdfPanel.OpenFile(zipFP);

        }
    }


当我尝试调用此函数以打开.zip时,出现运行时异常,内容为:


  AccessViolationException未处理
  
  MoonPdfLib.dll中发生了类型为'System.AccessViolationException'的未处理异常
  
  附加信息:尝试读取或写入受保护的内存。这通常表明其他内存已损坏。


我知道我无法在.zip(这是我从OpenFile使用的PdfPanel)中显示一个Zip文件夹,所以我知道在这里会出现异常。

如何将MoonPdfPanel的内容传递给对MoonPdfLibrary的调用,而不是将zipFP本身传递给它?

编辑3

好的,因此,当我打开代码时,我的代码当前正在从ZIP文件夹中成功提取PDF文件-我可以看到它已复制到我指定的目录中。我现在正在尝试使PDF自动显示在应用程序的PDF面板中-通过添加以下代码来完成此操作:

try{
    string extractPath = @"C:\Documents";
    using(ZipArchivev zip = ZipFile.Open(zipFP, ZipArchiveMode.Read))
        foreach(ZipArchiveEntry entry in zip.Entries){
            try{
                ZipFile.ExtractToDirectory(zipFP, extractPath);
                Console.WriteLine("zipFP: " + zipFP);
            }catch(System.IOException){
                Console.WriteLine("File already exists...");
            }
        }

        string ExtractedPDF = string.Concat(extractPath, zipFP);
        PdfPanel.OpenFile(ExtractedPDF);
}catch(AccessViolationException ex){
    Console.WriteLine("Can't display a zip in the PDF panel..." + ex.InnerException);
}


但是,当我的代码尝试执行PdfPanel.OpenFile()行时,出现一个异常:


  FileNotFoundException未处理| MoonPdfLib.dll中发生了类型为'System.IO.FileNotFoundException'的未处理异常


我知道发生这种情况是因为我试图在PDFPanel中显示的变量zipFP实际上保存了包含PDF的文件夹的路径,而不是PDF本身。我如何给它命名PDF文件,当我实际上不知道该PDF文件将被称为什么时候?

最佳答案

这是与您的请求类似的工作,代码背后的逻辑是:


仅在OpenFileDialog中显示zip和pdf文件
如果用户选择了pdf文件,则将其显示在面板中
如果用户选择了一个zip文件,请将OpenFileDialog的目录更改为该zip文件(像文件夹一样对其进行处理)


示例代码(工作代码...):

 OpenFileDialog ofd = new OpenFileDialog();
 ofd.Filter = "PDF files (.pdf)|*.pdf;*.zip";
 ofd.ShowDialog();

 //reopen OpenFileDialog if it is zip file. this part can be improved.
 if (ofd.FileName.EndsWith(".zip")) 
 {
     ofd.InitialDirectory = ofd.FileName;
     ofd.ShowDialog();
 }

 //if it's a PDF, note that you don't really need this check, 
 //as the only file can reache here will be a PDF, 
 //and it can be the temporary file that inside a zip. 
 if(ofd.FileName.EndsWith(".pdf"))
 {
    //show it in your PdfPanel
 }


根据您的新注释和添加的代码进行编辑。您需要将代码更改为以下内容,因为当前代码是该文件的错误目录:

try{
    string extractPath = @"C:\Documents";
    string ExtractedPDF ="";
    using(ZipArchivev zip = ZipFile.Open(zipFP, ZipArchiveMode.Read))
        foreach(ZipArchiveEntry entry in zip.Entries){
            try{
                ExtractedPDF= Path.Combine(extractPath, entry.FullName);
                entry.ExtractToFile(ExtractedPDF,true);

            }catch(System.IOException){
                Console.WriteLine("error during extraction...");
            }
        } 
        if( System.IO.File.Exists(ExtractedPDF))
        {
             PdfPanel.OpenFile(ExtractedPDF);
        }
}catch(AccessViolationException ex){
    Console.WriteLine("Can't display a zip in the PDF panel..." + ex.InnerException);
}

关于c# - C#OpenFileDialog打开包含单个文件的zip文件夹?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37593357/

相关文章:

c# - .NET SqlParameter 类 : will it truncate . 值字符串?

c# - EF6 - 在 SaveChanges() 之前截断字符串字段以避免数据库冲突

c# - CollectionViewSource with Sort 获取排序的项目

WPF 设计渲染速度极慢 Visual Studio 2008?有没有可以加快速度的调整?

pdf - 如何在iOS11的PDFKit中添加图片标注

java - 使用 Flying Saucer 和 CSS 进行分段页数统计

ruby-on-rails - PDFkit 在生成带有图像的 pdf 时挂起

c# - 是否可以强制更新接口(interface)?

c# - 使大型模型可观察

c# - 获取对 ASP.NET web.config customErrors 部分的引用