문제

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?

도움이 되었습니까?

해결책

Use

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;

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_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.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top