我正在尝试使用Delphi中的TRegistry组件将值写入HKLM注册表。

由于我在Windows 2000上以标准用户身份运行(或以XP作为标准用户身份,或者以Windows Vista作为标准用户身份,或者以Windows 7拥有标准用户身份)运行,因此我完全希望我将无法写入HKEY_LOCAL_MACHINE注册表的一部分:

reg := TRegistry.Create(KEY_WRITE);
try
   reg.Access := KEY_WRITE; //sure, set it again, why not
   reg.RootKey := HKEY_LOCAL_MACHINE;
   if not reg.OpenKey('\Software\Microsoft\SQMClient', True) then
      Exit;

   reg.WriteString('MachineId', s);
finally
   reg.Free;
end;

不幸的是,WriteString抛出了ERegistryException:
Failed to set data for 'MachineId`

这是完全可以预期的,这就是为什么我试图避免出现异常。我在CanWriteString中看不到任何TryWriteStringTRegistry

尝试写HKLM时如何不触发异常?

不言而喻的注意事项:
  • 如果用户实际上是管理员,则写操作应该能够成功
  • 将对WriteString的调用包装在try-except中:
    reg := TRegistry.Create(KEY_WRITE);
    try
      reg.RootKey := HKEY_LOCAL_MACHINE;
      if not reg.OpenKey('\Software\Microsoft\SQMClient', True) then
         Exit;
    
      try
         reg.WriteString('MachineId', s);
      except
         on E:ERegistryException do
            {nothing};
      end;
    finally
      reg.Free;
    end;
    

    不会阻止首先抛出异常。

  • 更新:从RTL来源:
    KEY_WRITE          = (STANDARD_RIGHTS_WRITE or
                            KEY_SET_VALUE or
                            KEY_CREATE_SUB_KEY) and not
                            SYNCHRONIZE;
    

    来自MSDN:

    最佳答案

    您无法使TRegistry表现出您想要的方式。没有TryXXX方法,也没有禁用异常的参数。您可以确定是这样,因为TRegistry方法不提供任何错误或状态代码。

    您将必须围绕Win32注册表API编写自己的包装器。

    顺便说一句,我同意您在评论中表达的观点,即TRegistry在这里缺乏功能。我们期望注册表操作失败,因此我们不必捕获异常即可处理。

    关于delphi - 尝试在标准用户上写入HKLM时如何不触发异常?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/10404564/

    10-11 23:09
    查看更多