I want associate my .jar file to open with java.exe using Windows registry and have a doubt about how return the complete path of java.exe file ignoring java version installed on computer.
Ex:
in my case i have:
C:\Program Files\Java\jdk1.7.0_45\bin\java.exe
then how access java.exe file ignoring this part 1.7.0_45?
uses
Windows, Registry;
function GetProgramFilesDir: string;
var
reg: TRegistry;
begin
reg := TRegistry.Create;
try
reg.RootKey := HKEY_LOCAL_MACHINE;
reg.OpenKey('SOFTWARE\Microsoft\Windows\CurrentVersion', False);
Result := reg.ReadString('ProgramFilesDir');
finally
reg.Free;
end;
end;
procedure RegisterFileType(cMyExt, cMyFileType, ExeName: string);
var
reg: TRegistry;
begin
reg := TRegistry.Create;
try
reg.RootKey := HKEY_CURRENT_USER;
if reg.OpenKey('\Software\Classes\.jar', True) then
reg.WriteString('', 'MyAppDataFile');
if reg.OpenKey('\Software\Classes\MyAppDataFile', True) then
reg.WriteString('', 'myappname');
if reg.OpenKey('\Software\Classes\MyAppDataFile\DefaultIcon', True) then
reg.WriteString('', GetProgramFilesDir + '\Java\jdk1.7.0_45\bin\java.exe');
if reg.OpenKey('\Software\Classes\MyAppDataFile\shell\open\command', True)
then
reg.WriteString('', GetProgramFilesDir + '\Java\jdk1.7.0_45\bin\java.exe "%1"');
finally
reg.Free;
end;
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, 0, 0);
end;
Don't use the Registry to discover the path to system folders, like Program Files
. Use SHGetFolderPath()
or SHGetKnownFolderPath()
instead, eg:
function GetProgramFilesDir: string;
var
path: array[MAX_PATH] of Char;
begin
if SHGetFolderPath(0, CSIDL_PROGRAM_FILES, 0, SHGFP_TYPE_CURRENT, path) = S_OK then
Result := IncludeTrailingPathDelimiter(path)
else
Result := '';
end;
function GetProgramFilesDir: string;
var
path: PChar;
begin
if SHGetKnownFolderPath(FOLDERID_ProgramFiles, 0, 0, path) = S_OK then
begin
try
Result := IncludeTrailingPathDelimiter(path);
finally
CoTaskMemFree(path);
end;
end else
Result := '';
end;
That being said, to get the current installed path of java.exe
, there are a few options you can try:
check if the %JAVA_HOME%
environment variable is set.
check the HKLM\SOFTWARE\JavaSoft\Java Runtime Environment\<version>
Registry key for a JavaHome
value (there may be multiple <version>
subkeys!).
search the %PATH%
environment variable for any listed folder that has java.exe
in it (there may be multiple folders!). You can parse the %PATH%
yourself manually, or you can use SearchPath()
with its lpPath
parameter set to NULL (if you only care about the first copy of java.exe
found).
function GetJavaPathViaEnvironment: string;
begin
Result := GetEnvironmentVariable('JAVA_HOME');
if Result <> '' then
begin
Result := IncludeTrailingPathDelimiter(Result) + 'bin' + PathDelim + 'java.exe';
// if not FileExists(Result) then Result := '';
end;
end;
function GetJavaPathViaRegistry: string;
const
JAVA_KEY: string = '\SOFTWARE\JavaSoft\Java Runtime Environment\';
Wow64Flags: array[0..2] of DWORD = (0, KEY_WOW64_32KEY, KEY_WOW64_64KEY);
var
reg: TRegistry;
s: string;
i: integer;
begin
Result := '';
reg := TRegistry.Create;
try
reg.RootKey := HKEY_LOCAL_MACHINE;
for i := Low(Wow64Flags) to High(Wow64Flags) do
begin
reg.Access := (reg.Access and not KEY_WOW64_RES) or Wow64Flags[i];
if reg.OpenKeyReadOnly(JAVA_KEY) then
begin
s := reg.ReadString('CurrentVersion');
if s <> '' then
begin
if reg.OpenKeyReadOnly(s) then
begin
s := reg.ReadString('JavaHome');
if s <> '' then
begin
Result := IncludeTrailingPathDelimiter(s) + 'bin' + PathDelim + 'java.exe';
// if not FileExists(Result) then Result := '' else
Exit;
end;
end;
end;
reg.CloseKey;
end;
end;
finally
reg.Free;
end;
end;
function GetJavaPathViaSearchPath: string;
var
path: array[0..MAX_PATH] of Char;
s: string;
len: DWORD;
begin
Result := '';
len := SearchPath(nil, 'java.exe', nil, Length(path), path, PPChar(nil)^);
if len <= Length(path) then
SetString(Result, path, len)
else
begin
repeat
SetLength(s, len);
len := SearchPath(nil, 'java.exe', nil, len, PChar(s), PPChar(nil)^);
until len <= Length(s);
SetString(Result, PChar(s), len);
end;
end;
function GetJavaPath: string;
begin
Result := GetJavaPathViaEnvironment;
if Result = '' then
Result := GetJavaPathViaRegistry;
if Result = '' then
Result := GetJavaPathViaSearchPath;
end;
Also, don't forget that paths with spaces must be wrapped in double-quotes. You can use Delphi's AnsiQuotedStr()
to help you with that, eg:
reg.WriteString('', AnsiQuotedStr(GetJavaPath, '"') + ' "%1"');