VALUE TYPE DATA "" REG_SZ "F:\Office\Office\EXCEL.EXE /automation" "LocalServer32" REG_MULTI_SZ "?0!!!gxsf(Ng]qF`H{LsEXCELFiles>xlT]jI{jf /automation"CheckServer() is interested in "F:\Office\Office\EXCEL.EXE /automation" and assumes that it is the FIRST entry. However, that is not always, on all machines, true. There is evidence that it was the SECOND entry, while the first entry was in that case the above mentioned second line. That line's value is of type REG_MULTI_SZ, which is not understood by the registry class. And also that value is not a file. The evidence has been found with Excel 2003. The registry was something like:
VALUE TYPE DATA "LocalServer32" REG_MULTI_SZ "?0!!!gxsf(Ng]qF`H{LsEXCELFiles>xlT]jI{jf /automation" "" REG_SZ "F:\Office\Office11\EXCEL.EXE /automation"CheckServer.prg has been modified by me and will now search for the entry that has an empty value name.
* CheckServer.PRG * Published in _Microsoft Office Automation with Visual FoxPro_, * Hentzenwerke Publishing, June, 2000. * www.hentzenwerke.com * Copyright 2000 by Tamar E. Granor and Della Martin All Rights Reserved * Improved version. 31/dec/2005 Peter de Valença * The value we're searching for is not always in aServerNameValues[2]. LPARAMETER cServerName LOCAL oRegistry, cClassID, cEXEName, lEXEExists, ; aClassIDValues, aClassIDValues, aServerNameValues, lnX IF VERSION() >= "Visual FoxPro 06" oRegistry = NewObject("Registry", HOME() + "FFC\Registry") ELSE SET PROCEDURE TO HOME() + "samples\classes\registry.prg" ADDITIVE oRegistry = CreateObject("Registry") ENDIF lEXEExists = .F. DECLARE aClassIDValues[1], aServerNameValues[1] WITH oRegistry * Find the CLSID of the server. First, look for * the Class's Key. IF .OpenKey(cServerName + "\CLSID") = 0 * The Class's Key is open, now enumerate its values .EnumKeyValues(@aClassIDValues) * The data portion of the first (only) value returned * is the CLSID. Find the LocalServer32 key for the CLSID IF .OpenKey("CLSID\" + aClassIDValues[1,2] + "\LocalServer32") = 0 * Enumerate the LocalServer32 values .EnumKeyValues(@aServerNameValues) * Most times the value we're looking for is in element 2, but * at some machines it can be in element 4. What we DO know is that * the preceeding element (1 or 3) will be the only one that is empty. cEXEName = "" * FOR lnX = 1 TO ALEN( aServerNameValues ) STEP 2 * IF EMPTY( aServerNameValues[ m.lnX ] ) && the value NAME ( = default = empty ) * cEXEName = aServerNameValues[m.lnX+1] && the value EXIT ENDIF NEXT * The value that's returned may have " -Automation" or " /Automation" or * " /AUTOMATION" & other trailing stuff at the end. Strip it off. IF ATC( "automation", m.cEXEName ) > 0 cEXEName = TRIM( LEFT(m.cEXEName, ATC("automation", m.cEXEName) - 2) ) ENDIF * Verify that the file exists lEXEExists = FILE(cEXEName) ENDIF ENDIF ENDWITH RETURN lEXEExists