return如何忽略java版本安装的java.exe文件的完整路径?
How return the complete path of java.exe file ignoring java version installed?
我想关联我的 .jar 文件以使用 Windows 注册表以 java.exe 打开,并且对如何 return [=27] 的完整路径有疑问=] 文件忽略计算机上安装的 java 版本。
例如:
就我而言,我有:
C:\Program Files\Java\jdk1.7.0_45\bin\java.exe
那么如何访问 java.exe 文件而忽略这部分 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;
不要使用注册表来发现系统文件夹的路径,如 Program Files
。使用 SHGetFolderPath()
or SHGetKnownFolderPath()
代替,例如:
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;
也就是说,要获取 java.exe
的当前安装路径,您可以尝试以下几个选项:
检查是否设置了%JAVA_HOME%
环境变量。
检查 HKLM\SOFTWARE\JavaSoft\Java Runtime Environment\<version>
注册表项中的 JavaHome
值(可能有多个 <version>
子项!)。
在 %PATH%
环境变量中搜索任何列出的包含 java.exe
的文件夹(可能有多个文件夹!)。您可以自己手动解析 %PATH%
,也可以使用 SearchPath()
并将其 lpPath
参数设置为 NULL(如果您只关心找到的 java.exe
的第一个副本)。
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 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;
另外,不要忘记带空格的路径必须用双引号引起来。您可以使用 Delphi 的 AnsiQuotedStr()
来帮助您,例如:
reg.WriteString('', AnsiQuotedStr(GetJavaPath, '"') + ' "%1"');
我想关联我的 .jar 文件以使用 Windows 注册表以 java.exe 打开,并且对如何 return [=27] 的完整路径有疑问=] 文件忽略计算机上安装的 java 版本。
例如:
就我而言,我有:
C:\Program Files\Java\jdk1.7.0_45\bin\java.exe
那么如何访问 java.exe 文件而忽略这部分 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;
不要使用注册表来发现系统文件夹的路径,如 Program Files
。使用 SHGetFolderPath()
or SHGetKnownFolderPath()
代替,例如:
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;
也就是说,要获取 java.exe
的当前安装路径,您可以尝试以下几个选项:
检查是否设置了
%JAVA_HOME%
环境变量。检查
HKLM\SOFTWARE\JavaSoft\Java Runtime Environment\<version>
注册表项中的JavaHome
值(可能有多个<version>
子项!)。在
%PATH%
环境变量中搜索任何列出的包含java.exe
的文件夹(可能有多个文件夹!)。您可以自己手动解析%PATH%
,也可以使用SearchPath()
并将其lpPath
参数设置为 NULL(如果您只关心找到的java.exe
的第一个副本)。
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 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;
另外,不要忘记带空格的路径必须用双引号引起来。您可以使用 Delphi 的 AnsiQuotedStr()
来帮助您,例如:
reg.WriteString('', AnsiQuotedStr(GetJavaPath, '"') + ' "%1"');