代码如下:
procedure TForm1.Button1Click(Sender: TObject);
var
  Reg:TRegistry;
  sList:TStringList;
  Key:string;
begin
  Key:='\System\CurrentControlSet\Enum';
  Reg:=TRegistry.Create();
  try
    Reg.RootKey:=HKEY_LOCAL_MACHINE;
    Reg.Access:=KEY_ALL_ACCESS;
    if Reg.OpenKey(Key,False) then
    begin
      sList:=TStringList.Create;
      try
        Reg.GetKeyNames(sList);
        ShowMessage(sList.Text);
      finally
        sList.Free;
      end;
    end
    else
      ShowMessage('失败');
  finally
    Reg.Free;
  end;
end;//总是显示‘失败’ 为何?
把    if Reg.OpenKey(Key,False) then 
改为 if Reg.OpenKeyReadOnly(Key) then
就可以,为什么?我的目的是要读写而不单单读,请高手赐教。

解决方案 »

  1.   

    是否有权限,WRITE和CREATE 一个KEY???
      

  2.   

    谢谢  jim138 这些我都试过了我是用的管理员登录的权限应该不是问题。在看如下代码只有 Key 和上面的不一样,就可以成功读取。
    只要把 Key中的层次缩短一层就可以。
    例如:  Key:='\System\CurrentControlSet';
    代码如下:procedure TForm1.Button1Click(Sender: TObject);
    var
      Reg:TRegistry;
      sList:TStringList;
      Key:string;
    begin
      Key:='\System\CurrentControlSet';
      Reg:=TRegistry.Create();
      try
        Reg.RootKey:=HKEY_LOCAL_MACHINE;
        Reg.Access:=KEY_ALL_ACCESS;
        if Reg.OpenKey(Key,False) then
        begin
          sList:=TStringList.Create;
          try
            Reg.GetKeyNames(sList);
            ShowMessage(sList.Text);
          finally
            sList.Free;
          end;
        end
        else
          ShowMessage('失败');
      finally
        Reg.Free;
      end;
    end;
      

  3.   

    忘了说,我用的操作系统是 XP 和 2003 Server 都不行。
      

  4.   

    '\System\CurrentControlSet\Enum'是否存在,你用
    OpenKey(const Key: String; CanCreate: Boolean):
    中的Cancreate指定为False是当Key不存在时不创建它。
      

  5.   

    谢谢  linzhengqun(风。爱的翔舞)  当然存在,:)
    你可以把我的代码拿下来试一下。
    这个键值每个人的机器都有。
      

  6.   

    而且我用 Regedit 打开就可以编辑,所以我很困惑,不知道问题出在哪里,是不是 M$ 对这一块注册表有什么限制啊?忘大家多多讨论,分不够另开。
      

  7.   

    //似乎真的是权限的问题,运行下面的代码吧
    var
      TempKey: HKey;
      Error: integer;
      lpMsgBuf:PChar;
    begin
      TempKey:= 0;
      Error:= RegOpenKeyEx(HKEY_LOCAL_MACHINE, 'System\CurrentControlSet\Enum', 0,
        KEY_ALL_ACCESS,TempKey);
      if Error = ERROR_SUCCESS then
        ShowMessage('成功')
      else begin
        lpMsgBuf:=StrAlloc(256*sizeof(char));
        FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, nil, Error, 0,
         lpMsgBuf, 256, nil);
        ShowMessage(lpMsgBuf);
        StrDispose(lpMsgBuf);
      end;
    end;
    得到的答案是拒绝访问,看来没有办法了。
      

  8.   

    OMG ,看来真是这个问题,真是的就这么被判死刑了吗?
      

  9.   

    出现这个问题的原因已查明,是注册表权限的问题,在注册表编辑器的菜单中可以设置某一项的访问权限。那么怎么样才能用程序来实现呢?有相关的 API 么,请高手赐教!
      

  10.   

    如果你不修改注册表,可以只读出来
    改这句:
    Reg.Access:=KEY_QUERY_VALUE;
    就可以了。
    如果要改注册表,那么只有修改注册表的权限了
      

  11.   

    再顶一下,有没有能用程序实现的高招。
    我自己现在是这么实现的,把我要改的项生成一个 Reg 文件
    再运行 Regedit 文件名 ,OMG,我自己都晕,界面很不爽,有两个提示,
    一个是是否加入注册表信息。
    一个是已经成功加入注册表。
    目的是达到了,但是,这多不爽啊,不是咱程序员的风格。
    有没有爽一点的,顶上来看看。
    谢谢 linzhengqun(风。爱的翔舞)  对此问题的关注,你一定有分:)
      

  12.   

    你可以看一下这个Blog里的方法:
    http://blog.csdn.net/freexploit/archive/2005/01/20/260331.aspx
    现在是上班时间,等晚上有时间再改成Delphi代码看看看。
      

  13.   

    谢谢 linzhengqun(风。爱的翔舞) 这点提示对我来说已经足够。代码我已经翻译完,见楼下,但是还有好多东西我不明白,只是时间问题。现在只有设置权限,没有恢复权限,总报错,所以我把它给去掉了,呵呵。
    代码我在楼下贴出,希望大家多多指点,看看是否有什么错误。再次感谢!linzhengqun(风。爱的翔舞) 有时间多多交流。兑现!
      

  14.   

    //翻译那段有点乱,因为实在搞不懂,所以大家凑合着看吧。-_-!
    procedure TForm1.Test();
    var
      Reg:TRegistry;
      sList:TStringList;
      Key:string;
    begin
      Key:='System\CurrentControlSet\Enum\USB\Vid_067b&Pid_2303';
      Reg:=TRegistry.Create();
      try
        Reg.RootKey:=HKEY_LOCAL_MACHINE;
        if Reg.OpenKey(Key,False) then
        begin
          sList:=TStringList.Create;
          try
            Reg.GetKeyNames(sList);
            ShowMessage(sList.Text);
          finally
            sList.Free;
          end;
        end
        else
          ShowMessage('失败');
      finally
        Reg.Free;
      end;
    end;procedure TForm1.Button1Click(Sender: TObject);
    var
      ObjectName:string;
      pOldDACL:PACL;
      pNewDACL:PACL;
      pSD:PSECURITY_DESCRIPTOR;
      ea:EXPLICIT_ACCESS;label CleanUP;begin
      ObjectName:='MACHINE\System\CurrentControlSet\Enum\USB\Vid_067b&Pid_2303';  //建立一个空的ACL;
      if (SetEntriesInAcl(0, nil, nil, pOldDACL)<>ERROR_SUCCESS) then Exit;
      if (SetEntriesInAcl(0, nil, nil, pNewDACL)<>ERROR_SUCCESS) then Exit;  //获取现有的ACL列表到OldDACL
      if(GetNamedSecurityInfo(PChar(ObjectName), SE_REGISTRY_KEY,
         DACL_SECURITY_INFORMATION,nil, nil,@pOldDACL, nil, pSD)<>ERROR_SUCCESS) then
      begin
        MessageBox(Handle,'指定的键不存在!','提示',MB_ICONINFORMATION);
        Exit;
      end;
      ZeroMemory(@ea,Sizeof(EXPLICIT_ACCESS));
      //设置用户名"Everyone"对指定的键有所有操作权到结构ea
      BuildExplicitAccessWithName(@ea,'Everyone',   // name of trustee
                                  GENERIC_ALL,     // type of access
                                  SET_ACCESS,      // access mode
                                  SUB_CONTAINERS_AND_OBJECTS_INHERIT); //让自健继承他的权限; inheritance mode  //合并结构ea和OldDACL的权限列表到新的NewDACL
      if(SetEntriesInAcl(1, @ea, nil, pNewDACL)<>ERROR_SUCCESS) then Goto CleanUp;
      //把新的ACL写入到指定的键
      SetNamedSecurityInfo(PChar(ObjectName),SE_REGISTRY_KEY,DACL_SECURITY_INFORMATION,
            nil, nil,pNewDACL, nil);  Test();  //恢复注册表的权限;
      BuildExplicitAccessWithName(@ea,'Everyone',
              GENERIC_READ,SET_ACCESS,NO_INHERITANCE); //让自键继承他的权限;  if (SetEntriesInAcl(1, @ea, nil, pOldDACL) <> ERROR_SUCCESS) then Goto CleanUp;
      //把旧的ACL写入到指定的键
      SetNamedSecurityInfo(PChar(ObjectName),SE_REGISTRY_KEY,
             DACL_SECURITY_INFORMATION,nil, nil, pOldDACL, nil);  CleanUp:
        if(pSD<>nil) then LocalFree(LongInt(pSD));
        if(pNewDACL<>nil) then LocalFree(LongInt(pNewDACL));
        if(pOldDACL<>nil) then LocalFree(LongInt(pOldDACL));
    end;
      

  15.   

    //恢复权限那段总报错,这是注释掉后的代码。
    procedure TForm1.Test();
    var
      Reg:TRegistry;
      sList:TStringList;
      Key:string;
    begin
      Key:='System\CurrentControlSet\Enum\USB\Vid_067b&Pid_2303';
      Reg:=TRegistry.Create();
      try
        Reg.RootKey:=HKEY_LOCAL_MACHINE;
        if Reg.OpenKey(Key,False) then
        begin
          sList:=TStringList.Create;
          try
            Reg.GetKeyNames(sList);
            ShowMessage(sList.Text);
          finally
            sList.Free;
          end;
        end
        else
          ShowMessage('失败');
      finally
        Reg.Free;
      end;
    end;procedure TForm1.Button1Click(Sender: TObject);
    var
      ObjectName:string;
      pOldDACL:PACL;
      pNewDACL:PACL;
      pSD:PSECURITY_DESCRIPTOR;
      ea:EXPLICIT_ACCESS;label CleanUP;begin
      ObjectName:='MACHINE\System\CurrentControlSet\Enum\USB\Vid_067b&Pid_2303';  //建立一个空的ACL;
      if (SetEntriesInAcl(0, nil, nil, pOldDACL)<>ERROR_SUCCESS) then Exit;
      if (SetEntriesInAcl(0, nil, nil, pNewDACL)<>ERROR_SUCCESS) then Exit;  //获取现有的ACL列表到OldDACL
      if(GetNamedSecurityInfo(PChar(ObjectName), SE_REGISTRY_KEY,
         DACL_SECURITY_INFORMATION,nil, nil,@pOldDACL, nil, pSD)<>ERROR_SUCCESS) then
      begin
        MessageBox(Handle,'指定的键不存在!','提示',MB_ICONINFORMATION);
        Exit;
      end;
      ZeroMemory(@ea,Sizeof(EXPLICIT_ACCESS));
      //设置用户名"Everyone"对指定的键有所有操作权到结构ea
      BuildExplicitAccessWithName(@ea,'Everyone',   // name of trustee
                                  GENERIC_ALL,     // type of access
                                  SET_ACCESS,      // access mode
                                  SUB_CONTAINERS_AND_OBJECTS_INHERIT); //让自健继承他的权限; inheritance mode  //合并结构ea和OldDACL的权限列表到新的NewDACL
      if(SetEntriesInAcl(1, @ea, nil, pNewDACL)<>ERROR_SUCCESS) then Goto CleanUp;
      //把新的ACL写入到指定的键
      SetNamedSecurityInfo(PChar(ObjectName),SE_REGISTRY_KEY,DACL_SECURITY_INFORMATION,
            nil, nil,pNewDACL, nil);  Test();
    {
      //恢复注册表的权限;
      BuildExplicitAccessWithName(@ea,'Everyone',
              GENERIC_READ,SET_ACCESS,NO_INHERITANCE); //让自键继承他的权限;  if (SetEntriesInAcl(1, @ea, nil, pOldDACL) <> ERROR_SUCCESS) then Goto CleanUp;
      //把旧的ACL写入到指定的键
      SetNamedSecurityInfo(PChar(ObjectName),SE_REGISTRY_KEY,
             DACL_SECURITY_INFORMATION,nil, nil, pOldDACL, nil);
    }
      CleanUp:
        if(pSD<>nil) then LocalFree(LongInt(pSD));
        if(pNewDACL<>nil) then LocalFree(LongInt(pNewDACL));
        if(pOldDACL<>nil) then LocalFree(LongInt(pOldDACL));
    end;