Delphi读取Windows 11系统路径

问题描述 投票:0回答:1

我正在开发在 64 位 Windows 11 上运行的 Delphi 12 应用程序。我的应用程序需要从注册表中读取路径(用户路径和系统路径),并且我的应用程序可以读取用户路径,但不能读取系统路径。

我使用“工具”->“选项”->“清单”要求管理员权限才能执行该程序,当我运行该应用程序时,它会提示我授权管理员模式,所以我知道它的一部分正在工作。

我已经在互联网上搜索了好几天寻找解决方案,并且尝试了我能找到的所有选项(Embarcadero 的网站本周关闭,这使得所有这一切变得更加困难,因为我在那里找到了许多文章参考文档)并且每个此时,代码成功打开指定的键 (

SYSTEM\CurrentControlSet\Control\Session Manager\Environment
),但无法读取其中的任何属性(如
path
属性)。

我什至尝试使用该键下的所有属性填充

TStringList

我创建了一个示例应用程序来演示这一点,您可以在https://github.com/johnwargo/Path-Test-2024找到它。

procedure PopulateList(pathList: TListBox; source: String; rootKey: HKEY;
  regKey, regProperty: String);
var
  Reg: TRegistry;
  pathArray: Tarray<String>;
  msg, pathStr: String;

begin
  LogMessage(Format('Reading "%s" Path from "%s"', [source, regKey]));
  // Reg := TRegistry.Create(KEY_ALL_ACCESS);
  // Reg := TRegistry.Create(KEY_ALL_ACCESS OR KEY_WOW64_64KEY);
  // Reg := TRegistry.Create(KEY_EXECUTE);
  // Reg := TRegistry.Create(KEY_EXECUTE OR KEY_WOW64_64KEY);
  // Reg := TRegistry.Create(KEY_READ OR KEY_WOW64_32KEY);
  Reg := TRegistry.Create(KEY_READ OR KEY_WOW64_64KEY);
  // Reg := TRegistry.Create(KEY_WRITE OR KEY_WOW64_32KEY);
  // https://stackoverflow.com/questions/2666807/registry-readstring-method-is-not-working-in-windows-7-in-delphi-7
  // Reg := TRegistry.Create(KEY_ENUMERATE_SUB_KEYS);

  with Reg do begin
    rootKey := rootKey;
    Access := KEY_READ;
    LogMessage(Format('Opening key: %s', [regKey]));
    if Reg.KeyExists(regKey) then begin
      if OpenKeyReadOnly(regKey) then begin
        LogMessage('Key opened');
        if ValueExists(regProperty) then begin
          LogMessage(Format('Reading property %s', [regProperty]));
          pathStr := Readstring(regProperty);
          if Length(pathStr) > 0 then begin
            LogMessage('Path: ' + pathStr);
            pathArray := pathStr.Split([';'], TStringSplitOptions.ExcludeEmpty);
            pathList.Items.AddStrings(pathArray);
          end;
        end else begin
          msg := Format('%s Path property "%s" does not exist.',
            [source, regProperty]);
          LogMessage(msg);
          ShowMessage(msg);
        end;
        CloseKey;
      end else begin
        msg := Format('Getting %s Path and cannot open open: %s',
          [source, regKey]);
        LogMessage(msg);
        ShowMessage(msg);
      end;
    end;
  end;
end;

procedure TfrmMain.FormActivate(Sender: TObject);
begin
  PopulateList(UserPathList, 'User', HKEY_CURRENT_USER, 'Environment',
    pathProperty);
  PopulateList(SystemPathList, 'System', HKEY_LOCAL_MACHINE,
    'SYSTEM\CurrentControlSet\Control\Session Manager\Environment',
    pathProperty);
end;

经过一番尝试,我添加了以下代码:

KeyInfo: TRegKeyInfo;

Reg.GetKeyInfo(KeyInfo);
LogMessage('Number of Keys: ' + IntToStr(KeyInfo.NumSubKeys));
LogMessage('Number of Subkeys: ' + IntToStr(KeyInfo.NumSubKeys));
LogMessage('Number of Values: ' + IntToStr(KeyInfo.NumValues));

它不显示键、子键或值:

1/19/2024 5:25:52 PM Number of Keys: 0
1/19/2024 5:25:52 PM Number of Subkeys: 0
1/19/2024 5:25:52 PM Number of Values: 0

Ii 我再上一层(

SYSTEM\CurrentControlSet\Control\Session Manager\
),得到以下结果:

1/19/2024 5:25:52 PM Number of Keys: 1
1/19/2024 5:25:52 PM Number of Subkeys: 1
1/19/2024 5:25:52 PM Number of Values: 0

即使此时注册表有 10 个或更多键和值。

有人可以帮我理解我在这里做错了什么吗?我从 80 年代中期开始就是一名 TurboPascal 开发人员,从 1.0 版本开始我就是一名 Delphi 开发人员。我通常可以找到摆脱此类情况的出路,但此时我遇到了困难。 Windows 中的某些内容阻止了对这些值的访问。

windows delphi path registry
1个回答
0
投票

问题就在这里:

with Reg do begin
    rootKey := rootKey; // <-- HERE

没有更新

Reg.RootKey
属性,正如您所期望的那样。实际上,您是将
rootKey
变量 分配回自身。因此,
Reg.RootKey
属性保持其默认值
HKEY_CURRENT_USER
,这就是打开
Environment
HKEY_LOCAL_MACHINE
键失败的原因。

这是为什么你不应该使用

with
语句的经典论点!

© www.soinside.com 2019 - 2024. All rights reserved.