如何在将文件上传到服务器之前检测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来确定该文件是否受密码保护。