如何在将文件上传到服务器之前检测Word文档是否受密码保护?

我正在一个网站上工作,它允许用户上传不同的文件格式。 我们需要限制用户上传受密码保护的文件。

有没有办法确定Microsoft Office文件(Word,Powerpoint和Excel)在上传文件之前是否受密码保护? 根据http://social.msdn.microsoft.com/Forums/en/oxmlsdk/thread/34701a34-f1d4-4802-9ce4-133f15039c69 ,我已实现以下内容,但它会抛出错误,说“文件包含损坏的数据” ,同时尝试打开受密码保护的文件。

using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(mem, false)) { DocumentProtection dp = wordDoc.MainDocumentPart.DocumentSettingsPart.Settings.GetFirstChild(); if (dp != null && dp.Enforcement == DocumentFormat.OpenXml.OnOffValue.FromBoolean(true)) { return true; } } 

还有其他方法可以确定吗?

尝试使用此代码:

 public static Boolean IsProtected(String file) { Byte[] bytes = File.ReadAllBytes(file); String prefix = Encoding.Default.GetString(bytes.Take(2).ToArray()); // Zip and not password protected. if (prefix == "PK") return false; // Office format. if (prefix == "ÐÏ") { // XLS 2003 if (bytes.Skip(0x208).Take(1).ToArray()[0] == 0xFE) return true; // XLS 2005 if (bytes.Skip(0x214).Take(1).ToArray()[0] == 0x2F) return true; // DOC 2005 if (bytes.Skip(0x20B).Take(1).ToArray()[0] == 0x13) return true; // Guessing if (bytes.Length < 2000) return false; // DOC/XLS 2007+ String start = Encoding.Default.GetString(bytes.Take(2000).ToArray()).Replace("\0", " "); if (start.Contains("E ncrypted P ackage")) return true; return false; } // Unknown format. return false; } 

回答这个问题:

为了判断文件是否受密码保护,您需要在浏览器中打开该文件并进行处理。 目前打开文件客户端的唯一机制是通过HTML5的FileAPI,这是普遍支持的。 这意味着没有可靠的方法来做到这一点。

现在,您可以测试服务器上的文件以确定它是否受密码保护,并根据您的规则将其丢弃或保存。

顺便提一下,您提供的代码是服务器端代码。 只需修改它以捕获损坏的exception,并向用户显示有关文件如何损坏或密码保护的消息,并附上有关如何不允许上载受密码保护的文件的说明。

以下是.aspx源文件

  Page Language="C#" AutoEventWireup="true" CodeBehind="TestForm.aspx.cs" Inherits="TestApp.TestForm" !DOCTYPE html PUBLIC Reference Page ="~/TestForm.aspx" // Note: Removed all HTML tags 
     protected void Upload_Click(object sender,EventArgs e)
     {
         String noPW =“C:\\ Users \\ David \\ Desktop \\ Doc1.docx”;
         String pwProtected =“C:\\ Users \\ David \\ Desktop \\ Test.docx”; 
     // if(isProtected(pwProtected))
     // outcome.Text =(“文档受密码保护”);
     //别的
     // outcome.Text =(“文档不受密码保护”);

         if(isProtected(noPW))
             outcome.Text =(“文档受密码保护”);
        其他
             outcome.Text =(“文档不受密码保护”);
     }

以下是文件后面的.aspx.cs代码


    使用系统;
    使用System.Collections.Generic;
    使用System.Linq;
    使用System.Web;
    使用System.Web.UI;
    使用System.Web.UI.WebControls;
    使用Microsoft.Office.Interop.Word;
    使用System.Runtime.InteropServices;
    使用Microsoft.Office.Interop.Word;


    命名空间TestApp
     {
         public partial class TestForm:System.Web.UI.Page
         {

             protected void Page_Load(object sender,EventArgs e)
             {

             }
             public static bool isProtected(object filePath)
             {
                应用程序myapp = new Application();

                 object pw =“thispassword”;
                尝试
                 {

                     //为Word文档尝试此操作
                     myapp.Documents.Open(ref filePath,PasswordDocument:ref pw);  //尝试打开
                     myapp.Documents [ref filePath] .Close();  //如果它打开就关闭它    
                 }
                 catch(COMException ex)
                 {
                     if(ex.HResult == -2146822880)//无法打开由无效密码引起的文档
                        返回true;
                    其他
                         Console.WriteLine(ex.Message +“”+ ex.HResult);  //对于调试,只测试了这一个文档。
                 }
                返回虚假;
             }
         }

     }

至少在我的计算机上,我得到了两个文件的预期输出,但这并不是你所谓的代码的详尽测试。 此外,我尝试使用FileUpload控件上传文件,我收到COM错误“无法找到C:\ Windows \ System \ fileName.docx”这让我感到困惑,因为上传的文件来自我的桌面,但是你可能知道为什么会这样,因为你比我更熟悉ASP.NET。 无论哪种方式,这个代码只是尝试一下,希望有所帮助。

就像notme一样,我不知道在上传部分文件之前判断一个文件是否受密码保护的方法,但这个问题的接受答案虽然技术上很好,但有点过分。

请参阅检测受密码保护的word文件,以获得更简单,更快速的方法来测试文件是否受密码保护。

此外,对于那些在VBA / S中寻找解决方案的人来说,以下是前者的版本,它很容易适应后者。 http://www.ozgrid.com/forum/showthread.php?t=148962。 虽然我建议检查err.number = 5408(在受保护的情况下使用错误密码抛出的内容),而不是使用任何err.number来确定该文件是否受密码保护。