检测密码何时用于打开或关闭的Excel工作簿

检测密码何时用于打开或关闭的Excel工作簿,excel,passwords,openxml,vba,Excel,Passwords,Openxml,Vba,我需要从VBA本身中修改Excel工作簿,用户将指出要修改的工作簿,然后修改工作簿的副本并以新名称保存。这可以是已打开的工作簿,也可以是磁盘上已关闭的工作簿,我需要从2000年起支持所有工作簿类型(2000-2016、二进制、加载项、模板等)。我需要修改工作簿的内容以及其中的任何自定义UI(功能区xml)。这一切都必须在我无法控制的随机Excel安装中完成 我面临的问题是如何处理受密码保护的工作簿-加密的工作簿,即打开时的密码。我的代码需要能够处理这些问题,并且在理想情况下,将任何使用过的密码应

我需要从VBA本身中修改Excel工作簿,用户将指出要修改的工作簿,然后修改工作簿的副本并以新名称保存。这可以是已打开的工作簿,也可以是磁盘上已关闭的工作簿,我需要从2000年起支持所有工作簿类型(2000-2016、二进制、加载项、模板等)。我需要修改工作簿的内容以及其中的任何自定义UI(功能区xml)。这一切都必须在我无法控制的随机Excel安装中完成

我面临的问题是如何处理受密码保护的工作簿-加密的工作簿,即打开时的密码。我的代码需要能够处理这些问题,并且在理想情况下,将任何使用过的密码应用到保存的、更新的副本上

代码流程如下所示:

  • 让用户选择要修改的工作簿(通过表单)
  • 如果工作簿处于打开状态:
  • .SaveCopyAs将其保存到临时文件夹
  • 指向保存的副本以供进一步处理
  • 在第二个Excel实例中打开用户选择的文件(不可见)
  • 更新打开的临时副本的内容
  • 。将临时副本另存为不带密码的临时文件夹,然后将其关闭
  • 更新已关闭临时副本的自定义UI
  • 重新打开更新的临时副本,并使用原始工作簿上的任何密码再次将其另存为
  • 在上面的步骤2.1中,.SaveCopyAs将保存打开的工作簿,并对副本应用任何密码,这将导致步骤3在所有情况下都请求密码。我无法使用.SaveAs删除步骤2.1中的过程,因为这将导致最终无法打开打开的工作簿。这也只是一个半措施,因为它不能阻止关闭的文件发生同样的事情

    在这种情况下,当Excel要求用户输入密码(至少在Excel 2010中是这样)时,密码提示仅显示文件名和密码的编辑框,下面会弹出一个空的Excel窗口,这是一个丑陋的景象。它不允许我为第7步捕获输入的密码

    我认为我能做的最好的事情就是检测磁盘上关闭的工作簿何时被加密,并在尝试打开它之前显示我自己的密码提示。但如何做到这一点呢?这些是我能想到的选择

  • 当我使用
    工作簿.Open(Filename:=…)
    时,Excel会显示密码提示,我喜欢通过事先询问密码来避免密码提示
  • 当我使用
    工作簿.Open(文件名:=…,密码:=“notthepassword”)
    时,至少Excel不再显示密码提示,没有密码的工作簿可以打开,而那些通过密码的工作簿现在生成错误1004。但是,我不能据此推断需要密码,因为1004是Excel的“捕获所有错误”编号,并且我无法检查
    Err.Description
    是否有“错误密码”之类的内容,因为我不知道客户端上运行的Excel GUI语言。还有,;当加密文件也有工作簿结构保护时,显然Excel将不再以这种方式打开它们-我测试了这个,它确实可以与我的2010 Excel一起使用,但听到这个消息并不是很令人鼓舞
  • 忽略Excel要求通过的丑陋,阅读任何
    工作簿。之后PasswordXxx
    属性不会显示任何内容;它们在所有情况下都返回相同的值(工作簿上有密码或没有密码)
  • 对于OOXML文件(.xlsm/.xlsx等),我可以事先检查文件的zip内容是否存在两个文件“EncryptionInfo”和“EncryptedPackage”,这表明该文件已加密,但2000-2003(.xls)文件如何?在这些文件中使用的BIFF文件结构上有一个命令,要求检查工作簿流中的FilePass记录;虽然我知道我可以实现这一逻辑(比如现在不支持的),但我宁愿不:)(附带问题:微软什么时候在没有签署保密协议和跳过法律的情况下发布了这些细节?!)

  • 是否有人对我如何编写代码步骤7有任何见解。上面的工作,除了使用Excel的提示和在我的应用程序中添加一个键盘记录器之外?:)

    @Raystafarian:那篇帖子问了一个与我类似但不相同的问题,他的用例让他有了一个我没有的解决方法(我在上面的第2点也链接到了它)。或者你想指出一些关于工作簿保护问题的信息吗?i.c.w.用.Open提供密码?@Raystafarian:啊,好吧,你想指出的内容对我来说有点模糊:)