代码之家  ›  专栏  ›  技术社区  ›  Brian Frost

非管理模式下的注册表访问

  •  6
  • Brian Frost  · 技术社区  · 16 年前

    我有几个用Delphi编写的长期应用程序,它们将设置保存在注册表中。我使用HKEY_LOCAL_MACHINE进行“硬”设置,如配置首选项,使用HKEY_CURRENT_USER进行“软”信息,如窗口位置、MRU列表等。

    6 回复  |  直到 16 年前
        1
  •  17
  •   Ken White    16 年前

    使用TRegistry。构造时创建(KEY_READ),并将RootKey设置为HKLM。

    var
      Reg: TRegistry;
    begin
      Reg := TRegistry.Create(KEY_READ)
      try
        Reg.RootKey := HKLM;
        // Read value here
      finally
        Reg.Free;
      end;
    end;
    

    您也可以使用TRegistry。打开特定注册表项时的OpenKeyReadOnly();这也有助于非管理员访问注册表区域。

        3
  •  2
  •   Community Mohan Dere    9 年前

    这里没有人提到的另一件事是Vista上的注册表虚拟化问题;Win7(至少)。 在你的特定场景中,这可能不是问题,但我想无论如何我都会提到它,以防它相关。
    即使您的用户拥有管理员权限,如果您的应用程序没有在Vista/Win7上“提升”运行,您的应用仍然无法写入您认为的“真实”HKLM密钥。它将被读写到只有特定用户才能看到的相应HKLM密钥的虚拟副本中。

    如果你使用的是Vista/Win7,当你说无法读取在管理模式下写入的键/值时,这可能就是你描述的问题。如果是这样,这是因为你的应用程序在某个阶段已经编写了现在虚拟化的密钥/值;即使管理员修改了“真实”值,您的应用程序现在也只能看到该键/值。

    • 根据此内容,向您的应用程序添加需要提升管理员权限的清单 example .
    • 将需要HKLM访问的功能拆分到一个单独的COM库中,并在需要时将其实例化为提升的COM对象。这更复杂,但是重构现有功能的合理方法。

    Here 这是另一个解决其中一些问题的SO问题。

        4
  •  1
  •   mj2008    16 年前

        5
  •  1
  •   NaN    13 年前

    从开发人员的角度来看,如果应用程序不是由管理员运行的,Windows的UAC可能会对Delphi应用程序的某些部分造成问题。其中一个操作是写入注册表数据库。

    您必须通过创建应用程序清单文件来“请求管理员权限”。...

    用户帐户控制是Windows Vista中的一个安全组件。UAC使用户能够以非管理员身份(在Windows Vista中称为标准用户)和管理员身份执行常见任务,而无需切换用户、注销或使用运行方式。

    从开发人员的角度来看,以下UAC功能很重要:

    更改Program files文件夹中的文件 更改HKLM\Software下的注册表 更改本地机器的日期和时间

    编程编辑注册表以在Windows启动时运行Delphi应用程序

    通过使用TRegistry对象以编程方式编辑Windows注册表,您可以在Windows启动时“自动”启动程序。

     procedure RunOnStartup(const sCmdLine: string; bRunOnce: boolean = false; Remove: Boolean = false) ;
     var
       sKey: string;
       Section: string;
     const
       ApplicationTitle = ”Your Application TITLE”;
     begin
       if (bRunOnce) then
         sKey := 'Once'
       else
         sKey := '';
    
       Section := 'Software\Microsoft\Windows\CurrentVersion\Run' + sKey + #0;
    
       with TRegIniFile.Create('') do
         try
           RootKey := HKEY_LOCAL_MACHINE;
           if Remove then
             DeleteKey(Section, ApplicationTitle)
           else
             WriteString(Section, ApplicationTitle, sCmdLine) ;
         finally
           Free;
         end;
     end;
    

    伪造UAC权限-如何请求执行级别

    即使运行上述代码的用户不是管理员,作为开发人员,您也可以用一种特殊的嵌入式资源来武装您的应用程序:应用程序清单文件。 拥有清单文件将确保Vista的UAC允许您的代码执行。

     <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
     <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0]
      <assemblyIdentity version="1.1.1.1"
       processorArchitecture="X86"
       name="YourApplicationExeName"
       type="win32"/>
      <description>elevate execution level</description>
      <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2]
      <security>
       <requestedPrivileges>
        <requestedExecutionLevel level="requireAdministrator" uiAccess="false"/>
       </requestedPrivileges>
      </security>
      </trustInfo>
     </assembly>
    

    将此XML文件命名为YourApplicationName.manifest 创建包含以下内容的文本文件: 1 24“YourApplicationName.manifest”

    使用命令行执行以下命令: brcc32您的应用程序名称。RC-foYourApplicationName。录像

    复制此YourApplicationName。将REC文件插入到应用程序的资源路径中。 将此资源文件包含到应用程序的DPR中,如下所示: {$R YourApplicationName.REC}

    注1:在上述步骤中,将“YourApplicationExeName”替换为您的实际应用程序名称。

    http://delphi.about.com/od/delphitips2009/qt/delphi-vista-registry-run-on-startup.htm

        6
  •  0
  •   Bob Moore    16 年前

    您的选项包括(a)在不需要管理员权限访问的位置使用INI/XML配置文件,或(b)使用SetACL(公共域)等工具修改HKLM中您自己的子项的安全性。