3

微软最近破解了我们长期以来(并由他们正式推荐)的代码,以读取 Excel 版本及其当前的 omacro 安全级别。

过去的工作:

// 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 开始​​的所有版本?

4

2 回答 2

4

采用

function GetExcelPath: string;
begin
  result := '';
  with TRegistry.Create do
    try
      RootKey := HKEY_LOCAL_MACHINE;
      if OpenKey('SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\excel.exe', false) then
        result := ReadString('Path') + 'excel.exe';
    finally
      Free;
    end;
end;

获取 excel.exe 文件的完整文件名。然后GetFileVersionInfo照常使用。

据我所知,这种方法总是有效的。

于 2010-08-17T21:53:50.340 回答
1

使用 OLE CreateOLEObject('Excel.Application'))

您可以使用此函数使用的相同注册表位置获取已安装的 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 命名的键等于 {00024500-0000-0000-C000-000000000046}- 将该索引获取到字符串变量。

然后进行第二次搜索 - 进入一个名为 like 的分支HKEY_CLASSES_ROOT\CLSID\{00024500-0000-0000-C000-000000000046}\LocalServer(使用获取的索引)

如果该分支存在 - 获取 nil 命名的“默认键”值以获得类似C:\PROGRA~1\MICROS~1\Office15\EXCEL.EXE /automation

最后一个结果是命令行。它以文件名开头(在此示例中未引用,但可能包含在引号中),后面是可选的命令行。您不需要命令行,因此您必须提取初始命令行,无论是否引用。

然后你必须检查这样的exe文件是否存在。如果是 - 您可以启动它,如果不是 - 检查其他 Excel 版本的注册表。

于 2017-05-04T17:43:57.993 回答