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

时间:2009-11-05 15:52:07

标签: delphi permissions registry

我使用Delphi编写的几个长期应用程序将其设置保留在注册表中。我已将HKEY_LOCAL_MACHINE用于“硬”设置(如配置首选项)和HKEY_CURRENT_USER用于“软”信息,例如窗口位置,MRU列表等。

现在我的用户告诉我,在非管理员(标准用户)模式下,应用程序不起作用。看,我发现当应用处于管理模式时,我无法读取放入HKEY_LOCAL_MACHINE的设置。

我有什么选择?我对标准模式以及它如何影响对注册表的访问几乎一无所知。任何信息赞赏。

6 个答案:

答案 0 :(得分:16)

您可以作为非管理员用户阅读HKLM;你不能写信给它。

构造时使用TRegistry.Create(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();这也有助于非管理员访问注册表区域。

答案 1 :(得分:7)

答案 2 :(得分:2)

此处没有人提到的另一件事是Vista& Win7(至少)。 在你的特定场景中它可能不是一个问题,但我认为无论如何我都会提到它,以防它是相关的 即使您的用户具有管理员权限,如果您的应用程序未在Vista / Win7上“提升”,您的应用程序仍然无法写入您认为的“真正的”HKLM密钥。它将被读取并写入只有特定用户看到的相应HKLM密钥的虚拟副本 通过“提升”,我的意思是你会在Vista / Win7上提示UAC提示。例如,在Vista / Win7上运行Regedit.exe,系统将提示您输入UAC提示符 如果您使用的是Vista / Win7,当您说无法读取以管理模式写入的键/值时,可能会出现这个问题。如果是这样,那将是因为您的应用程序在某个阶段编写了现在的虚拟化键/值;您的应用程序现在只会看到该键/值,即使管理员修改了“真实”值 正如其他人所说,您的应用不应该尝试写入HKLM。如果你觉得它确实需要写入HKLM,那么在Vista / Win7上你的选择是(并且这些选项也可以在XP上正常工作):

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

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

答案 3 :(得分:1)

我不赞成但会提及的一个选项是授予每个人(或定义的组等)访问密钥的权限。有多种方法可以做到这一点,JCL中有代码可以执行此操作,或者您可以使用Regedit。但是,如果你同意(对HKLM的特定分支),那么它将按你的意图运作。

答案 4 :(得分:1)

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

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

Windows Vista / 7 - 用户帐户控制

用户帐户控制是Windows Vista中的安全组件。 UAC使用户能够以非管理员(称为Windows Vista中的标准用户)和管理员身份执行常见任务,而无需切换用户,注销或使用“运行方式”。 为了帮助防止恶意软件无声地安装并导致计算机范围的感染,Microsoft开发了UAC功能。

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

默认情况下,所有进程都以标准用户身份启动 标准用户不能: 更改Program Files文件夹中的文件 更改Windows或System32文件夹中的文件 在HKLM \ Software下更改注册表 更改本地计算机的日期和时间 ......列表继续......

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

通过以编程方式编辑Windows注册表,使用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;

在Vista / 7上,如果运行该应用程序的用户没有管理员权限,则由于UAC,上述代码将失败!

伪造UAC权利 - 如何申请执行级别

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

以下是步骤:

使用以下内容创建XML文件:

 <?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”

将此文本文件命名为YourApplicationName.RC 使用命令行执行以下命令: brcc32 YourApplicationName.RC -foYourApplicationName.REC

这将创建一个名为YourApplicationName.REC

的新资源文件

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

最后构建您的应用程序 - 现在可以在Windows Vista上获得管理员权限了。 注意1:在上述步骤中,将“YourApplicationExeName”替换为您的实际应用程序名称。 注意2:上述步骤创建一个资源文件,存储在应用程序的EXE文件中。有关Delphi应用程序中的资源的更多信息。

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

中阅读更多内容

答案 5 :(得分:0)

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

选项a的问题是XP和Vista / W7之间文件夹安排的变化。我相信Vista加强了对CSIDL COMMON APPDATA的访问 - 如果内存服务,标准用户没有写访问权限。您可能必须将它们存储在您自己的文件夹中并自行安排访问权限。烦。

选项b的一个有趣问题是,现在企业环境中正在使用繁琐的小工具来爬行注册表并“纠正”他们认为错误的访问权限。我们尚未遇到使用这些产品的客户的问题,但我们知道它们存在。鉴于注册管理机构的表现,我们仍然倾向于采用修改后的HKLM方法,并将在可预见的未来继续这样做。