Ckeck if Excel is installed

Just starting out? Need help? Post your questions and find answers here.
User avatar
doctorized
Addict
Addict
Posts: 882
Joined: Fri Mar 27, 2009 9:41 am
Location: Athens, Greece

Ckeck if Excel is installed

Post by doctorized »

I make an app that uses vb script to read and save Excel files. I want to know if excel is installed, if not, my app will not try to read or write. If it is installed, I want to know the version to be able to save xlsx files if version is 2007 or higher. (Yes, a client may have 2003 or earlier version :evil:). I tried it via vbscript but some antivirus solutions prevent the script from running. So I tried to read the registry. When running:

Code: Select all

Procedure.s RegRead(Root, KeyPath.s, ValueName.s) 
	Protected valueData.s, hKey, size, type 

	If #ERROR_SUCCESS = RegOpenKeyEx_(Root, KeyPath, 0, #KEY_READ, @hKey)                 ; open with READ access rights 
		If #ERROR_SUCCESS = RegQueryValueEx_(hKey, ValueName, 0, @type, 0, @size)           ; get type and size 
			ValueData = Space(size)                                                           ; alloc memory 
			If #ERROR_SUCCESS = RegQueryValueEx_(hKey, ValueName, 0, 0, @valueData, @size)    ; get data to return 
			EndIf 
		EndIf
		RegCloseKey_(hKey) 
	EndIf
	ProcedureReturn valueData  ; return the result 
EndProcedure

