如何检测如果Word文档密码的文件上传到服务器之前保护?(How to detect if a Wo

2019-07-18 06:18发布

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

有没有一种方法,以确定是否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<DocumentProtection>();
     if (dp != null && dp.Enforcement == DocumentFormat.OpenXml.OnOffValue.FromBoolean(true))
     {
         return true;
     }
 }

是否有任何其他方式来确定呢?

Answer 1:

给这个代码一试:

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 n c r y p t e d P a c k a g e"))
            return true;

        return false;
    }

    // Unknown format.
    return false;
}


Answer 2:

要回答这个问题:

为了判断一个文件是密码保护,您将需要打开该文件在浏览器和处理它。 目前文件打开客户端的唯一机制就是通过HTML5的FileAPI这是没有得到普遍支持。 这意味着有这样做的没有可靠的方法。

现在,你可以在服务器上对文件进行测试,以确定它是否有密码保护或没有,要么把它扔掉或保存它取决于你的规则。

顺便说一句,你所提供的代码是服务器端代码。 只是修改它捕捉损坏的异常,并显示一条消息,有关文件是如何损坏或密码用你如何不允许密码保护的文件被上传一张纸条保护用户。



Answer 3:

以下是在.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 = ("Document Is Password Protected");
    //         else
    //             outcome.Text = ("Document Is NOT Password Protected");

        if (isProtected(noPW))
            outcome.Text = ("Document Is Password Protected");
        else
            outcome.Text = ("Document Is NOT Password Protected");
    }

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


    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using Microsoft.Office.Interop.Word;
    using System.Runtime.InteropServices;
    using Microsoft.Office.Interop.Word;


    namespace TestApp
    {
        public partial class TestForm : System.Web.UI.Page
        {

            protected void Page_Load(object sender, EventArgs e)
            {

            }
            public static bool isProtected(object filePath)
            {
                Application myapp = new Application();

                object pw = "thispassword";
                try
                {

                    // Trying this for Word document
                    myapp.Documents.Open(ref filePath, PasswordDocument: ref pw); // try open
                    myapp.Documents[ref filePath].Close();  // close it if it does open    
                }
                catch (COMException ex)
                {
                    if (ex.HResult == -2146822880) // Can't Open Doc Caused By Invalid Password
                        return true;
                    else
                        Console.WriteLine(ex.Message + "  " + ex.HResult);  // For debugging, have only tested this one document.
                }
                return false;
            }
        }

    }

至少在我的电脑上,我得到两个文件预期的输出,但是这不正是你所谓的代码的详尽测试。 此外,我试图上传使用FileUpload控件文件,我得到了COM错误“无法找到C:\ WINDOWS \ SYSTEM \ fileName.docx”,这让我感到困惑,只是因为上传的文件从我的桌面来了,但你大概知道为什么发生,你更熟悉ASP.NET比我。 无论哪种方式,这个代码只是一些尝试,希望帮助。



Answer 4:

像notme我不知道的方式来判断一个文件有密码之前获得上传文件的一部分,甚至保护,但接受了这个问题的答案,虽然在技术上是巨大的,是有点矫枉过正。

见检测密码保护的Word文件为一个更简单且快速的方法来测试文件是否受密码保护。

此外,对于那些寻找这个问题寻找VBA / S的解决方案,下面是版本在前,这是很容易适应了后者。 www.ozgrid.com/forum/showthread.php?t=148962。 虽然我会建议检查Err.Number的= 5408(什么得到了错误的密码抛出,当受保护),而不是用任何的Err.Number以确定该文件是密码保护。



文章来源: How to detect if a Word document is password protected before uploading the file to server?
标签: c# .net webforms