如何获取Excel版本和宏安全级别
Microsoft 最近破解了我们长期以来(并由他们官方推荐)的代码来读取 Excel 版本及其当前的 omamacro 安全级别。
曾经有效的:(
// Get the program associated with workbooks, e.g. "C:\Program Files\...\Excel.exe"
SHELLAPI.FindExecutable( 'OurWorkbook.xls', ...)
// Get the version of the .exe (from it's Properties...)
WINDOWS.GetFileVersionInfo()
// Use the version number to access the registry to determine the security level
// '...\software\microsoft\Office\' + VersionNumber + '.0\Excel\Security'
我总是觉得好笑的是,安全级别多年来一直存在于不安全的注册表项中......)
在 Office 2010 中,.xls 文件现在与“Microsoft Application Virtualization DDE Launcher”或 sftdde.exe 关联。这个exe的版本号显然不是Excel的版本。
我的问题:
除了实际启动 Excel 并查询其版本和安全级别(使用 OLE CreateOLEObject('Excel.Application'))之外,是否有一种更干净、更快或更可靠的方法来执行此操作,并且适用于从 Excel 2003 开始的所有版本?
Microsoft has recently broken our longtime (and officially recommended by them) code to read the version of Excel and its current omacro security level.
What used to work:
// Get the program associated with workbooks, e.g. "C:\Program Files\...\Excel.exe"
SHELLAPI.FindExecutable( 'OurWorkbook.xls', ...)
// Get the version of the .exe (from it's Properties...)
WINDOWS.GetFileVersionInfo()
// Use the version number to access the registry to determine the security level
// '...\software\microsoft\Office\' + VersionNumber + '.0\Excel\Security'
(I was always amused that the security level was for years in an insecure registry entry...)
In Office 2010, .xls files are now associated with "“Microsoft Application Virtualization DDE Launcher," or sftdde.exe. The version number of this exe is obviously not the version of Excel.
My question:
Other than actually launching Excel and querying it for version and security level (using OLE CreateOLEObject('Excel.Application')), is there a cleaner, faster, or more reliable way to do this that would work with all versions starting with Excel 2003?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
用于
获取 excel.exe 文件的完整文件名。然后照常使用
GetFileVersionInfo
。据我所知,这种方法永远有效。
Use
to get the full file name of the excel.exe file. Then use
GetFileVersionInfo
as usual.As far as I know, this approach will always work.
您可以使用此函数使用的同一注册表位置来获取已安装的 Excel 版本。
基本上,您必须克隆该函数注册表代码的很大一部分。
您可以通过 Microsoft Process Monitor 等工具监视该函数调用,也可以准确了解 Windows 如何查找已安装的 Excel,然后以完全相同的方式执行此操作。
您必须打开
HKEY_CLASSES_ROOT\
处的注册表并枚举名称以“Excel.Application”开头的所有分支。例如,在我的工作站上,我只安装了 Excel 2013,并且对应于 HKEY_CLASSES_ROOT\Excel.Application.15
但在我的另一个工作站上,我安装了 Excel 2003 和 Excel 2010,在这两个工作站中测试不同的 XLSX 实现,所以我有两个注册表项。
HKEY_CLASSES_ROOT\Excel.Application.12
HKEY_CLASSES_ROOT\Excel.Application.14
因此,您必须枚举具有该名称、点和编号的所有分支。
注意:键 HKEY_CLASSES_ROOT\Excel.Application\CurVer 的名称为“默认”Excel,但当安装了多个 Excel 时,“默认”的含义是不明确的。如果您不在乎,您可以采用该默认值,或者您可以根据自己的想法决定选择什么,例如您想要最大的 Excel 版本还是最小版本或其他版本。
然后,对于每个特定的 Excel 分支,您应该读取其 CLSID 子分支的默认键。
就像
HKEY_CLASSES_ROOT\Excel.Application.15\CLSID
的 nil-named 键等于{00024500-0000-0000-C000-000000000046}
- 将该索引提取到字符串变量。然后进行第二次搜索 - 进入名为
HKEY_CLASSES_ROOT\CLSID\{00024500-0000-0000-C000-000000000046}\LocalServer
的分支(使用获取的索引)如果该分支存在 - 获取 nil - 命名的“默认键”值,以获得类似
C:\PROGRA~1\MICROS~1\Office15\EXCEL.EXE /automation
最后的结果是命令行。它以文件名开头(在此示例中未加引号,但可以用引号引起来),后面是可选的命令行。
您不需要命令行,因此您必须提取初始命令行,无论是否带引号。
然后你必须检查是否存在这样的exe文件。如果是,您可以启动它,如果没有,请检查注册表中是否有其他 Excel 版本。
you can get installed Excel versions by using the same registry place, that this function uses.
Basically you have to clone a large part of that function registry code.
You can spy on that function call by tools like
Microsoft Process Monitor
too see exactly how does Windows look for installed Excel - and then to do it exactly the same way.You have to open registry at
HKEY_CLASSES_ROOT\
and enumerate all the branches, whose name starts with "Excel.Application."For example at this my workstation I only have Excel 2013 installed, and that corresponds to HKEY_CLASSES_ROOT\Excel.Application.15
But on my another workstation I have Excel 2003 and Excel 2010 installed, testing different XLSX implementations in those two, so I have two registry keys.
HKEY_CLASSES_ROOT\Excel.Application.12
HKEY_CLASSES_ROOT\Excel.Application.14
So, you have to enumerate all those branches with that name, dot, and number.
Note: the key HKEY_CLASSES_ROOT\Excel.Application\CurVer would have name of "default" Excel, but what "default" means is ambiguous when several Excels are installed. You may take that default value, if you do not care, or you may decide upon your own idea what to choose, like if you want the maximum Excel version or minimum or something.
Then when for every specific excel branch you should read the default key of its CLSID sub-branch.
Like
HKEY_CLASSES_ROOT\Excel.Application.15\CLSID
has nil-named key equal to{00024500-0000-0000-C000-000000000046}
- fetch that index to string variable.Then do a second search - go into a branch named like
HKEY_CLASSES_ROOT\CLSID\{00024500-0000-0000-C000-000000000046}\LocalServer
( use the fetched index )If that branch exists - fetch the nil-named "default key" value to get something like
C:\PROGRA~1\MICROS~1\Office15\EXCEL.EXE /automation
The last result is the command line. It starts with a filename (non-quoted in this example, but may be in-quotes) and is followed by optional command line.
You do not need command line, so you have to extract initial commanlind, quoted or not.
Then you have to check if such an exe file exists. If it does - you may launch it, if not - check the registry for other Excel versions.