Debug RegRead(#HKEY_LOCAL_MACHINE,"SOFTWARE\Microsoft\Office\16.0\Excel\InstallRoot","Path")
I get no return. That means I have no read access? (I have admin rights.)
Tried with #HKEY_CURRENT_USER:

Code: Select all

Procedure.s RegRead(Root, KeyPath.s, ValueName.s) 
	Protected valueData.s, hKey, size, type 

	If #ERROR_SUCCESS = RegOpenKeyEx_(Root, KeyPath, 0, #KEY_READ, @hKey)                 ; open with READ access rights 
		If #ERROR_SUCCESS = RegQueryValueEx_(hKey, ValueName, 0, @type, 0, @size)           ; get type and size 
			ValueData = Space(size)                                                           ; alloc memory 
			If #ERROR_SUCCESS = RegQueryValueEx_(hKey, ValueName, 0, 0, @valueData, @size)    ; get data to return 
			EndIf 
		EndIf
		RegCloseKey_(hKey) 
	EndIf
	ProcedureReturn valueData  ; return the result 
EndProcedure

Debug RegRead(#HKEY_CURRENT_USER,"SOFTWARE\Microsoft\Office\16.0\Excel","ExcelName")
and got "Excel" back.
My point is to do a check like:

Code: Select all

Procedure.s IsExcelInstalled()
	ExcelApp.s = RegRead(#HKEY_CLASSES_ROOT,"Excel.Application\CurVer","")	
	If ExcelApp = ""
		ProcedureReturn "No Excel found"; no version found
	Else;check which version
		If RegRead(#HKEY_LOCAL_MACHINE,"SOFTWARE\Microsoft\Office\16.0\Excel\InstallRoot","Path") <> ""
			ProcedureReturn "Excel 2016/2019/2021 found"
		ElseIf RegRead(#HKEY_LOCAL_MACHINE,"SOFTWARE\Microsoft\Office\15.0\Excel\InstallRoot","Path") <> ""
			ProcedureReturn "Excel 2013 found"
		ElseIf RegRead(#HKEY_LOCAL_MACHINE,"SOFTWARE\Microsoft\Office\14.0\Excel\InstallRoot","Path") <> ""
			ProcedureReturn "Excel 2010 found"
		ElseIf RegRead(#HKEY_LOCAL_MACHINE,"SOFTWARE\Microsoft\Office\12.0\Excel\InstallRoot","Path") <> ""
			ProcedureReturn "Excel 2007 found"
		ElseIf RegRead(#HKEY_LOCAL_MACHINE,"SOFTWARE\Microsoft\Office\11.0\Excel\InstallRoot","Path") <> ""
			ProcedureReturn "Excel 2003 found"
		Else
			ProcedureReturn "Excel older than 2003 found"
		EndIf
	EndIf
EndProcedure
Any idea why I get no return value with #HKEY_LOCAL_MACHINE?
Any better implementation?
BarryG
Addict
Addict
Posts: 4219
Joined: Thu Apr 18, 2019 8:17 am

Re: Ckeck if Excel is installed

Post by BarryG »

When I compile your code below, I get the following output even when NOT running as admin. In other words, "RegRead(#HKEY_LOCAL_MACHINE" is working here for me when run with limited rights. Your apps should always be able to read that hive when limited (just not write to it unless admin).

Code: Select all

Excel
Excel 2016/2019/2021 found

Code: Select all

Procedure.s RegRead(Root, KeyPath.s, ValueName.s) 
	Protected valueData.s, hKey, size, type 

	If #ERROR_SUCCESS = RegOpenKeyEx_(Root, KeyPath, 0, #KEY_READ, @hKey)                 ; open with READ access rights 
		If #ERROR_SUCCESS = RegQueryValueEx_(hKey, ValueName, 0, @type, 0, @size)           ; get type and size 
			ValueData = Space(size)                                                           ; alloc memory 
			If #ERROR_SUCCESS = RegQueryValueEx_(hKey, ValueName, 0, 0, @valueData, @size)    ; get data to return 
			EndIf 
		EndIf
		RegCloseKey_(hKey) 
	EndIf
	ProcedureReturn valueData  ; return the result 
EndProcedure

Debug RegRead(#HKEY_CURRENT_USER,"SOFTWARE\Microsoft\Office\16.0\Excel","ExcelName")
Procedure.s IsExcelInstalled()
	ExcelApp.s = RegRead(#HKEY_CLASSES_ROOT,"Excel.Application\CurVer","")	
	If ExcelApp = ""
		ProcedureReturn "No Excel found"; no version found
	Else;check which version
		If RegRead(#HKEY_LOCAL_MACHINE,"SOFTWARE\Microsoft\Office\16.0\Excel\InstallRoot","Path") <> ""
			ProcedureReturn "Excel 2016/2019/2021 found"
		ElseIf RegRead(#HKEY_LOCAL_MACHINE,"SOFTWARE\Microsoft\Office\15.0\Excel\InstallRoot","Path") <> ""
			ProcedureReturn "Excel 2013 found"
		ElseIf RegRead(#HKEY_LOCAL_MACHINE,"SOFTWARE\Microsoft\Office\14.0\Excel\InstallRoot","Path") <> ""
			ProcedureReturn "Excel 2010 found"
		ElseIf RegRead(#HKEY_LOCAL_MACHINE,"SOFTWARE\Microsoft\Office\12.0\Excel\InstallRoot","Path") <> ""
			ProcedureReturn "Excel 2007 found"
		ElseIf RegRead(#HKEY_LOCAL_MACHINE,"SOFTWARE\Microsoft\Office\11.0\Excel\InstallRoot","Path") <> ""
			ProcedureReturn "Excel 2003 found"
		Else
			ProcedureReturn "Excel older than 2003 found"
		EndIf
	EndIf
EndProcedure

Debug IsExcelInstalled()
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4991
Joined: Sun Apr 12, 2009 6:27 am

Re: Ckeck if Excel is installed

Post by RASHAD »

Use the next for both Windows x86,x64

Code: Select all

Procedure.s RegRead(Root, KeyPath.s, ValueName.s) 
	Protected valueData.s, hKey, size, type 

	If #ERROR_SUCCESS = RegOpenKeyEx_(Root, KeyPath, 0, #KEY_QUERY_VALUE|#KEY_ENUMERATE_SUB_KEYS|#KEY_WOW64_64KEY, @hKey)                 ; open with READ access rights 
		If #ERROR_SUCCESS = RegQueryValueEx_(hKey, ValueName, 0, @type, 0, @size)           ; get type and size 
			ValueData = Space(size)                                                           ; alloc memory 
			If #ERROR_SUCCESS = RegQueryValueEx_(hKey, ValueName, 0, 0, @valueData, @size)    ; get data to return 
			EndIf 
		EndIf
		RegCloseKey_(hKey) 
	EndIf
	ProcedureReturn valueData  ; return the result 
EndProcedure

Egypt my love
Post Reply