Как вернуть полный путь к файлу java.exe, игнорируя установленную версию java? - PullRequest
0 голосов
/ 02 октября 2018

Я хочу связать мой файл .jar с java.exe, используя реестр Windows, и у меня возникли сомнения относительно того, как вернуть полный путь к файлу java.exe , игнорируя версию java, установленную на компьютере.

Пример:

в моем случае у меня есть:

C: \ Program Files \ Java \ jdk 1.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;

1 Ответ

0 голосов
/ 02 октября 2018

Не используйте реестр для обнаружения пути к системным папкам, например Program Files.Вместо этого используйте SHGetFolderPath() или 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"');
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...