English 中文(简体)
How to get Excel version and macro security level
原标题:

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
//  ...softwaremicrosoftOffice  + VersionNumber +  .0ExcelSecurity 

(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?

最佳回答

Use

function GetExcelPath: string;
begin
  result :=   ;
  with TRegistry.Create do
    try
      RootKey := HKEY_LOCAL_MACHINE;
      if OpenKey( SOFTWAREMicrosoftWindowsCurrentVersionApp Pathsexcel.exe , false) then
        result := ReadString( Path ) +  excel.exe ;
    finally
      Free;
    end;
end;

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.

问题回答

using OLE CreateOLEObject( Excel.Application ))

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_ROOTExcel.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_ROOTExcel.Application.12 HKEY_CLASSES_ROOTExcel.Application.14

So, you have to enumerate all those branches with that name, dot, and number.

Note: the key HKEY_CLASSES_ROOTExcel.ApplicationCurVer 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_ROOTExcel.Application.15CLSID 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_ROOTCLSID{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~1MICROS~1Office15EXCEL.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.





相关问题
import of excel in SQL imports NULL lines

I have a stored procedure that imports differently formatted workbooks into a database table, does work on them then drops the table. Here is the populating query. SELECT IDENTITY(INT,1,1) AS ID ...

Connecting to Oracle 10g with ODBC from Excel VBA

The following code works. the connection opens fine but recordset.recordCount always returns -1 when there is data in the table. ANd If I try to call any methods/properties on recordset it crashes ...

Excel date to Unix timestamp

Does anyone know how to convert an Excel date to a correct Unix timestamp?

C# GemBox Excel Import Error

I am trying to import an excel file into a data table using GemBox and I keep getting this error: Invalid data value when extracting to DataTable at SourceRowIndex: 1, and SourceColumnIndex: 1. As ...

Importing from excel "applications" using SSIS

I am looking for any tips or resources on importing from excel into a SQL database, but specifically when the information is NOT in column and row format. I am currently doing some pre-development ...

热门标签